1/*
2 * Copyright 2001 Werner Freytag - please read to the LICENSE file
3 *
4 * Copyright 2002-2006, 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 <Cursor.h>
15#include <MessageRunner.h>
16#include <String.h>
17#include <Window.h>
18
19#include "cursors.h"
20#include "support_ui.h"
21
22// constructor
23ColorPreview::ColorPreview(BRect frame, rgb_color color)
24	: BControl(frame, "colorpreview", "", new BMessage(MSG_COLOR_PREVIEW),
25			   B_FOLLOW_TOP|B_FOLLOW_LEFT, B_WILL_DRAW),
26	  fColor(color),
27	  fOldColor(color),
28
29	  fMouseDown(false),
30
31	  fMessageRunner(0)
32{
33}
34
35// AttachedToWindow
36void
37ColorPreview::AttachedToWindow()
38{
39	BControl::AttachedToWindow();
40	SetViewColor(B_TRANSPARENT_COLOR);
41}
42
43// Draw
44void
45ColorPreview::Draw(BRect updateRect)
46{
47	rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
48	rgb_color shadow = tint_color(background, B_DARKEN_1_TINT);
49	rgb_color darkShadow = tint_color(background, B_DARKEN_3_TINT);
50	rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
51
52	BRect r(Bounds());
53	stroke_frame(this, r, shadow, shadow, light, light);
54	r.InsetBy(1.0, 1.0);
55	stroke_frame(this, r, darkShadow, darkShadow, background, background);
56	r.InsetBy(1.0, 1.0);
57
58	r.bottom = r.top + r.Height() / 2.0;
59	SetHighColor(fColor);
60	FillRect(r);
61
62	r.top = r.bottom + 1;
63	r.bottom = Bounds().bottom - 2.0;
64	SetHighColor(fOldColor);
65	FillRect(r);
66}
67
68// MessageReceived
69void
70ColorPreview::MessageReceived(BMessage* message)
71{
72	if (message->what == MSG_MESSAGERUNNER) {
73
74		BPoint	where;
75		uint32	buttons;
76
77		GetMouse(&where, &buttons);
78
79		_DragColor(where);
80
81	} else {
82#ifdef HAIKU_TARGET_PLATFORM_DANO
83		const
84#endif
85		char* nameFound;
86		type_code typeFound;
87
88		if (message->GetInfo(B_RGB_COLOR_TYPE, 0,
89							 &nameFound, &typeFound) != B_OK) {
90			BControl::MessageReceived(message);
91			return;
92		}
93
94	   	rgb_color* color;
95		ssize_t numBytes;
96		message->FindData(nameFound, typeFound,
97						  (const void**)&color, &numBytes);
98
99		BPoint where;
100		bool droppedOnNewArea = false;
101		if (message->FindPoint("_drop_point_", &where) == B_OK) {
102			ConvertFromScreen(&where);
103			if (where.y > Bounds().top + (Bounds().IntegerHeight() >> 1))
104				droppedOnNewArea = true;
105		}
106
107		if (droppedOnNewArea)
108			SetNewColor(*color);
109		else
110			SetColor(*color);
111		Invoke();
112	}
113}
114
115// MouseDown
116void
117ColorPreview::MouseDown(BPoint where)
118{
119	Window()->Activate();
120
121	fMouseDown = true;
122
123	fMessageRunner = new BMessageRunner(
124		this, new BMessage(MSG_MESSAGERUNNER), 300000, 1);
125
126	SetMouseEventMask(B_POINTER_EVENTS,
127					  B_SUSPEND_VIEW_FOCUS | B_LOCK_WINDOW_FOCUS);
128
129	BRect rect = Bounds().InsetByCopy(2.0, 2.0);
130	rect.top = rect.bottom/2 + 1;
131
132	if (rect.Contains( where ) ) {
133		fColor = fOldColor;
134		Draw( Bounds() );
135		Invoke();
136	}
137
138}
139
140// MouseUp
141void
142ColorPreview::MouseUp(BPoint where)
143{
144	delete fMessageRunner;
145	fMessageRunner = NULL;
146
147	fMouseDown = false;
148	BControl::MouseUp(where);
149}
150
151// MouseMoved
152void
153ColorPreview::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
154{
155	if (transit == B_ENTERED_VIEW) {
156		BCursor cursor(kDropperCursor);
157		SetViewCursor(&cursor, true);
158	}
159	if (fMouseDown)
160		_DragColor(where);
161}
162
163// Invoke
164status_t
165ColorPreview::Invoke(BMessage* message)
166{
167	if (!message)
168		message = Message();
169
170	if (message) {
171		message->RemoveName("color");
172		message->AddData("color", B_RGB_COLOR_TYPE, &fColor, sizeof(fColor));
173	}
174
175	return BControl::Invoke(message);
176}
177
178// SetColor
179void
180ColorPreview::SetColor(rgb_color color)
181{
182	color.alpha = 255;
183	fColor = color;
184
185	Invalidate();
186}
187
188// SetNewColor
189void
190ColorPreview::SetNewColor(rgb_color color)
191{
192	fColor = color;
193	fOldColor = color;
194
195	Invalidate();
196}
197
198// #pragma mark -
199
200// _DragColor
201void
202ColorPreview::_DragColor(BPoint where)
203{
204	BBitmap* bitmap = new BBitmap(BRect(0.0, 0.0, 15.0, 15.0), B_RGB32);
205	BMessage message = make_color_drop_message(fColor, bitmap);
206
207	DragMessage(&message, bitmap, B_OP_ALPHA, BPoint(9.0, 9.0));
208
209	MouseUp(where);
210}
211
212