24
#include "WindowCompositor.h"
30
static const UINT MENU_MINIMUM_WIDTH = 10;
31
static const UINT MENU_MINIMUM_HEIGHT = 16;
33
static const UINT MENUBAR_ICON_WIDTH = 24;
34
static const UINT MENUBAR_ICON_HEIGHT = 24;
36
IMPLEMENT_ROOT_OBJECT_TYPE(MenuBarItem);
37
IMPLEMENT_OBJECT_TYPE(MenuBar);
39
MenuBarItem::MenuBarItem()
41
area = smptr(CoreArea)(new CoreArea());
45
MenuBarItem::~MenuBarItem()
47
menu = smptr(MenuPage)(0);
48
area = smptr(CoreArea)(0);
52
: m_MenuIsActive(false)
54
, m_IsOpeningMenu(false)
57
m_hlayout = smptr(HLayout)(new HLayout());
58
m_hlayout->SetHorizontalInternalMargin(4);
59
m_hlayout->SetHorizontalExternalMargin(2);
61
SetMinimumSize(24, 24);
62
SetMaximumSize(BASEOBJECT_MAXWIDTH, 24);
63
setGeometry(Geometry(0, 0, 200, 20));
65
m_hlayout->SetHorizontalInternalMargin(4);
66
m_hlayout->SetVerticalExternalMargin(0);
67
m_hlayout->SetContentStacking(eStackLeft);
68
SetCompositionLayout(m_hlayout);
73
if(m_CurrentMenu.IsValid())
75
// m_CurrentMenu->area->OnMouseEnter.clear();
76
// m_CurrentMenu->area->OnMouseEnter.clear();
77
// m_CurrentMenu->area->OnMouseLeave.clear();
78
// m_CurrentMenu->area->OnMouseDown.clear();
79
// m_CurrentMenu->area->OnMouseDrag.clear();
80
// m_CurrentMenu->area->OnMouseUp.clear();
83
std::list< smptr(MenuBarItem) >::iterator it;
84
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
86
// (*it)->area->OnMouseEnter.clear();
87
// (*it)->area->OnMouseEnter.clear();
88
// (*it)->area->OnMouseLeave.clear();
89
// (*it)->area->OnMouseDown.clear();
90
// (*it)->area->OnMouseDrag.clear();
91
// (*it)->area->OnMouseUp.clear();
93
(*it) = smptr(MenuBarItem)(0);
95
m_MenuBarItemList.clear();
98
long MenuBar::ProcessEvent(IEvent &ievent, long TraverseInfo, long ProcessEventInfo)
100
long ret = TraverseInfo;
103
ret = TraverseInfo; // <<---- never forget this
105
std::list< smptr(MenuBarItem) >::iterator it;
107
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
109
(*it)->menu->m_MenuWindow = m_MenuBarWindow;
110
ret = (*it)->area->OnEvent(ievent, ret, ProcessEventInfo);
113
if(ievent.e_event == INL_MOUSE_PRESSED)
115
bool mouse_down_on_menu_item = false;
116
if(m_MenuIsActive == true)
118
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
120
if((*it)->area->IsMouseInside())
122
mouse_down_on_menu_item = true;
126
if(mouse_down_on_menu_item == false)
128
if(m_CurrentMenu->menu->TestMouseDown() == false)
130
RecvSigTerminateMenuCascade();
137
// PostProcessEvent2 must always have its last parameter set to 0
138
// because the m_BackgroundArea is the real physical limit of the window.
139
// So the previous test about IsPointInside do not prevail over m_BackgroundArea
140
// testing the event by itself.
141
ret = PostProcessEvent2(ievent, ret, 0);
145
void MenuBar::Draw(GraphicsContext& GfxContext, bool force_draw)
147
Geometry base = GetGeometry();
148
GfxContext.PushClippingRectangle(base);
150
Geometry item_geometry;
151
std::list< smptr(MenuBarItem) >::iterator it;
152
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
154
smptr(CoreArea) area = (*it)->area;
155
item_geometry = area->GetGeometry();
156
if(area->IsMouseInside())
159
gPainter.PaintBackground(GfxContext, item_geometry);
162
gPainter.Paint2DQuadColor(GfxContext, item_geometry, Color(0xFF000000));
163
//gPainter.PaintShape(GfxContext, item_geometry, Color(0xFF000000), eSHAPE_CORNER_ROUND2);
167
gPainter.Paint2DQuadColor(GfxContext, item_geometry, Color(0xFF000000));
168
//gPainter.PaintShapeCorner(GfxContext, item_geometry, Color(0xFF000000), eSHAPE_CORNER_ROUND2,
169
//eCornerTopLeft|eCornerTopRight, false);
174
GfxContext.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
175
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
176
gPainter.Draw2DTexture(GfxContext, (*it)->icon, item_geometry.x, item_geometry.y);
177
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
178
GfxContext.GetRenderStates().SetBlend(GL_FALSE);
182
gPainter.PaintTextLineStatic(GfxContext, GetFont(), item_geometry, area->GetBaseString().GetTCharPtr(), GetTextColor(), true, eAlignTextCenter);
187
gPainter.PaintBackground(GfxContext, item_geometry);
191
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
192
GfxContext.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
193
gPainter.Draw2DTexture(GfxContext, (*it)->icon, item_geometry.x, item_geometry.y);
194
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
195
GfxContext.GetRenderStates().SetBlend(GL_FALSE);
199
gPainter.PaintTextLineStatic(GfxContext, GetFont(), item_geometry, area->GetBaseString().GetTCharPtr(), GetTextColor(), true, eAlignTextCenter);
205
smptr(CoreArea) area(m_CurrentMenu->area);
206
item_geometry = area->GetGeometry();
207
gPainter.PaintBackground(GfxContext, item_geometry);
208
gPainter.Paint2DQuadColor(GfxContext, item_geometry, Color(0xFF000000));
209
//gPainter.PaintShapeCorner(GfxContext, item_geometry, Color(0xFF000000), eSHAPE_CORNER_ROUND2, eCornerTopLeft|eCornerTopRight, true);
211
if(m_CurrentMenu->icon)
213
GfxContext.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
214
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
215
gPainter.Draw2DTexture(GfxContext, m_CurrentMenu->icon, item_geometry.x, item_geometry.y);
216
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
217
GfxContext.GetRenderStates().SetBlend(GL_FALSE);
221
gPainter.PaintTextLineStatic(GfxContext, GetFont(), item_geometry, area->GetBaseString().GetTCharPtr(), GetTextColor(), true, eAlignTextCenter);
224
GfxContext.PopClippingRectangle();
227
void MenuBar::DrawContent(GraphicsContext& GfxContext, bool force_draw)
229
GfxContext.PushClippingRectangle(GetGeometry());
230
GfxContext.PopClippingRectangle();
233
void MenuBar::PostDraw(GraphicsContext& GfxContext, bool force_draw)
238
void MenuBar::AddMenu(const TCHAR* MenuLabel, smptr(MenuPage) menu)
240
AddMenu(MenuLabel, menu, 0);
243
void MenuBar::AddMenu(const TCHAR* MenuLabel, smptr(MenuPage) menu, NTexture *icon)
245
// Need to add INL_RETURN_IF_TRUE, INL_RETURN_IF_FALSE
246
INL_RETURN_IF_TRUE(menu.IsNull());
248
smptr(MenuBarItem) menubar_item(new MenuBarItem());
250
menu->m_IsTopOfMenuChain = true;
251
menubar_item->area->SetBaseString(MenuLabel);
252
menubar_item->menu = menu;
253
menubar_item->icon = icon;
255
m_MenuBarItemList.push_back(menubar_item);
256
//menubar_item->area->SetMinimumSize(DEFAULT_WIDGET_WIDTH, 40);
259
menubar_item->area->SetMinimumSize(Max(MENU_MINIMUM_WIDTH, (UINT)(10 + GetFont()->GetStringWidth(MenuLabel))), Max(MENU_MINIMUM_WIDTH, (UINT)16));
263
menubar_item->area->SetMinMaxSize(MENUBAR_ICON_WIDTH, MENUBAR_ICON_HEIGHT);
266
menubar_item->area->OnMouseEnter.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::EmitItemMouseEnter), weaksmptr(MenuBarItem)(menubar_item)));
267
menubar_item->area->OnMouseLeave.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::EmitItemMouseLeave), weaksmptr(MenuBarItem)(menubar_item)));
268
menubar_item->area->OnMouseDown.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::EmitItemMouseDown), weaksmptr(MenuBarItem)(menubar_item)));
269
menubar_item->area->OnMouseDrag.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::RecvItemMouseDrag), weaksmptr(MenuBarItem)(menubar_item)));
270
menubar_item->area->OnMouseUp.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::EmitItemMouseUp), weaksmptr(MenuBarItem)(menubar_item)));
272
menubar_item->menu->SetParentMenu(smptr(MenuPage)(0));
273
menubar_item->menu->sigActionTriggered.connect(sigc::mem_fun(this, &MenuBar::RecvSigActionTriggered));
274
menubar_item->menu->sigTerminateMenuCascade.connect(sigc::mem_fun(this, &MenuBar::RecvSigTerminateMenuCascade));
275
menubar_item->menu->sigMouseDownOutsideMenuCascade.connect(sigc::mem_fun(this, &MenuBar::RecvSigMouseDownOutsideMenuCascade));
277
m_hlayout->AddActiveInterfaceObject(menubar_item->area, 0, eCenter);
278
GetGraphicsThread()->ComputeElementLayout(m_hlayout);
281
void MenuBar::EmitItemMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
285
if(m_CurrentMenu.IsValid() && (m_CurrentMenu->menu != menubar_item->menu))
286
m_CurrentMenu->menu->StopMenu(0, 0);
288
Geometry geo = menubar_item->menu->GetGeometry();
289
menubar_item->menu->m_MenuWindow = m_MenuBarWindow;
290
menubar_item->menu->StartMenu(menubar_item->area->GetBaseX(),
291
menubar_item->area->GetBaseY() + menubar_item->area->GetBaseHeight(), 0, 0);
293
m_CurrentMenu = menubar_item;
295
m_IsOpeningMenu = true;
300
void MenuBar::EmitItemMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
304
void MenuBar::EmitItemMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
306
m_MenuBarWindow = GetThreadWindowCompositor().GetCurrentWindow();
307
if(m_MenuIsActive == false)
309
// Open the corresponding MenuPage
310
if(m_CurrentMenu.IsValid())
312
// This should never happen
314
m_CurrentMenu->menu->StopMenu();
317
m_MenuIsActive = true;
318
m_CurrentMenu = menubar_item;
319
m_CurrentMenu->menu->m_MenuWindow = m_MenuBarWindow;
320
m_IsOpeningMenu = true;
322
//m_CurrentMenu->area->ForceStopFocus(0, 0);
323
m_CurrentMenu->menu->StartMenu(menubar_item->area->GetBaseX(),
324
menubar_item->area->GetBaseY() + menubar_item->area->GetBaseHeight(), 0, 0);
328
// If the mouse up that follows happen inside the area, then it is going to close the menu.
329
m_IsOpeningMenu = false;
334
void MenuBar::EmitItemMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
338
if(m_CurrentMenu->area->IsMouseInside())
340
if(m_IsOpeningMenu == false)
342
// close the MenuPage that is Open
343
if(m_CurrentMenu.IsValid())
344
m_CurrentMenu->menu->StopMenu(0, 0);
345
m_MenuIsActive = false;
346
m_CurrentMenu = smptr(MenuBarItem)(0);
350
// The MousePress before this MouseRelease, caused the MenuPage to open.
351
// Set m_IsOpeningMenu so the next mouse release will close the menu.
352
m_IsOpeningMenu = false;
357
bool hit_inside_a_menu = false;
358
bool b = m_CurrentMenu->menu->TestMouseUp(x, y, button_flags, key_flags, hit_inside_a_menu);
359
if(b || (hit_inside_a_menu == false))
361
RecvSigTerminateMenuCascade();
368
void MenuBar::RecvItemMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
370
// Transition between one menu bar item to another
371
if(GetThreadWindowCompositor().GetMouseFocusArea() == menubar_item->area)
373
if(!menubar_item->area->IsMouseInside()) // can also test GetThreadWindowCompositor().GetMouseOverArea() != &menubar_item->area
376
std::list< smptr(MenuBarItem) >::iterator it;
377
// compute window coordinates x and y;
378
int winx = menubar_item->area->GetBaseX() + x;
379
int winy = menubar_item->area->GetBaseY() + y;
380
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
382
smptr(CoreArea) area = (*it)->area;
383
Geometry geometry = area->GetGeometry();
384
if(geometry.IsPointInside(winx, winy))
386
// Close the menu below menubar_item (the one that has the focus
387
menubar_item->area->ForceStopFocus(0, 0);
389
// EmitItemMouseEnter is going to open the menu below (*it)
391
EmitItemMouseEnter(winx, winy, button_flags, key_flags, (*it));
392
m_IsOpeningMenu = true;
393
area->ForceStartFocus(0, 0);
395
GetThreadWindowCompositor().SetMouseFocusArea(area);
396
GetThreadWindowCompositor().SetMouseOverArea(area);
406
void MenuBar::RecvSigActionTriggered(smptr(MenuPage) menu, const smptr(ActionItem) action)
408
m_MenuIsActive = false;
409
if(m_CurrentMenu.IsValid())
411
m_CurrentMenu->menu->StopMenu();
414
m_CurrentMenu = smptr(MenuBarItem)(0);
415
m_IsOpeningMenu = false;
417
// You can do something if you want with the menu* and the action*
421
void MenuBar::RecvSigTerminateMenuCascade()
423
m_MenuIsActive = false;
424
if(m_CurrentMenu.IsValid())
426
m_CurrentMenu->menu->StopMenu();
428
m_CurrentMenu = smptr(MenuBarItem)(0);
429
m_IsOpeningMenu = false;
434
void MenuBar::RecvSigMouseDownOutsideMenuCascade(smptr(MenuPage) menu, int x, int y)
437
std::list< smptr(MenuBarItem) >::iterator it;
438
UBOOL TerminateMenuCascade = 1;
439
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
441
smptr(CoreArea) area = (*it)->area;
442
geometry = area->GetGeometry();
443
if(geometry.IsPointInside(x, y))
445
// The event landed on one of the MenuBar item.
446
// Do nothing. This will be handled in the ProcessEvent of the MenuBar item where the mouse down landed.
447
TerminateMenuCascade = 0;
451
if(TerminateMenuCascade)
452
RecvSigTerminateMenuCascade();
24
#include "WindowCompositor.h"
30
static const UINT MENU_MINIMUM_WIDTH = 10;
31
static const UINT MENU_MINIMUM_HEIGHT = 16;
33
static const UINT MENUBAR_ICON_WIDTH = 24;
34
static const UINT MENUBAR_ICON_HEIGHT = 24;
36
IMPLEMENT_ROOT_OBJECT_TYPE(MenuBarItem);
37
IMPLEMENT_OBJECT_TYPE(MenuBar);
39
MenuBarItem::MenuBarItem()
41
area = smptr(CoreArea)(new CoreArea());
45
MenuBarItem::~MenuBarItem()
47
menu = smptr(MenuPage)(0);
48
area = smptr(CoreArea)(0);
52
: m_MenuIsActive(false)
54
, m_IsOpeningMenu(false)
57
m_hlayout = smptr(HLayout)(new HLayout());
58
m_hlayout->SetHorizontalInternalMargin(4);
59
m_hlayout->SetHorizontalExternalMargin(2);
61
SetMinimumSize(24, 24);
62
SetMaximumSize(BASEOBJECT_MAXWIDTH, 24);
63
setGeometry(Geometry(0, 0, 200, 20));
65
m_hlayout->SetHorizontalInternalMargin(4);
66
m_hlayout->SetVerticalExternalMargin(0);
67
m_hlayout->SetContentStacking(eStackLeft);
68
SetCompositionLayout(m_hlayout);
73
if(m_CurrentMenu.IsValid())
75
// m_CurrentMenu->area->OnMouseEnter.clear();
76
// m_CurrentMenu->area->OnMouseEnter.clear();
77
// m_CurrentMenu->area->OnMouseLeave.clear();
78
// m_CurrentMenu->area->OnMouseDown.clear();
79
// m_CurrentMenu->area->OnMouseDrag.clear();
80
// m_CurrentMenu->area->OnMouseUp.clear();
83
std::list< smptr(MenuBarItem) >::iterator it;
84
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
86
// (*it)->area->OnMouseEnter.clear();
87
// (*it)->area->OnMouseEnter.clear();
88
// (*it)->area->OnMouseLeave.clear();
89
// (*it)->area->OnMouseDown.clear();
90
// (*it)->area->OnMouseDrag.clear();
91
// (*it)->area->OnMouseUp.clear();
93
(*it) = smptr(MenuBarItem)(0);
95
m_MenuBarItemList.clear();
98
long MenuBar::ProcessEvent(IEvent &ievent, long TraverseInfo, long ProcessEventInfo)
100
long ret = TraverseInfo;
103
ret = TraverseInfo; // <<---- never forget this
105
std::list< smptr(MenuBarItem) >::iterator it;
107
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
109
(*it)->menu->m_MenuWindow = m_MenuBarWindow;
110
ret = (*it)->area->OnEvent(ievent, ret, ProcessEventInfo);
113
if(ievent.e_event == INL_MOUSE_PRESSED)
115
bool mouse_down_on_menu_item = false;
116
if(m_MenuIsActive == true)
118
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
120
if((*it)->area->IsMouseInside())
122
mouse_down_on_menu_item = true;
126
if(mouse_down_on_menu_item == false)
128
if(m_CurrentMenu->menu->TestMouseDown() == false)
130
RecvSigTerminateMenuCascade();
137
// PostProcessEvent2 must always have its last parameter set to 0
138
// because the m_BackgroundArea is the real physical limit of the window.
139
// So the previous test about IsPointInside do not prevail over m_BackgroundArea
140
// testing the event by itself.
141
ret = PostProcessEvent2(ievent, ret, 0);
145
void MenuBar::Draw(GraphicsContext& GfxContext, bool force_draw)
147
Geometry base = GetGeometry();
148
GfxContext.PushClippingRectangle(base);
150
Geometry item_geometry;
151
std::list< smptr(MenuBarItem) >::iterator it;
152
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
154
smptr(CoreArea) area = (*it)->area;
155
item_geometry = area->GetGeometry();
156
if(area->IsMouseInside())
159
gPainter.PaintBackground(GfxContext, item_geometry);
162
gPainter.Paint2DQuadColor(GfxContext, item_geometry, Color(0xFF000000));
163
//gPainter.PaintShape(GfxContext, item_geometry, Color(0xFF000000), eSHAPE_CORNER_ROUND2);
167
gPainter.Paint2DQuadColor(GfxContext, item_geometry, Color(0xFF000000));
168
//gPainter.PaintShapeCorner(GfxContext, item_geometry, Color(0xFF000000), eSHAPE_CORNER_ROUND2,
169
//eCornerTopLeft|eCornerTopRight, false);
174
GfxContext.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
175
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
176
gPainter.Draw2DTexture(GfxContext, (*it)->icon, item_geometry.x, item_geometry.y);
177
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
178
GfxContext.GetRenderStates().SetBlend(GL_FALSE);
182
gPainter.PaintTextLineStatic(GfxContext, GetFont(), item_geometry, area->GetBaseString().GetTCharPtr(), GetTextColor(), true, eAlignTextCenter);
187
gPainter.PaintBackground(GfxContext, item_geometry);
191
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
192
GfxContext.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
193
gPainter.Draw2DTexture(GfxContext, (*it)->icon, item_geometry.x, item_geometry.y);
194
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
195
GfxContext.GetRenderStates().SetBlend(GL_FALSE);
199
gPainter.PaintTextLineStatic(GfxContext, GetFont(), item_geometry, area->GetBaseString().GetTCharPtr(), GetTextColor(), true, eAlignTextCenter);
205
smptr(CoreArea) area(m_CurrentMenu->area);
206
item_geometry = area->GetGeometry();
207
gPainter.PaintBackground(GfxContext, item_geometry);
208
gPainter.Paint2DQuadColor(GfxContext, item_geometry, Color(0xFF000000));
209
//gPainter.PaintShapeCorner(GfxContext, item_geometry, Color(0xFF000000), eSHAPE_CORNER_ROUND2, eCornerTopLeft|eCornerTopRight, true);
211
if(m_CurrentMenu->icon)
213
GfxContext.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
214
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
215
gPainter.Draw2DTexture(GfxContext, m_CurrentMenu->icon, item_geometry.x, item_geometry.y);
216
GfxContext.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
217
GfxContext.GetRenderStates().SetBlend(GL_FALSE);
221
gPainter.PaintTextLineStatic(GfxContext, GetFont(), item_geometry, area->GetBaseString().GetTCharPtr(), GetTextColor(), true, eAlignTextCenter);
224
GfxContext.PopClippingRectangle();
227
void MenuBar::DrawContent(GraphicsContext& GfxContext, bool force_draw)
229
GfxContext.PushClippingRectangle(GetGeometry());
230
GfxContext.PopClippingRectangle();
233
void MenuBar::PostDraw(GraphicsContext& GfxContext, bool force_draw)
238
void MenuBar::AddMenu(const TCHAR* MenuLabel, smptr(MenuPage) menu)
240
AddMenu(MenuLabel, menu, 0);
243
void MenuBar::AddMenu(const TCHAR* MenuLabel, smptr(MenuPage) menu, NTexture *icon)
245
// Need to add INL_RETURN_IF_TRUE, INL_RETURN_IF_FALSE
246
INL_RETURN_IF_TRUE(menu.IsNull());
248
smptr(MenuBarItem) menubar_item(new MenuBarItem());
250
menu->m_IsTopOfMenuChain = true;
251
menubar_item->area->SetBaseString(MenuLabel);
252
menubar_item->menu = menu;
253
menubar_item->icon = icon;
255
m_MenuBarItemList.push_back(menubar_item);
256
//menubar_item->area->SetMinimumSize(DEFAULT_WIDGET_WIDTH, 40);
259
menubar_item->area->SetMinimumSize(Max(MENU_MINIMUM_WIDTH, (UINT)(10 + GetFont()->GetStringWidth(MenuLabel))), Max(MENU_MINIMUM_WIDTH, (UINT)16));
263
menubar_item->area->SetMinMaxSize(MENUBAR_ICON_WIDTH, MENUBAR_ICON_HEIGHT);
266
menubar_item->area->OnMouseEnter.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::EmitItemMouseEnter), weaksmptr(MenuBarItem)(menubar_item)));
267
menubar_item->area->OnMouseLeave.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::EmitItemMouseLeave), weaksmptr(MenuBarItem)(menubar_item)));
268
menubar_item->area->OnMouseDown.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::EmitItemMouseDown), weaksmptr(MenuBarItem)(menubar_item)));
269
menubar_item->area->OnMouseDrag.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::RecvItemMouseDrag), weaksmptr(MenuBarItem)(menubar_item)));
270
menubar_item->area->OnMouseUp.connect(sigc::bind( sigc::mem_fun(this, &MenuBar::EmitItemMouseUp), weaksmptr(MenuBarItem)(menubar_item)));
272
menubar_item->menu->SetParentMenu(smptr(MenuPage)(0));
273
menubar_item->menu->sigActionTriggered.connect(sigc::mem_fun(this, &MenuBar::RecvSigActionTriggered));
274
menubar_item->menu->sigTerminateMenuCascade.connect(sigc::mem_fun(this, &MenuBar::RecvSigTerminateMenuCascade));
275
menubar_item->menu->sigMouseDownOutsideMenuCascade.connect(sigc::mem_fun(this, &MenuBar::RecvSigMouseDownOutsideMenuCascade));
277
m_hlayout->AddActiveInterfaceObject(menubar_item->area, 0, eCenter);
278
GetGraphicsThread()->ComputeElementLayout(m_hlayout);
281
void MenuBar::EmitItemMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
285
if(m_CurrentMenu.IsValid() && (m_CurrentMenu->menu != menubar_item->menu))
286
m_CurrentMenu->menu->StopMenu(0, 0);
288
Geometry geo = menubar_item->menu->GetGeometry();
289
menubar_item->menu->m_MenuWindow = m_MenuBarWindow;
290
menubar_item->menu->StartMenu(menubar_item->area->GetBaseX(),
291
menubar_item->area->GetBaseY() + menubar_item->area->GetBaseHeight(), 0, 0);
293
m_CurrentMenu = menubar_item;
295
m_IsOpeningMenu = true;
300
void MenuBar::EmitItemMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
304
void MenuBar::EmitItemMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
306
m_MenuBarWindow = GetThreadWindowCompositor().GetCurrentWindow();
307
if(m_MenuIsActive == false)
309
// Open the corresponding MenuPage
310
if(m_CurrentMenu.IsValid())
312
// This should never happen
314
m_CurrentMenu->menu->StopMenu();
317
m_MenuIsActive = true;
318
m_CurrentMenu = menubar_item;
319
m_CurrentMenu->menu->m_MenuWindow = m_MenuBarWindow;
320
m_IsOpeningMenu = true;
322
//m_CurrentMenu->area->ForceStopFocus(0, 0);
323
m_CurrentMenu->menu->StartMenu(menubar_item->area->GetBaseX(),
324
menubar_item->area->GetBaseY() + menubar_item->area->GetBaseHeight(), 0, 0);
328
// If the mouse up that follows happen inside the area, then it is going to close the menu.
329
m_IsOpeningMenu = false;
334
void MenuBar::EmitItemMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
338
if(m_CurrentMenu->area->IsMouseInside())
340
if(m_IsOpeningMenu == false)
342
// close the MenuPage that is Open
343
if(m_CurrentMenu.IsValid())
344
m_CurrentMenu->menu->StopMenu(0, 0);
345
m_MenuIsActive = false;
346
m_CurrentMenu = smptr(MenuBarItem)(0);
350
// The MousePress before this MouseRelease, caused the MenuPage to open.
351
// Set m_IsOpeningMenu so the next mouse release will close the menu.
352
m_IsOpeningMenu = false;
357
bool hit_inside_a_menu = false;
358
bool b = m_CurrentMenu->menu->TestMouseUp(x, y, button_flags, key_flags, hit_inside_a_menu);
359
if(b || (hit_inside_a_menu == false))
361
RecvSigTerminateMenuCascade();
368
void MenuBar::RecvItemMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags, weaksmptr(MenuBarItem) menubar_item)
370
// Transition between one menu bar item to another
371
if(GetThreadWindowCompositor().GetMouseFocusArea() == menubar_item->area)
373
if(!menubar_item->area->IsMouseInside()) // can also test GetThreadWindowCompositor().GetMouseOverArea() != &menubar_item->area
376
std::list< smptr(MenuBarItem) >::iterator it;
377
// compute window coordinates x and y;
378
int winx = menubar_item->area->GetBaseX() + x;
379
int winy = menubar_item->area->GetBaseY() + y;
380
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
382
smptr(CoreArea) area = (*it)->area;
383
Geometry geometry = area->GetGeometry();
384
if(geometry.IsPointInside(winx, winy))
386
// Close the menu below menubar_item (the one that has the focus
387
menubar_item->area->ForceStopFocus(0, 0);
389
// EmitItemMouseEnter is going to open the menu below (*it)
391
EmitItemMouseEnter(winx, winy, button_flags, key_flags, (*it));
392
m_IsOpeningMenu = true;
393
area->ForceStartFocus(0, 0);
395
GetThreadWindowCompositor().SetMouseFocusArea(area);
396
GetThreadWindowCompositor().SetMouseOverArea(area);
406
void MenuBar::RecvSigActionTriggered(smptr(MenuPage) menu, const smptr(ActionItem) action)
408
m_MenuIsActive = false;
409
if(m_CurrentMenu.IsValid())
411
m_CurrentMenu->menu->StopMenu();
414
m_CurrentMenu = smptr(MenuBarItem)(0);
415
m_IsOpeningMenu = false;
417
// You can do something if you want with the menu* and the action*
421
void MenuBar::RecvSigTerminateMenuCascade()
423
m_MenuIsActive = false;
424
if(m_CurrentMenu.IsValid())
426
m_CurrentMenu->menu->StopMenu();
428
m_CurrentMenu = smptr(MenuBarItem)(0);
429
m_IsOpeningMenu = false;
434
void MenuBar::RecvSigMouseDownOutsideMenuCascade(smptr(MenuPage) menu, int x, int y)
437
std::list< smptr(MenuBarItem) >::iterator it;
438
UBOOL TerminateMenuCascade = 1;
439
for(it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++)
441
smptr(CoreArea) area = (*it)->area;
442
geometry = area->GetGeometry();
443
if(geometry.IsPointInside(x, y))
445
// The event landed on one of the MenuBar item.
446
// Do nothing. This will be handled in the ProcessEvent of the MenuBar item where the mouse down landed.
447
TerminateMenuCascade = 0;
451
if(TerminateMenuCascade)
452
RecvSigTerminateMenuCascade();