xref: /haiku/src/apps/deskbar/BarMenuTitle.cpp (revision 223ea4329f3dd3282de0ba198d36a515a4b20265)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
30 trademarks of Be Incorporated in the United States and other countries. Other
31 brand product names are registered trademarks or trademarks of their respective
32 holders.
33 All rights reserved.
34 */
35 
36 
37 #include "BarMenuTitle.h"
38 
39 #include <algorithm>
40 #include <new>
41 
42 #include <Bitmap.h>
43 #include <ControlLook.h>
44 #include <Debug.h>
45 #include <IconUtils.h>
46 
47 #include "BarApp.h"
48 #include "BarView.h"
49 #include "BarWindow.h"
50 #include "ResourceSet.h"
51 #include "StatusView.h"
52 
53 #include "icons.h"
54 
55 
56 TBarMenuTitle::TBarMenuTitle(float width, float height, const BBitmap* icon,
57 	BMenu* menu)
58 	:
59 	BMenuItem(menu, new BMessage(B_REFS_RECEIVED)),
60 	fWidth(width),
61 	fHeight(height),
62 	fIcon(icon)
63 {
64 }
65 
66 
67 TBarMenuTitle::~TBarMenuTitle()
68 {
69 }
70 
71 
72 void
73 TBarMenuTitle::SetContentSize(float width, float height)
74 {
75 	fWidth = width;
76 	fHeight = height;
77 }
78 
79 
80 void
81 TBarMenuTitle::GetContentSize(float* width, float* height)
82 {
83 	*width = fWidth;
84 	*height = fHeight;
85 }
86 
87 
88 void
89 TBarMenuTitle::Draw()
90 {
91 	BMenu* menu = Menu();
92 	if (menu == NULL)
93 		return;
94 
95 	BRect frame(Frame());
96 	rgb_color base = ui_color(B_MENU_BACKGROUND_COLOR);
97 
98 	menu->PushState();
99 
100 	BRect windowBounds = menu->Window()->Bounds();
101 	if (frame.right > windowBounds.right)
102 		frame.right = windowBounds.right;
103 
104 	// fill in background
105 	if (IsSelected()) {
106 		be_control_look->DrawMenuItemBackground(menu, frame, frame, base,
107 			BControlLook::B_ACTIVATED);
108 	} else
109 		be_control_look->DrawButtonBackground(menu, frame, frame, base);
110 
111 	menu->MovePenTo(ContentLocation());
112 	DrawContent();
113 
114 	menu->PopState();
115 }
116 
117 
118 void
119 TBarMenuTitle::DrawContent()
120 {
121 	if (fIcon == NULL)
122 		return;
123 
124 	BMenu* menu = Menu();
125 	BRect frame(Frame());
126 	BRect iconRect(fIcon->Bounds());
127 
128 	menu->SetDrawingMode(B_OP_ALPHA);
129 	iconRect.OffsetTo(frame.LeftTop());
130 
131 	float widthOffset = rintf((frame.Width() - iconRect.Width()) / 2);
132 	float heightOffset = rintf((frame.Height() - iconRect.Height()) / 2);
133 	iconRect.OffsetBy(widthOffset - 1, heightOffset - 1);
134 
135 	menu->DrawBitmapAsync(fIcon, iconRect);
136 }
137 
138 
139 status_t
140 TBarMenuTitle::Invoke(BMessage* message)
141 {
142 	TBarView* barview = dynamic_cast<TBarApp*>(be_app)->BarView();
143 	if (barview) {
144 		BLooper* looper = barview->Looper();
145 		if (looper->Lock()) {
146 			// tell barview to add the refs to the deskbar menu
147 			barview->HandleDeskbarMenu(NULL);
148 			looper->Unlock();
149 		}
150 	}
151 
152 	return BMenuItem::Invoke(message);
153 }
154 
155 
156 void
157 TBarMenuTitle::SetIcon(const BBitmap* icon)
158 {
159 	fIcon = icon;
160 }
161 
162 
163 //	#pragma mark - TDeskbarMenuTitle
164 
165 
166 const int32 kIconSizeCutoff = 48;
167 	// icon size to stop increasing logo width in horizontal mode
168 
169 
170 TDeskbarMenuTitle::TDeskbarMenuTitle(float width, float height,
171 	const BBitmap* icon, BMenu* menu)
172 	:
173 	TBarMenuTitle(width, height, icon, menu),
174 	fVectorIconData(NULL),
175 	fVectorIconSize(0)
176 {
177 }
178 
179 
180 TDeskbarMenuTitle::~TDeskbarMenuTitle()
181 {
182 	delete fIcon;
183 }
184 
185 
186 void
187 TDeskbarMenuTitle::SetIcon(const BBitmap* icon)
188 {
189 	delete fIcon;
190 	fIcon = icon;
191 }
192 
193 
194 void
195 TDeskbarMenuTitle::DrawContent()
196 {
197 	if (fIcon == NULL)
198 		return;
199 
200 	BMenu* menu = Menu();
201 	BRect frame(Frame());
202 	BRect iconRect(fIcon->Bounds());
203 
204 	menu->SetDrawingMode(B_OP_ALPHA);
205 	iconRect.OffsetTo(frame.LeftTop());
206 
207 	float widthOffset = rintf((frame.Width() - iconRect.Width()) / 2);
208 	float heightOffset = rintf((frame.Height() - iconRect.Height()) / 2);
209 
210 	// move bitmap down a few pixels so leaf gets cut off
211 	heightOffset += 3;
212 
213 	iconRect.OffsetBy(widthOffset - 1, heightOffset - 1);
214 
215 	menu->DrawBitmapAsync(fIcon, iconRect);
216 }
217 
218 
219 const BBitmap*
220 TDeskbarMenuTitle::FetchIcon()
221 {
222 	if (fVectorIconData == NULL || fVectorIconSize == 0) {
223 		// haven't fetched vector icon data yet, fetch it
224 		fVectorIconData = (const uint8*)AppResSet()->FindResource(
225 			B_VECTOR_ICON_TYPE, R_LeafLogoVector, &fVectorIconSize);
226 	}
227 
228 	float width = CalcIconWidth();
229 	BBitmap* icon = new(std::nothrow) BBitmap(BRect(0, 0, width - 1, width - 1),
230 		B_RGBA32);
231 	if (fVectorIconData != NULL && fVectorIconSize > 0 && icon != NULL
232 		&& BIconUtils::GetVectorIcon(fVectorIconData, fVectorIconSize, icon)
233 			== B_OK) {
234 		// rasterized vector icon into a bitmap
235 		SetIcon(icon);
236 	} else {
237 		// fetched bitmap instead
238 		const BBitmap* leaf = AppResSet()->FindBitmap(B_MESSAGE_TYPE,
239 			R_LeafLogoBitmap);
240 		// make a copy of the leaf bitmap that we can safely delete
241 		BBitmap* leafCopy = new BBitmap(leaf->Bounds(), leaf->ColorSpace());
242 		leafCopy->ImportBits(leaf);
243 		SetIcon(leafCopy);
244 		// TODO: scale the bitmap into icon
245 		delete icon;
246 	}
247 
248 	return fIcon;
249 }
250 
251 
252 float
253 TDeskbarMenuTitle::CalcIconWidth()
254 {
255 	TBarApp* barApp = static_cast<TBarApp*>(be_app);
256 	bool isVertical = barApp->BarView()->Vertical();
257 	bool hasBitmapIcon = fVectorIconData == NULL;
258 
259 	float m = 3;
260 	float x = (isVertical || hasBitmapIcon) ? kMinimumIconSize
261 		: std::min(barApp->IconSize(), kIconSizeCutoff);
262 	float b = kMinimumIconSize;
263 
264 	return m * x + b;
265 }
266