From 1f7b12cc494e8b492bd87207246265070b70d578 Mon Sep 17 00:00:00 2001 From: simonb Date: Sat, 6 Jan 2007 07:38:04 +0000 Subject: move triangle drawing into FbDrawable Make MenuItem triangles proportional --- ChangeLog | 6 +++++ src/ArrowButton.cc | 52 ++++++---------------------------------- src/ArrowButton.hh | 13 +++------- src/FbTk/FbDrawable.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/FbTk/FbDrawable.hh | 14 +++++++++++ src/FbTk/MenuItem.cc | 27 ++++++--------------- src/ToolFactory.cc | 8 +++---- src/WinButton.cc | 25 ++++++++++---------- 8 files changed, 118 insertions(+), 91 deletions(-) diff --git a/ChangeLog b/ChangeLog index be877c3..cf1727a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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) diff --git a/src/ArrowButton.cc b/src/ArrowButton.cc index aa319d6..e1a2fc9 100644 --- a/src/ArrowButton.cc +++ b/src/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 @@ void ArrowButton::leaveNotifyEvent(XCrossingEvent &ce) { 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 @@ void ArrowButton::updateTheme(const FbTk::Theme &theme) { const ButtonTheme &btheme = static_cast(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 } diff --git a/src/ArrowButton.hh b/src/ArrowButton.hh index 024ca05..2ae4b87 100644 --- a/src/ArrowButton.hh +++ b/src/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 @@ public: 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; }; diff --git a/src/FbTk/FbDrawable.cc b/src/FbTk/FbDrawable.cc index 061da0b..dd6e4a9 100644 --- a/src/FbTk/FbDrawable.cc +++ b/src/FbTk/FbDrawable.cc @@ -89,6 +89,70 @@ void FbDrawable::fillPolygon(GC gc, XPoint *points, int 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) diff --git a/src/FbTk/FbDrawable.hh b/src/FbTk/FbDrawable.hh index 7590f54..8d91377 100644 --- a/src/FbTk/FbDrawable.hh +++ b/src/FbTk/FbDrawable.hh @@ -48,6 +48,20 @@ public: 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 diff --git a/src/FbTk/MenuItem.cc b/src/FbTk/MenuItem.cc index fafedc0..a2c3fe2 100644 --- a/src/FbTk/MenuItem.cc +++ b/src/FbTk/MenuItem.cc @@ -216,26 +216,13 @@ void MenuItem::draw(FbDrawable &draw, 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: diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc index 242b3a0..798072b 100644 --- a/src/ToolFactory.cc +++ b/src/ToolFactory.cc @@ -112,9 +112,9 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow & 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 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow & 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, diff --git a/src/WinButton.cc b/src/WinButton.cc index f8421b5..f690f93 100644 --- a/src/WinButton.cc +++ b/src/WinButton.cc @@ -265,20 +265,21 @@ void WinButton::drawType() { 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()) { -- cgit v0.11.2