xref: /haiku/src/bin/desklink/DeskButton.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2 //
3 //	Copyright (c) 2003, OpenBeOS
4 //
5 //  This software is part of the OpenBeOS distribution and is covered
6 //  by the OpenBeOS license.
7 //
8 //
9 //  Program:	 desklink
10 //  Author:      Jérôme DUVAL
11 //  Description: VolumeControl and link items in Deskbar
12 //  Created :    October 20, 2003
13 //	Modified by: Jérome Duval
14 //
15 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
16 
17 #include <Dragger.h>
18 #include <Bitmap.h>
19 #include <Message.h>
20 #include <String.h>
21 #include <Alert.h>
22 #include <NodeInfo.h>
23 #include <PopUpMenu.h>
24 #include <MenuItem.h>
25 #include <Roster.h>
26 #include <stdlib.h>
27 #include "DeskButton.h"
28 
29 #define OPEN_REF	'opre'
30 #define DO_ACTION	'doac'
31 
32 extern char *app_signature;
33 
34 DeskButton::DeskButton(BRect frame, entry_ref *entry_ref, const char *name, BList &titles, BList &actions,
35 		uint32 resizeMask, uint32 flags)
36 	:	BView(frame, name, resizeMask, flags),
37 		ref(*entry_ref),
38 		actionList(actions),
39 		titleList(titles)
40 {
41 	// Background Color
42 	SetViewColor(184,184,184);
43 
44 	//add dragger
45 	BRect rect(Bounds());
46 	rect.left = rect.right-7.0;
47 	rect.top = rect.bottom-7.0;
48 	BDragger *dragger = new BDragger(rect, this, B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
49 	AddChild(dragger);
50 	dragger->SetViewColor(B_TRANSPARENT_32_BIT);
51 
52 	segments = new BBitmap(BRect(0,0,15,15), B_CMAP8);
53 	BNodeInfo::GetTrackerIcon(&ref, segments, B_MINI_ICON);
54 }
55 
56 
57 DeskButton::DeskButton(BMessage *message)
58 	:	BView(message)
59 {
60 	message->FindRef("ref", &ref);
61 
62 	BString title, action;
63 	int32 index = 0;
64 	while(message->FindString("title", index, &title)==B_OK
65 		&& message->FindString("action", index, &action)==B_OK) {
66 		titleList.AddItem(new BString(title));
67 		actionList.AddItem(new BString(action));
68 		index++;
69 	}
70 
71 	segments = new BBitmap(BRect(0,0,15,15), B_CMAP8);
72 	BNodeInfo::GetTrackerIcon(&ref, segments, B_MINI_ICON);
73 }
74 
75 
76 DeskButton::~DeskButton()
77 {
78 	delete segments;
79 }
80 
81 
82 // archiving overrides
83 DeskButton *
84 DeskButton::Instantiate(BMessage *data)
85 {
86 	if (!validate_instantiation(data, "DeskButton"))
87 		return NULL;
88 	return new DeskButton(data);
89 }
90 
91 
92 status_t
93 DeskButton::Archive(BMessage *data, bool deep) const
94 {
95 	BView::Archive(data, deep);
96 
97 	data->AddRef("ref", &ref);
98 
99 	for(int32 i=0; i<titleList.CountItems() &&
100 		i<actionList.CountItems(); i++) {
101 		data->AddString("title", *(BString*)titleList.ItemAt(i));
102 		data->AddString("action", *(BString*)actionList.ItemAt(i));
103 	}
104 
105 	data->AddString("add_on", app_signature);
106 	return B_NO_ERROR;
107 }
108 
109 
110 void
111 DeskButton::MessageReceived(BMessage *message)
112 {
113 	switch (message->what) {
114 		case B_ABOUT_REQUESTED:
115 			(new BAlert("About Desklink", "Desklink (Replicant)\n"
116 				"  Brought to you by Jérôme DUVAL.\n\n"
117 				"OpenBeOS, 2003","OK"))->Go();
118 			break;
119 		case OPEN_REF:
120 			be_roster->Launch(&ref);
121 			break;
122 		case DO_ACTION:
123 		{
124 			BString action;
125 			if(message->FindString("action", &action)==B_OK) {
126 				action += " &";
127 				system(action.String());
128 			}
129 			break;
130 		}
131 		default:
132 			BView::MessageReceived(message);
133 			break;
134 	}
135 }
136 
137 
138 void
139 DeskButton::Draw(BRect rect)
140 {
141 	BView::Draw(rect);
142 
143 	SetDrawingMode(B_OP_OVER);
144 	DrawBitmap(segments);
145 }
146 
147 
148 void
149 DeskButton::MouseDown(BPoint point)
150 {
151 	uint32 mouseButtons;
152 	BPoint where;
153 	GetMouse(&where, &mouseButtons, true);
154 
155 	where = ConvertToScreen(point);
156 
157 	if (mouseButtons & B_SECONDARY_MOUSE_BUTTON) {
158 		BString label = "Open ";
159 		label += ref.name;
160 		BPopUpMenu *menu = new BPopUpMenu("", false, false);
161 		menu->SetFont(be_plain_font);
162 		menu->AddItem(new BMenuItem(label.String(), new BMessage(OPEN_REF)));
163 		if(titleList.CountItems()>0 && actionList.CountItems()>0) {
164 			menu->AddSeparatorItem();
165 			for(int32 i=0; i<titleList.CountItems() && i<actionList.CountItems(); i++) {
166 				BMessage *message = new BMessage(DO_ACTION);
167 				message->AddString("action", *(BString*)actionList.ItemAt(i));
168 				menu->AddItem(new BMenuItem(((BString*)titleList.ItemAt(i))->String(), message));
169 			}
170 		}
171 
172 		menu->SetTargetForItems(this);
173 		menu->Go(where, true, true, BRect(where - BPoint(4, 4),
174 			where + BPoint(4, 4)));
175 	} else if (mouseButtons & B_PRIMARY_MOUSE_BUTTON) {
176 		be_roster->Launch(&ref);
177 	}
178 }
179