implement vertical toolbar placement options
jump to
@@ -1,5 +1,10 @@
(Format: Year/Month/Day) Changes for 0.9.16: +*06/04/16: + * Vertical toolbar (Simon) + Toolbar.cc ToolbarItem.hh/cc IconbarTool.hh/cc IconButton.hh/cc + ClockTool.hh/cc ButtonTool.cc WorkspaceNameTool.hh/cc Container.cc + SystemTray.cc FbTk/TextButton.cc *06/04/14: * Fix type of last_release_time, affected double click functions on 64-bit platforms (sf.net #1467871, thanks davidhi) (Simon)
@@ -67,7 +67,7 @@ m_cache_pm = 0;
btn.setBackgroundColor(theme().texture().color()); } else { m_cache_pm = m_image_ctrl.renderImage(width(), height(), - theme().texture()); + theme().texture(), orientation()); btn.setBackgroundPixmap(m_cache_pm); } if (old_pm)@@ -79,7 +79,7 @@ m_cache_pressed_pm = 0;
btn.setPressedColor(static_cast<const ButtonTheme &>(theme()).pressed().color()); } else { m_cache_pressed_pm = m_image_ctrl.renderImage(width(), height(), - static_cast<const ButtonTheme &>(theme()).pressed()); + static_cast<const ButtonTheme &>(theme()).pressed(), orientation()); btn.setPressedPixmap(m_cache_pressed_pm); }
@@ -215,9 +215,13 @@
// + 2 to make the entire text fit inside std::string text(m_button.text().size() + 2, '0'); - int new_width = m_theme.font().textWidth(text.c_str(), text.size()); - if (new_width != m_button.width()) { - resize(new_width, m_button.height()); + unsigned int new_width = m_button.width(); + unsigned int new_height = m_button.height(); + translateSize(orientation(), new_width, new_height); + new_width = m_theme.font().textWidth(text.c_str(), text.size()); + translateSize(orientation(), new_width, new_height); + if (new_width != m_button.width() || new_height != m_button.height()) { + resize(new_width, new_height); resizeSig().notify(); }@@ -272,7 +276,7 @@ m_screen.imageControl().removeImage(m_pixmap);
if (m_theme.texture().usePixmap()) { m_pixmap = m_screen.imageControl().renderImage(width(), height(), - m_theme.texture()); + m_theme.texture(), orientation()); m_button.setBackgroundPixmap(m_pixmap); } else { m_pixmap = 0;@@ -291,3 +295,8 @@ m_button.setBorderWidth(m_theme.border().width());
m_button.setBorderColor(m_theme.border().color()); m_button.clear(); } + +void ClockTool::setOrientation(FbTk::Orientation orient) { + m_button.setOrientation(orient); + ToolbarItem::setOrientation(orient); +}
@@ -62,6 +62,9 @@ unsigned int width() const;
unsigned int height() const; unsigned int borderWidth() const; inline const std::string &timeFormat() const { return *m_timeformat; } + + void setOrientation(FbTk::Orientation orient); + private: void updateTime(); void update(FbTk::Subject *subj);
@@ -482,7 +482,8 @@ else {
int borderW = m_item_list.front()->borderWidth(); // there're count-1 borders to fit in with the windows // -> 1 per window plus end - unsigned int w = width(); + unsigned int w = width(), h = height(); + translateSize(m_orientation, w, h); if (w < (size()-1)*borderW) return 1; else
@@ -92,6 +92,7 @@ // no need to set new font if it's the same
if (&font == m_font) return; m_font = &font; + font.validOrientation(m_orientation); // load the orientation! } /// set bevel and redraw text
@@ -67,6 +67,7 @@
inline FbTk::Justify justify() const { return m_justify; } inline const std::string &text() const { return m_text; } inline FbTk::Font &font() const { return *m_font; } + inline FbTk::Orientation orientation() const { return m_orientation; } unsigned int textWidth() const; unsigned int textHeight() const; int bevel() const { return m_bevel; }
@@ -39,7 +39,6 @@ #include "FbTk/Command.hh"
#include "FbTk/RefCount.hh" #include "FbTk/Menu.hh" - #ifdef HAVE_CONFIG_H #include "config.h" #endif // HAVE_CONFIG_H@@ -241,13 +240,30 @@
if (m_use_pixmap && (hints->flags & IconPixmapHint) && hints->icon_pixmap != 0) { // setup icon window m_icon_window.show(); - int new_height = height() - 2*m_icon_window.y(); // equally padded - int new_width = new_height; - m_icon_window.resize((new_width>0) ? new_width : 1, (new_height>0) ? new_height : 1); + unsigned int w = width(); + unsigned int h = height(); + FbTk::translateSize(orientation(), w, h); + int iconx = 1, icony = 1; + unsigned int neww = w, newh = h; + if (newh > 2*icony) + newh -= 2*icony; + else + newh = 1; + neww = newh; + + FbTk::translateCoords(orientation(), iconx, icony, w, h); + FbTk::translatePosition(orientation(), iconx, icony, neww, newh, 0); + + neww = newh; + m_icon_window.moveResize(iconx, icony, neww, newh); m_icon_pixmap.copy(hints->icon_pixmap, DefaultDepth(display, screen), screen); m_icon_pixmap.scale(m_icon_window.width(), m_icon_window.height()); + // rotate the icon or not?? lets go not for now, and see what they say... + // need to rotate mask too if we do do this + m_icon_pixmap.rotate(orientation()); + m_icon_window.setBackgroundPixmap(m_icon_pixmap.drawable()); } else { // no icon pixmap@@ -259,6 +275,7 @@
if(m_use_pixmap && (hints->flags & IconMaskHint)) { m_icon_mask.copy(hints->icon_mask, 0, 0); m_icon_mask.scale(m_icon_pixmap.width(), m_icon_pixmap.height()); + m_icon_mask.rotate(orientation()); } else m_icon_mask = 0;@@ -304,4 +321,20 @@ else
FbTk::TextButton::drawText(1, y, drawable); } +bool IconButton::setOrientation(FbTk::Orientation orient) { + if (orientation() == orient) + return true; + + if (FbTk::TextButton::setOrientation(orient)) { + int iconx = 1, icony = 1; + unsigned int tmpw = width(), tmph = height(); + FbTk::translateSize(orient, tmpw, tmph); + FbTk::translateCoords(orient, iconx, icony, tmpw, tmph); + FbTk::translatePosition(orient, iconx, icony, m_icon_window.width(), m_icon_window.height(), 0); + m_icon_window.move(iconx, icony); + return true; + } else { + return false; + } +}
@@ -53,6 +53,8 @@
FluxboxWindow &win() { return m_win; } const FluxboxWindow &win() const { return m_win; } + bool setOrientation(FbTk::Orientation orient); + protected: void drawText(int x, int y, FbTk::FbDrawable *drawable_override); private:
@@ -695,17 +695,25 @@ updateSizing();
Pixmap tmp = m_focused_pm; Pixmap err_tmp = m_focused_err_pm; - unsigned int icon_width = m_icon_container.maxWidthPerClient(); + unsigned int icon_width, icon_height; + if (orientation() == FbTk::ROT0 || orientation() == FbTk::ROT180) { + icon_width = m_icon_container.maxWidthPerClient(); + icon_height = m_icon_container.height(); + } else { + icon_width = m_icon_container.width(); + icon_height = m_icon_container.maxWidthPerClient(); + } + if (!m_theme.focusedTexture().usePixmap()) { m_focused_pm = 0; m_focused_err_pm = 0; } else { m_focused_pm = m_screen.imageControl().renderImage(icon_width, - m_icon_container.height(), - m_theme.focusedTexture()); + icon_height, + m_theme.focusedTexture(), orientation()); m_focused_err_pm = m_screen.imageControl().renderImage(icon_width+1, - m_icon_container.height(), - m_theme.focusedTexture()); + icon_height, + m_theme.focusedTexture(), orientation()); } if (tmp)@@ -721,11 +729,11 @@ m_unfocused_pm = 0;
m_unfocused_err_pm = 0; } else { m_unfocused_pm = m_screen.imageControl().renderImage(icon_width, - m_icon_container.height(), - m_theme.unfocusedTexture()); + icon_height, + m_theme.unfocusedTexture(), orientation()); m_unfocused_err_pm = m_screen.imageControl().renderImage(icon_width+1, - m_icon_container.height(), - m_theme.unfocusedTexture()); + icon_height, + m_theme.unfocusedTexture(), orientation()); } if (tmp) m_screen.imageControl().removeImage(tmp);@@ -740,7 +748,7 @@ m_icon_container.setBackgroundColor(m_theme.emptyTexture().color());
} else { m_empty_pm = m_screen.imageControl().renderImage(m_icon_container.width(), m_icon_container.height(), - m_theme.emptyTexture()); + m_theme.emptyTexture(), orientation()); m_icon_container.setBackgroundPixmap(m_empty_pm); }@@ -768,7 +776,8 @@
// The last button is always the regular width bool wider_button = false; if (!m_icon_container.empty()) - wider_button = (button.width() != m_icon_container.back()->width()); + wider_button = (button.width() != m_icon_container.back()->width() || // height to cover both orients + button.height() != m_icon_container.back()->height()); if (button.win().isFocused()) { // focused texture m_icon_container.setSelected(m_icon_container.find(&button));@@ -968,3 +977,7 @@ if (current_button != 0)
renderButton(*current_button); } +void IconbarTool::setOrientation(FbTk::Orientation orient) { + m_icon_container.setOrientation(orient); + ToolbarItem::setOrientation(orient); +}
@@ -95,6 +95,7 @@ Mode mode() const { return *m_rc_mode; }
DeiconifyMode deiconifyMode() const { return *m_deiconify_mode; } WheelMode wheelMode() const { return *m_wheel_mode; } + void setOrientation(FbTk::Orientation orient); Container::Alignment alignment() const { return m_icon_container.alignment(); } private: /// @return button associated with window
@@ -213,11 +213,17 @@ m_window.show();
} unsigned int SystemTray::width() const { + if (orientation() == FbTk::ROT90 || orientation() == FbTk::ROT270) + return m_window.width(); + return m_clients.size()* (height() - 2 * m_theme.border().width()); } unsigned int SystemTray::height() const { - return m_window.height(); + if (orientation() == FbTk::ROT0 || orientation() == FbTk::ROT180) + return m_window.height(); + + return m_clients.size()* (width() - 2 * m_theme.border().width()); } unsigned int SystemTray::borderWidth() const {@@ -362,10 +368,12 @@ }
} void SystemTray::rearrangeClients() { - const unsigned int h = height(); + unsigned int w_rot0 = width(), h_rot0 = height(); const unsigned int bw = m_theme.border().width(); - int final_size = m_clients.size()*h + bw; - resize(final_size, h); + FbTk::translateSize(orientation(), w_rot0, h_rot0); + unsigned int trayw = m_clients.size()*h_rot0 + bw, trayh = h_rot0; + FbTk::translateSize(orientation(), trayw, trayh); + resize(trayw, trayh); update(0); // move and resize clients@@ -373,9 +381,13 @@ ClientList::iterator client_it = m_clients.begin();
ClientList::iterator client_it_end = m_clients.end(); int next_x = bw; for (; client_it != client_it_end; - ++client_it, next_x += h+bw) { - (*client_it)->moveResize(next_x, bw, h, h); - (*client_it)->sendConfigureNotify(next_x, bw, h, h); + ++client_it, next_x += h_rot0+bw) { + int x = next_x, y = bw; + translateCoords(orientation(), x, y, w_rot0, h_rot0); + translatePosition(orientation(), x, y, h_rot0, h_rot0, 0); + + (*client_it)->moveResize(x, y, h_rot0, h_rot0); + (*client_it)->sendConfigureNotify(x, y, h_rot0, h_rot0); } client_it = m_clients.begin();@@ -401,7 +413,7 @@ else {
if(m_pixmap) m_screen.imageControl().removeImage(m_pixmap); m_pixmap = m_screen.imageControl().renderImage(width(), height(), - m_theme.texture()); + m_theme.texture(), orientation()); m_window.setBackgroundPixmap(m_pixmap); }@@ -409,11 +421,7 @@ // "themereconfigure"
if (subject) { ClientList::iterator client_it = m_clients.begin(); ClientList::iterator client_it_end = m_clients.end(); - int next_x = 0; - const unsigned int h = height(); - const unsigned int b = m_theme.border().width(); - for (; client_it != client_it_end; - ++client_it, next_x += h - 2 * b) { + for (; client_it != client_it_end; ++client_it) { // maybe not the best solution (yet), force a refresh of the // background of the client
@@ -599,6 +599,8 @@ }
void Toolbar::setPlacement(Toolbar::Placement where) { // disable vertical toolbar + +/* switch (where) { case LEFTTOP: case LEFTCENTER:@@ -611,6 +613,7 @@ break;
default: break; } +*/ *m_rc_placement = where; int head_x = 0,@@ -626,6 +629,10 @@ head_w = screen().getHeadWidth(head);
head_h = screen().getHeadHeight(head); } + FbTk::Orientation was_orient = FbTk::ROT0; + if (!m_item_list.empty()) + was_orient = m_item_list.front()->orientation(); // all save orient (for rendering) + int bevel_width = theme().bevelWidth(); int border_width = theme().border().width();@@ -656,6 +663,8 @@
// So we get at least one pixel visible in hidden mode if (bevel_width <= border_width) bevel_width = border_width + 1; + + FbTk::Orientation orient = FbTk::ROT0; switch (where) { case TOPLEFT:@@ -703,7 +712,6 @@ m_shape->setPlaces(Shape::TOPRIGHT | Shape::TOPLEFT);
break; case BOTTOMCENTER: // default is BOTTOMCENTER - default: frame.x = head_x + (head_w - frame.width) / 2 - border_width; frame.y = head_y + head_h - frame.height - border_width*2; frame.x_hidden = frame.x;@@ -712,6 +720,7 @@ if (m_shape.get())
m_shape->setPlaces(Shape::TOPRIGHT | Shape::TOPLEFT); break; case LEFTCENTER: + orient = FbTk::ROT90; frame.x = head_x; frame.y = head_y + (head_h - frame.height)/2 - border_width; frame.x_hidden = frame.x - frame.width + bevel_width + border_width;@@ -720,6 +729,7 @@ if (m_shape.get())
m_shape->setPlaces(Shape::TOPRIGHT | Shape::BOTTOMRIGHT); break; case LEFTTOP: + orient = FbTk::ROT90; frame.x = head_x; frame.y = head_y; frame.x_hidden = frame.x - frame.width + bevel_width + border_width;@@ -728,6 +738,7 @@ if (m_shape.get())
m_shape->setPlaces(Shape::TOPRIGHT | Shape::BOTTOMRIGHT); break; case LEFTBOTTOM: + orient = FbTk::ROT90; frame.x = head_x; frame.y = head_y + head_h - frame.height - border_width*2; frame.x_hidden = frame.x - frame.width + bevel_width + border_width;@@ -736,6 +747,7 @@ if (m_shape.get())
m_shape->setPlaces(Shape::TOPRIGHT | Shape::BOTTOMRIGHT); break; case RIGHTCENTER: + orient = FbTk::ROT270; frame.x = head_x + head_w - frame.width - border_width*2; frame.y = head_y + (head_h - frame.height)/2 - border_width; frame.x_hidden = frame.x + frame.width - bevel_width - border_width;@@ -744,6 +756,7 @@ if (m_shape.get())
m_shape->setPlaces(Shape::TOPLEFT | Shape::BOTTOMLEFT); break; case RIGHTTOP: + orient = FbTk::ROT270; frame.x = head_x + head_w - frame.width - border_width*2; frame.y = head_y; frame.x_hidden = frame.x + frame.width - bevel_width - border_width;@@ -752,6 +765,7 @@ if (m_shape.get())
m_shape->setPlaces(Shape::TOPLEFT | Shape::BOTTOMLEFT); break; case RIGHTBOTTOM: + orient = FbTk::ROT270; frame.x = head_x + head_w - frame.width - border_width*2; frame.y = head_y + head_h - frame.height - border_width*2; frame.x_hidden = frame.x + frame.width - bevel_width - border_width;@@ -760,6 +774,19 @@ if (m_shape.get())
m_shape->setPlaces(Shape::TOPLEFT | Shape::BOTTOMLEFT); break; } + + if (was_orient != orient) { + // hide for all this moving around + if (*m_rc_visible) + frame.window.hide(); + ItemList::iterator item_it = m_item_list.begin(); + ItemList::iterator item_it_end = m_item_list.end(); + for (; item_it != item_it_end; ++item_it) { + (*item_it)->setOrientation(orient); + } + if (*m_rc_visible) + frame.window.show(); + } } void Toolbar::updateVisibleState() {@@ -920,6 +947,22 @@ if (m_resize_lock || screen().isShuttingdown() ||
m_item_list.empty()) return; + FbTk::Orientation orient = FbTk::ROT0; + switch (placement()) { + case LEFTTOP: + case LEFTCENTER: + case LEFTBOTTOM: + orient = FbTk::ROT90; + break; + case RIGHTTOP: + case RIGHTCENTER: + case RIGHTBOTTOM: + orient = FbTk::ROT270; + break; + default: + orient = FbTk::ROT0; + } + // lock this m_resize_lock = true; // calculate size for fixed items@@ -931,6 +974,12 @@ int fixed_items = 0; // number of fixed items
int relative_items = 0; int last_bw = 0; // we show the largest border of adjoining items bool first = true; + + unsigned int width = this->width(), height = this->height(); + unsigned int tmpw, tmph; + int tmpx, tmpy; + FbTk::translateSize(orient, width, height); + for (; item_it != item_it_end; ++item_it) { if (!(*item_it)->active()) continue;@@ -953,12 +1002,16 @@ }
last_bw = borderW; + tmpw = (*item_it)->width(); + tmph = (*item_it)->height(); + FbTk::translateSize(orient, tmpw, tmph); + if ((*item_it)->type() == ToolbarItem::FIXED) { - fixed_width += (*item_it)->width(); + fixed_width += tmpw; fixed_items++; } else if ((*item_it)->type() == ToolbarItem::SQUARE) { - fixed_width += height() - 2*bevel_width; - if (bevel_width != 0) fixed_width -= 2*borderW; + fixed_width += tmph; + //if (bevel_width != 0) fixed_width -= 2*borderW; fixed_items++; } else { relative_items++;@@ -969,13 +1022,13 @@ // calculate what's going to be le ft over to the relative sized items
int relative_width = 0; int rounding_error = 0; if (fixed_items == 0) // no fixed items, then the rest is the entire width - relative_width = width(); + relative_width = width; else { if (relative_items == 0) relative_width = 0; else { // size left after fixed items / number of relative items - relative_width = (width() - fixed_width)/relative_items; - rounding_error = width() - fixed_width - relative_items*(relative_width); + relative_width = (width - fixed_width)/relative_items; + rounding_error = width - fixed_width - relative_items*(relative_width); } }@@ -991,7 +1044,9 @@ int borderW = (*item_it)->borderWidth();
if (!(*item_it)->active()) { (*item_it)->hide(); // make sure it still gets told the toolbar height - (*item_it)->resize(1, height()-2*(bevel_width+borderW)); // width of 0 changes to 1 anyway + tmpw = 1; tmph = height - 2*(bevel_width+borderW); + FbTk::translateSize(orient, tmpw, tmph); + (*item_it)->resize(tmpw, tmph); // width of 0 changes to 1 anyway continue; } int offset = bevel_width;@@ -1007,24 +1062,34 @@ next_x += last_bw;
} last_bw = borderW; + int tmpx = next_x + offset, + tmpy = offset; + if ((*item_it)->type() == ToolbarItem::RELATIVE) { int extra = 0; if (rounding_error != 0) { // distribute rounding error over all relatives extra = 1; --rounding_error; } - (*item_it)->moveResize(next_x + offset, offset, extra + relative_width, height() - size_offset); + tmpw = extra + relative_width; + tmph = height - size_offset; } else if ((*item_it)->type() == ToolbarItem::SQUARE) { - (*item_it)->moveResize(next_x + offset, offset, - height() - size_offset, height() - size_offset); + tmpw = tmph = height - size_offset; } else { // fixed size - (*item_it)->moveResize(next_x + offset, offset, - (*item_it)->width(), height() - size_offset); + unsigned int itemw = (*item_it)->width(), itemh = (*item_it)->height(); + FbTk::translateSize(orient, itemw, itemh); + tmpw = itemw; + tmph = height - size_offset; } - (*item_it)->show(); - next_x += (*item_it)->width() + bevel_width; + next_x += tmpw + bevel_width; if (bevel_width != 0) next_x += 2*borderW; + + FbTk::translateCoords(orient, tmpx, tmpy, width, height); + FbTk::translatePosition(orient, tmpx, tmpy, tmpw, tmph, borderW); + FbTk::translateSize(orient, tmpw, tmph); + (*item_it)->moveResize(tmpx, tmpy, tmpw, tmph); + (*item_it)->show(); } // unlock
@@ -24,7 +24,7 @@ // $Id$
#include "ToolbarItem.hh" -ToolbarItem::ToolbarItem(Type type):m_type(type) { +ToolbarItem::ToolbarItem(Type type):m_type(type), m_orientation(FbTk::ROT0) { }
@@ -26,6 +26,7 @@ #ifndef TOOLBARITEM_HH
#define TOOLBARITEM_HH #include "FbTk/Subject.hh" +#include "FbTk/Text.hh" // orientation /// An item in the toolbar that has either fixed or relative size to the toolbar class ToolbarItem {@@ -65,10 +66,15 @@
void setType(Type type) { m_type = type; } Type type() const { return m_type; } + inline FbTk::Orientation orientation() const { return m_orientation; } + virtual void setOrientation(FbTk::Orientation orient) { m_orientation = orient; } + class ToolbarItemSubject : public FbTk::Subject {}; private: Type m_type; + + FbTk::Orientation m_orientation; ToolbarItemSubject m_resize_sig; };
@@ -82,7 +82,10 @@ }
unsigned int WorkspaceNameTool::width() const { // calculate largest size + if (orientation() == FbTk::ROT90 || orientation() == FbTk::ROT270) + return m_button.width(); unsigned int max_size = 0; + const BScreen::Workspaces& workspaces = m_screen.getWorkspacesList(); BScreen::Workspaces::const_iterator it; for (it = workspaces.begin(); it != workspaces.end(); it++) {@@ -97,7 +100,21 @@ return max_size;
} unsigned int WorkspaceNameTool::height() const { - return m_button.height(); + if (orientation() == FbTk::ROT0 || orientation() == FbTk::ROT180) + return m_button.height(); + + unsigned int max_size = 0; + const BScreen::Workspaces& workspaces = m_screen.getWorkspacesList(); + BScreen::Workspaces::const_iterator it; + for (it = workspaces.begin(); it != workspaces.end(); it++) { + const std::string &name = (*it)->name(); + max_size = std::max(m_theme.font().textWidth(name.c_str(), name.size()), + max_size); + } + // so align text dont cut the last character + max_size += 2; + + return max_size; } unsigned int WorkspaceNameTool::borderWidth() const {@@ -121,7 +138,7 @@ if (m_theme.texture().usePixmap()) {
if (m_pixmap) m_screen.imageControl().removeImage(m_pixmap); m_pixmap = m_screen.imageControl().renderImage(width(), height(), - m_theme.texture()); + m_theme.texture(), orientation()); m_button.setBackgroundPixmap(m_pixmap); } }@@ -144,3 +161,8 @@ }
m_button.clear(); } + +void WorkspaceNameTool::setOrientation(FbTk::Orientation orient) { + m_button.setOrientation(orient); + ToolbarItem::setOrientation(orient); +}
@@ -52,6 +52,8 @@
void update(FbTk::Subject *subj); FbTk::Button &button() { return m_button; } const FbTk::Button &button() const { return m_button; } + void setOrientation(FbTk::Orientation orient); + private: void renderTheme(unsigned char alpha); void reRender();