all repos — fluxbox @ 1f7b12cc494e8b492bd87207246265070b70d578

custom fork of the fluxbox windowmanager

move triangle drawing into FbDrawable
Make MenuItem triangles proportional
simonb simonb
commit

1f7b12cc494e8b492bd87207246265070b70d578

parent

2e438fde2c4c6f660649c69f05681d50c72f849e

M ChangeLogChangeLog

@@ -1,5 +1,11 @@

(Format: Year/Month/Day) Changes for 1.0rc3: +*07/01/06: + * Move triangle drawing into a generic function in FbDrawable (Simon) + Make submenu triangles in MenuItems proportional to the icon size + (alternate implementation of sf.net patch #1526813) + FbTk/... FbDrawable.hh/cc MenuItem.cc + ArrowButton.hh/cc WinButton.cc ToolFactory.cc *07/01/05: * When a client in an unfocused tab creates a transient window, set that client to the active tab (Mark)
M src/ArrowButton.ccsrc/ArrowButton.cc

@@ -24,27 +24,27 @@

#include "ArrowButton.hh" #include "ButtonTheme.hh" -ArrowButton::ArrowButton(ArrowButton::Type arrow_type, +ArrowButton::ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, const FbTk::FbWindow &parent, int x, int y, unsigned int width, unsigned int height): FbTk::Button(parent, x, y, width, height), m_arrow_type(arrow_type), m_mouse_handler(0), - m_arrowscale(300) { + m_arrowscale(250) { setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask); } -ArrowButton::ArrowButton(ArrowButton::Type arrow_type, +ArrowButton::ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, int screen_num, int x, int y, unsigned int width, unsigned int height): FbTk::Button(screen_num, x, y, width, height), m_arrow_type(arrow_type), m_mouse_handler(0), - m_arrowscale(300) { + m_arrowscale(250) { setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);

@@ -84,46 +84,8 @@ /**

redraws the arrow button */ void ArrowButton::drawArrow() { - XPoint pts[3]; - unsigned int w = width(); - unsigned int h = height(); - - int arrowscale_n = m_arrowscale; - int arrowscale_d = 100; - unsigned int ax = arrowscale_d * w / arrowscale_n; - unsigned int ay = arrowscale_d * h / arrowscale_n; - // if these aren't an even number, left and right arrows end up different - if (( ax % 2 ) == 1) ax++; - if (( ay % 2 ) == 1) ay++; - switch (m_arrow_type) { - case LEFT: - // start at the tip - pts[0].x = (w / 2) - (ax / 2); pts[0].y = h / 2; - pts[1].x = ax; pts[1].y = -ay / 2; - pts[2].x = 0; pts[2].y = ay; - break; - case RIGHT: - pts[0].x = (w / 2) + (ax / 2); pts[0].y = h / 2; - pts[1].x = - ax; pts[1].y = ay / 2; - pts[2].x = 0; pts[2].y = - ay; - break; - case UP: - pts[0].x = (w / 2); pts[0].y = (h / 2) - (ay / 2); - pts[1].x = ax / 2; pts[1].y = ay; - pts[2].x = - ax; pts[2].y = 0; - break; - case DOWN: - pts[0].x = (w / 2); pts[0].y = (h / 2) + (ay / 2); - pts[1].x = ax / 2; pts[1].y = - ay; - pts[2].x = - ax; pts[2].y = 0; - break; - } - - if (gc() != 0) { - fillPolygon(gc(), - pts, 3, - Convex, CoordModePrevious); - } + if (gc() != 0) + drawTriangle(gc(), m_arrow_type, 0, 0, width(), height(), m_arrowscale); } void ArrowButton::updateTheme(const FbTk::Theme &theme) {

@@ -131,7 +93,7 @@ // it must be a button theme

const ButtonTheme &btheme = static_cast<const ButtonTheme &>(theme); m_arrowscale = btheme.scale(); - if (m_arrowscale == 0) m_arrowscale = 300; // default is 0 => 300 + if (m_arrowscale == 0) m_arrowscale = 250; // default is 0 => 300 else if (m_arrowscale < 100) m_arrowscale = 100; // otherwise clamp else if (m_arrowscale > 100000) m_arrowscale = 100000; // clamp below overflow when *100 }
M src/ArrowButton.hhsrc/ArrowButton.hh

@@ -29,18 +29,11 @@

/// Displays a arrow on a button class ArrowButton: public FbTk::Button { public: - /// type of arrow that should be drawn - enum Type { - LEFT, - RIGHT, - UP, - DOWN - }; - ArrowButton(ArrowButton::Type arrow_type, const FbTk::FbWindow &parent, + ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, const FbTk::FbWindow &parent, int x, int y, unsigned int width, unsigned int height); - ArrowButton(ArrowButton::Type arrow_type, int screen_num, + ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, int screen_num, int x, int y, unsigned int width, unsigned int height); void clear();

@@ -53,7 +46,7 @@

void updateTheme(const FbTk::Theme &theme); private: void drawArrow(); - Type m_arrow_type; + FbTk::FbDrawable::TriangleType m_arrow_type; FbTk::EventHandler *m_mouse_handler; int m_arrowscale; };
M src/FbTk/FbDrawable.ccsrc/FbTk/FbDrawable.cc

@@ -89,6 +89,70 @@ drawable(), gc, points, npoints,

shape, mode); } +// x, y, width and height define a space within which we're drawing a triangle (centred) +// scale defines number of triangles that'd fit in a space of 100 width x 100 height +// (i.e. 200 = half size, 300 = a third). Its a bit backwards but it allows more flexibility +void FbDrawable::drawTriangle(GC gc, FbDrawable::TriangleType type, + int x, int y, unsigned int width, unsigned int height, + int scale) { + if (drawable() == 0 || gc == 0 || width == 0 || height == 0) + return; + + XPoint pts[3]; + + if (scale < 100) scale = 100; // not bigger than the space allowed + else if (scale > 10000) scale = 10000; // not too small... + + int arrowscale_n = scale; + int arrowscale_d = 100; + unsigned int ax = arrowscale_d * width / arrowscale_n; + unsigned int ay = arrowscale_d * height / arrowscale_n; + // if these aren't an even number, left and right arrows end up different + if (type == FbTk::FbDrawable::LEFT || + type == FbTk::FbDrawable::RIGHT) { + if (( ax % 2 ) == 1) ax--; + if (( ay % 2 ) == 1) ay--; + } else { + if (( ax % 2 ) == 0) ax--; + } + + switch (type) { + case FbTk::FbDrawable::LEFT: + // start at the tip + pts[0].x = (width / 2) - (ax / 2); pts[0].y = height / 2; + pts[1].x = ax; pts[1].y = -ay / 2; + pts[2].x = 0; pts[2].y = ay; + break; + case FbTk::FbDrawable::RIGHT: + pts[0].x = (width / 2) + (ax / 2); pts[0].y = height / 2; + pts[1].x = - ax; pts[1].y = ay / 2; + pts[2].x = 0; pts[2].y = - ay; + break; + case FbTk::FbDrawable::UP: + pts[0].x = (width / 2); pts[0].y = (height / 2) - (ay / 2)-1; + pts[1].x = ax / 2; pts[1].y = ay+1; + pts[2].x = - ax; pts[2].y = 0; + break; + case FbTk::FbDrawable::DOWN: + /* I tried and tried, but couldn't get the left diagonal of the down + arrow to be symmetrical with the right (for small widths)! + So we opt for this setup. It is symmetrical with larger widths */ + pts[0].x = (width / 2) ; pts[0].y = (height / 2) + (ay / 2); + pts[1].x = -ax/2+1; pts[1].y = -ay; + pts[2].x = ax-1; pts[2].y = 0; + break; + + } + + // re-centre on the specified points + pts[0].x += x; + pts[0].y += y; + + fillPolygon(gc, + pts, 3, + Convex, CoordModePrevious); +} + #ifdef NOT_USED void FbDrawable::drawPoint(GC gc, int x, int y) { if (drawable() == 0 || gc == 0)
M src/FbTk/FbDrawable.hhsrc/FbTk/FbDrawable.hh

@@ -48,6 +48,20 @@ int end_x, int end_y);

virtual void fillPolygon(GC gc, XPoint *points, int npoints, int shape, int mode); + /// type of arrow that should be drawn + enum TriangleType { + LEFT, + RIGHT, + UP, + DOWN + }; + + // x, y, width and height define a space within which we're drawing a triangle + // scale defines number of triangles that'd fit in a space of 100 width x 100 height + // (i.e. 200 = half size, 300 = a third). + + virtual void drawTriangle(GC gc, TriangleType type, int x, int y, unsigned int width, unsigned int height, int scale); + #ifdef NOT_USED virtual void drawPoint(GC gc, int x, int y); #endif
M src/FbTk/MenuItem.ccsrc/FbTk/MenuItem.cc

@@ -216,26 +216,13 @@ draw.drawRectangle(gc, sel_x+quarter_w, y+quarter_w, half_w, half_w);

break; case MenuTheme::TRIANGLE: - XPoint tri[3]; - - if (theme.bulletPos() == FbTk::RIGHT) { - tri[0].x = sel_x + half_w - 2; - tri[0].y = sel_y + half_w - 2; - tri[1].x = 4; - tri[1].y = 2; - tri[2].x = -4; - tri[2].y = 2; - } else { // point the other way - tri[0].x = sel_x + half_w - 2; - tri[0].y = sel_y + half_w; - tri[1].x = 4; - tri[1].y = 2; - tri[2].x = 0; - tri[2].y = -4; - } - - draw.fillPolygon(gc, tri, 3, Convex, - CoordModePrevious); + draw.drawTriangle(gc, ((theme.bulletPos() == FbTk::RIGHT)? + FbTk::FbDrawable::RIGHT: + FbTk::FbDrawable::LEFT), + sel_x, sel_y, + item_pm_height, + item_pm_height, + 300); // 33% triangle break; case MenuTheme::DIAMOND:
M src/ToolFactory.ccsrc/ToolFactory.cc

@@ -112,9 +112,9 @@ if (*cmd == 0) // we need a command

return 0; // TODO maybe direction of arrows should depend on toolbar layout ? - ArrowButton::Type arrow_type = ArrowButton::LEFT; + FbTk::FbDrawable::TriangleType arrow_type = FbTk::FbDrawable::UP; if (name == "nextworkspace") - arrow_type = ArrowButton::RIGHT; + arrow_type = FbTk::FbDrawable::DOWN; ArrowButton *win = new ArrowButton(arrow_type, parent, 0, 0,

@@ -131,9 +131,9 @@ FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine(name));

if (*cmd == 0) // we need a command return 0; - ArrowButton::Type arrow_type = ArrowButton::LEFT; + FbTk::FbDrawable::TriangleType arrow_type = FbTk::FbDrawable::LEFT; if (name == "nextwindow") - arrow_type = ArrowButton::RIGHT; + arrow_type = FbTk::FbDrawable::RIGHT; ArrowButton *win = new ArrowButton(arrow_type, parent, 0, 0,
M src/WinButton.ccsrc/WinButton.cc

@@ -265,20 +265,21 @@ width() - 3, 2);

break; case SHADE: - drawRectangle(gc(), 2, 2, width() - 5 - oddW, 2); + { + int size = width() - 5 - oddW; + + drawRectangle(gc(), 2, 2, size, 2); - XPoint points[3]; - if (m_listen_to.isShaded()) { - points[1].x = (width() / 2) - 3; points[1].y = 7; - points[2].x = (width() / 2) + 4 - oddW; points[2].y = 7; - points[0].x = (width() / 2); points[0].y = height() / 2 + 2; - } else { - points[0].x = (width() / 2); points[0].y = 6; - points[1].x = (width() / 2) - 4; points[1].y = height() / 2 + 2; - points[2].x = (width() / 2) + 4 - oddW; points[2].y = height() / 2 + 2; - } - fillPolygon(gc(), points, 3, Convex, CoordModeOrigin); + // draw a one-quarter triangle below the rectangle + drawTriangle(gc(), (m_listen_to.isShaded() ? + FbTk::FbDrawable::DOWN: + FbTk::FbDrawable::UP), + 4, 6, + size-2, size/2 - 1, + 100); + break; + } case MENUICON: if (m_icon_pixmap.drawable()) {