1 /*
2 * Copyright 2003-2007, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Jérôme Duval
7 * Jonas Sundström
8 */
9
10
11 #include "DeskButton.h"
12
13 #include <Alert.h>
14 #include <Bitmap.h>
15 #include <Catalog.h>
16 #include <ControlLook.h>
17 #include <Dragger.h>
18 #include <MenuItem.h>
19 #include <Message.h>
20 #include <NodeInfo.h>
21 #include <PopUpMenu.h>
22 #include <Roster.h>
23 #include <String.h>
24
25 #include <stdlib.h>
26
27 #define OPEN_REF 'opre'
28 #define DO_ACTION 'doac'
29
30
31 #undef B_TRANSLATION_CONTEXT
32 #define B_TRANSLATION_CONTEXT "DeskButton"
33
34
35 extern const char *kAppSignature;
36 // from desklink.cpp
37
38
DeskButton(BRect frame,entry_ref * ref,const char * name,BList & titles,BList & actions,uint32 resizeMask,uint32 flags)39 DeskButton::DeskButton(BRect frame, entry_ref* ref, const char* name,
40 BList& titles, BList& actions, uint32 resizeMask, uint32 flags)
41 : BView(frame, name, resizeMask, flags),
42 fRef(*ref),
43 fActionList(actions),
44 fTitleList(titles)
45 {
46 fSegments = new BBitmap(frame, B_RGBA32);
47 BNodeInfo::GetTrackerIcon(&fRef, fSegments, (icon_size)-1);
48 }
49
50
DeskButton(BMessage * message)51 DeskButton::DeskButton(BMessage *message)
52 : BView(message)
53 {
54 message->FindRef("ref", &fRef);
55
56 BString title, action;
57 int32 index = 0;
58 while(message->FindString("title", index, &title)==B_OK
59 && message->FindString("action", index, &action)==B_OK) {
60 fTitleList.AddItem(new BString(title));
61 fActionList.AddItem(new BString(action));
62 index++;
63 }
64
65 BRect bounds;
66 message->FindRect("bounds", &bounds);
67
68 fSegments = new BBitmap(bounds, B_RGBA32);
69 BNodeInfo::GetTrackerIcon(&fRef, fSegments, (icon_size)-1);
70 }
71
72
~DeskButton()73 DeskButton::~DeskButton()
74 {
75 delete fSegments;
76 }
77
78
79 // archiving overrides
80 DeskButton *
Instantiate(BMessage * data)81 DeskButton::Instantiate(BMessage *data)
82 {
83 if (!validate_instantiation(data, "DeskButton"))
84 return NULL;
85
86 return new DeskButton(data);
87 }
88
89
90 status_t
Archive(BMessage * data,bool deep) const91 DeskButton::Archive(BMessage *data, bool deep) const
92 {
93 BView::Archive(data, deep);
94
95 data->AddRef("ref", &fRef);
96
97 for (int32 i = 0; i < fTitleList.CountItems()
98 && i < fActionList.CountItems(); i++) {
99 data->AddString("title", *(BString*)fTitleList.ItemAt(i));
100 data->AddString("action", *(BString*)fActionList.ItemAt(i));
101 }
102
103 data->AddRect("bounds", fSegments->Bounds());
104
105 data->AddString("add_on", kAppSignature);
106 return B_NO_ERROR;
107 }
108
109
110 void
MessageReceived(BMessage * message)111 DeskButton::MessageReceived(BMessage *message)
112 {
113 switch (message->what) {
114 case OPEN_REF:
115 be_roster->Launch(&fRef);
116 break;
117
118 case DO_ACTION:
119 {
120 BString action;
121 if (message->FindString("action", &action) == B_OK) {
122 action += " &";
123 system(action.String());
124 }
125 break;
126 }
127
128 default:
129 BView::MessageReceived(message);
130 break;
131 }
132 }
133
134
135 void
AttachedToWindow()136 DeskButton::AttachedToWindow()
137 {
138 BView *parent = Parent();
139 if (parent)
140 SetViewColor(parent->ViewColor());
141
142 BView::AttachedToWindow();
143 }
144
145
146 void
Draw(BRect rect)147 DeskButton::Draw(BRect rect)
148 {
149 BView::Draw(rect);
150
151 #ifdef __HAIKU__
152 SetDrawingMode(B_OP_ALPHA);
153 SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
154 #else
155 SetDrawingMode(B_OP_OVER);
156 #endif
157 DrawBitmap(fSegments);
158 }
159
160
161 void
MouseDown(BPoint point)162 DeskButton::MouseDown(BPoint point)
163 {
164 uint32 mouseButtons = 0;
165 if (Window()->CurrentMessage() != NULL)
166 mouseButtons = Window()->CurrentMessage()->FindInt32("buttons");
167
168 BPoint where = ConvertToScreen(point);
169
170 if (mouseButtons & B_SECONDARY_MOUSE_BUTTON) {
171 BString label = B_TRANSLATE_COMMENT("Open %name", "Don't translate "
172 "variable %name");
173 label.ReplaceFirst("%name", fRef.name);
174 BPopUpMenu *menu = new BPopUpMenu("", false, false);
175 menu->SetFont(be_plain_font);
176 menu->AddItem(new BMenuItem(label.String(), new BMessage(OPEN_REF)));
177 if (fTitleList.CountItems() > 0 && fActionList.CountItems() > 0) {
178 menu->AddSeparatorItem();
179 for (int32 i = 0; i < fTitleList.CountItems()
180 && i < fActionList.CountItems(); i++) {
181 BMessage *message = new BMessage(DO_ACTION);
182 message->AddString("action", *(BString*)fActionList.ItemAt(i));
183 menu->AddItem(new BMenuItem(((BString*)fTitleList.ItemAt(i))->String(), message));
184 }
185 }
186
187 menu->SetTargetForItems(this);
188 menu->Go(where, true, true, BRect(where - BPoint(4, 4),
189 where + BPoint(4, 4)));
190 } else if (mouseButtons & B_PRIMARY_MOUSE_BUTTON) {
191 be_roster->Launch(&fRef);
192 }
193 }
194