1 /*
2 * Copyright 2016 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 "ColorWhichListView.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 "ColorWhichItem.h"
21 #include "defs.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 - ColorWhichListView
32
33
ColorWhichListView(const char * name,list_view_type type,uint32 flags)34 ColorWhichListView::ColorWhichListView(const char* name,
35 list_view_type type, uint32 flags)
36 :
37 BListView(name, type, flags)
38 {
39 }
40
41
~ColorWhichListView()42 ColorWhichListView::~ColorWhichListView()
43 {
44 }
45
46
47 bool
InitiateDrag(BPoint where,int32 index,bool wasSelected)48 ColorWhichListView::InitiateDrag(BPoint where, int32 index, bool wasSelected)
49 {
50 ColorWhichItem* colorWhichItem
51 = dynamic_cast<ColorWhichItem*>(ItemAt(index));
52 if (colorWhichItem == NULL)
53 return false;
54
55 rgb_color color = colorWhichItem->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 = colorWhichItem->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
112 void
MessageReceived(BMessage * message)113 ColorWhichListView::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 ColorWhichItem* item = dynamic_cast<ColorWhichItem*>(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 APRView
126 int32 command = index == CurrentSelection()
127 ? SET_CURRENT_COLOR : 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 == SET_COLOR)
132 setColorMessage.AddUInt32(kWhich, (uint32)item->ColorWhich());
133
134 // build messenger and send message
135 BMessenger messenger = BMessenger(Parent());
136 if (messenger.IsValid()) {
137 messenger.SendMessage(&setColorMessage);
138 if (command == SET_COLOR) {
139 // redraw item, 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