xref: /haiku/src/kits/interface/MenuWindow.cpp (revision 55b40aa53a835472ec7952b138ae4256203d02e4)
1 /*
2  * Copyright 2001-2006, Haiku, Inc.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Marc Flerackers (mflerackers@androme.be)
7  *		Stefano Ceccherini (burton666@libero.it)
8  */
9 
10 //!	BMenuWindow is a custom BWindow for BMenus.
11 
12 // TODO: Add scrollers
13 
14 #include <Menu.h>
15 
16 #include <MenuPrivate.h>
17 #include <MenuWindow.h>
18 #include <WindowPrivate.h>
19 
20 
21 // This draws the frame around the BMenu
22 class BMenuFrame : public BView {
23 	public:
24 		BMenuFrame(BMenu *menu);
25 
26 		virtual void AttachedToWindow();
27 		virtual void DetachedFromWindow();
28 		virtual void Draw(BRect updateRect);
29 
30 	private:
31 		BMenu *fMenu;
32 };
33 
34 
35 BMenuWindow::BMenuWindow(const char *name)
36 	// The window will be resized by BMenu, so just pass a dummy rect
37 	: BWindow(BRect(0, 0, 0, 0), name, B_BORDERED_WINDOW_LOOK, kMenuWindowFeel,
38 			B_NOT_ZOOMABLE | B_AVOID_FOCUS),
39 	fUpperScroller(NULL),
40 	fLowerScroller(NULL)
41 {
42 }
43 
44 
45 BMenuWindow::~BMenuWindow()
46 {
47 }
48 
49 
50 void
51 BMenuWindow::AttachMenu(BMenu *menu)
52 {
53 	if (CountChildren() > 0)
54 		debugger("BMenuWindow (%s): a menu is already attached!");
55 	if (menu != NULL) {
56 		BMenuFrame *menuFrame = new BMenuFrame(menu);
57 		AddChild(menuFrame);
58 		menu->MakeFocus(true);
59 	}
60 }
61 
62 
63 void
64 BMenuWindow::DetachMenu()
65 {
66 	if (CountChildren() > 0)
67 		RemoveChild(ChildAt(0));
68 }
69 
70 
71 //	#pragma mark -
72 
73 
74 BMenuFrame::BMenuFrame(BMenu *menu)
75 	: BView(BRect(0, 0, 1, 1), "menu frame", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
76 	fMenu(menu)
77 {
78 }
79 
80 
81 void
82 BMenuFrame::AttachedToWindow()
83 {
84 	BView::AttachedToWindow();
85 
86 	if (fMenu != NULL)
87 		AddChild(fMenu);
88 
89 	ResizeTo(Window()->Bounds().Width(), Window()->Bounds().Height());
90 	if (fMenu != NULL) {
91 		BFont font;
92 		fMenu->GetFont(&font);
93 		SetFont(&font);
94 	}
95 }
96 
97 
98 void
99 BMenuFrame::DetachedFromWindow()
100 {
101 	if (fMenu != NULL)
102 		RemoveChild(fMenu);
103 }
104 
105 
106 void
107 BMenuFrame::Draw(BRect updateRect)
108 {
109 	if (fMenu != NULL && fMenu->CountItems() == 0) {
110 		// TODO: Review this as it's a bit hacky.
111 		// Menu has a size of 0, 0, since there are no items in it.
112 		// So the BMenuFrame class has to fake it and draw an empty item.
113 		// Note that we can't add a real "empty" item because then we couldn't
114 		// tell if the item was added by us or not.
115 		// See also BMenu::UpdateWindowViewSize()
116 		SetHighColor(ui_color(B_MENU_BACKGROUND_COLOR));
117 		SetLowColor(HighColor());
118 		FillRect(updateRect);
119 
120 		font_height height;
121 		GetFontHeight(&height);
122 		SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DISABLED_LABEL_TINT));
123 		BPoint where((Bounds().Width() - fMenu->StringWidth(kEmptyMenuLabel)) / 2, ceilf(height.ascent + 1));
124 		DrawString(kEmptyMenuLabel, where);
125 	}
126 
127 	SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT));
128 	BRect bounds(Bounds());
129 
130 	StrokeLine(BPoint(bounds.right, bounds.top),
131 		BPoint(bounds.right, bounds.bottom - 1));
132 	StrokeLine(BPoint(bounds.left + 1, bounds.bottom),
133 		BPoint(bounds.right, bounds.bottom));
134 }
135