1/* 2 * Copyright 2016-2022 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * John Scipione, jscipione@gmail.com 7 */ 8 9 10#include "ColorListView.h" 11 12#include <algorithm> 13 14#include <math.h> 15#include <stdio.h> 16 17#include <Bitmap.h> 18#include <String.h> 19 20#include "ColorItem.h" 21#include "ThemeView.h" 22 23 24// golden ratio 25#ifdef M_PHI 26# undef M_PHI 27#endif 28#define M_PHI 1.61803398874989484820 29 30 31// #pragma mark - ColorListView 32 33 34ColorListView::ColorListView(const char* name, 35 list_view_type type, uint32 flags) 36 : 37 BListView(name, type, flags) 38{ 39} 40 41 42ColorListView::~ColorListView() 43{ 44} 45 46 47bool 48ColorListView::InitiateDrag(BPoint where, int32 index, bool wasSelected) 49{ 50 ColorItem* colorItem 51 = dynamic_cast<ColorItem*>(ItemAt(index)); 52 if (colorItem == NULL) 53 return false; 54 55 rgb_color color = colorItem->Color(); 56 57 BString hexStr; 58 hexStr.SetToFormat("#%.2X%.2X%.2X", color.red, color.green, color.blue); 59 60 BMessage message(B_PASTE); 61 message.AddData("text/plain", B_MIME_TYPE, hexStr.String(), 62 hexStr.Length()); 63 message.AddData(kRGBColor, B_RGB_COLOR_TYPE, &color, sizeof(color)); 64 65 float itemHeight = colorItem->Height() - 5; 66 BRect rect(0.0f, 0.0f, roundf(itemHeight * M_PHI) - 1, itemHeight - 1); 67 68 BBitmap* bitmap = new BBitmap(rect, B_RGB32, true); 69 if (bitmap->Lock()) { 70 BView* view = new BView(rect, "", B_FOLLOW_NONE, B_WILL_DRAW); 71 bitmap->AddChild(view); 72 73 view->SetHighColor(B_TRANSPARENT_COLOR); 74 view->FillRect(view->Bounds()); 75 76 ++rect.top; 77 ++rect.left; 78 79 view->SetHighColor(0, 0, 0, 100); 80 view->FillRect(rect); 81 rect.OffsetBy(-1.0f, -1.0f); 82 83 view->SetHighColor(std::min(255, (int)(1.2 * color.red + 40)), 84 std::min(255, (int)(1.2 * color.green + 40)), 85 std::min(255, (int)(1.2 * color.blue + 40))); 86 view->StrokeRect(rect); 87 88 ++rect.left; 89 ++rect.top; 90 91 view->SetHighColor((int32)(0.8 * color.red), 92 (int32)(0.8 * color.green), 93 (int32)(0.8 * color.blue)); 94 view->StrokeRect(rect); 95 96 --rect.right; 97 --rect.bottom; 98 99 view->SetHighColor(color.red, color.green, color.blue); 100 view->FillRect(rect); 101 view->Sync(); 102 103 bitmap->Unlock(); 104 } 105 106 DragMessage(&message, bitmap, B_OP_ALPHA, BPoint(14.0f, 14.0f)); 107 108 return true; 109} 110 111 112void 113ColorListView::MessageReceived(BMessage* message) 114{ 115 // if we received a dropped message, see if it contains color data 116 if (message->WasDropped()) { 117 BPoint dropPoint = message->DropPoint(); 118 ConvertFromScreen(&dropPoint); 119 int32 index = IndexOf(dropPoint); 120 ColorItem* item = dynamic_cast<ColorItem*>(ItemAt(index)); 121 rgb_color* color; 122 ssize_t size; 123 if (item != NULL && message->FindData(kRGBColor, B_RGB_COLOR_TYPE, 124 (const void**)&color, &size) == B_OK) { 125 // build message to send to ThemeView 126 uint32 command = index == CurrentSelection() 127 ? MSG_SET_CURRENT_COLOR : MSG_SET_COLOR; 128 BMessage setColorMessage = BMessage(command); 129 setColorMessage.AddData(kRGBColor, B_RGB_COLOR_TYPE, color, size); 130 // if setting different color, add which color to set 131 if (command == MSG_SET_COLOR) 132 setColorMessage.AddString(kName, item->Text()); 133 134 // build messenger and send message 135 BMessenger messenger = BMessenger(Parent()); 136 if (messenger.IsValid()) { 137 messenger.SendMessage(&setColorMessage); 138 if (command == MSG_SET_COLOR) { 139 // redraw item, MSG_SET_CURRENT_COLOR does this for us 140 item->SetColor(*color); 141 InvalidateItem(index); 142 } 143 } 144 } 145 } 146 147 BListView::MessageReceived(message); 148} 149