xref: /haiku/src/apps/terminal/ColorPreview.cpp (revision 1b370545d7f2051a6a89189505242cfdd69cbd4b)
1*1b370545SJessica Hamilton /*
2*1b370545SJessica Hamilton  * Copyright 2002-2022 Haiku, Inc. All rights reserved.
3*1b370545SJessica Hamilton  * Distributed under the terms of the MIT License.
4*1b370545SJessica Hamilton  *
5*1b370545SJessica Hamilton  * Authors:
6*1b370545SJessica Hamilton  *		DarkWyrm, darkwyrm@earthlink.net
7*1b370545SJessica Hamilton  *		John Scipione, jscipione@gmail.com
8*1b370545SJessica Hamilton  */
9*1b370545SJessica Hamilton 
10*1b370545SJessica Hamilton 
11*1b370545SJessica Hamilton #include "ColorPreview.h"
12*1b370545SJessica Hamilton 
13*1b370545SJessica Hamilton #include <algorithm>
14*1b370545SJessica Hamilton 
15*1b370545SJessica Hamilton #include <stdio.h>
16*1b370545SJessica Hamilton 
17*1b370545SJessica Hamilton #include <Bitmap.h>
18*1b370545SJessica Hamilton #include <Message.h>
19*1b370545SJessica Hamilton #include <MessageRunner.h>
20*1b370545SJessica Hamilton #include <String.h>
21*1b370545SJessica Hamilton #include <View.h>
22*1b370545SJessica Hamilton #include <Window.h>
23*1b370545SJessica Hamilton 
24*1b370545SJessica Hamilton #include "ThemeView.h"
25*1b370545SJessica Hamilton #include "TermConst.h"
26*1b370545SJessica Hamilton 
27*1b370545SJessica Hamilton 
28*1b370545SJessica Hamilton static const int32 kMsgMessageRunner = 'MsgR';
29*1b370545SJessica Hamilton 
30*1b370545SJessica Hamilton 
31*1b370545SJessica Hamilton //	#pragma mark - ColorPreview
32*1b370545SJessica Hamilton 
33*1b370545SJessica Hamilton 
ColorPreview(BMessage * message,uint32 flags)34*1b370545SJessica Hamilton ColorPreview::ColorPreview(BMessage* message, uint32 flags)
35*1b370545SJessica Hamilton 	:
36*1b370545SJessica Hamilton 	BControl("ColorPreview", "", message, flags | B_WILL_DRAW),
37*1b370545SJessica Hamilton 	fColor(ui_color(B_PANEL_BACKGROUND_COLOR)),
38*1b370545SJessica Hamilton 	fDisabledColor((rgb_color){ 128, 128, 128 }),
39*1b370545SJessica Hamilton 	fMessageRunner(NULL),
40*1b370545SJessica Hamilton 	fIsRectangle(true)
41*1b370545SJessica Hamilton {
42*1b370545SJessica Hamilton 	SetViewColor(B_TRANSPARENT_COLOR);
43*1b370545SJessica Hamilton 	SetLowColor(0, 0, 0);
44*1b370545SJessica Hamilton 	SetExplicitSize(BSize(StringWidth("M") * 8, StringWidth("M") * 7));
45*1b370545SJessica Hamilton }
46*1b370545SJessica Hamilton 
47*1b370545SJessica Hamilton 
~ColorPreview(void)48*1b370545SJessica Hamilton ColorPreview::~ColorPreview(void)
49*1b370545SJessica Hamilton {
50*1b370545SJessica Hamilton }
51*1b370545SJessica Hamilton 
52*1b370545SJessica Hamilton 
53*1b370545SJessica Hamilton void
Draw(BRect updateRect)54*1b370545SJessica Hamilton ColorPreview::Draw(BRect updateRect)
55*1b370545SJessica Hamilton {
56*1b370545SJessica Hamilton 	rgb_color color;
57*1b370545SJessica Hamilton 	if (IsEnabled())
58*1b370545SJessica Hamilton 		color = fColor;
59*1b370545SJessica Hamilton 	else
60*1b370545SJessica Hamilton 		color = fDisabledColor;
61*1b370545SJessica Hamilton 
62*1b370545SJessica Hamilton 	if (fIsRectangle) {
63*1b370545SJessica Hamilton 		if (IsEnabled()) {
64*1b370545SJessica Hamilton 			rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
65*1b370545SJessica Hamilton 			rgb_color shadow = tint_color(background, B_DARKEN_1_TINT);
66*1b370545SJessica Hamilton 			rgb_color darkShadow = tint_color(background, B_DARKEN_3_TINT);
67*1b370545SJessica Hamilton 			rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
68*1b370545SJessica Hamilton 
69*1b370545SJessica Hamilton 			BRect bounds(Bounds());
70*1b370545SJessica Hamilton 
71*1b370545SJessica Hamilton 			BeginLineArray(4);
72*1b370545SJessica Hamilton 			AddLine(BPoint(bounds.left, bounds.bottom),
73*1b370545SJessica Hamilton 			BPoint(bounds.left, bounds.top), shadow);
74*1b370545SJessica Hamilton 			AddLine(BPoint(bounds.left + 1.0, bounds.top),
75*1b370545SJessica Hamilton 			BPoint(bounds.right, bounds.top), shadow);
76*1b370545SJessica Hamilton 			AddLine(BPoint(bounds.right, bounds.top + 1.0),
77*1b370545SJessica Hamilton 			BPoint(bounds.right, bounds.bottom), light);
78*1b370545SJessica Hamilton 			AddLine(BPoint(bounds.right - 1.0, bounds.bottom),
79*1b370545SJessica Hamilton 			BPoint(bounds.left + 1.0, bounds.bottom), light);
80*1b370545SJessica Hamilton 			EndLineArray();
81*1b370545SJessica Hamilton 			bounds.InsetBy(1.0, 1.0);
82*1b370545SJessica Hamilton 
83*1b370545SJessica Hamilton 			BeginLineArray(4);
84*1b370545SJessica Hamilton 			AddLine(BPoint(bounds.left, bounds.bottom),
85*1b370545SJessica Hamilton 			BPoint(bounds.left, bounds.top), darkShadow);
86*1b370545SJessica Hamilton 			AddLine(BPoint(bounds.left + 1.0, bounds.top),
87*1b370545SJessica Hamilton 			BPoint(bounds.right, bounds.top), darkShadow);
88*1b370545SJessica Hamilton 			AddLine(BPoint(bounds.right, bounds.top + 1.0),
89*1b370545SJessica Hamilton 			BPoint(bounds.right, bounds.bottom), background);
90*1b370545SJessica Hamilton 			AddLine(BPoint(bounds.right - 1.0, bounds.bottom),
91*1b370545SJessica Hamilton 			BPoint(bounds.left + 1.0, bounds.bottom), background);
92*1b370545SJessica Hamilton 			EndLineArray();
93*1b370545SJessica Hamilton 			bounds.InsetBy(1.0, 1.0);
94*1b370545SJessica Hamilton 
95*1b370545SJessica Hamilton 			SetHighColor(color);
96*1b370545SJessica Hamilton 			FillRect(bounds);
97*1b370545SJessica Hamilton 		} else {
98*1b370545SJessica Hamilton 			SetHighColor(color);
99*1b370545SJessica Hamilton 			FillRect(Bounds());
100*1b370545SJessica Hamilton 		}
101*1b370545SJessica Hamilton 	} else {
102*1b370545SJessica Hamilton 		// fill background
103*1b370545SJessica Hamilton 		SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
104*1b370545SJessica Hamilton 		FillRect(updateRect);
105*1b370545SJessica Hamilton 
106*1b370545SJessica Hamilton 		SetHighColor(color);
107*1b370545SJessica Hamilton 		FillEllipse(Bounds());
108*1b370545SJessica Hamilton 
109*1b370545SJessica Hamilton 		if (IsEnabled())
110*1b370545SJessica Hamilton 			StrokeEllipse(Bounds(), B_SOLID_LOW);
111*1b370545SJessica Hamilton 	}
112*1b370545SJessica Hamilton }
113*1b370545SJessica Hamilton 
114*1b370545SJessica Hamilton 
115*1b370545SJessica Hamilton void
MessageReceived(BMessage * message)116*1b370545SJessica Hamilton ColorPreview::MessageReceived(BMessage* message)
117*1b370545SJessica Hamilton {
118*1b370545SJessica Hamilton 	// If we received a dropped message, see if it contains color data
119*1b370545SJessica Hamilton 	if (message->WasDropped()) {
120*1b370545SJessica Hamilton 		rgb_color* color;
121*1b370545SJessica Hamilton 		ssize_t size;
122*1b370545SJessica Hamilton 		if (message->FindData(kRGBColor, B_RGB_COLOR_TYPE,
123*1b370545SJessica Hamilton 				(const void**)&color, &size) == B_OK) {
124*1b370545SJessica Hamilton 			BMessage setColorMessage(MSG_SET_CURRENT_COLOR);
125*1b370545SJessica Hamilton 			setColorMessage.AddData(kRGBColor, B_RGB_COLOR_TYPE, color,
126*1b370545SJessica Hamilton 				sizeof(rgb_color));
127*1b370545SJessica Hamilton 			Invoke(&setColorMessage);
128*1b370545SJessica Hamilton 		}
129*1b370545SJessica Hamilton 	} else if ((int32)message->what == kMsgMessageRunner) {
130*1b370545SJessica Hamilton 		BPoint where;
131*1b370545SJessica Hamilton 		uint32 buttons;
132*1b370545SJessica Hamilton 		GetMouse(&where, &buttons);
133*1b370545SJessica Hamilton 
134*1b370545SJessica Hamilton 		_DragColor(where);
135*1b370545SJessica Hamilton 	}
136*1b370545SJessica Hamilton 
137*1b370545SJessica Hamilton 	BControl::MessageReceived(message);
138*1b370545SJessica Hamilton }
139*1b370545SJessica Hamilton 
140*1b370545SJessica Hamilton 
141*1b370545SJessica Hamilton void
MouseDown(BPoint where)142*1b370545SJessica Hamilton ColorPreview::MouseDown(BPoint where)
143*1b370545SJessica Hamilton {
144*1b370545SJessica Hamilton 	BWindow* window = Window();
145*1b370545SJessica Hamilton 	if (window != NULL)
146*1b370545SJessica Hamilton 		window->Activate();
147*1b370545SJessica Hamilton 
148*1b370545SJessica Hamilton 	fMessageRunner = new BMessageRunner(this, new BMessage(kMsgMessageRunner),
149*1b370545SJessica Hamilton 		300000, 1);
150*1b370545SJessica Hamilton 
151*1b370545SJessica Hamilton 	SetMouseEventMask(B_POINTER_EVENTS,
152*1b370545SJessica Hamilton 		B_SUSPEND_VIEW_FOCUS | B_LOCK_WINDOW_FOCUS);
153*1b370545SJessica Hamilton 
154*1b370545SJessica Hamilton 	BRect rect = Bounds().InsetByCopy(2.0f, 2.0f);
155*1b370545SJessica Hamilton 	rect.top = roundf(rect.bottom / 2.0f + 1);
156*1b370545SJessica Hamilton 
157*1b370545SJessica Hamilton 	if (rect.Contains(where)) {
158*1b370545SJessica Hamilton 		Invalidate();
159*1b370545SJessica Hamilton 		Invoke();
160*1b370545SJessica Hamilton 	}
161*1b370545SJessica Hamilton 
162*1b370545SJessica Hamilton 	BControl::MouseDown(where);
163*1b370545SJessica Hamilton }
164*1b370545SJessica Hamilton 
165*1b370545SJessica Hamilton 
166*1b370545SJessica Hamilton void
MouseMoved(BPoint where,uint32 transit,const BMessage * message)167*1b370545SJessica Hamilton ColorPreview::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
168*1b370545SJessica Hamilton {
169*1b370545SJessica Hamilton 	if (fMessageRunner != NULL)
170*1b370545SJessica Hamilton 		_DragColor(where);
171*1b370545SJessica Hamilton 
172*1b370545SJessica Hamilton 	BControl::MouseMoved(where, transit, message);
173*1b370545SJessica Hamilton }
174*1b370545SJessica Hamilton 
175*1b370545SJessica Hamilton 
176*1b370545SJessica Hamilton void
MouseUp(BPoint where)177*1b370545SJessica Hamilton ColorPreview::MouseUp(BPoint where)
178*1b370545SJessica Hamilton {
179*1b370545SJessica Hamilton 	delete fMessageRunner;
180*1b370545SJessica Hamilton 	fMessageRunner = NULL;
181*1b370545SJessica Hamilton 
182*1b370545SJessica Hamilton 	BControl::MouseUp(where);
183*1b370545SJessica Hamilton }
184*1b370545SJessica Hamilton 
185*1b370545SJessica Hamilton 
186*1b370545SJessica Hamilton rgb_color
Color(void) const187*1b370545SJessica Hamilton ColorPreview::Color(void) const
188*1b370545SJessica Hamilton {
189*1b370545SJessica Hamilton 	return fColor;
190*1b370545SJessica Hamilton }
191*1b370545SJessica Hamilton 
192*1b370545SJessica Hamilton 
193*1b370545SJessica Hamilton void
SetColor(rgb_color color)194*1b370545SJessica Hamilton ColorPreview::SetColor(rgb_color color)
195*1b370545SJessica Hamilton {
196*1b370545SJessica Hamilton 	color.alpha = 255;
197*1b370545SJessica Hamilton 
198*1b370545SJessica Hamilton 	SetHighColor(color);
199*1b370545SJessica Hamilton 	fColor = color;
200*1b370545SJessica Hamilton 
201*1b370545SJessica Hamilton 	Invalidate();
202*1b370545SJessica Hamilton 	Invoke();
203*1b370545SJessica Hamilton }
204*1b370545SJessica Hamilton 
205*1b370545SJessica Hamilton 
206*1b370545SJessica Hamilton void
SetColor(uint8 red,uint8 green,uint8 blue)207*1b370545SJessica Hamilton ColorPreview::SetColor(uint8 red, uint8 green, uint8 blue)
208*1b370545SJessica Hamilton {
209*1b370545SJessica Hamilton 	SetHighColor(red, green, blue);
210*1b370545SJessica Hamilton 	fColor.red = red;
211*1b370545SJessica Hamilton 	fColor.green = green;
212*1b370545SJessica Hamilton 	fColor.blue = blue;
213*1b370545SJessica Hamilton 	fColor.alpha = 255;
214*1b370545SJessica Hamilton 
215*1b370545SJessica Hamilton 	Invalidate();
216*1b370545SJessica Hamilton 	Invoke();
217*1b370545SJessica Hamilton }
218*1b370545SJessica Hamilton 
219*1b370545SJessica Hamilton 
220*1b370545SJessica Hamilton void
SetMode(bool rectangle)221*1b370545SJessica Hamilton ColorPreview::SetMode(bool rectangle)
222*1b370545SJessica Hamilton {
223*1b370545SJessica Hamilton 	fIsRectangle = rectangle;
224*1b370545SJessica Hamilton }
225*1b370545SJessica Hamilton 
226*1b370545SJessica Hamilton 
227*1b370545SJessica Hamilton //	#pragma mark - ColorPreview private methods
228*1b370545SJessica Hamilton 
229*1b370545SJessica Hamilton 
230*1b370545SJessica Hamilton void
_DragColor(BPoint where)231*1b370545SJessica Hamilton ColorPreview::_DragColor(BPoint where)
232*1b370545SJessica Hamilton {
233*1b370545SJessica Hamilton 	BString hexStr;
234*1b370545SJessica Hamilton 	hexStr.SetToFormat("#%.2X%.2X%.2X", fColor.red, fColor.green, fColor.blue);
235*1b370545SJessica Hamilton 
236*1b370545SJessica Hamilton 	BMessage message(B_PASTE);
237*1b370545SJessica Hamilton 	message.AddData("text/plain", B_MIME_TYPE, hexStr.String(),
238*1b370545SJessica Hamilton 		hexStr.Length());
239*1b370545SJessica Hamilton 	message.AddData(kRGBColor, B_RGB_COLOR_TYPE, &fColor, sizeof(fColor));
240*1b370545SJessica Hamilton 
241*1b370545SJessica Hamilton 	BRect rect(0.0f, 0.0f, 20.0f, 20.0f);
242*1b370545SJessica Hamilton 
243*1b370545SJessica Hamilton 	BBitmap* bitmap = new BBitmap(rect, B_RGB32, true);
244*1b370545SJessica Hamilton 	if (bitmap->Lock()) {
245*1b370545SJessica Hamilton 		BView* view = new BView(rect, "", B_FOLLOW_NONE, B_WILL_DRAW);
246*1b370545SJessica Hamilton 		bitmap->AddChild(view);
247*1b370545SJessica Hamilton 
248*1b370545SJessica Hamilton 		view->SetHighColor(B_TRANSPARENT_COLOR);
249*1b370545SJessica Hamilton 		view->FillRect(view->Bounds());
250*1b370545SJessica Hamilton 
251*1b370545SJessica Hamilton 		++rect.top;
252*1b370545SJessica Hamilton 		++rect.left;
253*1b370545SJessica Hamilton 
254*1b370545SJessica Hamilton 		view->SetHighColor(0, 0, 0, 100);
255*1b370545SJessica Hamilton 		view->FillRect(rect);
256*1b370545SJessica Hamilton 		rect.OffsetBy(-1.0f, -1.0f);
257*1b370545SJessica Hamilton 
258*1b370545SJessica Hamilton 		view->SetHighColor(std::min(255, (int)(1.2 * fColor.red + 40)),
259*1b370545SJessica Hamilton 			std::min(255, (int)(1.2 * fColor.green + 40)),
260*1b370545SJessica Hamilton 			std::min(255, (int)(1.2 * fColor.blue + 40)));
261*1b370545SJessica Hamilton 		view->StrokeRect(rect);
262*1b370545SJessica Hamilton 
263*1b370545SJessica Hamilton 		++rect.left;
264*1b370545SJessica Hamilton 		++rect.top;
265*1b370545SJessica Hamilton 
266*1b370545SJessica Hamilton 		view->SetHighColor((int32)(0.8 * fColor.red),
267*1b370545SJessica Hamilton 			(int32)(0.8 * fColor.green),
268*1b370545SJessica Hamilton 			(int32)(0.8 * fColor.blue));
269*1b370545SJessica Hamilton 		view->StrokeRect(rect);
270*1b370545SJessica Hamilton 
271*1b370545SJessica Hamilton 		--rect.right;
272*1b370545SJessica Hamilton 		--rect.bottom;
273*1b370545SJessica Hamilton 
274*1b370545SJessica Hamilton 		view->SetHighColor(fColor.red, fColor.green, fColor.blue);
275*1b370545SJessica Hamilton 		view->FillRect(rect);
276*1b370545SJessica Hamilton 		view->Sync();
277*1b370545SJessica Hamilton 
278*1b370545SJessica Hamilton 		bitmap->Unlock();
279*1b370545SJessica Hamilton 	}
280*1b370545SJessica Hamilton 
281*1b370545SJessica Hamilton 	DragMessage(&message, bitmap, B_OP_ALPHA, BPoint(14.0f, 14.0f));
282*1b370545SJessica Hamilton 
283*1b370545SJessica Hamilton 	MouseUp(where);
284*1b370545SJessica Hamilton }
285