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