1/* 2 * Copyright 2001 Werner Freytag - please read to the LICENSE file 3 * 4 * Copyright 2002-2015, Stephan Aßmus <superstippi@gmx.de> 5 * All rights reserved. 6 * 7 */ 8 9#include "ColorPreview.h" 10 11#include <stdio.h> 12 13#include <Bitmap.h> 14#include <ControlLook.h> 15#include <Cursor.h> 16#include <LayoutUtils.h> 17#include <MessageRunner.h> 18#include <String.h> 19#include <Window.h> 20 21#include "cursors.h" 22#include "support_ui.h" 23 24 25ColorPreview::ColorPreview(BRect frame, rgb_color color) 26 : 27 BControl(frame, "colorpreview", "", new BMessage(MSG_COLOR_PREVIEW), 28 B_FOLLOW_TOP | B_FOLLOW_LEFT, B_WILL_DRAW), 29 fColor(color), 30 fOldColor(color), 31 32 fMouseDown(false), 33 34 fMessageRunner(0), 35 fBorderStyle(B_FANCY_BORDER) 36{ 37} 38 39 40ColorPreview::ColorPreview(rgb_color color) 41 : 42 BControl("colorpreview", "", new BMessage(MSG_COLOR_PREVIEW), B_WILL_DRAW), 43 fColor(color), 44 fOldColor(color), 45 46 fMouseDown(false), 47 48 fMessageRunner(0), 49 fBorderStyle(B_FANCY_BORDER) 50{ 51} 52 53 54BSize 55ColorPreview::MinSize() 56{ 57 BSize minSize(32, 36); 58 return BLayoutUtils::ComposeSize(ExplicitMinSize(), minSize); 59} 60 61 62BSize 63ColorPreview::PreferredSize() 64{ 65 BSize preferredSize(66, 70); 66 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), preferredSize); 67} 68 69 70BSize 71ColorPreview::MaxSize() 72{ 73 BSize maxSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED); 74 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), maxSize); 75} 76 77 78void 79ColorPreview::AttachedToWindow() 80{ 81 BControl::AttachedToWindow(); 82 SetViewColor(B_TRANSPARENT_COLOR); 83} 84 85 86void 87ColorPreview::Draw(BRect updateRect) 88{ 89 BRect bounds(Bounds()); 90 91 // Frame 92 if (fBorderStyle == B_FANCY_BORDER) { 93 rgb_color color = LowColor(); 94 be_control_look->DrawTextControlBorder(this, bounds, updateRect, color); 95 } 96 97 BRect r(bounds.left, bounds.top, bounds.right, 98 bounds.top + bounds.Height() / 2); 99 SetHighColor(fColor); 100 FillRect(r); 101 102 r.top = r.bottom + 1; 103 r.bottom = bounds.bottom; 104 SetHighColor(fOldColor); 105 FillRect(r); 106} 107 108 109void 110ColorPreview::MessageReceived(BMessage* message) 111{ 112 if (message->what == MSG_MESSAGERUNNER) { 113 114 BPoint where; 115 uint32 buttons; 116 117 GetMouse(&where, &buttons); 118 119 _DragColor(where); 120 121 } else { 122#ifdef HAIKU_TARGET_PLATFORM_DANO 123 const 124#endif 125 char* nameFound; 126 type_code typeFound; 127 128 if (message->GetInfo(B_RGB_COLOR_TYPE, 0, 129 &nameFound, &typeFound) != B_OK) { 130 BControl::MessageReceived(message); 131 return; 132 } 133 134 rgb_color* color; 135 ssize_t numBytes; 136 message->FindData(nameFound, typeFound, 137 (const void**)&color, &numBytes); 138 139 BPoint where; 140 bool droppedOnNewArea = false; 141 if (message->FindPoint("_drop_point_", &where) == B_OK) { 142 ConvertFromScreen(&where); 143 if (where.y > Bounds().top + (Bounds().IntegerHeight() >> 1)) 144 droppedOnNewArea = true; 145 } 146 147 if (droppedOnNewArea) 148 SetNewColor(*color); 149 else 150 SetColor(*color); 151 Invoke(); 152 } 153} 154 155 156void 157ColorPreview::MouseDown(BPoint where) 158{ 159 Window()->Activate(); 160 161 fMouseDown = true; 162 163 fMessageRunner = new BMessageRunner( 164 this, new BMessage(MSG_MESSAGERUNNER), 300000, 1); 165 166 SetMouseEventMask(B_POINTER_EVENTS, 167 B_SUSPEND_VIEW_FOCUS | B_LOCK_WINDOW_FOCUS); 168 169 BRect rect = Bounds().InsetByCopy(2.0, 2.0); 170 rect.top = rect.bottom/2 + 1; 171 172 if (rect.Contains( where ) ) { 173 fColor = fOldColor; 174 Draw( Bounds() ); 175 Invoke(); 176 } 177 178} 179 180 181void 182ColorPreview::MouseUp(BPoint where) 183{ 184 delete fMessageRunner; 185 fMessageRunner = NULL; 186 187 fMouseDown = false; 188 BControl::MouseUp(where); 189} 190 191 192void 193ColorPreview::MouseMoved(BPoint where, uint32 transit, const BMessage* message) 194{ 195 if (transit == B_ENTERED_VIEW) { 196 BCursor cursor(kDropperCursor); 197 SetViewCursor(&cursor, true); 198 } 199 if (fMouseDown) 200 _DragColor(where); 201} 202 203 204status_t 205ColorPreview::Invoke(BMessage* message) 206{ 207 if (message == NULL) 208 message = Message(); 209 210 if (message) { 211 message->RemoveName("color"); 212 message->AddData("color", B_RGB_COLOR_TYPE, &fColor, sizeof(fColor)); 213 } 214 215 return BControl::Invoke(message); 216} 217 218 219void 220ColorPreview::SetColor(rgb_color color) 221{ 222 color.alpha = 255; 223 fColor = color; 224 225 Invalidate(); 226} 227 228 229void 230ColorPreview::SetNewColor(rgb_color color) 231{ 232 fColor = color; 233 fOldColor = color; 234 235 Invalidate(); 236} 237 238 239// #pragma mark - 240 241 242void 243ColorPreview::_DragColor(BPoint where) 244{ 245 BBitmap* bitmap = new BBitmap(BRect(0.0, 0.0, 15.0, 15.0), B_RGB32); 246 BMessage message = make_color_drop_message(fColor, bitmap); 247 248 DragMessage(&message, bitmap, B_OP_ALPHA, BPoint(9.0, 9.0)); 249 250 MouseUp(where); 251} 252 253