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 fSegments = new BBitmap(BRect(BPoint(0, 0), be_control_look->ComposeIconSize(B_MINI_ICON)), 66 B_RGBA32); 67 BNodeInfo::GetTrackerIcon(&fRef, fSegments, 68 (icon_size)(fSegments->Bounds().IntegerWidth() + 1)); 69 } 70 71 72 DeskButton::~DeskButton() 73 { 74 delete fSegments; 75 } 76 77 78 // archiving overrides 79 DeskButton * 80 DeskButton::Instantiate(BMessage *data) 81 { 82 if (!validate_instantiation(data, "DeskButton")) 83 return NULL; 84 85 return new DeskButton(data); 86 } 87 88 89 status_t 90 DeskButton::Archive(BMessage *data, bool deep) const 91 { 92 BView::Archive(data, deep); 93 94 data->AddRef("ref", &fRef); 95 96 for (int32 i = 0; i < fTitleList.CountItems() 97 && i < fActionList.CountItems(); i++) { 98 data->AddString("title", *(BString*)fTitleList.ItemAt(i)); 99 data->AddString("action", *(BString*)fActionList.ItemAt(i)); 100 } 101 102 data->AddString("add_on", kAppSignature); 103 return B_NO_ERROR; 104 } 105 106 107 void 108 DeskButton::MessageReceived(BMessage *message) 109 { 110 switch (message->what) { 111 case OPEN_REF: 112 be_roster->Launch(&fRef); 113 break; 114 115 case DO_ACTION: 116 { 117 BString action; 118 if (message->FindString("action", &action) == B_OK) { 119 action += " &"; 120 system(action.String()); 121 } 122 break; 123 } 124 125 default: 126 BView::MessageReceived(message); 127 break; 128 } 129 } 130 131 132 void 133 DeskButton::AttachedToWindow() 134 { 135 BView *parent = Parent(); 136 if (parent) 137 SetViewColor(parent->ViewColor()); 138 139 BView::AttachedToWindow(); 140 } 141 142 143 void 144 DeskButton::Draw(BRect rect) 145 { 146 BView::Draw(rect); 147 148 #ifdef __HAIKU__ 149 SetDrawingMode(B_OP_ALPHA); 150 SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); 151 #else 152 SetDrawingMode(B_OP_OVER); 153 #endif 154 DrawBitmap(fSegments); 155 } 156 157 158 void 159 DeskButton::MouseDown(BPoint point) 160 { 161 uint32 mouseButtons = 0; 162 if (Window()->CurrentMessage() != NULL) 163 mouseButtons = Window()->CurrentMessage()->FindInt32("buttons"); 164 165 BPoint where = ConvertToScreen(point); 166 167 if (mouseButtons & B_SECONDARY_MOUSE_BUTTON) { 168 BString label = B_TRANSLATE_COMMENT("Open %name", "Don't translate " 169 "variable %name"); 170 label.ReplaceFirst("%name", fRef.name); 171 BPopUpMenu *menu = new BPopUpMenu("", false, false); 172 menu->SetFont(be_plain_font); 173 menu->AddItem(new BMenuItem(label.String(), new BMessage(OPEN_REF))); 174 if (fTitleList.CountItems() > 0 && fActionList.CountItems() > 0) { 175 menu->AddSeparatorItem(); 176 for (int32 i = 0; i < fTitleList.CountItems() 177 && i < fActionList.CountItems(); i++) { 178 BMessage *message = new BMessage(DO_ACTION); 179 message->AddString("action", *(BString*)fActionList.ItemAt(i)); 180 menu->AddItem(new BMenuItem(((BString*)fTitleList.ItemAt(i))->String(), message)); 181 } 182 } 183 184 menu->SetTargetForItems(this); 185 menu->Go(where, true, true, BRect(where - BPoint(4, 4), 186 where + BPoint(4, 4))); 187 } else if (mouseButtons & B_PRIMARY_MOUSE_BUTTON) { 188 be_roster->Launch(&fRef); 189 } 190 } 191