diff options
author | simonb <simonb> | 2007-01-06 07:38:04 (GMT) |
---|---|---|
committer | simonb <simonb> | 2007-01-06 07:38:04 (GMT) |
commit | 1f7b12cc494e8b492bd87207246265070b70d578 (patch) | |
tree | 7923939f792e790913548f684cf7ea57095c7626 | |
parent | 2e438fde2c4c6f660649c69f05681d50c72f849e (diff) | |
download | fluxbox-1f7b12cc494e8b492bd87207246265070b70d578.zip fluxbox-1f7b12cc494e8b492bd87207246265070b70d578.tar.bz2 |
move triangle drawing into FbDrawable
Make MenuItem triangles proportional
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/ArrowButton.cc | 52 | ||||
-rw-r--r-- | src/ArrowButton.hh | 13 | ||||
-rw-r--r-- | src/FbTk/FbDrawable.cc | 64 | ||||
-rw-r--r-- | src/FbTk/FbDrawable.hh | 14 | ||||
-rw-r--r-- | src/FbTk/MenuItem.cc | 27 | ||||
-rw-r--r-- | src/ToolFactory.cc | 8 | ||||
-rw-r--r-- | src/WinButton.cc | 25 |
8 files changed, 118 insertions, 91 deletions
@@ -1,5 +1,11 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 1.0rc3: | 2 | Changes for 1.0rc3: |
3 | *07/01/06: | ||
4 | * Move triangle drawing into a generic function in FbDrawable (Simon) | ||
5 | Make submenu triangles in MenuItems proportional to the icon size | ||
6 | (alternate implementation of sf.net patch #1526813) | ||
7 | FbTk/... FbDrawable.hh/cc MenuItem.cc | ||
8 | ArrowButton.hh/cc WinButton.cc ToolFactory.cc | ||
3 | *07/01/05: | 9 | *07/01/05: |
4 | * When a client in an unfocused tab creates a transient window, set that | 10 | * When a client in an unfocused tab creates a transient window, set that |
5 | client to the active tab (Mark) | 11 | 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 @@ | |||
24 | #include "ArrowButton.hh" | 24 | #include "ArrowButton.hh" |
25 | #include "ButtonTheme.hh" | 25 | #include "ButtonTheme.hh" |
26 | 26 | ||
27 | ArrowButton::ArrowButton(ArrowButton::Type arrow_type, | 27 | ArrowButton::ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, |
28 | const FbTk::FbWindow &parent, | 28 | const FbTk::FbWindow &parent, |
29 | int x, int y, | 29 | int x, int y, |
30 | unsigned int width, unsigned int height): | 30 | unsigned int width, unsigned int height): |
31 | FbTk::Button(parent, x, y, width, height), | 31 | FbTk::Button(parent, x, y, width, height), |
32 | m_arrow_type(arrow_type), | 32 | m_arrow_type(arrow_type), |
33 | m_mouse_handler(0), | 33 | m_mouse_handler(0), |
34 | m_arrowscale(300) { | 34 | m_arrowscale(250) { |
35 | 35 | ||
36 | setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | | 36 | setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | |
37 | EnterWindowMask | LeaveWindowMask); | 37 | EnterWindowMask | LeaveWindowMask); |
38 | } | 38 | } |
39 | 39 | ||
40 | ArrowButton::ArrowButton(ArrowButton::Type arrow_type, | 40 | ArrowButton::ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, |
41 | int screen_num, | 41 | int screen_num, |
42 | int x, int y, | 42 | int x, int y, |
43 | unsigned int width, unsigned int height): | 43 | unsigned int width, unsigned int height): |
44 | FbTk::Button(screen_num, x, y, width, height), | 44 | FbTk::Button(screen_num, x, y, width, height), |
45 | m_arrow_type(arrow_type), | 45 | m_arrow_type(arrow_type), |
46 | m_mouse_handler(0), | 46 | m_mouse_handler(0), |
47 | m_arrowscale(300) { | 47 | m_arrowscale(250) { |
48 | 48 | ||
49 | setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | | 49 | setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | |
50 | EnterWindowMask | LeaveWindowMask); | 50 | EnterWindowMask | LeaveWindowMask); |
@@ -84,46 +84,8 @@ void ArrowButton::leaveNotifyEvent(XCrossingEvent &ce) { | |||
84 | redraws the arrow button | 84 | redraws the arrow button |
85 | */ | 85 | */ |
86 | void ArrowButton::drawArrow() { | 86 | void ArrowButton::drawArrow() { |
87 | XPoint pts[3]; | 87 | if (gc() != 0) |
88 | unsigned int w = width(); | 88 | drawTriangle(gc(), m_arrow_type, 0, 0, width(), height(), m_arrowscale); |
89 | unsigned int h = height(); | ||
90 | |||
91 | int arrowscale_n = m_arrowscale; | ||
92 | int arrowscale_d = 100; | ||
93 | unsigned int ax = arrowscale_d * w / arrowscale_n; | ||
94 | unsigned int ay = arrowscale_d * h / arrowscale_n; | ||
95 | // if these aren't an even number, left and right arrows end up different | ||
96 | if (( ax % 2 ) == 1) ax++; | ||
97 | if (( ay % 2 ) == 1) ay++; | ||
98 | switch (m_arrow_type) { | ||
99 | case LEFT: | ||
100 | // start at the tip | ||
101 | pts[0].x = (w / 2) - (ax / 2); pts[0].y = h / 2; | ||
102 | pts[1].x = ax; pts[1].y = -ay / 2; | ||
103 | pts[2].x = 0; pts[2].y = ay; | ||
104 | break; | ||
105 | case RIGHT: | ||
106 | pts[0].x = (w / 2) + (ax / 2); pts[0].y = h / 2; | ||
107 | pts[1].x = - ax; pts[1].y = ay / 2; | ||
108 | pts[2].x = 0; pts[2].y = - ay; | ||
109 | break; | ||
110 | case UP: | ||
111 | pts[0].x = (w / 2); pts[0].y = (h / 2) - (ay / 2); | ||
112 | pts[1].x = ax / 2; pts[1].y = ay; | ||
113 | pts[2].x = - ax; pts[2].y = 0; | ||
114 | break; | ||
115 | case DOWN: | ||
116 | pts[0].x = (w / 2); pts[0].y = (h / 2) + (ay / 2); | ||
117 | pts[1].x = ax / 2; pts[1].y = - ay; | ||
118 | pts[2].x = - ax; pts[2].y = 0; | ||
119 | break; | ||
120 | } | ||
121 | |||
122 | if (gc() != 0) { | ||
123 | fillPolygon(gc(), | ||
124 | pts, 3, | ||
125 | Convex, CoordModePrevious); | ||
126 | } | ||
127 | } | 89 | } |
128 | 90 | ||
129 | void ArrowButton::updateTheme(const FbTk::Theme &theme) { | 91 | void ArrowButton::updateTheme(const FbTk::Theme &theme) { |
@@ -131,7 +93,7 @@ void ArrowButton::updateTheme(const FbTk::Theme &theme) { | |||
131 | const ButtonTheme &btheme = static_cast<const ButtonTheme &>(theme); | 93 | const ButtonTheme &btheme = static_cast<const ButtonTheme &>(theme); |
132 | 94 | ||
133 | m_arrowscale = btheme.scale(); | 95 | m_arrowscale = btheme.scale(); |
134 | if (m_arrowscale == 0) m_arrowscale = 300; // default is 0 => 300 | 96 | if (m_arrowscale == 0) m_arrowscale = 250; // default is 0 => 300 |
135 | else if (m_arrowscale < 100) m_arrowscale = 100; // otherwise clamp | 97 | else if (m_arrowscale < 100) m_arrowscale = 100; // otherwise clamp |
136 | else if (m_arrowscale > 100000) m_arrowscale = 100000; // clamp below overflow when *100 | 98 | else if (m_arrowscale > 100000) m_arrowscale = 100000; // clamp below overflow when *100 |
137 | } | 99 | } |
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 @@ | |||
29 | /// Displays a arrow on a button | 29 | /// Displays a arrow on a button |
30 | class ArrowButton: public FbTk::Button { | 30 | class ArrowButton: public FbTk::Button { |
31 | public: | 31 | public: |
32 | /// type of arrow that should be drawn | ||
33 | enum Type { | ||
34 | LEFT, | ||
35 | RIGHT, | ||
36 | UP, | ||
37 | DOWN | ||
38 | }; | ||
39 | 32 | ||
40 | ArrowButton(ArrowButton::Type arrow_type, const FbTk::FbWindow &parent, | 33 | ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, const FbTk::FbWindow &parent, |
41 | int x, int y, | 34 | int x, int y, |
42 | unsigned int width, unsigned int height); | 35 | unsigned int width, unsigned int height); |
43 | ArrowButton(ArrowButton::Type arrow_type, int screen_num, | 36 | ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, int screen_num, |
44 | int x, int y, | 37 | int x, int y, |
45 | unsigned int width, unsigned int height); | 38 | unsigned int width, unsigned int height); |
46 | void clear(); | 39 | void clear(); |
@@ -53,7 +46,7 @@ public: | |||
53 | void updateTheme(const FbTk::Theme &theme); | 46 | void updateTheme(const FbTk::Theme &theme); |
54 | private: | 47 | private: |
55 | void drawArrow(); | 48 | void drawArrow(); |
56 | Type m_arrow_type; | 49 | FbTk::FbDrawable::TriangleType m_arrow_type; |
57 | FbTk::EventHandler *m_mouse_handler; | 50 | FbTk::EventHandler *m_mouse_handler; |
58 | int m_arrowscale; | 51 | int m_arrowscale; |
59 | }; | 52 | }; |
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, | |||
89 | shape, mode); | 89 | shape, mode); |
90 | } | 90 | } |
91 | 91 | ||
92 | // x, y, width and height define a space within which we're drawing a triangle (centred) | ||
93 | // scale defines number of triangles that'd fit in a space of 100 width x 100 height | ||
94 | // (i.e. 200 = half size, 300 = a third). Its a bit backwards but it allows more flexibility | ||
95 | void FbDrawable::drawTriangle(GC gc, FbDrawable::TriangleType type, | ||
96 | int x, int y, unsigned int width, unsigned int height, | ||
97 | int scale) { | ||
98 | if (drawable() == 0 || gc == 0 || width == 0 || height == 0) | ||
99 | return; | ||
100 | |||
101 | XPoint pts[3]; | ||
102 | |||
103 | if (scale < 100) scale = 100; // not bigger than the space allowed | ||
104 | else if (scale > 10000) scale = 10000; // not too small... | ||
105 | |||
106 | int arrowscale_n = scale; | ||
107 | int arrowscale_d = 100; | ||
108 | unsigned int ax = arrowscale_d * width / arrowscale_n; | ||
109 | unsigned int ay = arrowscale_d * height / arrowscale_n; | ||
110 | // if these aren't an even number, left and right arrows end up different | ||
111 | if (type == FbTk::FbDrawable::LEFT || | ||
112 | type == FbTk::FbDrawable::RIGHT) { | ||
113 | if (( ax % 2 ) == 1) ax--; | ||
114 | if (( ay % 2 ) == 1) ay--; | ||
115 | } else { | ||
116 | if (( ax % 2 ) == 0) ax--; | ||
117 | } | ||
118 | |||
119 | switch (type) { | ||
120 | case FbTk::FbDrawable::LEFT: | ||
121 | // start at the tip | ||
122 | pts[0].x = (width / 2) - (ax / 2); pts[0].y = height / 2; | ||
123 | pts[1].x = ax; pts[1].y = -ay / 2; | ||
124 | pts[2].x = 0; pts[2].y = ay; | ||
125 | break; | ||
126 | case FbTk::FbDrawable::RIGHT: | ||
127 | pts[0].x = (width / 2) + (ax / 2); pts[0].y = height / 2; | ||
128 | pts[1].x = - ax; pts[1].y = ay / 2; | ||
129 | pts[2].x = 0; pts[2].y = - ay; | ||
130 | break; | ||
131 | case FbTk::FbDrawable::UP: | ||
132 | pts[0].x = (width / 2); pts[0].y = (height / 2) - (ay / 2)-1; | ||
133 | pts[1].x = ax / 2; pts[1].y = ay+1; | ||
134 | pts[2].x = - ax; pts[2].y = 0; | ||
135 | break; | ||
136 | case FbTk::FbDrawable::DOWN: | ||
137 | /* I tried and tried, but couldn't get the left diagonal of the down | ||
138 | arrow to be symmetrical with the right (for small widths)! | ||
139 | So we opt for this setup. It is symmetrical with larger widths */ | ||
140 | pts[0].x = (width / 2) ; pts[0].y = (height / 2) + (ay / 2); | ||
141 | pts[1].x = -ax/2+1; pts[1].y = -ay; | ||
142 | pts[2].x = ax-1; pts[2].y = 0; | ||
143 | break; | ||
144 | |||
145 | } | ||
146 | |||
147 | // re-centre on the specified points | ||
148 | pts[0].x += x; | ||
149 | pts[0].y += y; | ||
150 | |||
151 | fillPolygon(gc, | ||
152 | pts, 3, | ||
153 | Convex, CoordModePrevious); | ||
154 | } | ||
155 | |||
92 | #ifdef NOT_USED | 156 | #ifdef NOT_USED |
93 | void FbDrawable::drawPoint(GC gc, int x, int y) { | 157 | void FbDrawable::drawPoint(GC gc, int x, int y) { |
94 | if (drawable() == 0 || gc == 0) | 158 | 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: | |||
48 | virtual void fillPolygon(GC gc, XPoint *points, int npoints, | 48 | virtual void fillPolygon(GC gc, XPoint *points, int npoints, |
49 | int shape, int mode); | 49 | int shape, int mode); |
50 | 50 | ||
51 | /// type of arrow that should be drawn | ||
52 | enum TriangleType { | ||
53 | LEFT, | ||
54 | RIGHT, | ||
55 | UP, | ||
56 | DOWN | ||
57 | }; | ||
58 | |||
59 | // x, y, width and height define a space within which we're drawing a triangle | ||
60 | // scale defines number of triangles that'd fit in a space of 100 width x 100 height | ||
61 | // (i.e. 200 = half size, 300 = a third). | ||
62 | |||
63 | virtual void drawTriangle(GC gc, TriangleType type, int x, int y, unsigned int width, unsigned int height, int scale); | ||
64 | |||
51 | #ifdef NOT_USED | 65 | #ifdef NOT_USED |
52 | virtual void drawPoint(GC gc, int x, int y); | 66 | virtual void drawPoint(GC gc, int x, int y); |
53 | #endif | 67 | #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, | |||
216 | break; | 216 | break; |
217 | 217 | ||
218 | case MenuTheme::TRIANGLE: | 218 | case MenuTheme::TRIANGLE: |
219 | XPoint tri[3]; | 219 | draw.drawTriangle(gc, ((theme.bulletPos() == FbTk::RIGHT)? |
220 | 220 | FbTk::FbDrawable::RIGHT: | |
221 | if (theme.bulletPos() == FbTk::RIGHT) { | 221 | FbTk::FbDrawable::LEFT), |
222 | tri[0].x = sel_x + half_w - 2; | 222 | sel_x, sel_y, |
223 | tri[0].y = sel_y + half_w - 2; | 223 | item_pm_height, |
224 | tri[1].x = 4; | 224 | item_pm_height, |
225 | tri[1].y = 2; | 225 | 300); // 33% triangle |
226 | tri[2].x = -4; | ||
227 | tri[2].y = 2; | ||
228 | } else { // point the other way | ||
229 | tri[0].x = sel_x + half_w - 2; | ||
230 | tri[0].y = sel_y + half_w; | ||
231 | tri[1].x = 4; | ||
232 | tri[1].y = 2; | ||
233 | tri[2].x = 0; | ||
234 | tri[2].y = -4; | ||
235 | } | ||
236 | |||
237 | draw.fillPolygon(gc, tri, 3, Convex, | ||
238 | CoordModePrevious); | ||
239 | break; | 226 | break; |
240 | 227 | ||
241 | case MenuTheme::DIAMOND: | 228 | 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 & | |||
112 | return 0; | 112 | return 0; |
113 | 113 | ||
114 | // TODO maybe direction of arrows should depend on toolbar layout ? | 114 | // TODO maybe direction of arrows should depend on toolbar layout ? |
115 | ArrowButton::Type arrow_type = ArrowButton::LEFT; | 115 | FbTk::FbDrawable::TriangleType arrow_type = FbTk::FbDrawable::UP; |
116 | if (name == "nextworkspace") | 116 | if (name == "nextworkspace") |
117 | arrow_type = ArrowButton::RIGHT; | 117 | arrow_type = FbTk::FbDrawable::DOWN; |
118 | 118 | ||
119 | ArrowButton *win = new ArrowButton(arrow_type, parent, | 119 | ArrowButton *win = new ArrowButton(arrow_type, parent, |
120 | 0, 0, | 120 | 0, 0, |
@@ -131,9 +131,9 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow & | |||
131 | if (*cmd == 0) // we need a command | 131 | if (*cmd == 0) // we need a command |
132 | return 0; | 132 | return 0; |
133 | 133 | ||
134 | ArrowButton::Type arrow_type = ArrowButton::LEFT; | 134 | FbTk::FbDrawable::TriangleType arrow_type = FbTk::FbDrawable::LEFT; |
135 | if (name == "nextwindow") | 135 | if (name == "nextwindow") |
136 | arrow_type = ArrowButton::RIGHT; | 136 | arrow_type = FbTk::FbDrawable::RIGHT; |
137 | 137 | ||
138 | ArrowButton *win = new ArrowButton(arrow_type, parent, | 138 | ArrowButton *win = new ArrowButton(arrow_type, parent, |
139 | 0, 0, | 139 | 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() { | |||
265 | break; | 265 | break; |
266 | case SHADE: | 266 | case SHADE: |
267 | 267 | ||
268 | drawRectangle(gc(), 2, 2, width() - 5 - oddW, 2); | 268 | { |
269 | int size = width() - 5 - oddW; | ||
270 | |||
271 | drawRectangle(gc(), 2, 2, size, 2); | ||
269 | 272 | ||
270 | XPoint points[3]; | 273 | // draw a one-quarter triangle below the rectangle |
271 | if (m_listen_to.isShaded()) { | 274 | drawTriangle(gc(), (m_listen_to.isShaded() ? |
272 | points[1].x = (width() / 2) - 3; points[1].y = 7; | 275 | FbTk::FbDrawable::DOWN: |
273 | points[2].x = (width() / 2) + 4 - oddW; points[2].y = 7; | 276 | FbTk::FbDrawable::UP), |
274 | points[0].x = (width() / 2); points[0].y = height() / 2 + 2; | 277 | 4, 6, |
275 | } else { | 278 | size-2, size/2 - 1, |
276 | points[0].x = (width() / 2); points[0].y = 6; | 279 | 100); |
277 | points[1].x = (width() / 2) - 4; points[1].y = height() / 2 + 2; | 280 | |
278 | points[2].x = (width() / 2) + 4 - oddW; points[2].y = height() / 2 + 2; | ||
279 | } | ||
280 | fillPolygon(gc(), points, 3, Convex, CoordModeOrigin); | ||
281 | break; | 281 | break; |
282 | } | ||
282 | case MENUICON: | 283 | case MENUICON: |
283 | if (m_icon_pixmap.drawable()) { | 284 | if (m_icon_pixmap.drawable()) { |
284 | 285 | ||