4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcmenubar.h"
23 #include "bcmenuitem.h"
24 #include "bcmenupopup.h"
27 #include "bcpopupmenu.h"
28 #include "bcresources.h"
29 #include "bcsignals.h"
30 #include "bcwindowbase.h"
42 #define MENUITEM_MARGIN 2
44 // ================================ Menu Item ==================================
46 BC_MenuItem::BC_MenuItem(const char *text, const char *hotkey_text, int hotkey)
49 this->hotkey_text = 0;
52 if(text) set_text(text);
53 if(hotkey_text) set_hotkey_text(hotkey_text);
55 this->hotkey = hotkey;
67 BC_MenuItem::~BC_MenuItem()
69 if(text) delete [] text;
71 if(hotkey_text) delete [] hotkey_text;
73 if(submenu) delete submenu;
76 menu_popup->remove_item(this);
79 void BC_MenuItem::reset()
86 int BC_MenuItem::initialize(BC_WindowBase *top_level, BC_MenuBar *menu_bar, BC_MenuPopup *menu_popup)
88 this->top_level = top_level;
89 this->menu_popup = menu_popup;
90 this->menu_bar = menu_bar;
94 int BC_MenuItem::set_checked(int value)
96 this->checked = value;
100 int BC_MenuItem::get_checked()
105 void BC_MenuItem::set_icon(BC_Pixmap *icon)
110 BC_Pixmap* BC_MenuItem::get_icon()
115 void BC_MenuItem::set_text(const char *text)
117 delete [] this->text;
118 this->text = cstrdup(text);
121 void BC_MenuItem::set_hotkey_text(const char *text)
123 delete [] this->hotkey_text;
124 this->hotkey_text = cstrdup(text);
127 int BC_MenuItem::deactivate_submenus(BC_MenuPopup *exclude)
129 if(submenu && submenu != exclude)
131 submenu->deactivate_submenus(exclude);
132 submenu->deactivate_menu();
133 submenu->popup_menu = 0;
139 int BC_MenuItem::get_enabled()
143 void BC_MenuItem::set_enabled(int v)
149 int BC_MenuItem::activate_submenu()
152 if(menu_popup->popup && submenu && !submenu->popup)
155 XTranslateCoordinates(top_level->display,
156 menu_popup->get_popup()->win,
163 submenu->popup_menu = menu_popup->popup_menu;
164 submenu->activate_menu(new_x + xS(5), new_y, menu_popup->w - xS(10), h, 0, 0);
171 int BC_MenuItem::dispatch_button_press()
177 result = submenu->dispatch_button_press();
180 if(!result && menu_popup->get_popup()->is_event_win())
182 if(top_level->cursor_x >= 0 && top_level->cursor_x < menu_popup->get_w() &&
183 top_level->cursor_y >= y && top_level->cursor_y < y + h)
202 int BC_MenuItem::dispatch_button_release(int &redraw)
204 int len = strlen(text);
205 if( len > 0 && text[0] == '-' && text[len-1] == '-' ) return 0;
210 result = submenu->dispatch_button_release();
213 if( !result && menu_popup->cursor_inside() ) {
214 int cursor_x, cursor_y;
215 menu_popup->get_popup()->get_relative_cursor(cursor_x, cursor_y);
216 if( cursor_x >= 0 && cursor_x < menu_popup->get_w() &&
217 cursor_y >= y && cursor_y < y + h ) {
219 menu_bar->deactivate();
221 menu_popup->popup_menu->deactivate();
223 if(!handle_event() && menu_popup && menu_popup->popup_menu)
225 menu_popup->popup_menu->set_text(text);
226 menu_popup->popup_menu->handle_event();
234 int BC_MenuItem::dispatch_motion_event(int &redraw)
240 result = submenu->dispatch_motion_event();
243 if( !result && menu_popup->cursor_inside() ) {
244 int cursor_x, cursor_y;
245 menu_popup->get_popup()->get_relative_cursor(cursor_x, cursor_y);
246 if( cursor_x >= 0 && cursor_x < menu_popup->get_w() &&
247 cursor_y >= y && cursor_y < y + h) {
248 // Highlight the item
251 // Deactivate submenus in the parent menu excluding this one.
252 menu_popup->deactivate_submenus(submenu);
254 if(submenu) activate_submenu();
270 int BC_MenuItem::dispatch_translation_event()
273 submenu->dispatch_translation_event();
277 int BC_MenuItem::dispatch_cursor_leave()
282 result = submenu->dispatch_cursor_leave();
285 if(!result && highlighted && menu_popup->get_popup()->is_event_win())
293 int BC_MenuItem::dispatch_key_press()
298 result = submenu->dispatch_key_press();
304 if(top_level->get_keypress() == hotkey &&
305 shift_hotkey == top_level->shift_down() &&
306 alt_hotkey == top_level->alt_down() &&
307 ctrl_hotkey == top_level->ctrl_down())
317 int BC_MenuItem::draw()
319 int text_line = top_level->get_text_descent(MEDIUMFONT);
320 BC_Resources *resources = top_level->get_resources();
322 if(!strcmp(text, "-")) {
323 int bx = xS(5), by = y+h/2, bw = menu_popup->get_w()-xS(10);
324 draw_bar(bx, by, bw);
326 else if( text[0] == '-' && text[strlen(text)-1] == '-' ) {
330 int xoffset = 0, yoffset = 0;
334 //int w = menu_popup->get_w() - 4;
338 if(top_level->get_button_down() && !submenu)
340 if(menu_popup->item_bg[MENUITEM_DN])
342 // menu_popup->get_popup()->draw_9segment(MENUITEM_MARGIN,
344 // menu_popup->get_w() - MENUITEM_MARGIN * 2,
346 // menu_popup->item_bg[MENUITEM_DN]);
347 menu_popup->get_popup()->draw_3segmenth(MENUITEM_MARGIN,
349 menu_popup->get_w() - MENUITEM_MARGIN * 2,
350 menu_popup->item_bg[MENUITEM_DN]);
354 menu_popup->get_popup()->draw_3d_box(MENUITEM_MARGIN,
356 menu_popup->get_w() - MENUITEM_MARGIN * 2,
358 resources->menu_shadow,
360 resources->menu_down,
361 resources->menu_down,
362 resources->menu_light);
364 xoffset = xS(1); yoffset = yS(1);
369 if(menu_popup->item_bg[MENUITEM_HI])
371 // menu_popup->get_popup()->draw_9segment(MENUITEM_MARGIN,
373 // menu_popup->get_w() - MENUITEM_MARGIN * 2,
375 // menu_popup->item_bg[MENUITEM_HI]);
376 menu_popup->get_popup()->draw_3segmenth(MENUITEM_MARGIN,
378 menu_popup->get_w() - MENUITEM_MARGIN * 2,
379 menu_popup->item_bg[MENUITEM_HI]);
383 menu_popup->get_popup()->set_color(resources->menu_highlighted);
384 menu_popup->get_popup()->draw_box(MENUITEM_MARGIN,
386 menu_popup->get_w() - MENUITEM_MARGIN * 2,
390 menu_popup->get_popup()->set_color(resources->menu_highlighted_fontcolor);
394 menu_popup->get_popup()->set_color(resources->menu_item_text);
398 // menu_popup->get_popup()->draw_check(xS(10) + xoffset, y + 2 + yoffset);
399 menu_popup->get_popup()->draw_pixmap(menu_popup->check,
401 y + (this->h - menu_popup->check->get_h()) / 2 + yoffset);
402 menu_popup->get_popup()->set_font(MEDIUMFONT);
403 menu_popup->get_popup()->draw_text(menu_popup->check->get_w() + xoffset,
404 y + h - text_line - 2 + yoffset,
406 menu_popup->get_popup()->draw_text(menu_popup->get_key_x() + xoffset,
407 y + h - text_line - 2 + yoffset,
412 menu_popup->get_popup()->set_font(MEDIUMFONT);
413 menu_popup->get_popup()->draw_text(xS(10) + xoffset, y + h - text_line - 2 + yoffset, text);
414 menu_popup->get_popup()->draw_text(menu_popup->get_key_x() + xoffset, y + h - text_line - 2 + yoffset, hotkey_text);
420 void BC_MenuItem::draw_bar(int bx, int by, int bw)
422 BC_Popup *popup = menu_popup->get_popup();
423 popup->set_color(DKGREY);
424 popup->draw_line(bx, by, bx+bw, by);
425 popup->set_color(LTGREY); ++by;
426 popup->draw_line(bx, by, bx+bw, by);
429 void BC_MenuItem::draw_title_bar()
431 BC_Popup *popup = menu_popup->get_popup();
432 int len = strlen(text)-2;
433 if( len <= 0 ) return;
434 int tw = popup->get_text_width(MEDIUMFONT, text+1, len);
435 int th = popup->get_text_ascent(MEDIUMFONT);
436 int mw = menu_popup->get_w(), lw = mw - tw;
437 int x1 = xS(5), y1 = y+h/2;
438 int tx = lw/4, ty = y1 + th/2;
439 int w1 = tx - x1 - xS(5);
440 if( w1 > 0 ) draw_bar(x1, y1, w1);
441 BC_Resources *resources = top_level->get_resources();
442 popup->set_color(resources->text_background_hi);
443 popup->draw_text(tx, ty, text+1, len);
444 int x2 = tx + tw + xS(5), w2 = mw - xS(5) - x2;
445 if( w2 > 0 ) draw_bar(x2, y1, w2);
448 int BC_MenuItem::add_submenu(BC_SubMenu *submenu)
450 this->submenu = submenu;
451 submenu->initialize(top_level, menu_bar, 0, this, 0);
455 BC_SubMenu* BC_MenuItem::get_submenu()
460 char* BC_MenuItem::get_text()
465 BC_WindowBase* BC_MenuItem::get_top_level()
470 BC_PopupMenu* BC_MenuItem::get_popup_menu()
472 return menu_popup->popup_menu;
475 int BC_MenuItem::set_shift(int value)
477 shift_hotkey = value;
481 int BC_MenuItem::set_alt(int value)
487 void BC_MenuItem::set_ctrl(int value)