summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsimonb <simonb>2007-01-06 07:38:04 (GMT)
committersimonb <simonb>2007-01-06 07:38:04 (GMT)
commit1f7b12cc494e8b492bd87207246265070b70d578 (patch)
tree7923939f792e790913548f684cf7ea57095c7626
parent2e438fde2c4c6f660649c69f05681d50c72f849e (diff)
downloadfluxbox_lack-1f7b12cc494e8b492bd87207246265070b70d578.zip
fluxbox_lack-1f7b12cc494e8b492bd87207246265070b70d578.tar.bz2
move triangle drawing into FbDrawable
Make MenuItem triangles proportional
-rw-r--r--ChangeLog6
-rw-r--r--src/ArrowButton.cc52
-rw-r--r--src/ArrowButton.hh13
-rw-r--r--src/FbTk/FbDrawable.cc64
-rw-r--r--src/FbTk/FbDrawable.hh14
-rw-r--r--src/FbTk/MenuItem.cc27
-rw-r--r--src/ToolFactory.cc8
-rw-r--r--src/WinButton.cc25
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 @@
1 (Format: Year/Month/Day) 1 (Format: Year/Month/Day)
2Changes for 1.0rc3: 2Changes 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
27ArrowButton::ArrowButton(ArrowButton::Type arrow_type, 27ArrowButton::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
40ArrowButton::ArrowButton(ArrowButton::Type arrow_type, 40ArrowButton::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*/
86void ArrowButton::drawArrow() { 86void 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
129void ArrowButton::updateTheme(const FbTk::Theme &theme) { 91void 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
30class ArrowButton: public FbTk::Button { 30class ArrowButton: public FbTk::Button {
31public: 31public:
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);
54private: 47private:
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
95void 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
93void FbDrawable::drawPoint(GC gc, int x, int y) { 157void 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