1/*
2 * Copyright 2006, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Stephan Aßmus <superstippi@gmx.de>
7 */
8
9#include "support_ui.h"
10
11#include <stdio.h>
12#include <string.h>
13
14#include <Bitmap.h>
15#include <DataIO.h>
16#include <Directory.h>
17#include <File.h>
18#include <FindDirectory.h>
19#include <Screen.h>
20#include <String.h>
21#include <Path.h>
22#include <View.h>
23
24// stroke_frame
25void
26stroke_frame(BView* v, BRect r, rgb_color left, rgb_color top,
27			 rgb_color right, rgb_color bottom)
28{
29	if (v && r.IsValid()) {
30		v->BeginLineArray(4);
31			v->AddLine(BPoint(r.left, r.bottom),
32					   BPoint(r.left, r.top), left);
33			v->AddLine(BPoint(r.left + 1.0, r.top),
34					   BPoint(r.right, r.top), top);
35			v->AddLine(BPoint(r.right, r.top + 1.0),
36					   BPoint(r.right, r.bottom), right);
37			v->AddLine(BPoint(r.right - 1.0, r.bottom),
38					   BPoint(r.left + 1.0, r.bottom), bottom);
39		v->EndLineArray();
40	}
41}
42
43// store_color_in_message
44status_t
45store_color_in_message(BMessage* message, rgb_color color)
46{
47	status_t ret = B_BAD_VALUE;
48	if (message) {
49		ret = message->AddData("RGBColor", B_RGB_COLOR_TYPE,
50							   (void*)&color, sizeof(rgb_color));
51	}
52	return ret;
53}
54
55// restore_color_from_message
56status_t
57restore_color_from_message(const BMessage* message, rgb_color& color, int32 index)
58{
59	status_t ret = B_BAD_VALUE;
60	if (message) {
61			const void* colorPointer;
62			ssize_t size = sizeof(rgb_color);
63			ret = message->FindData("RGBColor", B_RGB_COLOR_TYPE, index,
64									&colorPointer, &size);
65			if (ret >= B_OK)
66				color = *(const rgb_color*)colorPointer;
67	}
68	return ret;
69}
70
71// make_color_drop_message
72BMessage
73make_color_drop_message(rgb_color color, BBitmap* bitmap)
74{
75	// prepare message
76	BMessage message(B_PASTE);
77	char hexString[8];
78	snprintf(hexString, sizeof(hexString), "#%.2X%.2X%.2X",
79		color.red, color.green, color.blue);
80	message.AddData("text/plain", B_MIME_TYPE, &hexString, sizeof(hexString));
81	message.AddData("RGBColor", B_RGB_COLOR_TYPE, &color, sizeof(color));
82	// prepare bitmap
83	if (bitmap && bitmap->IsValid()
84		&& (bitmap->ColorSpace() == B_RGB32
85			|| bitmap->ColorSpace() == B_RGBA32)) {
86		uint8* bits = (uint8*)bitmap->Bits();
87		uint32 bpr = bitmap->BytesPerRow();
88		uint32 width = bitmap->Bounds().IntegerWidth() + 1;
89		uint32 height = bitmap->Bounds().IntegerHeight() + 1;
90		for (uint32 y = 0; y < height; y++) {
91			uint8* bitsHandle = bits;
92			for (uint32 x = 0; x < width; x++) {
93				if (x == 0 || y == 0 ) {
94					// top or left border
95					bitsHandle[0] = (uint8)min_c(255, color.blue * 1.2 + 40);
96					bitsHandle[1] = (uint8)min_c(255, color.green * 1.2 + 40);
97					bitsHandle[2] = (uint8)min_c(255, color.red * 1.2 + 40);
98					bitsHandle[3] = 180;
99				} else if ((x == width - 2 || y == height - 2)
100						   && !(x == width - 1 || y == height - 1)) {
101					// bottom or right border
102					bitsHandle[0] = (uint8)(color.blue * 0.8);
103					bitsHandle[1] = (uint8)(color.green * 0.8);
104					bitsHandle[2] = (uint8)(color.red * 0.8);
105					bitsHandle[3] = 180;
106				} else if (x == width - 1 || y == height - 1) {
107					// shadow
108					bitsHandle[0] = 0;
109					bitsHandle[1] = 0;
110					bitsHandle[2] = 0;
111					bitsHandle[3] = 100;
112				} else {
113					// color
114					bitsHandle[0] = color.blue;
115					bitsHandle[1] = color.green;
116					bitsHandle[2] = color.red;
117					bitsHandle[3] = 180;
118				}
119				if ((x == 0 && y == height - 1) || (y == 0 && x == width - 1)) {
120					// spare pixels of shadow
121					bitsHandle[0] = 0;
122					bitsHandle[1] = 0;
123					bitsHandle[2] = 0;
124					bitsHandle[3] = 50;
125				}
126				bitsHandle += 4;
127			}
128			bits += bpr;
129		}
130	}
131	return message;
132}
133
134// make_sure_frame_is_on_screen
135void
136make_sure_frame_is_on_screen(BRect& frame, BWindow* window)
137{
138	if (!frame.IsValid())
139		return;
140
141	BRect screenFrame;
142	if (window) {
143		BScreen screen(window);
144		if (!screen.IsValid())
145			return;
146		screenFrame = screen.Frame();
147	} else {
148		BScreen screen(B_MAIN_SCREEN_ID);
149		if (!screen.IsValid())
150			return;
151		screenFrame = screen.Frame();
152	}
153	if (!screenFrame.Contains(frame)) {
154		// make sure frame fits in the screen
155		if (frame.Width() > screenFrame.Width())
156			frame.right -= frame.Width() - screenFrame.Width() + 10.0;
157		if (frame.Height() > screenFrame.Height())
158			frame.bottom -= frame.Height() - screenFrame.Height() + 30.0;
159		// frame is now at the most the size of the screen
160		if (frame.right > screenFrame.right)
161			frame.OffsetBy(-(frame.right - screenFrame.right), 0.0);
162		if (frame.bottom > screenFrame.bottom)
163			frame.OffsetBy(0.0, -(frame.bottom - screenFrame.bottom));
164		if (frame.left < screenFrame.left)
165			frame.OffsetBy((screenFrame.left - frame.left), 0.0);
166		if (frame.top < screenFrame.top)
167			frame.OffsetBy(0.0, (screenFrame.top - frame.top));
168	}
169}
170
171// print_modifiers
172void
173print_modifiers()
174{
175	uint32 mods = modifiers();
176	if (mods & B_SHIFT_KEY)
177		printf("B_SHIFT_KEY\n");
178	if (mods & B_COMMAND_KEY)
179		printf("B_COMMAND_KEY\n");
180	if (mods & B_CONTROL_KEY)
181		printf("B_CONTROL_KEY\n");
182	if (mods & B_CAPS_LOCK)
183		printf("B_CAPS_LOCK\n");
184	if (mods & B_SCROLL_LOCK)
185		printf("B_SCROLL_LOCK\n");
186	if (mods & B_NUM_LOCK)
187		printf("B_NUM_LOCK\n");
188	if (mods & B_OPTION_KEY)
189		printf("B_OPTION_KEY\n");
190	if (mods & B_MENU_KEY)
191		printf("B_MENU_KEY\n");
192	if (mods & B_LEFT_SHIFT_KEY)
193		printf("B_LEFT_SHIFT_KEY\n");
194	if (mods & B_RIGHT_SHIFT_KEY)
195		printf("B_RIGHT_SHIFT_KEY\n");
196	if (mods & B_LEFT_COMMAND_KEY)
197		printf("B_LEFT_COMMAND_KEY\n");
198	if (mods & B_RIGHT_COMMAND_KEY)
199		printf("B_RIGHT_COMMAND_KEY\n");
200	if (mods & B_LEFT_CONTROL_KEY)
201		printf("B_LEFT_CONTROL_KEY\n");
202	if (mods & B_RIGHT_CONTROL_KEY)
203		printf("B_RIGHT_CONTROL_KEY\n");
204	if (mods & B_LEFT_OPTION_KEY)
205		printf("B_LEFT_OPTION_KEY\n");
206	if (mods & B_RIGHT_OPTION_KEY)
207		printf("B_RIGHT_OPTION_KEY\n");
208}
209
210/*
211// convert_cap_mode
212agg::line_cap_e
213convert_cap_mode(uint32 mode)
214{
215	agg::line_cap_e aggMode = agg::butt_cap;
216	switch (mode) {
217		case CAP_MODE_BUTT:
218			aggMode = agg::butt_cap;
219			break;
220		case CAP_MODE_SQUARE:
221			aggMode = agg::square_cap;
222			break;
223		case CAP_MODE_ROUND:
224			aggMode = agg::round_cap;
225			break;
226	}
227	return aggMode;
228}
229
230// convert_cap_mode
231agg::line_join_e
232convert_join_mode(uint32 mode)
233{
234	agg::line_join_e aggMode = agg::miter_join;
235	switch (mode) {
236		case JOIN_MODE_MITER:
237			aggMode = agg::miter_join;
238			break;
239		case JOIN_MODE_ROUND:
240			aggMode = agg::round_join;
241			break;
242		case JOIN_MODE_BEVEL:
243			aggMode = agg::bevel_join;
244			break;
245	}
246	return aggMode;
247}
248*/
249
250// string_for_color_space
251const char*
252string_for_color_space(color_space format)
253{
254	const char* name = "<unkown format>";
255	switch (format) {
256		case B_RGB32:
257			name = "B_RGB32";
258			break;
259		case B_RGBA32:
260			name = "B_RGBA32";
261			break;
262		case B_RGB32_BIG:
263			name = "B_RGB32_BIG";
264			break;
265		case B_RGBA32_BIG:
266			name = "B_RGBA32_BIG";
267			break;
268		case B_RGB24:
269			name = "B_RGB24";
270			break;
271		case B_RGB24_BIG:
272			name = "B_RGB24_BIG";
273			break;
274		case B_CMAP8:
275			name = "B_CMAP8";
276			break;
277		case B_GRAY8:
278			name = "B_GRAY8";
279			break;
280		case B_GRAY1:
281			name = "B_GRAY1";
282			break;
283
284		// YCbCr
285		case B_YCbCr422:
286			name = "B_YCbCr422";
287			break;
288		case B_YCbCr411:
289			name = "B_YCbCr411";
290			break;
291		case B_YCbCr444:
292			name = "B_YCbCr444";
293			break;
294		case B_YCbCr420:
295			name = "B_YCbCr420";
296			break;
297
298		// YUV
299		case B_YUV422:
300			name = "B_YUV422";
301			break;
302		case B_YUV411:
303			name = "B_YUV411";
304			break;
305		case B_YUV444:
306			name = "B_YUV444";
307			break;
308		case B_YUV420:
309			name = "B_YUV420";
310			break;
311
312		case B_YUV9:
313			name = "B_YUV9";
314			break;
315		case B_YUV12:
316			name = "B_YUV12";
317			break;
318
319		default:
320			break;
321	}
322	return name;
323}
324
325// print_color_space
326void
327print_color_space(color_space format)
328{
329	printf("%s\n", string_for_color_space(format));
330}
331
332