r370: Heroine Virutal's official release 1.2.1
[cinelerra_cv/mob.git] / hvirtual / guicast / bcmenupopup.C
blob59db5b3325f077d95c52ef67ea3e66bdb34d3a79
1 #include "bcmenubar.h"
2 #include "bcmenuitem.h"
3 #include "bcmenupopup.h"
4 #include "bcpopup.h"
5 #include "bcresources.h"
6 #include "bcwindowbase.h"
9 #include <string.h>
13 // ==================================== Menu Popup =============================
15 // Types of menu popups
16 #define MENUPOPUP_MENUBAR 0
17 #define MENUPOPUP_SUBMENU 1
18 #define MENUPOPUP_POPUP   2
20 BC_MenuPopup::BC_MenuPopup()
24 BC_MenuPopup::~BC_MenuPopup()
26         while(menu_items.total)
27         {
28 // Each menuitem recursively removes itself from the arraylist
29                 delete menu_items.values[0];
30         }
33 int BC_MenuPopup::initialize(BC_WindowBase *top_level, 
34                 BC_MenuBar *menu_bar, 
35                 BC_Menu *menu, 
36                 BC_MenuItem *menu_item, 
37                 BC_PopupMenu *popup_menu)
39         popup = 0;
40         active = 0;
41         this->menu = menu;
42         this->menu_bar = menu_bar;
43         this->menu_item = menu_item;
44         this->popup_menu = popup_menu;
45         this->top_level = top_level;
47         if(menu_item) this->type = MENUPOPUP_SUBMENU;
48         else
49         if(menu) this->type = MENUPOPUP_MENUBAR;
50         else
51         if(popup_menu) this->type = MENUPOPUP_POPUP;
53         return 0;
56 int BC_MenuPopup::add_item(BC_MenuItem *item)
58         menu_items.append(item);
59         item->initialize(top_level, menu_bar, this);
60         return 0;
63 int BC_MenuPopup::remove_item(BC_MenuItem *item)
65         if(!item)
66         {
67                 item = menu_items.values[menu_items.total - 1];
68                 delete item;
69         }
70         if(item) menu_items.remove(item);
71         return 0;
74 int BC_MenuPopup::total_menuitems()
76         return menu_items.total;
79 int BC_MenuPopup::dispatch_button_press()
81         int result = 0;
82         if(popup)
83         {
84                 for(int i = 0; i < menu_items.total && !result; i++)
85                 {
86                         result = menu_items.values[i]->dispatch_button_press();
87                 }
88                 if(result) draw_items();
89         }
90         return 0;
93 int BC_MenuPopup::dispatch_button_release()
95         int result = 0, redraw = 0;
96         if(popup)
97         {
98                 for(int i = 0; i < menu_items.total && !result; i++)
99                 {
100                         result = menu_items.values[i]->dispatch_button_release(redraw);
101                 }
102                 if(redraw) draw_items();
103         }
104         return result;
107 int BC_MenuPopup::dispatch_key_press()
109         int result = 0;
110         for(int i = 0; i < menu_items.total && !result; i++)
111         {
112                 result = menu_items.values[i]->dispatch_key_press();
113         }
114         return result;
117 int BC_MenuPopup::dispatch_motion_event()
119         int i, result = 0, redraw = 0;
120         Window tempwin;
122         if(popup)
123         {
124 // Try submenus and items
125                 for(i = 0; i < menu_items.total; i++)
126                 {
127                         result |= menu_items.values[i]->dispatch_motion_event(redraw);
128                 }
130                 if(redraw) draw_items();
131         }
133         return result;
136 int BC_MenuPopup::dispatch_translation_event()
138         if(popup)
139         {
140                 int new_x = x + 
141                         (top_level->last_translate_x - 
142                         top_level->prev_x - 
143                         top_level->get_resources()->get_left_border());
144                 int new_y = y + 
145                         (top_level->last_translate_y - 
146                         top_level->prev_y -
147                         top_level->get_resources()->get_top_border());
149 // printf("BC_MenuPopup::dispatch_translation_event %d %d %d %d\n", 
150 // top_level->prev_x, 
151 // top_level->last_translate_x, 
152 // top_level->prev_y, 
153 // top_level->last_translate_y);
154                 popup->reposition_window(new_x, new_y, popup->get_w(), popup->get_h());
155                 top_level->flush();
156                 this->x = new_x;
157                 this->y = new_y;
159                 for(int i = 0; i < menu_items.total; i++)
160                 {
161                         menu_items.values[i]->dispatch_translation_event();
162                 }
163         }
164         return 0;
168 int BC_MenuPopup::dispatch_cursor_leave()
170         int result = 0;
171         
172         if(popup)
173         {
174                 for(int i = 0; i < menu_items.total; i++)
175                 {
176                         result |= menu_items.values[i]->dispatch_cursor_leave();
177                 }
178                 if(result) draw_items();
179         }
180         return 0;
183 int BC_MenuPopup::activate_menu(int x, 
184         int y, 
185         int w, 
186         int h, 
187         int top_window_coords, 
188         int vertical_justify)
190         Window tempwin;
191         int new_x, new_y, top_w, top_h;
192         top_w = top_level->get_root_w(1, 0);
193         top_h = top_level->get_root_h(0);
195         get_dimensions();
197 // Coords are relative to the main window
198         if(top_window_coords)
199                 XTranslateCoordinates(top_level->display, 
200                         top_level->win, 
201                         top_level->rootwin, 
202                         x, 
203                         y, 
204                         &new_x, 
205                         &new_y, 
206                         &tempwin);
207         else
208 // Coords are absolute
209         {
210                 new_x = x; 
211                 new_y = y; 
212         }
214 // All coords are now relative to root window.
215         if(vertical_justify)
216         {
217                 this->x = new_x;
218                 this->y = new_y + h;
219                 if(this->x + this->w > top_w) this->x -= this->x + this->w - top_w; // Right justify
220                 if(this->y + this->h > top_h) this->y -= this->h + h; // Bottom justify
221         }
222         else
223         {
224                 this->x = new_x + w;
225                 this->y = new_y;
226                 if(this->x + this->w > top_w) this->x = new_x - this->w;
227                 if(this->y + this->h > top_h) this->y = new_y + h - this->h;
228         }
230         active = 1;
231         if(menu_bar)
232         {
233                 popup = new BC_Popup(menu_bar, 
234                                         this->x, 
235                                         this->y, 
236                                         this->w, 
237                                         this->h, 
238                                         top_level->get_resources()->menu_up,
239                                         1,
240                                         menu_bar->bg_pixmap);
241         }
242         else
243         {
244                 popup = new BC_Popup(top_level, 
245                                         this->x, 
246                                         this->y, 
247                                         this->w, 
248                                         this->h, 
249                                         top_level->get_resources()->menu_up,
250                                         1,
251                                         0);
252 //              popup->set_background(top_level->get_resources()->menu_bg);
253         }
254         draw_items();
255         popup->show_window();
256         return 0;
259 int BC_MenuPopup::deactivate_submenus(BC_MenuPopup *exclude)
261         for(int i = 0; i < menu_items.total; i++)
262         {
263                 menu_items.values[i]->deactivate_submenus(exclude);
264         }
265         return 0;
268 int BC_MenuPopup::deactivate_menu()
270         deactivate_submenus(0);
272         if(popup) delete popup;
273         popup = 0;
274         active = 0;
276         return 0;
279 int BC_MenuPopup::draw_items()
281         if(menu_bar)
282                 popup->draw_top_tiles(menu_bar, 0, 0, w, h);
283         else
284                 popup->draw_top_tiles(popup, 0, 0, w, h);
286         popup->draw_3d_border(0, 0, w, h, 
287                 top_level->get_resources()->menu_light,
288                 top_level->get_resources()->menu_up,
289                 top_level->get_resources()->menu_shadow,
290                 BLACK);
292         for(int i = 0; i < menu_items.total; i++)
293         {
294                 menu_items.values[i]->draw();
295         }
296         popup->flash();
297 //printf("BC_MenuPopup::draw_items 1\n");
298         return 0;
301 int BC_MenuPopup::get_dimensions()
303         int widest_text = 10, widest_key = 10;
304         int text_w, key_w;
305         int i = 0;
307 // pad for border
308         h = 2;
309 // Set up parameters in each item and get total h. 
310         for(i = 0; i < menu_items.total; i++)
311         {
312                 text_w = 10 + top_level->get_text_width(MEDIUMFONT, menu_items.values[i]->text);
313                 if(menu_items.values[i]->checked) text_w += 20;
315                 key_w = 10 + top_level->get_text_width(MEDIUMFONT, menu_items.values[i]->hotkey_text);
316                 if(text_w > widest_text) widest_text = text_w;
317                 if(key_w > widest_key) widest_key = key_w;
319                 if(!strcmp(menu_items.values[i]->text, "-")) 
320                         menu_items.values[i]->h = 5;
321                 else
322                         menu_items.values[i]->h = top_level->get_text_height(MEDIUMFONT) + 4;
324                 menu_items.values[i]->y = h;
325                 menu_items.values[i]->highlighted = 0;
326                 menu_items.values[i]->down = 0;
327                 h += menu_items.values[i]->h;
328         }
329         w = widest_text + widest_key + 10;
330 // pad for division
331         key_x = widest_text + 5;
332 // pad for border
333         h += 2;
334         return 0;
337 int BC_MenuPopup::get_key_x()
339         return key_x;
342 BC_Popup* BC_MenuPopup::get_popup()
344         return popup;
347 int BC_MenuPopup::get_w()
349         return w;
356 // ================================= Sub Menu ==================================
358 BC_SubMenu::BC_SubMenu() : BC_MenuPopup()
362 BC_SubMenu::~BC_SubMenu()
366 int BC_SubMenu::add_submenuitem(BC_MenuItem *item)
368         add_item(item);
369         return 0;