xref: /haiku/src/bin/desklink/DeskButton.cpp (revision a162e7af99792f851398580f9f8f1014117b2f79)
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