Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

bcmenupopup.C

Go to the documentation of this file.
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 // ==================================== Menu Popup =============================
00015 
00016 // Types of menu popups
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 // Each menuitem recursively removes itself from the arraylist
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 // Try submenus and items
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 // printf("BC_MenuPopup::dispatch_translation_event %d %d %d %d\n", 
00171 // top_level->prev_x, 
00172 // top_level->last_translate_x, 
00173 // top_level->prev_y, 
00174 // top_level->last_translate_y);
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 // Coords are relative to the main window
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 // Coords are absolute
00230         {
00231                 new_x = x; 
00232                 new_y = y; 
00233         }
00234 
00235 // All coords are now relative to root window.
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; // Right justify
00241                 if(this->y + this->h > top_h) this->y -= this->h + h; // Bottom justify
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 //              popup->set_background(top_level->get_resources()->menu_bg);
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 // pad for border
00341         h = 2;
00342 // Set up parameters in each item and get total h. 
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 // pad for division
00366         key_x = widest_text + 5;
00367 // pad for border
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 // ================================= Sub Menu ==================================
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 

Generated on Sun Jan 8 13:26:32 2006 for Guicast-svn by  doxygen 1.4.4