diff options
Diffstat (limited to 'src/FbTk/Menu.cc')
-rw-r--r-- | src/FbTk/Menu.cc | 113 |
1 files changed, 50 insertions, 63 deletions
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc index 451f620..1710db4 100644 --- a/src/FbTk/Menu.cc +++ b/src/FbTk/Menu.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Menu.cc,v 1.4 2003/01/10 00:47:59 fluxgen Exp $ | 25 | // $Id: Menu.cc,v 1.5 2003/01/12 17:01:02 fluxgen Exp $ |
26 | 26 | ||
27 | //use GNU extensions | 27 | //use GNU extensions |
28 | #ifndef _GNU_SOURCE | 28 | #ifndef _GNU_SOURCE |
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include "Menu.hh" | 32 | #include "Menu.hh" |
33 | 33 | ||
34 | #include "MenuItem.hh" | ||
34 | #include "ImageControl.hh" | 35 | #include "ImageControl.hh" |
35 | #include "MenuTheme.hh" | 36 | #include "MenuTheme.hh" |
36 | #include "App.hh" | 37 | #include "App.hh" |
@@ -134,17 +135,16 @@ Menu::Menu(MenuTheme &tm, int screen_num, ImageControl &imgctrl): | |||
134 | evm.add(*this, menu.frame); | 135 | evm.add(*this, menu.frame); |
135 | } | 136 | } |
136 | 137 | ||
137 | |||
138 | Menu::~Menu() { | 138 | Menu::~Menu() { |
139 | menu.window.hide(); | 139 | menu.window.hide(); |
140 | 140 | ||
141 | if (shown && shown->windowID() == windowID()) | 141 | if (shown && shown->windowID() == windowID()) |
142 | shown = (Menu *) 0; | 142 | shown = (Menu *) 0; |
143 | 143 | ||
144 | //TODO: this looks kind of strange | 144 | while (!menuitems.empty()) { |
145 | int n = menuitems.size() - 1; | 145 | delete menuitems.back(); |
146 | for (int i = 0; i < n; ++i) | 146 | menuitems.pop_back(); |
147 | remove(0); | 147 | } |
148 | 148 | ||
149 | if (menu.title_pixmap) | 149 | if (menu.title_pixmap) |
150 | m_image_ctrl.removeImage(menu.title_pixmap); | 150 | m_image_ctrl.removeImage(menu.title_pixmap); |
@@ -166,35 +166,25 @@ Menu::~Menu() { | |||
166 | } | 166 | } |
167 | 167 | ||
168 | int Menu::insert(const char *label, RefCount<Command> &cmd, int pos) { | 168 | int Menu::insert(const char *label, RefCount<Command> &cmd, int pos) { |
169 | MenuItem *item = new MenuItem(label, cmd); | 169 | return insert(new MenuItem(label, cmd), pos); |
170 | if (pos < 0) | ||
171 | menuitems.push_back(item); | ||
172 | else { | ||
173 | if ( pos > menuitems.size()) | ||
174 | pos = menuitems.size(); | ||
175 | menuitems.insert(menuitems.begin() + pos, item); | ||
176 | } | ||
177 | } | 170 | } |
171 | |||
178 | int Menu::insert(const char *label, int pos) { | 172 | int Menu::insert(const char *label, int pos) { |
179 | MenuItem *item = new MenuItem(label); | 173 | return insert(new MenuItem(label), pos); |
180 | if (pos == -1) | ||
181 | menuitems.push_back(item); | ||
182 | else | ||
183 | menuitems.insert(menuitems.begin() + pos, item); | ||
184 | return menuitems.size(); | 174 | return menuitems.size(); |
185 | } | 175 | } |
186 | 176 | ||
187 | int Menu::insert(const char *label, Menu *submenu, int pos) { | 177 | int Menu::insert(const char *label, Menu *submenu, int pos) { |
188 | MenuItem *item = new MenuItem(label, submenu); | 178 | submenu->m_parent = this; |
179 | return insert(new MenuItem(label, submenu), pos); | ||
180 | } | ||
181 | |||
182 | int Menu::insert(MenuItem *item, int pos) { | ||
189 | if (pos == -1) { | 183 | if (pos == -1) { |
190 | menuitems.push_back(item); | 184 | menuitems.push_back(item); |
191 | } else { | 185 | } else { |
192 | menuitems.insert(menuitems.begin() + pos, item); | 186 | menuitems.insert(menuitems.begin() + pos, item); |
193 | } | 187 | } |
194 | |||
195 | submenu->m_parent = this; | ||
196 | |||
197 | return menuitems.size(); | ||
198 | } | 188 | } |
199 | 189 | ||
200 | int Menu::remove(unsigned int index) { | 190 | int Menu::remove(unsigned int index) { |
@@ -213,7 +203,7 @@ int Menu::remove(unsigned int index) { | |||
213 | if (item) { | 203 | if (item) { |
214 | menuitems.erase(it); | 204 | menuitems.erase(it); |
215 | if ((! internal_menu) && (item->submenu())) { | 205 | if ((! internal_menu) && (item->submenu())) { |
216 | Menu *tmp = (Menu *) item->submenu(); | 206 | Menu *tmp = item->submenu(); |
217 | 207 | ||
218 | if (! tmp->internal_menu) { | 208 | if (! tmp->internal_menu) { |
219 | delete tmp; | 209 | delete tmp; |
@@ -289,7 +279,7 @@ void Menu::update() { | |||
289 | menu.sublevels = 1; | 279 | menu.sublevels = 1; |
290 | 280 | ||
291 | while (menu.item_h * (menuitems.size() + 1) / menu.sublevels + | 281 | while (menu.item_h * (menuitems.size() + 1) / menu.sublevels + |
292 | menu.title_h + m_border_width > m_screen_height) | 282 | menu.title_h + m_border_width > m_screen_height) |
293 | menu.sublevels++; | 283 | menu.sublevels++; |
294 | 284 | ||
295 | if (menu.sublevels < menu.minsub) | 285 | if (menu.sublevels < menu.minsub) |
@@ -543,8 +533,10 @@ void Menu::drawSubmenu(unsigned int index) { | |||
543 | if (! moving) | 533 | if (! moving) |
544 | drawItem(index, True); | 534 | drawItem(index, True); |
545 | 535 | ||
546 | if (! item->submenu()->isVisible()) | 536 | if (! item->submenu()->isVisible()) { |
547 | item->submenu()->show(); | 537 | item->submenu()->show(); |
538 | item->submenu()->raise(); | ||
539 | } | ||
548 | 540 | ||
549 | item->submenu()->moving = moving; | 541 | item->submenu()->moving = moving; |
550 | which_sub = index; | 542 | which_sub = index; |
@@ -568,18 +560,16 @@ bool Menu::hasSubmenu(unsigned int index) const { | |||
568 | void Menu::drawItem(unsigned int index, bool highlight, bool clear, | 560 | void Menu::drawItem(unsigned int index, bool highlight, bool clear, |
569 | int x, int y, unsigned int w, unsigned int h) | 561 | int x, int y, unsigned int w, unsigned int h) |
570 | { | 562 | { |
571 | if (index >= menuitems.size() || menuitems.size() == 0) | 563 | if (index >= menuitems.size() || menuitems.size() == 0 || |
564 | menu.persub == 0) | ||
572 | return; | 565 | return; |
573 | 566 | ||
574 | MenuItem *item = menuitems[index]; | 567 | MenuItem *item = menuitems[index]; |
575 | if (! item) return; | 568 | if (! item) return; |
576 | 569 | ||
577 | bool dotext = true, dohilite = true, dosel = true; | 570 | bool dotext = true, dohilite = true, dosel = true; |
578 | const char *text = item->label().c_str(); | 571 | const char *text = item->label().c_str(); |
579 | int sbl = 0, i = index - (sbl * menu.persub); | 572 | int sbl = index / menu.persub, i = index - (sbl * menu.persub); |
580 | if (menu.persub != 0) | ||
581 | sbl = index / menu.persub; | ||
582 | |||
583 | int item_x = (sbl * menu.item_w), item_y = (i * menu.item_h); | 573 | int item_x = (sbl * menu.item_w), item_y = (i * menu.item_h); |
584 | int hilite_x = item_x, hilite_y = item_y, hoff_x = 0, hoff_y = 0; | 574 | int hilite_x = item_x, hilite_y = item_y, hoff_x = 0, hoff_y = 0; |
585 | int text_x = 0, text_y = 0, len = strlen(text), sel_x = 0, sel_y = 0; | 575 | int text_x = 0, text_y = 0, len = strlen(text), sel_x = 0, sel_y = 0; |
@@ -621,7 +611,7 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, | |||
621 | 611 | ||
622 | sel_x += quarter_w; | 612 | sel_x += quarter_w; |
623 | sel_y = item_y + quarter_w; | 613 | sel_y = item_y + quarter_w; |
624 | 614 | ||
625 | if (clear) { | 615 | if (clear) { |
626 | XClearArea(m_display, menu.frame.window(), item_x, item_y, menu.item_w, menu.item_h, | 616 | XClearArea(m_display, menu.frame.window(), item_x, item_y, menu.item_w, menu.item_h, |
627 | False); | 617 | False); |
@@ -829,30 +819,29 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) { | |||
829 | re.x >= 0 && re.x < (signed) menu.width && | 819 | re.x >= 0 && re.x < (signed) menu.width && |
830 | re.y >= 0 && re.y < (signed) menu.frame_h) { | 820 | re.y >= 0 && re.y < (signed) menu.frame_h) { |
831 | 821 | ||
832 | if (re.button == 3) { | 822 | |
833 | hide(); | 823 | |
834 | } else { | 824 | int sbl = (re.x / menu.item_w), i = (re.y / menu.item_h), |
835 | int sbl = (re.x / menu.item_w), i = (re.y / menu.item_h), | 825 | ix = sbl * menu.item_w, iy = i * menu.item_h, |
836 | ix = sbl * menu.item_w, iy = i * menu.item_h, | 826 | w = (sbl * menu.persub) + i, |
837 | w = (sbl * menu.persub) + i, | 827 | p = (which_sbl * menu.persub) + which_press; |
838 | p = (which_sbl * menu.persub) + which_press; | 828 | |
839 | 829 | if (w < static_cast<int>(menuitems.size()) && w >= 0) { | |
840 | if (w < static_cast<int>(menuitems.size()) && w >= 0) { | 830 | drawItem(p, (p == which_sub), True); |
841 | drawItem(p, (p == which_sub), True); | 831 | |
842 | 832 | if (p == w && isItemEnabled(w)) { | |
843 | if (p == w && isItemEnabled(w)) { | 833 | if (re.x > ix && re.x < (signed) (ix + menu.item_w) && |
844 | if (re.x > ix && re.x < (signed) (ix + menu.item_w) && | 834 | re.y > iy && re.y < (signed) (iy + menu.item_h)) { |
845 | re.y > iy && re.y < (signed) (iy + menu.item_h)) { | 835 | menuitems[w]->click(re.button, re.time); |
846 | if (*menuitems[w]->command() != 0) | 836 | itemSelected(re.button, w); |
847 | menuitems[w]->command()->execute(); | 837 | |
848 | else | 838 | update(); // update any changed item |
849 | itemSelected(re.button, w); | ||
850 | } | ||
851 | } | 839 | } |
852 | } else | 840 | } |
853 | drawItem(p, false, true); | 841 | } else |
842 | drawItem(p, false, true); | ||
854 | 843 | ||
855 | } | 844 | |
856 | } | 845 | } |
857 | } | 846 | } |
858 | 847 | ||
@@ -924,25 +913,23 @@ void Menu::exposeEvent(XExposeEvent &ee) { | |||
924 | // first... we see in which sub level the expose starts... and how many | 913 | // first... we see in which sub level the expose starts... and how many |
925 | // items down in that sublevel | 914 | // items down in that sublevel |
926 | 915 | ||
927 | int sbl = (ee.x / menu.item_w), id = (ee.y / menu.item_h), | 916 | unsigned int sbl = (ee.x / menu.item_w), id = (ee.y / menu.item_h), |
928 | // next... figure out how many sublevels over the redraw spans | 917 | // next... figure out how many sublevels over the redraw spans |
929 | sbl_d = ((ee.x + ee.width) / menu.item_w), | 918 | sbl_d = ((ee.x + ee.width) / menu.item_w), |
930 | // then we see how many items down to redraw | 919 | // then we see how many items down to redraw |
931 | id_d = ((ee.y + ee.height) / menu.item_h); | 920 | id_d = ((ee.y + ee.height) / menu.item_h); |
932 | |||
933 | if (id_d > menu.persub) id_d = menu.persub; | 921 | if (id_d > menu.persub) id_d = menu.persub; |
934 | 922 | ||
935 | // draw the sublevels and the number of items the exposure spans | 923 | // draw the sublevels and the number of items the exposure spans |
936 | int i, ii; | 924 | unsigned int i, ii; |
937 | for (i = sbl; i <= sbl_d; i++) { | 925 | for (i = sbl; i <= sbl_d; i++) { |
938 | // set the iterator to the first item in the sublevel needing redrawing | 926 | // set the iterator to the first item in the sublevel needing redrawing |
939 | int index = id + i * menu.persub; | 927 | unsigned int index = id + i * menu.persub; |
940 | if (index < static_cast<int>(menuitems.size()) && index >= 0) { | 928 | if (index < static_cast<int>(menuitems.size()) && index >= 0) { |
941 | Menuitems::iterator it = menuitems.begin() + index; | 929 | Menuitems::iterator it = menuitems.begin() + index; |
942 | Menuitems::iterator it_end = menuitems.end(); | 930 | Menuitems::iterator it_end = menuitems.end(); |
943 | for (ii = id; ii <= id_d && it != it_end; ++it, ii++) { | 931 | for (ii = id; ii <= id_d && it != it_end; ++it, ii++) { |
944 | int index = ii + (i * menu.persub); | 932 | unsigned int index = ii + (i * menu.persub); |
945 | // redraw the item | ||
946 | drawItem(index, (which_sub == index), true, | 933 | drawItem(index, (which_sub == index), true, |
947 | ee.x, ee.y, ee.width, ee.height); | 934 | ee.x, ee.y, ee.width, ee.height); |
948 | } | 935 | } |