00001 #include "bcmenubar.h"
00002 #include "bcmenuitem.h"
00003 #include "bcmenupopup.h"
00004 #include "bcpixmap.h"
00005 #include "bcpopup.h"
00006 #include "bcresources.h"
00007 #include "bcwindowbase.h"
00008 #include "clip.h"
00009
00010 #include <string.h>
00011
00012
00013
00014
00015
00016
00017 #define MENUPOPUP_MENUBAR 0
00018 #define MENUPOPUP_SUBMENU 1
00019 #define MENUPOPUP_POPUP 2
00020
00021 BC_MenuPopup::BC_MenuPopup()
00022 {
00023 window_bg = 0;
00024 item_bg[0] = 0;
00025 item_bg[1] = 0;
00026 item_bg[2] = 0;
00027 }
00028
00029 BC_MenuPopup::~BC_MenuPopup()
00030 {
00031 while(menu_items.total)
00032 {
00033
00034 delete menu_items.values[0];
00035 }
00036 delete window_bg;
00037 delete item_bg[0];
00038 delete item_bg[1];
00039 delete item_bg[2];
00040 }
00041
00042 int BC_MenuPopup::initialize(BC_WindowBase *top_level,
00043 BC_MenuBar *menu_bar,
00044 BC_Menu *menu,
00045 BC_MenuItem *menu_item,
00046 BC_PopupMenu *popup_menu)
00047 {
00048 popup = 0;
00049 active = 0;
00050 this->menu = menu;
00051 this->menu_bar = menu_bar;
00052 this->menu_item = menu_item;
00053 this->popup_menu = popup_menu;
00054 this->top_level = top_level;
00055
00056 if(menu_item) this->type = MENUPOPUP_SUBMENU;
00057 else
00058 if(menu) this->type = MENUPOPUP_MENUBAR;
00059 else
00060 if(popup_menu) this->type = MENUPOPUP_POPUP;
00061
00062 BC_Resources *resources = top_level->get_resources();
00063 if(resources->menu_popup_bg)
00064 {
00065 window_bg = new BC_Pixmap(top_level, resources->menu_popup_bg);
00066 }
00067 if(resources->menu_item_bg)
00068 {
00069 item_bg[0] = new BC_Pixmap(top_level, resources->menu_item_bg[0], PIXMAP_ALPHA);
00070 item_bg[1] = new BC_Pixmap(top_level, resources->menu_item_bg[1], PIXMAP_ALPHA);
00071 item_bg[2] = new BC_Pixmap(top_level, resources->menu_item_bg[2], PIXMAP_ALPHA);
00072 }
00073
00074 return 0;
00075 }
00076
00077 int BC_MenuPopup::add_item(BC_MenuItem *item)
00078 {
00079 menu_items.append(item);
00080 item->initialize(top_level, menu_bar, this);
00081 return 0;
00082 }
00083
00084 int BC_MenuPopup::remove_item(BC_MenuItem *item)
00085 {
00086 if(!item)
00087 {
00088 item = menu_items.values[menu_items.total - 1];
00089 delete item;
00090 }
00091 if(item) menu_items.remove(item);
00092 return 0;
00093 }
00094
00095 int BC_MenuPopup::total_menuitems()
00096 {
00097 return menu_items.total;
00098 }
00099
00100 int BC_MenuPopup::dispatch_button_press()
00101 {
00102 int result = 0;
00103 if(popup)
00104 {
00105 for(int i = 0; i < menu_items.total && !result; i++)
00106 {
00107 result = menu_items.values[i]->dispatch_button_press();
00108 }
00109 if(result) draw_items();
00110 }
00111 return 0;
00112 }
00113
00114 int BC_MenuPopup::dispatch_button_release()
00115 {
00116 int result = 0, redraw = 0;
00117 if(popup)
00118 {
00119 for(int i = 0; i < menu_items.total && !result; i++)
00120 {
00121 result = menu_items.values[i]->dispatch_button_release(redraw);
00122 }
00123 if(redraw) draw_items();
00124 }
00125 return result;
00126 }
00127
00128 int BC_MenuPopup::dispatch_key_press()
00129 {
00130 int result = 0;
00131 for(int i = 0; i < menu_items.total && !result; i++)
00132 {
00133 result = menu_items.values[i]->dispatch_key_press();
00134 }
00135 return result;
00136 }
00137
00138 int BC_MenuPopup::dispatch_motion_event()
00139 {
00140 int i, result = 0, redraw = 0;
00141 Window tempwin;
00142
00143 if(popup)
00144 {
00145
00146 for(i = 0; i < menu_items.total; i++)
00147 {
00148 result |= menu_items.values[i]->dispatch_motion_event(redraw);
00149 }
00150
00151 if(redraw) draw_items();
00152 }
00153
00154 return result;
00155 }
00156
00157 int BC_MenuPopup::dispatch_translation_event()
00158 {
00159 if(popup)
00160 {
00161 int new_x = x +
00162 (top_level->last_translate_x -
00163 top_level->prev_x -
00164 top_level->get_resources()->get_left_border());
00165 int new_y = y +
00166 (top_level->last_translate_y -
00167 top_level->prev_y -
00168 top_level->get_resources()->get_top_border());
00169
00170
00171
00172
00173
00174
00175 popup->reposition_window(new_x, new_y, popup->get_w(), popup->get_h());
00176 top_level->flush();
00177 this->x = new_x;
00178 this->y = new_y;
00179
00180 for(int i = 0; i < menu_items.total; i++)
00181 {
00182 menu_items.values[i]->dispatch_translation_event();
00183 }
00184 }
00185 return 0;
00186 }
00187
00188
00189 int BC_MenuPopup::dispatch_cursor_leave()
00190 {
00191 int result = 0;
00192
00193 if(popup)
00194 {
00195 for(int i = 0; i < menu_items.total; i++)
00196 {
00197 result |= menu_items.values[i]->dispatch_cursor_leave();
00198 }
00199 if(result) draw_items();
00200 }
00201 return 0;
00202 }
00203
00204 int BC_MenuPopup::activate_menu(int x,
00205 int y,
00206 int w,
00207 int h,
00208 int top_window_coords,
00209 int vertical_justify)
00210 {
00211 Window tempwin;
00212 int new_x, new_y, top_w, top_h;
00213 top_w = top_level->get_root_w(1, 0);
00214 top_h = top_level->get_root_h(0);
00215
00216 get_dimensions();
00217
00218
00219 if(top_window_coords)
00220 XTranslateCoordinates(top_level->display,
00221 top_level->win,
00222 top_level->rootwin,
00223 x,
00224 y,
00225 &new_x,
00226 &new_y,
00227 &tempwin);
00228 else
00229
00230 {
00231 new_x = x;
00232 new_y = y;
00233 }
00234
00235
00236 if(vertical_justify)
00237 {
00238 this->x = new_x;
00239 this->y = new_y + h;
00240 if(this->x + this->w > top_w) this->x -= this->x + this->w - top_w;
00241 if(this->y + this->h > top_h) this->y -= this->h + h;
00242 }
00243 else
00244 {
00245 this->x = new_x + w;
00246 this->y = new_y;
00247 if(this->x + this->w > top_w) this->x = new_x - this->w;
00248 if(this->y + this->h > top_h) this->y = new_y + h - this->h;
00249 }
00250
00251 active = 1;
00252 if(menu_bar)
00253 {
00254 popup = new BC_Popup(menu_bar,
00255 this->x,
00256 this->y,
00257 this->w,
00258 this->h,
00259 top_level->get_resources()->menu_up,
00260 1,
00261 menu_bar->bg_pixmap);
00262 }
00263 else
00264 {
00265 popup = new BC_Popup(top_level,
00266 this->x,
00267 this->y,
00268 this->w,
00269 this->h,
00270 top_level->get_resources()->menu_up,
00271 1,
00272 0);
00273
00274 }
00275 draw_items();
00276 popup->show_window();
00277 return 0;
00278 }
00279
00280 int BC_MenuPopup::deactivate_submenus(BC_MenuPopup *exclude)
00281 {
00282 for(int i = 0; i < menu_items.total; i++)
00283 {
00284 menu_items.values[i]->deactivate_submenus(exclude);
00285 }
00286 return 0;
00287 }
00288
00289 int BC_MenuPopup::deactivate_menu()
00290 {
00291 deactivate_submenus(0);
00292
00293 if(popup) delete popup;
00294 popup = 0;
00295 active = 0;
00296
00297 return 0;
00298 }
00299
00300 int BC_MenuPopup::draw_items()
00301 {
00302 if(menu_bar)
00303 popup->draw_top_tiles(menu_bar, 0, 0, w, h);
00304 else
00305 popup->draw_top_tiles(popup, 0, 0, w, h);
00306
00307 if(window_bg)
00308 {
00309 popup->draw_9segment(0,
00310 0,
00311 w,
00312 h,
00313 window_bg);
00314 }
00315 else
00316 {
00317 popup->draw_3d_border(0, 0, w, h,
00318 top_level->get_resources()->menu_light,
00319 top_level->get_resources()->menu_up,
00320 top_level->get_resources()->menu_shadow,
00321 BLACK);
00322 }
00323
00324 for(int i = 0; i < menu_items.total; i++)
00325 {
00326 menu_items.values[i]->draw();
00327 }
00328 popup->flash();
00329
00330
00331 return 0;
00332 }
00333
00334 int BC_MenuPopup::get_dimensions()
00335 {
00336 int widest_text = 10, widest_key = 10;
00337 int text_w, key_w;
00338 int i = 0;
00339
00340
00341 h = 2;
00342
00343 for(i = 0; i < menu_items.total; i++)
00344 {
00345 text_w = 10 + top_level->get_text_width(MEDIUMFONT, menu_items.values[i]->text);
00346 if(menu_items.values[i]->checked) text_w += 20;
00347
00348 key_w = 10 + top_level->get_text_width(MEDIUMFONT, menu_items.values[i]->hotkey_text);
00349 if(text_w > widest_text) widest_text = text_w;
00350 if(key_w > widest_key) widest_key = key_w;
00351
00352 if(!strcmp(menu_items.values[i]->text, "-"))
00353 menu_items.values[i]->h = 5;
00354 else
00355 menu_items.values[i]->h = top_level->get_text_height(MEDIUMFONT) + 4;
00356
00357 menu_items.values[i]->y = h;
00358 menu_items.values[i]->highlighted = 0;
00359 menu_items.values[i]->down = 0;
00360 h += menu_items.values[i]->h;
00361 }
00362 w = widest_text + widest_key + 10;
00363
00364 w = MAX(w, top_level->get_resources()->min_menu_w);
00365
00366 key_x = widest_text + 5;
00367
00368 h += 2;
00369 return 0;
00370 }
00371
00372 int BC_MenuPopup::get_key_x()
00373 {
00374 return key_x;
00375 }
00376
00377 BC_Popup* BC_MenuPopup::get_popup()
00378 {
00379 return popup;
00380 }
00381
00382 int BC_MenuPopup::get_w()
00383 {
00384 return w;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393 BC_SubMenu::BC_SubMenu() : BC_MenuPopup()
00394 {
00395 }
00396
00397 BC_SubMenu::~BC_SubMenu()
00398 {
00399 }
00400
00401 int BC_SubMenu::add_submenuitem(BC_MenuItem *item)
00402 {
00403 add_item(item);
00404 return 0;
00405 }
00406