xref: /haiku/src/kits/interface/BMCPrivate.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		BMCPrivate.cpp
23 //	Author:			Marc Flerackers (mflerackers@androme.be)
24 //	Description:	The BMCPrivate classes are used by BMenuField.
25 //------------------------------------------------------------------------------
26 
27 // Standard Includes -----------------------------------------------------------
28 
29 // System Includes -------------------------------------------------------------
30 #include <BMCPrivate.h>
31 #include <MenuField.h>
32 #include <MenuItem.h>
33 #include <Message.h>
34 #include <Region.h>
35 #include <Window.h>
36 
37 // Project Includes ------------------------------------------------------------
38 
39 // Local Includes --------------------------------------------------------------
40 
41 // Local Defines ---------------------------------------------------------------
42 
43 // Globals ---------------------------------------------------------------------
44 
45 //------------------------------------------------------------------------------
46 _BMCItem_::_BMCItem_(BMenu *menu)
47 	:	BMenuItem(menu),
48 		fShowPopUpMarker(true)
49 {
50 }
51 //------------------------------------------------------------------------------
52 _BMCItem_::_BMCItem_(BMessage *message)
53 	:	BMenuItem(message),
54 		fShowPopUpMarker(true)
55 {
56 }
57 //------------------------------------------------------------------------------
58 _BMCItem_::~_BMCItem_()
59 {
60 }
61 //------------------------------------------------------------------------------
62 BArchivable *_BMCItem_::Instantiate(BMessage *data)
63 {
64 	if (validate_instantiation(data, "_BMCItem_"))
65 		return new _BMCItem_(data);
66 	else
67 		return NULL;
68 }
69 //------------------------------------------------------------------------------
70 void _BMCItem_::Draw()
71 {
72 	BMenuItem::Draw();
73 
74 	if (!fShowPopUpMarker)
75 		return;
76 
77 	BMenu *menu = Menu();
78 	BRect rect(menu->Bounds());
79 
80 	rect.right -= 4;
81 	rect.bottom -= 5;
82 	rect.left = rect.right - 4;
83 	rect.top = rect.bottom - 2;
84 
85 	if (IsEnabled())
86 		menu->SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
87 			B_DARKEN_4_TINT));
88 	else
89 		menu->SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
90 			B_DARKEN_4_TINT));
91 
92 	menu->StrokeLine(BPoint(rect.left, rect.top), BPoint(rect.right, rect.top));
93 	menu->StrokeLine(BPoint(rect.left + 1.0f, rect.top + 1.0f),
94 		BPoint(rect.right - 1.0f, rect.top + 1.0f));
95 	menu->StrokeLine(BPoint(rect.left + 2.0f, rect.bottom),
96 		BPoint(rect.left + 2.0f, rect.bottom));
97 }
98 //------------------------------------------------------------------------------
99 void _BMCItem_::GetContentSize(float *width, float *height)
100 {
101 	BMenuItem::GetContentSize(width, height);
102 }
103 //------------------------------------------------------------------------------
104 /*_BMCFilter_::_BMCFilter_(BMenuField *menuField, uint32)
105 {
106 }
107 //------------------------------------------------------------------------------
108 _BMCFilter_::~_BMCFilter_()
109 {
110 }
111 //------------------------------------------------------------------------------
112 filter_result _BMCFilter_::Filter(BMessage *message, BHandler **handler)
113 {
114 }
115 //------------------------------------------------------------------------------
116 _BMCFilter_ &_BMCFilter_::operator=(const _BMCFilter_ &)
117 {
118 	return *this;
119 }*/
120 //------------------------------------------------------------------------------
121 _BMCMenuBar_::_BMCMenuBar_(BRect frame, bool fixed_size, BMenuField *menuField)
122 	:	BMenuBar(frame, "_mc_mb_", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_ITEMS_IN_ROW,
123 			!fixed_size)
124 {
125 	SetFlags(Flags() | B_FRAME_EVENTS);
126 	SetBorder(B_BORDER_CONTENTS);
127 
128 
129 	fMenuField = menuField;
130 	fFixedSize = fixed_size;
131 	fRunner = NULL;
132 
133 	float left, top, right, bottom;
134 
135 	GetItemMargins(&left, &top, &right, &bottom);
136 	SetItemMargins(left, top, right, bottom); // TODO:
137 
138 	SetMaxContentWidth(frame.Width() - (left + right));
139 }
140 //------------------------------------------------------------------------------
141 _BMCMenuBar_::_BMCMenuBar_(BMessage *data)
142 	:	BMenuBar(data)
143 {
144 	SetFlags(Flags() | B_FRAME_EVENTS);
145 
146 	bool rsize_to_fit;
147 
148 	if (data->FindBool("_rsize_to_fit", &rsize_to_fit) == B_OK)
149 		fFixedSize = !rsize_to_fit;
150 	else
151 		fFixedSize = true;
152 }
153 //------------------------------------------------------------------------------
154 _BMCMenuBar_::~_BMCMenuBar_()
155 {
156 }
157 //------------------------------------------------------------------------------
158 BArchivable *_BMCMenuBar_::Instantiate(BMessage *data)
159 {
160 	if (validate_instantiation(data, "_BMCMenuBar_"))
161 		return new _BMCMenuBar_(data);
162 	else
163 		return NULL;
164 }
165 //------------------------------------------------------------------------------
166 void _BMCMenuBar_::AttachedToWindow()
167 {
168 	fMenuField = (BMenuField*)Parent();
169 
170 	BMenuBar *menuBar = Window()->KeyMenuBar();
171 	BMenuBar::AttachedToWindow();
172 	Window()->SetKeyMenuBar(menuBar);
173 }
174 //------------------------------------------------------------------------------
175 void _BMCMenuBar_::Draw(BRect updateRect)
176 {
177 	// TODO: The commented code locks up the
178 	// window thread.
179 	// draw the right and bottom line here in a darker tint
180 	BRegion oldClipping;
181 	GetClippingRegion(&oldClipping);
182 
183 	BRect bounds(Bounds());
184 	bounds.right -= 2.0;
185 	bounds.bottom -= 1.0;
186 	bounds = bounds & updateRect;
187 	BRegion clipping(bounds);
188 	ConstrainClippingRegion(&clipping);
189 
190 	BMenuBar::Draw(updateRect);
191 
192 	bounds.right += 2.0;
193 	bounds.bottom += 1.0;
194 	ConstrainClippingRegion(&oldClipping);
195 //BRect bounds(Bounds());
196 	SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_4_TINT));
197 	StrokeLine(BPoint(bounds.left, bounds.bottom),
198 			   BPoint(bounds.right, bounds.bottom));
199 	StrokeLine(BPoint(bounds.right, bounds.bottom - 1),
200 			   BPoint(bounds.right, bounds.top));
201 	SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT));
202 	StrokeLine(BPoint(bounds.right - 1, bounds.bottom - 2),
203 			   BPoint(bounds.right - 1, bounds.top + 1));
204 }
205 //------------------------------------------------------------------------------
206 void _BMCMenuBar_::FrameResized(float width, float height)
207 {
208 	// TODO:
209 	BMenuBar::FrameResized(width, height);
210 }
211 //------------------------------------------------------------------------------
212 void _BMCMenuBar_::MessageReceived(BMessage *msg)
213 {
214 	if (msg->what == 'TICK')
215 	{
216 		BMenuItem *item = ItemAt(0);
217 
218 		if (item && item->Submenu() &&  item->Submenu()->Window())
219 		{
220 			BMessage message(B_KEY_DOWN);
221 
222 			message.AddInt8("byte", B_ESCAPE);
223 			message.AddInt8("key", B_ESCAPE);
224 			message.AddInt32("modifiers", 0);
225 			message.AddInt8("raw_char", B_ESCAPE);
226 
227 			Window()->PostMessage(&message, this, NULL);
228 		}
229 	}
230 
231 	BMenuBar::MessageReceived(msg);
232 }
233 //------------------------------------------------------------------------------
234 void _BMCMenuBar_::MakeFocus(bool focused)
235 {
236 	if (IsFocus() == focused)
237 		return;
238 
239 	BMenuBar::MakeFocus(focused);
240 
241 	if (focused)
242 	{
243 		BMessage message('TICK');
244 		//fRunner = new BMessageRunner(BMessenger(this, NULL, NULL), &message,
245 		//	50000, -1);
246 	}
247 	else if (fRunner)
248 	{
249 		//delete fRunner;
250 		fRunner = NULL;
251 	}
252 
253 	if (focused)
254 		return;
255 
256 	fMenuField->fSelected = false;
257 	fMenuField->fTransition = true;
258 
259 	BRect bounds(fMenuField->Bounds());
260 
261 	fMenuField->Invalidate(BRect(bounds.left, bounds.top, fMenuField->fDivider,
262 		bounds.bottom));
263 }
264 //------------------------------------------------------------------------------
265 _BMCMenuBar_ &_BMCMenuBar_::operator=(const _BMCMenuBar_ &)
266 {
267 	return *this;
268 }
269 //------------------------------------------------------------------------------
270