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 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 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 73 DeskButton::~DeskButton() 74 { 75 delete fSegments; 76 } 77 78 79 // archiving overrides 80 DeskButton * 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 91 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 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 136 DeskButton::AttachedToWindow() 137 { 138 BView *parent = Parent(); 139 if (parent) 140 SetViewColor(parent->ViewColor()); 141 142 BView::AttachedToWindow(); 143 } 144 145 146 void 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 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