xref: /haiku/src/preferences/printers/TestPageView.cpp (revision ae0a10cad3999b13cbfa47a3d947a5219d2d90f4)
1 /*
2  * Copyright 2011, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Philippe Houdoin
7  */
8 
9 
10 #include "TestPageView.h"
11 
12 #include <math.h>
13 
14 #include <AffineTransform.h>
15 #include <Catalog.h>
16 #include <Font.h>
17 #include <GradientLinear.h>
18 #include <GradientRadial.h>
19 #include <GridLayoutBuilder.h>
20 #include <GroupLayoutBuilder.h>
21 #include <LayoutUtils.h>
22 #include <TextView.h>
23 #include <Shape.h>
24 #include <String.h>
25 #include <StringView.h>
26 
27 #include "PrinterListView.h"
28 
29 
30 #undef B_TRANSLATION_CONTEXT
31 #define B_TRANSLATION_CONTEXT "TestPageView"
32 
33 
34 // #pragma mark LeafView
35 
36 
37 // path data for the leaf shape
38 static const BPoint kLeafBegin(56.24793f, 15.46287f);
39 static BPoint kLeafCurves[][3] = {
40 	{ BPoint(61.14, 28.89), BPoint(69.78, 38.25), BPoint(83.48, 44.17) },
41 	{ BPoint(99.46, 37.52), BPoint(113.27, 29.61), BPoint(134.91, 30.86) },
42 	{ BPoint(130.58, 36.53), BPoint(126.74, 42.44), BPoint(123.84, 48.81) },
43 	{ BPoint(131.81, 42.22), BPoint(137.53, 38.33), BPoint(144.37, 33.10) },
44 	{ BPoint(169.17, 23.55), BPoint(198.90, 15.55), BPoint(232.05, 10.51) },
45 	{ BPoint(225.49, 18.37), BPoint(219.31, 28.17), BPoint(217.41, 40.24) },
46 	{ BPoint(227.70, 26.60), BPoint(239.97, 14.63), BPoint(251.43, 8.36) },
47 	{ BPoint(288.89, 9.12), BPoint(322.73, 14.33), BPoint(346.69, 31.67) },
48 	{ BPoint(330.49, 37.85), BPoint(314.36, 44.25), BPoint(299.55, 54.17) },
49 	{ BPoint(292.48, 52.54), BPoint(289.31, 49.70), BPoint(285.62, 47.03) },
50 	{ BPoint(283.73, 54.61), BPoint(284.46, 57.94), BPoint(285.62, 60.60) },
51 	{ BPoint(259.78, 76.14), BPoint(233.24, 90.54), BPoint(202.41, 98.10) },
52 	{ BPoint(194.43, 95.36), BPoint(185.96, 92.39), BPoint(179.63, 88.33) },
53 	{ BPoint(180.15, 94.75), BPoint(182.73, 99.76), BPoint(185.62, 104.53) },
54 	{ BPoint(154.83, 119.46), BPoint(133.21, 118.97), BPoint(125.62, 94.88) },
55 	{ BPoint(124.70, 98.79), BPoint(124.11, 103.67), BPoint(124.19, 110.60) },
56 	{ BPoint(116.42, 111.81), BPoint(85.82, 99.60), BPoint(83.25, 51.96) },
57 	{ BPoint(62.50, 42.57), BPoint(58.12, 33.18), BPoint(50.98, 23.81) } };
58 static const int kNumLeafCurves = sizeof(kLeafCurves) / sizeof(kLeafCurves[0]);
59 static const float kLeafWidth = 372.f;
60 static const float kLeafHeight = 121.f;
61 
62 
63 class LeafView : public BView {
64 public:
65 								LeafView();
66 	virtual	void				Draw(BRect updateRect);
67 };
68 
69 
70 LeafView::LeafView()
71 	:
72 	BView("leafview", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE)
73 {
74 	SetViewColor(255, 255, 255);
75 }
76 
77 
78 void
79 LeafView::Draw(BRect updateRect)
80 {
81 	float scale = Bounds().Width() / kLeafWidth;
82 	BAffineTransform transform;
83 	transform.ScaleBy(scale);
84 
85 	// BGradientRadial gradient(BPoint(kLeafWidth * 0.75, kLeafHeight * 1.5),
86 	//	kLeafWidth * 2);
87 	BGradientLinear gradient(B_ORIGIN,
88 		transform.Apply(BPoint(kLeafWidth, kLeafHeight)));
89 	rgb_color lightBlue = make_color(6, 169, 255);
90 	rgb_color darkBlue = make_color(0, 50, 126);
91 	gradient.AddColor(darkBlue, 0.0);
92 	gradient.AddColor(lightBlue, 255.0);
93 
94 	// build leaf shape
95 	BShape leafShape;
96 	leafShape.MoveTo(transform.Apply(kLeafBegin));
97 	for (int i = 0; i < kNumLeafCurves; ++i) {
98 		BPoint controlPoints[3];
99 		for (int j = 0; j < 3; ++j)
100 			controlPoints[j] = transform.Apply(kLeafCurves[i][j]);
101 		leafShape.BezierTo(controlPoints);
102 	}
103 	leafShape.Close();
104 
105 	PushState();
106 	SetDrawingMode(B_OP_ALPHA);
107 	SetHighColor(0, 0, 0, 50);
108 	for (int i = 2; i >= 0; --i) {
109 		SetOrigin(i * 0.1, i * 0.3);
110 		SetPenSize(i * 2);
111 		StrokeShape(&leafShape);
112 	}
113 	PopState();
114 
115 	FillShape(&leafShape, gradient);
116 }
117 
118 
119 // #pragma mark -
120 
121 
122 class RadialLinesView : public BView {
123 public:
124 								RadialLinesView();
125 
126 	virtual	void				Draw(BRect updateRect);
127 
128 	virtual bool				HasHeightForWidth() { return true; }
129 	virtual void				GetHeightForWidth(float width, float* min,
130 									float* max, float* preferred);
131 };
132 
133 
134 RadialLinesView::RadialLinesView()
135 	: BView("radiallinesview", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE)
136 {
137 	SetViewColor(255, 255, 255);
138 }
139 
140 
141 void
142 RadialLinesView::GetHeightForWidth(float width,
143 	float* min, float* max, float* preferred)
144 {
145 	// Enforce a width/height ratio of 1
146 
147 	if (min)
148 		*min = width;
149 
150 	if (max)
151 		*max = width;
152 
153 	if (preferred)
154 		*preferred = width;
155 }
156 
157 
158 void
159 RadialLinesView::Draw(BRect updateRect)
160 {
161 	const rgb_color black = { 0, 0, 0, 255 };
162 	const int angleStep = 4;
163 
164 	BRect rect(Bounds());
165 	float size = rect.Width();
166 	if (size > rect.Height())
167 		size = rect.Height();
168 	size *= 0.45; // leave 10% of margin
169 
170 	BPoint center(rect.Width() / 2, rect.Height() / 2);
171 
172 	BeginLineArray(360 / angleStep);
173 	for (int i = 0; i < 360; i += angleStep) {
174 		double angle = i * M_PI / 180;
175 		BPoint pt(size * cos(angle), size * sin(angle));
176 		AddLine(center, center + pt, black);
177 	}
178 	EndLineArray();
179 }
180 
181 
182 // #pragma mark -
183 
184 
185 static const struct {
186 	const char* name;
187 	rgb_color	color;
188 } kColorGradients[] = {
189 	{ B_TRANSLATE_MARK("Red"), 		{255, 0, 0, 255} },
190 	{ B_TRANSLATE_MARK("Green"), 	{0, 255, 0, 255} },
191 	{ B_TRANSLATE_MARK("Blue"), 	{0, 0, 255, 255} },
192 	{ B_TRANSLATE_MARK("Yellow"), 	{255, 255, 0, 255} },
193 	{ B_TRANSLATE_MARK("Magenta"), 	{255, 0, 255, 255} },
194 	{ B_TRANSLATE_MARK("Cyan"), 	{0, 255, 255, 255} },
195 	{ B_TRANSLATE_MARK("Black"), 	{0, 0, 0, 255} }
196 };
197 static const int kNumColorGradients = sizeof(kColorGradients)
198 	/ sizeof(kColorGradients[0]);
199 
200 
201 class ColorGradientView : public BView {
202 public:
203 								ColorGradientView(rgb_color color);
204 	virtual	void				Draw(BRect updateRect);
205 
206 private:
207 			rgb_color			fColor;
208 };
209 
210 
211 ColorGradientView::ColorGradientView(rgb_color color)
212 	:
213 	BView("colorgradientview", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
214 	fColor(color)
215 {
216 }
217 
218 
219 void
220 ColorGradientView::Draw(BRect updateRect)
221 {
222 	BRect rect(Bounds());
223 
224 	BGradientLinear gradient(rect.LeftTop(), rect.RightBottom());
225 	rgb_color white = make_color(255, 255, 255);
226 	gradient.AddColor(white, 0.0);
227 	gradient.AddColor(fColor, 255.0);
228 
229 	FillRect(rect, gradient);
230 	StrokeRect(rect);
231 }
232 
233 
234 // #pragma mark -
235 
236 
237 TestPageView::TestPageView(BRect frame, PrinterItem* printer)
238 	: BView(frame, "testpage", B_FOLLOW_ALL,
239 		B_DRAW_ON_CHILDREN | B_FULL_UPDATE_ON_RESIZE),
240 	fPrinter(printer)
241 {
242 	SetViewColor(255, 255, 255);
243 }
244 
245 
246 void
247 TestPageView::AttachedToWindow()
248 {
249 	BTextView* statusView = new BTextView("statusView",
250 		be_plain_font, NULL, B_WILL_DRAW);
251 
252 	statusView->SetInsets(10, 10, 10, 10);
253 	statusView->MakeEditable(false);
254 	statusView->MakeSelectable(false);
255 
256 	const char* title = B_TRANSLATE("Test page");
257 	BString text;
258 	text << title << "\n\n";
259 	text << B_TRANSLATE(
260 		"Printer: %printer_name%\n"
261 		"Driver:  %driver%\n");
262 
263 	text.ReplaceFirst("%printer_name%", fPrinter->Name());
264 	text.ReplaceFirst("%driver%", fPrinter->Driver());
265 	if (strlen(fPrinter->Transport()) > 0) {
266 		text << B_TRANSLATE("Transport: %transport% %transport_address%");
267 
268 		text.ReplaceFirst("%transport%", fPrinter->Transport());
269 		text.ReplaceFirst("%transport_address%", fPrinter->TransportAddress());
270 	}
271 
272 	statusView->SetText(text.String());
273 	BFont font;
274 	statusView->SetStylable(true);
275 	statusView->GetFont(&font);
276 	font.SetFace(B_BOLD_FACE);
277 	font.SetSize(font.Size() * 1.7);
278 	statusView->SetFontAndColor(0, strlen(title), &font);
279 
280 	BGridLayoutBuilder gradients(2.0);
281 	gradients.View()->SetViewColor(B_TRANSPARENT_COLOR);
282 
283 	for (int i = 0; i < kNumColorGradients; ++i) {
284 		BStringView* label = new BStringView(
285 			kColorGradients[i].name,
286 			B_TRANSLATE(kColorGradients[i].name));
287 		// label->SetAlignment(B_ALIGN_RIGHT);
288 		gradients.Add(label, 0, i);
289 		gradients.Add(new ColorGradientView(kColorGradients[i].color), 1, i);
290 	}
291 
292 	SetLayout(new BGroupLayout(B_HORIZONTAL));
293 	AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
294 		.Add(BGroupLayoutBuilder(B_HORIZONTAL, 0)
295 			.Add(statusView)
296 			.Add(new LeafView())
297 		)
298 		.Add(BGroupLayoutBuilder(B_HORIZONTAL, 0)
299 			.Add(gradients, 0.60)
300 			.Add(new RadialLinesView(), 0.40)
301 		)
302 		.AddGlue()
303 		.End()
304 	);
305 
306 	// set layout background color to transparent instead
307 	// of default UI panel color
308 	ChildAt(0)->SetViewColor(B_TRANSPARENT_COLOR);
309 }
310 
311 
312 void
313 TestPageView::DrawAfterChildren(BRect updateRect)
314 {
315 	// Draw corners marks
316 
317 	float width = Bounds().Width();
318 	float height = Bounds().Height();
319 	float minDimension = MIN(width, height);
320 
321 	float size = minDimension * 0.05;
322 
323 	SetPenSize(3.0);
324 
325 	BPoint pt = Bounds().LeftTop();
326 	StrokeLine(pt, BPoint(pt.x + size, pt.y));
327 	StrokeLine(pt, BPoint(pt.x, pt.y + size));
328 
329 	pt = Bounds().RightTop();
330 	StrokeLine(pt, BPoint(pt.x - size, pt.y));
331 	StrokeLine(pt, BPoint(pt.x, pt.y + size));
332 
333 	pt = Bounds().RightBottom();
334 	StrokeLine(pt, BPoint(pt.x - size, pt.y));
335 	StrokeLine(pt, BPoint(pt.x, pt.y - size));
336 
337 	pt = Bounds().LeftBottom();
338 	StrokeLine(pt, BPoint(pt.x + size, pt.y));
339 	StrokeLine(pt, BPoint(pt.x, pt.y - size));
340 }
341