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 = "Open "; 174 label += fRef.name; 175 BPopUpMenu *menu = new BPopUpMenu("", false, false); 176 menu->SetFont(be_plain_font); 177 menu->AddItem(new BMenuItem(label.String(), new BMessage(OPEN_REF))); 178 if (fTitleList.CountItems() > 0 && fActionList.CountItems() > 0) { 179 menu->AddSeparatorItem(); 180 for (int32 i = 0; i < fTitleList.CountItems() 181 && i < fActionList.CountItems(); i++) { 182 BMessage *message = new BMessage(DO_ACTION); 183 message->AddString("action", *(BString*)fActionList.ItemAt(i)); 184 menu->AddItem(new BMenuItem(((BString*)fTitleList.ItemAt(i))->String(), message)); 185 } 186 } 187 188 menu->SetTargetForItems(this); 189 menu->Go(where, true, true, BRect(where - BPoint(4, 4), 190 where + BPoint(4, 4))); 191 } else if (mouseButtons & B_PRIMARY_MOUSE_BUTTON) { 192 be_roster->Launch(&fRef); 193 } 194 } 195