xref: /haiku/src/preferences/appearance/ColorPreview.cpp (revision 97f11716bfaa0f385eb0e28a52bf56a5023b9e99)
12c765fafSJohn Scipione /*
2*5ef3f386SJohn Scipione  * Copyright 2002-2022 Haiku, Inc. All rights reserved.
32c765fafSJohn Scipione  * Distributed under the terms of the MIT License.
42c765fafSJohn Scipione  *
52c765fafSJohn Scipione  * Authors:
62c765fafSJohn Scipione  *		DarkWyrm, darkwyrm@earthlink.net
72c765fafSJohn Scipione  *		John Scipione, jscipione@gmail.com
82c765fafSJohn Scipione  */
92c765fafSJohn Scipione 
102c765fafSJohn Scipione 
112c765fafSJohn Scipione #include "ColorPreview.h"
122c765fafSJohn Scipione 
136f222a33SJohn Scipione #include <algorithm>
142c765fafSJohn Scipione 
156f222a33SJohn Scipione #include <stdio.h>
166f222a33SJohn Scipione 
176f222a33SJohn Scipione #include <Bitmap.h>
186f222a33SJohn Scipione #include <Message.h>
196f222a33SJohn Scipione #include <MessageRunner.h>
20fe3a2895SAugustin Cavalier #include <String.h>
216f222a33SJohn Scipione #include <View.h>
226f222a33SJohn Scipione #include <Window.h>
236f222a33SJohn Scipione 
24e88a89e6SJohn Scipione #include "defs.h"
25e88a89e6SJohn Scipione 
266f222a33SJohn Scipione 
276f222a33SJohn Scipione 
286f222a33SJohn Scipione static const int32 kMsgMessageRunner = 'MsgR';
296f222a33SJohn Scipione 
306f222a33SJohn Scipione 
316f222a33SJohn Scipione //	#pragma mark - ColorPreview
326f222a33SJohn Scipione 
336f222a33SJohn Scipione 
ColorPreview(BMessage * message,uint32 flags)34*5ef3f386SJohn Scipione ColorPreview::ColorPreview(BMessage* message, uint32 flags)
352c765fafSJohn Scipione 	:
36*5ef3f386SJohn Scipione 	BControl("ColorPreview", "", message, flags | B_WILL_DRAW),
376f222a33SJohn Scipione 	fColor(ui_color(B_PANEL_BACKGROUND_COLOR)),
386f222a33SJohn Scipione 	fDisabledColor((rgb_color){ 128, 128, 128 }),
396f222a33SJohn Scipione 	fMessageRunner(NULL),
406f222a33SJohn Scipione 	fIsRectangle(true)
412c765fafSJohn Scipione {
422c765fafSJohn Scipione 	SetViewColor(B_TRANSPARENT_COLOR);
432c765fafSJohn Scipione 	SetLowColor(0, 0, 0);
44*5ef3f386SJohn Scipione 	SetExplicitSize(BSize(StringWidth("M") * 8, StringWidth("M") * 7));
452c765fafSJohn Scipione }
462c765fafSJohn Scipione 
472c765fafSJohn Scipione 
~ColorPreview(void)482c765fafSJohn Scipione ColorPreview::~ColorPreview(void)
492c765fafSJohn Scipione {
502c765fafSJohn Scipione }
512c765fafSJohn Scipione 
522c765fafSJohn Scipione 
532c765fafSJohn Scipione void
Draw(BRect updateRect)546f222a33SJohn Scipione ColorPreview::Draw(BRect updateRect)
552c765fafSJohn Scipione {
562c765fafSJohn Scipione 	rgb_color color;
576f222a33SJohn Scipione 	if (IsEnabled())
586f222a33SJohn Scipione 		color = fColor;
592c765fafSJohn Scipione 	else
606f222a33SJohn Scipione 		color = fDisabledColor;
612c765fafSJohn Scipione 
626f222a33SJohn Scipione 	if (fIsRectangle) {
636f222a33SJohn Scipione 		if (IsEnabled()) {
6497ef596fSJohn Scipione 			rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
6597ef596fSJohn Scipione 			rgb_color shadow = tint_color(background, B_DARKEN_1_TINT);
6697ef596fSJohn Scipione 			rgb_color darkShadow = tint_color(background, B_DARKEN_3_TINT);
6797ef596fSJohn Scipione 			rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
682c765fafSJohn Scipione 
6997ef596fSJohn Scipione 			BRect bounds(Bounds());
702c765fafSJohn Scipione 
7197ef596fSJohn Scipione 			BeginLineArray(4);
7297ef596fSJohn Scipione 			AddLine(BPoint(bounds.left, bounds.bottom),
7397ef596fSJohn Scipione 			BPoint(bounds.left, bounds.top), shadow);
7497ef596fSJohn Scipione 			AddLine(BPoint(bounds.left + 1.0, bounds.top),
7597ef596fSJohn Scipione 			BPoint(bounds.right, bounds.top), shadow);
7697ef596fSJohn Scipione 			AddLine(BPoint(bounds.right, bounds.top + 1.0),
7797ef596fSJohn Scipione 			BPoint(bounds.right, bounds.bottom), light);
7897ef596fSJohn Scipione 			AddLine(BPoint(bounds.right - 1.0, bounds.bottom),
7997ef596fSJohn Scipione 			BPoint(bounds.left + 1.0, bounds.bottom), light);
8097ef596fSJohn Scipione 			EndLineArray();
8197ef596fSJohn Scipione 			bounds.InsetBy(1.0, 1.0);
822c765fafSJohn Scipione 
8397ef596fSJohn Scipione 			BeginLineArray(4);
8497ef596fSJohn Scipione 			AddLine(BPoint(bounds.left, bounds.bottom),
8597ef596fSJohn Scipione 			BPoint(bounds.left, bounds.top), darkShadow);
8697ef596fSJohn Scipione 			AddLine(BPoint(bounds.left + 1.0, bounds.top),
8797ef596fSJohn Scipione 			BPoint(bounds.right, bounds.top), darkShadow);
8897ef596fSJohn Scipione 			AddLine(BPoint(bounds.right, bounds.top + 1.0),
8997ef596fSJohn Scipione 			BPoint(bounds.right, bounds.bottom), background);
9097ef596fSJohn Scipione 			AddLine(BPoint(bounds.right - 1.0, bounds.bottom),
9197ef596fSJohn Scipione 			BPoint(bounds.left + 1.0, bounds.bottom), background);
9297ef596fSJohn Scipione 			EndLineArray();
9397ef596fSJohn Scipione 			bounds.InsetBy(1.0, 1.0);
942c765fafSJohn Scipione 
952c765fafSJohn Scipione 			SetHighColor(color);
9697ef596fSJohn Scipione 			FillRect(bounds);
972c765fafSJohn Scipione 		} else {
982c765fafSJohn Scipione 			SetHighColor(color);
992c765fafSJohn Scipione 			FillRect(Bounds());
1002c765fafSJohn Scipione 		}
1012c765fafSJohn Scipione 	} else {
1022c765fafSJohn Scipione 		// fill background
1032c765fafSJohn Scipione 		SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
1046f222a33SJohn Scipione 		FillRect(updateRect);
1052c765fafSJohn Scipione 
1062c765fafSJohn Scipione 		SetHighColor(color);
1072c765fafSJohn Scipione 		FillEllipse(Bounds());
1086f222a33SJohn Scipione 
1096f222a33SJohn Scipione 		if (IsEnabled())
1102c765fafSJohn Scipione 			StrokeEllipse(Bounds(), B_SOLID_LOW);
1112c765fafSJohn Scipione 	}
1122c765fafSJohn Scipione }
1132c765fafSJohn Scipione 
1142c765fafSJohn Scipione 
1152c765fafSJohn Scipione void
MessageReceived(BMessage * message)1162c765fafSJohn Scipione ColorPreview::MessageReceived(BMessage* message)
1172c765fafSJohn Scipione {
1182c765fafSJohn Scipione 	// If we received a dropped message, see if it contains color data
1192c765fafSJohn Scipione 	if (message->WasDropped()) {
120e88a89e6SJohn Scipione 		rgb_color* color;
1212c765fafSJohn Scipione 		ssize_t size;
122e88a89e6SJohn Scipione 		if (message->FindData(kRGBColor, B_RGB_COLOR_TYPE,
123e88a89e6SJohn Scipione 				(const void**)&color, &size) == B_OK) {
124e88a89e6SJohn Scipione 			BMessage setColorMessage(SET_CURRENT_COLOR);
125e88a89e6SJohn Scipione 			setColorMessage.AddData(kRGBColor, B_RGB_COLOR_TYPE, color,
126ff38df48SAdrien Destugues 				sizeof(rgb_color));
127e88a89e6SJohn Scipione 			Invoke(&setColorMessage);
1282c765fafSJohn Scipione 		}
1296f222a33SJohn Scipione 	} else if ((int32)message->what == kMsgMessageRunner) {
1306f222a33SJohn Scipione 		BPoint where;
1316f222a33SJohn Scipione 		uint32 buttons;
1326f222a33SJohn Scipione 		GetMouse(&where, &buttons);
1336f222a33SJohn Scipione 
1346f222a33SJohn Scipione 		_DragColor(where);
1352c765fafSJohn Scipione 	}
1362c765fafSJohn Scipione 
1376f222a33SJohn Scipione 	BControl::MessageReceived(message);
1382c765fafSJohn Scipione }
1392c765fafSJohn Scipione 
1402c765fafSJohn Scipione 
1412c765fafSJohn Scipione void
MouseDown(BPoint where)1426f222a33SJohn Scipione ColorPreview::MouseDown(BPoint where)
1432c765fafSJohn Scipione {
1446f222a33SJohn Scipione 	BWindow* window = Window();
1456f222a33SJohn Scipione 	if (window != NULL)
1466f222a33SJohn Scipione 		window->Activate();
1476f222a33SJohn Scipione 
1486f222a33SJohn Scipione 	fMessageRunner = new BMessageRunner(this, new BMessage(kMsgMessageRunner),
1496f222a33SJohn Scipione 		300000, 1);
1506f222a33SJohn Scipione 
1516f222a33SJohn Scipione 	SetMouseEventMask(B_POINTER_EVENTS,
1526f222a33SJohn Scipione 		B_SUSPEND_VIEW_FOCUS | B_LOCK_WINDOW_FOCUS);
1536f222a33SJohn Scipione 
1546f222a33SJohn Scipione 	BRect rect = Bounds().InsetByCopy(2.0f, 2.0f);
1556f222a33SJohn Scipione 	rect.top = roundf(rect.bottom / 2.0f + 1);
1566f222a33SJohn Scipione 
1576f222a33SJohn Scipione 	if (rect.Contains(where)) {
1582c765fafSJohn Scipione 		Invalidate();
1596f222a33SJohn Scipione 		Invoke();
1602c765fafSJohn Scipione 	}
1616f222a33SJohn Scipione 
1626f222a33SJohn Scipione 	BControl::MouseDown(where);
1632c765fafSJohn Scipione }
1642c765fafSJohn Scipione 
1652c765fafSJohn Scipione 
1662c765fafSJohn Scipione void
MouseMoved(BPoint where,uint32 transit,const BMessage * message)1676f222a33SJohn Scipione ColorPreview::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
1682c765fafSJohn Scipione {
1696f222a33SJohn Scipione 	if (fMessageRunner != NULL)
1706f222a33SJohn Scipione 		_DragColor(where);
1716f222a33SJohn Scipione 
1726f222a33SJohn Scipione 	BControl::MouseMoved(where, transit, message);
1736f222a33SJohn Scipione }
1746f222a33SJohn Scipione 
1756f222a33SJohn Scipione 
1766f222a33SJohn Scipione void
MouseUp(BPoint where)1776f222a33SJohn Scipione ColorPreview::MouseUp(BPoint where)
1786f222a33SJohn Scipione {
1796f222a33SJohn Scipione 	delete fMessageRunner;
1806f222a33SJohn Scipione 	fMessageRunner = NULL;
1816f222a33SJohn Scipione 
1826f222a33SJohn Scipione 	BControl::MouseUp(where);
1832c765fafSJohn Scipione }
1842c765fafSJohn Scipione 
1852c765fafSJohn Scipione 
1862c765fafSJohn Scipione rgb_color
Color(void) const1872c765fafSJohn Scipione ColorPreview::Color(void) const
1882c765fafSJohn Scipione {
1896f222a33SJohn Scipione 	return fColor;
1902c765fafSJohn Scipione }
1912c765fafSJohn Scipione 
1922c765fafSJohn Scipione 
1932c765fafSJohn Scipione void
SetColor(rgb_color color)1946f222a33SJohn Scipione ColorPreview::SetColor(rgb_color color)
1952c765fafSJohn Scipione {
1966f222a33SJohn Scipione 	color.alpha = 255;
1976f222a33SJohn Scipione 
1986f222a33SJohn Scipione 	SetHighColor(color);
1996f222a33SJohn Scipione 	fColor = color;
2006f222a33SJohn Scipione 
2016f222a33SJohn Scipione 	Invalidate();
2026f222a33SJohn Scipione 	Invoke();
2032c765fafSJohn Scipione }
2042c765fafSJohn Scipione 
2052c765fafSJohn Scipione 
2062c765fafSJohn Scipione void
SetColor(uint8 red,uint8 green,uint8 blue)2076f222a33SJohn Scipione ColorPreview::SetColor(uint8 red, uint8 green, uint8 blue)
2082c765fafSJohn Scipione {
2096f222a33SJohn Scipione 	SetHighColor(red, green, blue);
2106f222a33SJohn Scipione 	fColor.red = red;
2116f222a33SJohn Scipione 	fColor.green = green;
2126f222a33SJohn Scipione 	fColor.blue = blue;
2136f222a33SJohn Scipione 	fColor.alpha = 255;
2146f222a33SJohn Scipione 
2156f222a33SJohn Scipione 	Invalidate();
2166f222a33SJohn Scipione 	Invoke();
2172c765fafSJohn Scipione }
2182c765fafSJohn Scipione 
2192c765fafSJohn Scipione 
2202c765fafSJohn Scipione void
SetMode(bool rectangle)2216f222a33SJohn Scipione ColorPreview::SetMode(bool rectangle)
2222c765fafSJohn Scipione {
2236f222a33SJohn Scipione 	fIsRectangle = rectangle;
2246f222a33SJohn Scipione }
2256f222a33SJohn Scipione 
2266f222a33SJohn Scipione 
2276f222a33SJohn Scipione //	#pragma mark - ColorPreview private methods
2286f222a33SJohn Scipione 
2296f222a33SJohn Scipione 
2306f222a33SJohn Scipione void
_DragColor(BPoint where)2316f222a33SJohn Scipione ColorPreview::_DragColor(BPoint where)
2326f222a33SJohn Scipione {
233fe3a2895SAugustin Cavalier 	BString hexStr;
234fe3a2895SAugustin Cavalier 	hexStr.SetToFormat("#%.2X%.2X%.2X", fColor.red, fColor.green, fColor.blue);
2356f222a33SJohn Scipione 
2366f222a33SJohn Scipione 	BMessage message(B_PASTE);
237e88a89e6SJohn Scipione 	message.AddData("text/plain", B_MIME_TYPE, hexStr.String(),
238e88a89e6SJohn Scipione 		hexStr.Length());
239e88a89e6SJohn Scipione 	message.AddData(kRGBColor, B_RGB_COLOR_TYPE, &fColor, sizeof(fColor));
2406f222a33SJohn Scipione 
2416f222a33SJohn Scipione 	BRect rect(0.0f, 0.0f, 20.0f, 20.0f);
2426f222a33SJohn Scipione 
2436f222a33SJohn Scipione 	BBitmap* bitmap = new BBitmap(rect, B_RGB32, true);
2446f222a33SJohn Scipione 	if (bitmap->Lock()) {
2456f222a33SJohn Scipione 		BView* view = new BView(rect, "", B_FOLLOW_NONE, B_WILL_DRAW);
2466f222a33SJohn Scipione 		bitmap->AddChild(view);
2476f222a33SJohn Scipione 
2486f222a33SJohn Scipione 		view->SetHighColor(B_TRANSPARENT_COLOR);
2496f222a33SJohn Scipione 		view->FillRect(view->Bounds());
2506f222a33SJohn Scipione 
2516f222a33SJohn Scipione 		++rect.top;
2526f222a33SJohn Scipione 		++rect.left;
2536f222a33SJohn Scipione 
2546f222a33SJohn Scipione 		view->SetHighColor(0, 0, 0, 100);
2556f222a33SJohn Scipione 		view->FillRect(rect);
2566f222a33SJohn Scipione 		rect.OffsetBy(-1.0f, -1.0f);
2576f222a33SJohn Scipione 
2586f222a33SJohn Scipione 		view->SetHighColor(std::min(255, (int)(1.2 * fColor.red + 40)),
2596f222a33SJohn Scipione 			std::min(255, (int)(1.2 * fColor.green + 40)),
2606f222a33SJohn Scipione 			std::min(255, (int)(1.2 * fColor.blue + 40)));
2616f222a33SJohn Scipione 		view->StrokeRect(rect);
2626f222a33SJohn Scipione 
2636f222a33SJohn Scipione 		++rect.left;
2646f222a33SJohn Scipione 		++rect.top;
2656f222a33SJohn Scipione 
2666f222a33SJohn Scipione 		view->SetHighColor((int32)(0.8 * fColor.red),
2676f222a33SJohn Scipione 			(int32)(0.8 * fColor.green),
2686f222a33SJohn Scipione 			(int32)(0.8 * fColor.blue));
2696f222a33SJohn Scipione 		view->StrokeRect(rect);
2706f222a33SJohn Scipione 
2716f222a33SJohn Scipione 		--rect.right;
2726f222a33SJohn Scipione 		--rect.bottom;
2736f222a33SJohn Scipione 
2746f222a33SJohn Scipione 		view->SetHighColor(fColor.red, fColor.green, fColor.blue);
2756f222a33SJohn Scipione 		view->FillRect(rect);
2766f222a33SJohn Scipione 		view->Sync();
2776f222a33SJohn Scipione 
2786f222a33SJohn Scipione 		bitmap->Unlock();
2796f222a33SJohn Scipione 	}
2806f222a33SJohn Scipione 
2816f222a33SJohn Scipione 	DragMessage(&message, bitmap, B_OP_ALPHA, BPoint(14.0f, 14.0f));
2826f222a33SJohn Scipione 
2836f222a33SJohn Scipione 	MouseUp(where);
2842c765fafSJohn Scipione }
285