1dc3bd077SAxel Dörfler /*
2dc3bd077SAxel Dörfler * Copyright 2006-2009, Stephan Aßmus <superstippi@gmx.de>
3dc3bd077SAxel Dörfler * All rights reserved. Distributed under the terms of the MIT License.
4dc3bd077SAxel Dörfler */
5dc3bd077SAxel Dörfler
6dc3bd077SAxel Dörfler
7dc3bd077SAxel Dörfler #include "LaunchButton.h"
8dc3bd077SAxel Dörfler
9dc3bd077SAxel Dörfler #include <stdio.h>
10dc3bd077SAxel Dörfler #include <stdlib.h>
11dc3bd077SAxel Dörfler #include <string.h>
12dc3bd077SAxel Dörfler
13dc3bd077SAxel Dörfler #include <AppDefs.h>
14dc3bd077SAxel Dörfler #include <AppFileInfo.h>
15dc3bd077SAxel Dörfler #include <Application.h>
16dc3bd077SAxel Dörfler #include <Bitmap.h>
17dc3bd077SAxel Dörfler #include <Catalog.h>
18dc3bd077SAxel Dörfler #include <File.h>
19dc3bd077SAxel Dörfler #include <Node.h>
20dc3bd077SAxel Dörfler #include <NodeInfo.h>
21dc3bd077SAxel Dörfler #include <Region.h>
22dc3bd077SAxel Dörfler #include <Roster.h>
23dc3bd077SAxel Dörfler #include <Window.h>
24dc3bd077SAxel Dörfler
25dc3bd077SAxel Dörfler
26dc3bd077SAxel Dörfler #define DEFAULT_ICON_SIZE 64
27dc3bd077SAxel Dörfler
28*546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
29*546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "LaunchBox"
30dc3bd077SAxel Dörfler
31dc3bd077SAxel Dörfler
32dc3bd077SAxel Dörfler static const float kDragStartDist = 10.0;
33dc3bd077SAxel Dörfler static const float kDragBitmapAlphaScale = 0.6;
34dc3bd077SAxel Dörfler
35dc3bd077SAxel Dörfler
36dc3bd077SAxel Dörfler bigtime_t LaunchButton::sClickSpeed = 0;
37dc3bd077SAxel Dörfler bool LaunchButton::sIgnoreDoubleClick = true;
38dc3bd077SAxel Dörfler
39dc3bd077SAxel Dörfler
LaunchButton(const char * name,const char * label,BMessage * message,BHandler * target)40dc3bd077SAxel Dörfler LaunchButton::LaunchButton(const char* name, const char* label,
41dc3bd077SAxel Dörfler BMessage* message, BHandler* target)
42dc3bd077SAxel Dörfler :
43dc3bd077SAxel Dörfler BIconButton(name, label, message, target),
44dc3bd077SAxel Dörfler fRef(NULL),
45dc3bd077SAxel Dörfler fAppSig(NULL),
46dc3bd077SAxel Dörfler fDescription(""),
47dc3bd077SAxel Dörfler fAnticipatingDrop(false),
48dc3bd077SAxel Dörfler fLastClickTime(0),
49dc3bd077SAxel Dörfler fIconSize(DEFAULT_ICON_SIZE)
50dc3bd077SAxel Dörfler {
51dc3bd077SAxel Dörfler if (sClickSpeed == 0 || get_click_speed(&sClickSpeed) != B_OK)
52dc3bd077SAxel Dörfler sClickSpeed = 500000;
53dc3bd077SAxel Dörfler }
54dc3bd077SAxel Dörfler
55dc3bd077SAxel Dörfler
~LaunchButton()56dc3bd077SAxel Dörfler LaunchButton::~LaunchButton()
57dc3bd077SAxel Dörfler {
58dc3bd077SAxel Dörfler delete fRef;
59dc3bd077SAxel Dörfler free(fAppSig);
60dc3bd077SAxel Dörfler }
61dc3bd077SAxel Dörfler
62dc3bd077SAxel Dörfler
63dc3bd077SAxel Dörfler void
AttachedToWindow()64dc3bd077SAxel Dörfler LaunchButton::AttachedToWindow()
65dc3bd077SAxel Dörfler {
66dc3bd077SAxel Dörfler BIconButton::AttachedToWindow();
67dc3bd077SAxel Dörfler _UpdateToolTip();
68dc3bd077SAxel Dörfler }
69dc3bd077SAxel Dörfler
70dc3bd077SAxel Dörfler
71dc3bd077SAxel Dörfler void
Draw(BRect updateRect)72dc3bd077SAxel Dörfler LaunchButton::Draw(BRect updateRect)
73dc3bd077SAxel Dörfler {
74dc3bd077SAxel Dörfler if (fAnticipatingDrop) {
75dc3bd077SAxel Dörfler rgb_color color = fRef ? ui_color(B_KEYBOARD_NAVIGATION_COLOR)
76dc3bd077SAxel Dörfler : (rgb_color){ 0, 130, 60, 255 };
77dc3bd077SAxel Dörfler SetHighColor(color);
78dc3bd077SAxel Dörfler // limit clipping region to exclude the blue rect we just drew
79dc3bd077SAxel Dörfler BRect r(Bounds());
80dc3bd077SAxel Dörfler StrokeRect(r);
81dc3bd077SAxel Dörfler r.InsetBy(1.0, 1.0);
82dc3bd077SAxel Dörfler BRegion region(r);
83dc3bd077SAxel Dörfler ConstrainClippingRegion(®ion);
84dc3bd077SAxel Dörfler }
85dc3bd077SAxel Dörfler if (IsValid()) {
86dc3bd077SAxel Dörfler BIconButton::Draw(updateRect);
87dc3bd077SAxel Dörfler } else {
88dc3bd077SAxel Dörfler rgb_color background = LowColor();
89dc3bd077SAxel Dörfler rgb_color lightShadow = tint_color(background,
90dc3bd077SAxel Dörfler (B_NO_TINT + B_DARKEN_1_TINT) / 2.0);
91dc3bd077SAxel Dörfler rgb_color shadow = tint_color(background, B_DARKEN_1_TINT);
92dc3bd077SAxel Dörfler rgb_color light = tint_color(background, B_LIGHTEN_1_TINT);
93dc3bd077SAxel Dörfler BRect r(Bounds());
94dc3bd077SAxel Dörfler _DrawFrame(r, shadow, light, lightShadow, lightShadow);
95dc3bd077SAxel Dörfler r.InsetBy(2.0, 2.0);
96dc3bd077SAxel Dörfler SetHighColor(lightShadow);
97dc3bd077SAxel Dörfler FillRect(r);
98dc3bd077SAxel Dörfler }
99dc3bd077SAxel Dörfler }
100dc3bd077SAxel Dörfler
101dc3bd077SAxel Dörfler
102dc3bd077SAxel Dörfler void
MessageReceived(BMessage * message)103dc3bd077SAxel Dörfler LaunchButton::MessageReceived(BMessage* message)
104dc3bd077SAxel Dörfler {
105dc3bd077SAxel Dörfler switch (message->what) {
106dc3bd077SAxel Dörfler case B_SIMPLE_DATA:
107dc3bd077SAxel Dörfler case B_REFS_RECEIVED: {
108dc3bd077SAxel Dörfler entry_ref ref;
109dc3bd077SAxel Dörfler if (message->FindRef("refs", &ref) == B_OK) {
110dc3bd077SAxel Dörfler if (fRef) {
111dc3bd077SAxel Dörfler if (ref != *fRef) {
112dc3bd077SAxel Dörfler BEntry entry(fRef, true);
113dc3bd077SAxel Dörfler if (entry.IsDirectory()) {
114dc3bd077SAxel Dörfler message->PrintToStream();
115dc3bd077SAxel Dörfler // copy stuff into the directory
116dc3bd077SAxel Dörfler } else {
117dc3bd077SAxel Dörfler message->what = B_REFS_RECEIVED;
118dc3bd077SAxel Dörfler team_id team;
119dc3bd077SAxel Dörfler if (fAppSig)
120dc3bd077SAxel Dörfler team = be_roster->TeamFor(fAppSig);
121dc3bd077SAxel Dörfler else
122dc3bd077SAxel Dörfler team = be_roster->TeamFor(fRef);
123dc3bd077SAxel Dörfler if (team < 0) {
124dc3bd077SAxel Dörfler if (fAppSig)
125dc3bd077SAxel Dörfler be_roster->Launch(fAppSig, message, &team);
126dc3bd077SAxel Dörfler else
127dc3bd077SAxel Dörfler be_roster->Launch(fRef, message, &team);
128dc3bd077SAxel Dörfler } else {
129dc3bd077SAxel Dörfler app_info appInfo;
130dc3bd077SAxel Dörfler if (team >= 0
131dc3bd077SAxel Dörfler && be_roster->GetRunningAppInfo(team,
132dc3bd077SAxel Dörfler &appInfo) == B_OK) {
133dc3bd077SAxel Dörfler BMessenger messenger(appInfo.signature,
134dc3bd077SAxel Dörfler team);
135dc3bd077SAxel Dörfler if (messenger.IsValid())
136dc3bd077SAxel Dörfler messenger.SendMessage(message);
137dc3bd077SAxel Dörfler }
138dc3bd077SAxel Dörfler }
139dc3bd077SAxel Dörfler }
140dc3bd077SAxel Dörfler }
141dc3bd077SAxel Dörfler } else {
142dc3bd077SAxel Dörfler SetTo(&ref);
143dc3bd077SAxel Dörfler }
144dc3bd077SAxel Dörfler }
145dc3bd077SAxel Dörfler break;
146dc3bd077SAxel Dörfler }
147dc3bd077SAxel Dörfler case B_PASTE:
148dc3bd077SAxel Dörfler case B_MODIFIERS_CHANGED:
149dc3bd077SAxel Dörfler default:
150dc3bd077SAxel Dörfler BIconButton::MessageReceived(message);
151dc3bd077SAxel Dörfler break;
152dc3bd077SAxel Dörfler }
153dc3bd077SAxel Dörfler }
154dc3bd077SAxel Dörfler
155dc3bd077SAxel Dörfler
156dc3bd077SAxel Dörfler void
MouseDown(BPoint where)157dc3bd077SAxel Dörfler LaunchButton::MouseDown(BPoint where)
158dc3bd077SAxel Dörfler {
159dc3bd077SAxel Dörfler bigtime_t now = system_time();
160dc3bd077SAxel Dörfler bool callInherited = true;
161dc3bd077SAxel Dörfler if (sIgnoreDoubleClick && now - fLastClickTime < sClickSpeed)
162dc3bd077SAxel Dörfler callInherited = false;
163dc3bd077SAxel Dörfler fLastClickTime = now;
164dc3bd077SAxel Dörfler if (BMessage* message = Window()->CurrentMessage()) {
165dc3bd077SAxel Dörfler uint32 buttons;
166dc3bd077SAxel Dörfler message->FindInt32("buttons", (int32*)&buttons);
167dc3bd077SAxel Dörfler if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0 && IsInside()) {
168dc3bd077SAxel Dörfler // context menu?
169dc3bd077SAxel Dörfler } else
170dc3bd077SAxel Dörfler fDragStart = where;
171dc3bd077SAxel Dörfler }
172dc3bd077SAxel Dörfler if (callInherited)
173dc3bd077SAxel Dörfler BIconButton::MouseDown(where);
174dc3bd077SAxel Dörfler }
175dc3bd077SAxel Dörfler
176dc3bd077SAxel Dörfler
177dc3bd077SAxel Dörfler void
MouseUp(BPoint where)178dc3bd077SAxel Dörfler LaunchButton::MouseUp(BPoint where)
179dc3bd077SAxel Dörfler {
180dc3bd077SAxel Dörfler if (fAnticipatingDrop) {
181dc3bd077SAxel Dörfler fAnticipatingDrop = false;
182dc3bd077SAxel Dörfler Invalidate();
183dc3bd077SAxel Dörfler }
184dc3bd077SAxel Dörfler BIconButton::MouseUp(where);
185dc3bd077SAxel Dörfler }
186dc3bd077SAxel Dörfler
187dc3bd077SAxel Dörfler
188dc3bd077SAxel Dörfler void
MouseMoved(BPoint where,uint32 transit,const BMessage * dragMessage)189dc3bd077SAxel Dörfler LaunchButton::MouseMoved(BPoint where, uint32 transit,
190dc3bd077SAxel Dörfler const BMessage* dragMessage)
191dc3bd077SAxel Dörfler {
192dc3bd077SAxel Dörfler if ((dragMessage && (transit == B_ENTERED_VIEW || transit == B_INSIDE_VIEW))
193dc3bd077SAxel Dörfler && ((dragMessage->what == B_SIMPLE_DATA
194dc3bd077SAxel Dörfler || dragMessage->what == B_REFS_RECEIVED) || fRef)) {
195dc3bd077SAxel Dörfler if (!fAnticipatingDrop) {
196dc3bd077SAxel Dörfler fAnticipatingDrop = true;
197dc3bd077SAxel Dörfler Invalidate();
198dc3bd077SAxel Dörfler }
199dc3bd077SAxel Dörfler }
200dc3bd077SAxel Dörfler if (!dragMessage || (transit == B_EXITED_VIEW || transit == B_OUTSIDE_VIEW)) {
201dc3bd077SAxel Dörfler if (fAnticipatingDrop) {
202dc3bd077SAxel Dörfler fAnticipatingDrop = false;
203dc3bd077SAxel Dörfler Invalidate();
204dc3bd077SAxel Dörfler }
205dc3bd077SAxel Dörfler }
206dc3bd077SAxel Dörfler
207dc3bd077SAxel Dörfler BIconButton::MouseMoved(where, transit, dragMessage);
208dc3bd077SAxel Dörfler }
209dc3bd077SAxel Dörfler
210dc3bd077SAxel Dörfler
211dc3bd077SAxel Dörfler BSize
MinSize()212dc3bd077SAxel Dörfler LaunchButton::MinSize()
213dc3bd077SAxel Dörfler {
214dc3bd077SAxel Dörfler return PreferredSize();
215dc3bd077SAxel Dörfler }
216dc3bd077SAxel Dörfler
217dc3bd077SAxel Dörfler
218dc3bd077SAxel Dörfler BSize
PreferredSize()219dc3bd077SAxel Dörfler LaunchButton::PreferredSize()
220dc3bd077SAxel Dörfler {
221dc3bd077SAxel Dörfler float minWidth = fIconSize;
222dc3bd077SAxel Dörfler float minHeight = fIconSize;
223dc3bd077SAxel Dörfler
224dc3bd077SAxel Dörfler float hPadding = max_c(6.0, ceilf(minHeight / 3.0));
225dc3bd077SAxel Dörfler float vPadding = max_c(6.0, ceilf(minWidth / 3.0));
226dc3bd077SAxel Dörfler
227dc3bd077SAxel Dörfler if (Label() != NULL && Label()[0] != '\0') {
228dc3bd077SAxel Dörfler font_height fh;
229dc3bd077SAxel Dörfler GetFontHeight(&fh);
230dc3bd077SAxel Dörfler minHeight += ceilf(fh.ascent + fh.descent) + vPadding;
231dc3bd077SAxel Dörfler minWidth += StringWidth(Label()) + vPadding;
232dc3bd077SAxel Dörfler }
233dc3bd077SAxel Dörfler
234dc3bd077SAxel Dörfler return BSize(minWidth + hPadding, minHeight + vPadding);
235dc3bd077SAxel Dörfler }
236dc3bd077SAxel Dörfler
237dc3bd077SAxel Dörfler
238dc3bd077SAxel Dörfler BSize
MaxSize()239dc3bd077SAxel Dörfler LaunchButton::MaxSize()
240dc3bd077SAxel Dörfler {
241dc3bd077SAxel Dörfler return PreferredSize();
242dc3bd077SAxel Dörfler }
243dc3bd077SAxel Dörfler
244dc3bd077SAxel Dörfler
245dc3bd077SAxel Dörfler // #pragma mark -
246dc3bd077SAxel Dörfler
247dc3bd077SAxel Dörfler
248dc3bd077SAxel Dörfler void
SetTo(const entry_ref * ref)249dc3bd077SAxel Dörfler LaunchButton::SetTo(const entry_ref* ref)
250dc3bd077SAxel Dörfler {
251dc3bd077SAxel Dörfler free(fAppSig);
252dc3bd077SAxel Dörfler fAppSig = NULL;
253dc3bd077SAxel Dörfler
254dc3bd077SAxel Dörfler delete fRef;
255dc3bd077SAxel Dörfler if (ref) {
256dc3bd077SAxel Dörfler fRef = new entry_ref(*ref);
257dc3bd077SAxel Dörfler // follow links
258dc3bd077SAxel Dörfler BEntry entry(fRef, true);
259dc3bd077SAxel Dörfler entry.GetRef(fRef);
260dc3bd077SAxel Dörfler
261dc3bd077SAxel Dörfler _UpdateIcon(fRef);
262dc3bd077SAxel Dörfler // see if this is an application
263dc3bd077SAxel Dörfler BFile file(ref, B_READ_ONLY);
264dc3bd077SAxel Dörfler BAppFileInfo info;
265dc3bd077SAxel Dörfler if (info.SetTo(&file) == B_OK) {
266dc3bd077SAxel Dörfler char mimeSig[B_MIME_TYPE_LENGTH];
267dc3bd077SAxel Dörfler if (info.GetSignature(mimeSig) == B_OK) {
268dc3bd077SAxel Dörfler SetTo(mimeSig, false);
269dc3bd077SAxel Dörfler } else {
270dc3bd077SAxel Dörfler fprintf(stderr, "no MIME signature for '%s'\n", fRef->name);
271dc3bd077SAxel Dörfler }
272dc3bd077SAxel Dörfler } else {
273dc3bd077SAxel Dörfler fprintf(stderr, "no BAppFileInfo for '%s'\n", fRef->name);
274dc3bd077SAxel Dörfler }
275dc3bd077SAxel Dörfler } else {
276dc3bd077SAxel Dörfler fRef = NULL;
277dc3bd077SAxel Dörfler ClearIcon();
278dc3bd077SAxel Dörfler }
279dc3bd077SAxel Dörfler _UpdateToolTip();
280dc3bd077SAxel Dörfler }
281dc3bd077SAxel Dörfler
282dc3bd077SAxel Dörfler
283dc3bd077SAxel Dörfler entry_ref*
Ref() const284dc3bd077SAxel Dörfler LaunchButton::Ref() const
285dc3bd077SAxel Dörfler {
286dc3bd077SAxel Dörfler return fRef;
287dc3bd077SAxel Dörfler }
288dc3bd077SAxel Dörfler
289dc3bd077SAxel Dörfler
290dc3bd077SAxel Dörfler void
SetTo(const char * appSig,bool updateIcon)291dc3bd077SAxel Dörfler LaunchButton::SetTo(const char* appSig, bool updateIcon)
292dc3bd077SAxel Dörfler {
293dc3bd077SAxel Dörfler if (appSig) {
294dc3bd077SAxel Dörfler free(fAppSig);
295dc3bd077SAxel Dörfler fAppSig = strdup(appSig);
296dc3bd077SAxel Dörfler if (updateIcon) {
297dc3bd077SAxel Dörfler entry_ref ref;
298dc3bd077SAxel Dörfler if (be_roster->FindApp(fAppSig, &ref) == B_OK)
299dc3bd077SAxel Dörfler SetTo(&ref);
300dc3bd077SAxel Dörfler }
301dc3bd077SAxel Dörfler }
302dc3bd077SAxel Dörfler _UpdateToolTip();
303dc3bd077SAxel Dörfler }
304dc3bd077SAxel Dörfler
305dc3bd077SAxel Dörfler
306dc3bd077SAxel Dörfler void
SetDescription(const char * text)307dc3bd077SAxel Dörfler LaunchButton::SetDescription(const char* text)
308dc3bd077SAxel Dörfler {
309dc3bd077SAxel Dörfler fDescription.SetTo(text);
310dc3bd077SAxel Dörfler _UpdateToolTip();
311dc3bd077SAxel Dörfler }
312dc3bd077SAxel Dörfler
313dc3bd077SAxel Dörfler
314dc3bd077SAxel Dörfler void
SetIconSize(uint32 size)315dc3bd077SAxel Dörfler LaunchButton::SetIconSize(uint32 size)
316dc3bd077SAxel Dörfler {
317dc3bd077SAxel Dörfler if (fIconSize == size)
318dc3bd077SAxel Dörfler return;
319dc3bd077SAxel Dörfler
320dc3bd077SAxel Dörfler fIconSize = size;
321dc3bd077SAxel Dörfler _UpdateIcon(fRef);
322dc3bd077SAxel Dörfler
323dc3bd077SAxel Dörfler InvalidateLayout();
324dc3bd077SAxel Dörfler Invalidate();
325dc3bd077SAxel Dörfler }
326dc3bd077SAxel Dörfler
327dc3bd077SAxel Dörfler
328dc3bd077SAxel Dörfler void
SetIgnoreDoubleClick(bool refuse)329dc3bd077SAxel Dörfler LaunchButton::SetIgnoreDoubleClick(bool refuse)
330dc3bd077SAxel Dörfler {
331dc3bd077SAxel Dörfler sIgnoreDoubleClick = refuse;
332dc3bd077SAxel Dörfler }
333dc3bd077SAxel Dörfler
334dc3bd077SAxel Dörfler
335dc3bd077SAxel Dörfler // #pragma mark -
336dc3bd077SAxel Dörfler
337dc3bd077SAxel Dörfler
338dc3bd077SAxel Dörfler void
_UpdateToolTip()339dc3bd077SAxel Dörfler LaunchButton::_UpdateToolTip()
340dc3bd077SAxel Dörfler {
341dc3bd077SAxel Dörfler // TODO: This works around a bug in the tool tip management.
342dc3bd077SAxel Dörfler // Remove when fixed (although no harm done...)
343dc3bd077SAxel Dörfler HideToolTip();
344dc3bd077SAxel Dörfler SetToolTip(static_cast<BToolTip*>(NULL));
345dc3bd077SAxel Dörfler
346dc3bd077SAxel Dörfler if (fRef) {
347dc3bd077SAxel Dörfler BString helper(fRef->name);
348dc3bd077SAxel Dörfler if (fDescription.CountChars() > 0) {
349dc3bd077SAxel Dörfler if (fDescription != helper)
350dc3bd077SAxel Dörfler helper << "\n\n" << fDescription.String();
351dc3bd077SAxel Dörfler } else {
352dc3bd077SAxel Dörfler BFile file(fRef, B_READ_ONLY);
353dc3bd077SAxel Dörfler BAppFileInfo appFileInfo;
354dc3bd077SAxel Dörfler version_info info;
355dc3bd077SAxel Dörfler if (appFileInfo.SetTo(&file) == B_OK
356dc3bd077SAxel Dörfler && appFileInfo.GetVersionInfo(&info,
357dc3bd077SAxel Dörfler B_APP_VERSION_KIND) == B_OK
358dc3bd077SAxel Dörfler && strlen(info.short_info) > 0
359dc3bd077SAxel Dörfler && helper.Compare(info.short_info) != 0) {
360dc3bd077SAxel Dörfler helper << "\n\n" << info.short_info;
361dc3bd077SAxel Dörfler }
362dc3bd077SAxel Dörfler }
363dc3bd077SAxel Dörfler SetToolTip(helper.String());
364dc3bd077SAxel Dörfler }
365dc3bd077SAxel Dörfler }
366dc3bd077SAxel Dörfler
367dc3bd077SAxel Dörfler
368dc3bd077SAxel Dörfler void
_UpdateIcon(const entry_ref * ref)369dc3bd077SAxel Dörfler LaunchButton::_UpdateIcon(const entry_ref* ref)
370dc3bd077SAxel Dörfler {
371dc3bd077SAxel Dörfler BBitmap* icon = new BBitmap(BRect(0.0, 0.0, fIconSize - 1,
372dc3bd077SAxel Dörfler fIconSize - 1), B_RGBA32);
373dc3bd077SAxel Dörfler // NOTE: passing an invalid/unknown icon_size argument will cause
374dc3bd077SAxel Dörfler // the BNodeInfo to ignore it and just use the bitmap bounds.
375dc3bd077SAxel Dörfler if (BNodeInfo::GetTrackerIcon(ref, icon, (icon_size)fIconSize) == B_OK)
376dc3bd077SAxel Dörfler SetIcon(icon);
377dc3bd077SAxel Dörfler
378dc3bd077SAxel Dörfler delete icon;
379dc3bd077SAxel Dörfler }
380dc3bd077SAxel Dörfler
381dc3bd077SAxel Dörfler
382dc3bd077SAxel Dörfler void
_DrawFrame(BRect r,rgb_color col1,rgb_color col2,rgb_color col3,rgb_color col4)383dc3bd077SAxel Dörfler LaunchButton::_DrawFrame(BRect r, rgb_color col1, rgb_color col2,
384dc3bd077SAxel Dörfler rgb_color col3, rgb_color col4)
385dc3bd077SAxel Dörfler {
386dc3bd077SAxel Dörfler BeginLineArray(8);
387dc3bd077SAxel Dörfler AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col1);
388dc3bd077SAxel Dörfler AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col1);
389dc3bd077SAxel Dörfler AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col2);
390dc3bd077SAxel Dörfler AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col2);
391dc3bd077SAxel Dörfler r.InsetBy(1.0, 1.0);
392dc3bd077SAxel Dörfler AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col3);
393dc3bd077SAxel Dörfler AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col3);
394dc3bd077SAxel Dörfler AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col4);
395dc3bd077SAxel Dörfler AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col4);
396dc3bd077SAxel Dörfler EndLineArray();
397dc3bd077SAxel Dörfler }
398