diff options
Diffstat (limited to 'src/FbTk/MenuItem.cc')
-rw-r--r-- | src/FbTk/MenuItem.cc | 247 |
1 files changed, 149 insertions, 98 deletions
diff --git a/src/FbTk/MenuItem.cc b/src/FbTk/MenuItem.cc index 1f3125c..1ed3ebd 100644 --- a/src/FbTk/MenuItem.cc +++ b/src/FbTk/MenuItem.cc | |||
@@ -39,142 +39,194 @@ void MenuItem::click(int button, int time) { | |||
39 | 39 | ||
40 | void MenuItem::draw(FbDrawable &draw, | 40 | void MenuItem::draw(FbDrawable &draw, |
41 | const MenuTheme &theme, | 41 | const MenuTheme &theme, |
42 | bool highlight, | 42 | bool highlight, bool draw_foreground, bool draw_background, |
43 | int x, int y, | 43 | int x, int y, |
44 | unsigned int width, unsigned int height) const { | 44 | unsigned int width, unsigned int height) const { |
45 | 45 | ||
46 | // text and submenu icon are background | ||
47 | // selected pixmaps are foreground | ||
48 | |||
46 | Display *disp = App::instance()->display(); | 49 | Display *disp = App::instance()->display(); |
47 | // | 50 | // |
48 | // Icon | 51 | // Icon |
49 | // | 52 | // |
50 | if (m_icon.get() != 0 && m_icon->pixmap.get() != 0) { | 53 | if (draw_background) { |
51 | // scale pixmap to right size | 54 | if (m_icon.get() != 0 && m_icon->pixmap.get() != 0) { |
52 | if (height - 2*theme.bevelWidth() != m_icon->pixmap->height() && | 55 | // scale pixmap to right size |
53 | !m_icon->filename.empty()) { | 56 | if (height - 2*theme.bevelWidth() != m_icon->pixmap->height() && |
54 | unsigned int scale_size = height - 2*theme.bevelWidth(); | 57 | !m_icon->filename.empty()) { |
55 | m_icon->pixmap->scale(scale_size, scale_size); | 58 | unsigned int scale_size = height - 2*theme.bevelWidth(); |
56 | } | 59 | m_icon->pixmap->scale(scale_size, scale_size); |
57 | 60 | } | |
58 | if (m_icon->pixmap->pixmap().drawable() != 0) { | ||
59 | GC gc = theme.frameTextGC().gc(); | ||
60 | int icon_x = x + theme.bevelWidth(); | ||
61 | int icon_y = y + theme.bevelWidth(); | ||
62 | // enable clip mask | ||
63 | XSetClipMask(disp, gc, m_icon->pixmap->mask().drawable()); | ||
64 | XSetClipOrigin(disp, gc, icon_x, icon_y); | ||
65 | |||
66 | draw.copyArea(m_icon->pixmap->pixmap().drawable(), | ||
67 | gc, | ||
68 | 0, 0, | ||
69 | icon_x, icon_y, | ||
70 | m_icon->pixmap->width(), m_icon->pixmap->height()); | ||
71 | 61 | ||
72 | // restore clip mask | 62 | if (m_icon->pixmap->pixmap().drawable() != 0) { |
73 | XSetClipMask(disp, gc, None); | 63 | GC gc = theme.frameTextGC().gc(); |
64 | int icon_x = x + theme.bevelWidth(); | ||
65 | int icon_y = y + theme.bevelWidth(); | ||
66 | // enable clip mask | ||
67 | XSetClipMask(disp, gc, m_icon->pixmap->mask().drawable()); | ||
68 | XSetClipOrigin(disp, gc, icon_x, icon_y); | ||
69 | |||
70 | draw.copyArea(m_icon->pixmap->pixmap().drawable(), | ||
71 | gc, | ||
72 | 0, 0, | ||
73 | icon_x, icon_y, | ||
74 | m_icon->pixmap->width(), m_icon->pixmap->height()); | ||
75 | |||
76 | // restore clip mask | ||
77 | XSetClipMask(disp, gc, None); | ||
78 | } | ||
74 | } | 79 | } |
75 | |||
76 | } | 80 | } |
77 | 81 | ||
78 | if (label().empty()) | 82 | if (label().empty()) |
79 | return; | 83 | return; |
80 | 84 | ||
81 | const GContext &tgc = | 85 | // text is background |
82 | (highlight ? theme.hiliteTextGC() : | 86 | if (draw_background) { |
83 | (isEnabled() ? theme.frameTextGC() : theme.disableTextGC() ) ); | 87 | const GContext &tgc = |
84 | // | 88 | (highlight ? theme.hiliteTextGC() : |
85 | // Text | 89 | (isEnabled() ? theme.frameTextGC() : theme.disableTextGC() ) ); |
86 | // | 90 | // |
87 | int text_y = y, text_x = x; | 91 | // Text |
88 | 92 | // | |
89 | int text_w = theme.frameFont().textWidth(label().c_str(), label().size()); | 93 | int text_y = y, text_x = x; |
90 | 94 | ||
91 | int height_offset = theme.itemHeight() - (theme.frameFont().height() + 2*theme.bevelWidth()); | 95 | int text_w = theme.frameFont().textWidth(label().c_str(), label().size()); |
92 | text_y = y + theme.bevelWidth() + theme.frameFont().ascent() + height_offset/2; ///2 + height/2; | 96 | |
93 | 97 | int height_offset = theme.itemHeight() - (theme.frameFont().height() + 2*theme.bevelWidth()); | |
94 | switch(theme.frameFontJustify()) { | 98 | text_y = y + theme.bevelWidth() + theme.frameFont().ascent() + height_offset/2; |
95 | case FbTk::LEFT: | 99 | |
96 | text_x = x + theme.bevelWidth() + height + 1; | 100 | switch(theme.frameFontJustify()) { |
97 | break; | 101 | case FbTk::LEFT: |
102 | text_x = x + theme.bevelWidth() + height + 1; | ||
103 | break; | ||
104 | |||
105 | case FbTk::RIGHT: | ||
106 | text_x = x + width - (height + theme.bevelWidth() + text_w); | ||
107 | break; | ||
108 | default: //center | ||
109 | text_x = x + ((width + 1 - text_w) / 2); | ||
110 | break; | ||
111 | } | ||
98 | 112 | ||
99 | case FbTk::RIGHT: | 113 | theme.frameFont().drawText(draw, // drawable |
100 | text_x = x + width - (height + theme.bevelWidth() + text_w); | 114 | theme.screenNum(), |
101 | break; | 115 | tgc.gc(), |
102 | default: //center | 116 | m_label.c_str(), m_label.size(), // text string and lenght |
103 | text_x = x + ((width + 1 - text_w) / 2); | 117 | text_x, text_y); // position |
104 | break; | ||
105 | } | 118 | } |
106 | 119 | ||
107 | theme.frameFont().drawText(draw, // drawable | 120 | GC gc = (highlight) ? theme.hiliteTextGC().gc() : |
108 | theme.screenNum(), | 121 | theme.frameTextGC().gc(); |
109 | tgc.gc(), | 122 | int sel_x = x; |
110 | m_label.c_str(), m_label.size(), // text string and lenght | 123 | int sel_y = y; |
111 | text_x, text_y); // position | 124 | unsigned int item_pm_height = theme.itemHeight(); |
112 | |||
113 | GC gc = | ||
114 | ((highlight || isSelected()) ? theme.hiliteTextGC().gc() : | ||
115 | theme.frameTextGC().gc()); | ||
116 | 125 | ||
117 | int sel_x = x + height/4; | 126 | if (theme.bulletPos() == FbTk::RIGHT) |
127 | sel_x += width - height - theme.bevelWidth(); | ||
118 | 128 | ||
129 | // selected pixmap is foreground | ||
130 | if (draw_foreground && isToggleItem()) { | ||
119 | 131 | ||
120 | if (theme.bulletPos() == FbTk::RIGHT) | 132 | // |
121 | sel_x += width - height - 2*theme.bevelWidth(); | 133 | // ToggleItem |
134 | // | ||
135 | const PixmapWithMask *pm = 0; | ||
122 | 136 | ||
123 | // | 137 | if (isSelected()) { |
124 | // ToggleItem | 138 | if (highlight && theme.highlightSelectedPixmap().pixmap().drawable() != 0) |
125 | // | 139 | pm = &theme.highlightSelectedPixmap(); |
126 | if (isToggleItem() && theme.unselectedPixmap().pixmap().drawable() != 0) { | 140 | else |
127 | XSetClipMask(disp, gc, theme.unselectedPixmap().mask().drawable()); | 141 | pm = &theme.selectedPixmap(); |
128 | XSetClipOrigin(disp, gc, sel_x, y); | 142 | } else { |
129 | // copy bullet pixmap to drawable | 143 | if (highlight && theme.highlightUnselectedPixmap().pixmap().drawable() != 0) |
130 | draw.copyArea(theme.unselectedPixmap().pixmap().drawable(), | 144 | pm = &theme.highlightUnselectedPixmap(); |
131 | gc, | 145 | else |
132 | 0, 0, | 146 | pm = &theme.unselectedPixmap(); |
133 | sel_x, y, | 147 | } |
134 | theme.unselectedPixmap().width(), | 148 | if (pm != 0 && pm->pixmap().drawable() != 0) { |
135 | theme.unselectedPixmap().height()); | 149 | unsigned int selw = pm->width(); |
136 | // disable clip mask | 150 | unsigned int selh = pm->height(); |
137 | XSetClipMask(disp, gc, None); | 151 | int offset_x = 0; |
152 | int offset_y = 0; | ||
153 | if (selw < item_pm_height) | ||
154 | offset_x += (item_pm_height - selw) / 2; | ||
155 | if (selh < item_pm_height) | ||
156 | offset_y += (item_pm_height - selh) / 2; | ||
157 | |||
158 | XSetClipMask(disp, gc, pm->mask().drawable()); | ||
159 | XSetClipOrigin(disp, gc, sel_x+offset_x, sel_y+offset_y); | ||
160 | // copy bullet pixmap to drawable | ||
161 | draw.copyArea(pm->pixmap().drawable(), | ||
162 | gc, | ||
163 | 0, 0, | ||
164 | sel_x+offset_x, sel_y+offset_y, | ||
165 | selw, | ||
166 | selh); | ||
167 | // disable clip mask | ||
168 | XSetClipMask(disp, gc, None); | ||
169 | } else if (isSelected()) { | ||
170 | draw.fillRectangle(theme.hiliteGC().gc(), | ||
171 | sel_x+item_pm_height/4, sel_y+item_pm_height/4, item_pm_height/2, item_pm_height/2); | ||
172 | } | ||
138 | } | 173 | } |
139 | 174 | ||
140 | // | 175 | // |
141 | // Submenu | 176 | // Submenu (background) |
142 | // | 177 | // |
143 | if (submenu()) { | 178 | if (draw_background && submenu()) { |
144 | if (theme.bulletPixmap().pixmap().drawable() != 0) { | 179 | |
145 | // enable clip mask | 180 | const PixmapWithMask *pm = 0; |
146 | XSetClipMask(disp, gc, theme.bulletPixmap().mask().drawable()); | 181 | |
147 | XSetClipOrigin(disp, gc, sel_x, y); | 182 | if (highlight && theme.highlightBulletPixmap().pixmap().drawable() != 0) |
148 | // copy bullet pixmap to frame | 183 | pm = &theme.highlightBulletPixmap(); |
149 | draw.copyArea(theme.bulletPixmap().pixmap().drawable(), | 184 | else |
185 | pm = &theme.bulletPixmap(); | ||
186 | |||
187 | if (pm && pm->pixmap().drawable() != 0) { | ||
188 | unsigned int selw = pm->width(); | ||
189 | unsigned int selh = pm->height(); | ||
190 | |||
191 | int offset_x = 0; | ||
192 | int offset_y = 0; | ||
193 | if (selw < item_pm_height) | ||
194 | offset_x += (item_pm_height - selw) / 2; | ||
195 | if (selh < item_pm_height) | ||
196 | offset_y += (item_pm_height - selh) / 2; | ||
197 | |||
198 | XSetClipMask(disp, gc, pm->mask().drawable()); | ||
199 | XSetClipOrigin(disp, gc, sel_x+offset_x, sel_y+offset_y); | ||
200 | // copy bullet pixmap to drawable | ||
201 | draw.copyArea(pm->pixmap().drawable(), | ||
150 | gc, | 202 | gc, |
151 | 0, 0, | 203 | 0, 0, |
152 | sel_x, y, | 204 | sel_x+offset_x, sel_y+offset_y, |
153 | theme.bulletPixmap().width(), | 205 | selw, |
154 | theme.bulletPixmap().height()); | 206 | selh); |
155 | // disable clip mask | 207 | // disable clip mask |
156 | XSetClipMask(disp, gc, None); | 208 | XSetClipMask(disp, gc, None); |
209 | |||
157 | } else { | 210 | } else { |
158 | unsigned int half_w = height / 2, quarter_w = height / 4; | 211 | unsigned int half_w = item_pm_height / 2, quarter_w = item_pm_height / 4; |
159 | int sel_y = y + height/4; | ||
160 | switch (theme.bullet()) { | 212 | switch (theme.bullet()) { |
161 | case MenuTheme::SQUARE: | 213 | case MenuTheme::SQUARE: |
162 | draw.drawRectangle(gc, sel_x, sel_y, half_w, half_w); | 214 | draw.drawRectangle(gc, sel_x+quarter_w, y+quarter_w, half_w, half_w); |
163 | break; | 215 | break; |
164 | 216 | ||
165 | case MenuTheme::TRIANGLE: | 217 | case MenuTheme::TRIANGLE: |
166 | XPoint tri[3]; | 218 | XPoint tri[3]; |
167 | 219 | ||
168 | if (theme.bulletPos() == FbTk::RIGHT) { | 220 | if (theme.bulletPos() == FbTk::RIGHT) { |
169 | tri[0].x = sel_x + quarter_w - 2; | 221 | tri[0].x = sel_x + half_w - 2; |
170 | tri[0].y = sel_y + quarter_w - 2; | 222 | tri[0].y = sel_y + half_w - 2; |
171 | tri[1].x = 4; | 223 | tri[1].x = 4; |
172 | tri[1].y = 2; | 224 | tri[1].y = 2; |
173 | tri[2].x = -4; | 225 | tri[2].x = -4; |
174 | tri[2].y = 2; | 226 | tri[2].y = 2; |
175 | } else { | 227 | } else { // point the other way |
176 | tri[0].x = sel_x + quarter_w - 2; | 228 | tri[0].x = sel_x + half_w - 2; |
177 | tri[0].y = y + half_w; | 229 | tri[0].y = sel_y + half_w; |
178 | tri[1].x = 4; | 230 | tri[1].x = 4; |
179 | tri[1].y = 2; | 231 | tri[1].y = 2; |
180 | tri[2].x = 0; | 232 | tri[2].x = 0; |
@@ -188,8 +240,8 @@ void MenuItem::draw(FbDrawable &draw, | |||
188 | case MenuTheme::DIAMOND: | 240 | case MenuTheme::DIAMOND: |
189 | XPoint dia[4]; | 241 | XPoint dia[4]; |
190 | 242 | ||
191 | dia[0].x = sel_x + quarter_w - 3; | 243 | dia[0].x = sel_x + half_w - 3; |
192 | dia[0].y = y + half_w; | 244 | dia[0].y = sel_y + half_w; |
193 | dia[1].x = 3; | 245 | dia[1].x = 3; |
194 | dia[1].y = -3; | 246 | dia[1].y = -3; |
195 | dia[2].x = 3; | 247 | dia[2].x = 3; |
@@ -225,7 +277,7 @@ void MenuItem::setIcon(const std::string &filename, int screen_num) { | |||
225 | } | 277 | } |
226 | 278 | ||
227 | unsigned int MenuItem::height(const MenuTheme &theme) const { | 279 | unsigned int MenuItem::height(const MenuTheme &theme) const { |
228 | return std::max(theme.frameFont().height() + theme.bevelWidth(), theme.itemHeight()); | 280 | return std::max(theme.frameFont().height() + 2*theme.bevelWidth(), theme.itemHeight()); |
229 | } | 281 | } |
230 | 282 | ||
231 | unsigned int MenuItem::width(const MenuTheme &theme) const { | 283 | unsigned int MenuItem::width(const MenuTheme &theme) const { |
@@ -233,7 +285,6 @@ unsigned int MenuItem::width(const MenuTheme &theme) const { | |||
233 | const unsigned int icon_width = height(theme); | 285 | const unsigned int icon_width = height(theme); |
234 | const unsigned int normal = theme.frameFont().textWidth(label().c_str(), label().size()) + | 286 | const unsigned int normal = theme.frameFont().textWidth(label().c_str(), label().size()) + |
235 | 2 * (theme.bevelWidth() + icon_width); | 287 | 2 * (theme.bevelWidth() + icon_width); |
236 | |||
237 | return m_icon.get() == 0 ? normal : normal + icon_width; | 288 | return m_icon.get() == 0 ? normal : normal + icon_width; |
238 | } | 289 | } |
239 | 290 | ||