xref: /haiku/src/preferences/screen/MonitorView.cpp (revision 13581b3d2a71545960b98fefebc5225b5bf29072)
1 /*
2  * Copyright 2001-2009, Haiku.
3  * Copyright 2002, Thomas Kurschel.
4  * Distributed under the terms of the MIT License.
5  *
6  * Authors:
7  *		Rafael Romo
8  *		Thomas Kurschel
9  *		Axel Dörfler, axeld@pinc-software.de
10  */
11 
12 
13 #include "MonitorView.h"
14 
15 #include <stdio.h>
16 
17 #include <Catalog.h>
18 #include <Locale.h>
19 #include <Roster.h>
20 #include <Screen.h>
21 
22 #include "Constants.h"
23 
24 #undef B_TRANSLATION_CONTEXT
25 #define B_TRANSLATION_CONTEXT "Monitor View"
26 
27 
28 MonitorView::MonitorView(BRect rect, const char *name, int32 width, int32 height)
29 	: BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
30 	fMaxWidth(1920),
31 	fMaxHeight(1200),
32 	fWidth(width),
33 	fHeight(height),
34 	fDPI(0)
35 {
36 	BScreen screen(B_MAIN_SCREEN_ID);
37 	fDesktopColor = screen.DesktopColor(current_workspace());
38 }
39 
40 
41 MonitorView::~MonitorView()
42 {
43 }
44 
45 
46 void
47 MonitorView::AttachedToWindow()
48 {
49 	SetViewColor(B_TRANSPARENT_COLOR);
50 	fBackgroundColor = ui_color(B_PANEL_BACKGROUND_COLOR);
51 
52 	_UpdateDPI();
53 }
54 
55 
56 void
57 MonitorView::MouseDown(BPoint point)
58 {
59 	be_roster->Launch(kBackgroundsSignature);
60 }
61 
62 
63 void
64 MonitorView::Draw(BRect updateRect)
65 {
66 	rgb_color darkColor = {160, 160, 160, 255};
67 	rgb_color blackColor = {0, 0, 0, 255};
68 	rgb_color redColor = {228, 0, 0, 255};
69 	rgb_color whiteColor = {255, 255, 255, 255};
70 	BRect outerRect = _MonitorBounds();
71 
72 	SetHighColor(fBackgroundColor);
73 	FillRect(updateRect);
74 
75 	SetDrawingMode(B_OP_OVER);
76 
77 	// frame & background
78 
79 	SetHighColor(darkColor);
80 	FillRoundRect(outerRect, 3.0, 3.0);
81 
82 	SetHighColor(blackColor);
83 	StrokeRoundRect(outerRect, 3.0, 3.0);
84 
85 	SetHighColor(fDesktopColor);
86 
87 	BRect innerRect(outerRect.InsetByCopy(4, 4));
88 	FillRoundRect(innerRect, 2.0, 2.0);
89 
90 	SetHighColor(blackColor);
91 	StrokeRoundRect(innerRect, 2.0, 2.0);
92 
93 	SetDrawingMode(B_OP_COPY);
94 
95 	// power light
96 
97 	SetHighColor(redColor);
98 	BPoint powerPos(outerRect.left + 5, outerRect.bottom - 2);
99 	StrokeLine(powerPos, BPoint(powerPos.x + 2, powerPos.y));
100 
101 	// DPI
102 
103 	if (fDPI == 0)
104 		return;
105 
106 	font_height fontHeight;
107 	GetFontHeight(&fontHeight);
108 	float height = ceilf(fontHeight.ascent + fontHeight.descent);
109 
110 	char text[64];
111 	snprintf(text, sizeof(text), B_TRANSLATE("%ld dpi"), (long int)fDPI);
112 
113 	float width = StringWidth(text);
114 	if (width > innerRect.Width() || height > innerRect.Height())
115 		return;
116 
117 	SetLowColor(fDesktopColor);
118 	SetHighColor(whiteColor);
119 
120 	DrawString(text, BPoint(innerRect.left + (innerRect.Width() - width) / 2,
121 		innerRect.top + fontHeight.ascent + (innerRect.Height() - height) / 2));
122 }
123 
124 
125 void
126 MonitorView::SetResolution(int32 width, int32 height)
127 {
128 	if (fWidth == width && fHeight == height)
129 		return;
130 
131 	fWidth = width;
132 	fHeight = height;
133 
134 	_UpdateDPI();
135 	Invalidate();
136 }
137 
138 
139 void
140 MonitorView::SetMaxResolution(int32 width, int32 height)
141 {
142 	if (fMaxWidth == width && fMaxHeight == height)
143 		return;
144 
145 	fMaxWidth = width;
146 	fMaxHeight = height;
147 
148 	Invalidate();
149 }
150 
151 
152 void
153 MonitorView::MessageReceived(BMessage* message)
154 {
155 	switch (message->what) {
156 		case B_COLORS_UPDATED:
157 		{
158 			message->FindColor(ui_color_name(B_PANEL_BACKGROUND_COLOR),
159 				&fBackgroundColor);
160 			break;
161 		}
162 		case UPDATE_DESKTOP_MSG:
163 		{
164 			int32 width, height;
165 			if (message->FindInt32("width", &width) == B_OK
166 				&& message->FindInt32("height", &height) == B_OK)
167 				SetResolution(width, height);
168 			break;
169 		}
170 
171 		case UPDATE_DESKTOP_COLOR_MSG:
172 		{
173 			BScreen screen(Window());
174 			rgb_color color = screen.DesktopColor(current_workspace());
175 			if (color != fDesktopColor) {
176 				fDesktopColor = color;
177 				Invalidate();
178 			}
179 			break;
180 		}
181 
182 		default:
183 			BView::MessageReceived(message);
184 			break;
185 	}
186 }
187 
188 
189 BRect
190 MonitorView::_MonitorBounds()
191 {
192 	float maxWidth = Bounds().Width();
193 	float maxHeight = Bounds().Height();
194 	if (maxWidth / maxHeight > (float)fMaxWidth / fMaxHeight)
195 		maxWidth = maxHeight / fMaxHeight * fMaxWidth;
196 	else
197 		maxHeight = maxWidth / fMaxWidth * fMaxHeight;
198 
199 	float factorX = (float)fWidth / fMaxWidth;
200 	float factorY = (float)fHeight / fMaxHeight;
201 
202 	if (factorX > factorY && factorX > 1) {
203 		factorY /= factorX;
204 		factorX = 1;
205 	} else if (factorY > factorX && factorY > 1) {
206 		factorX /= factorY;
207 		factorY = 1;
208 	}
209 
210 	float width = maxWidth * factorX;
211 	float height = maxHeight * factorY;
212 
213 	BSize size = Bounds().Size();
214 	return BRect((size.width - width) / 2, (size.height - height) / 2,
215 		(size.width + width) / 2, (size.height + height) / 2);
216 }
217 
218 
219 void
220 MonitorView::_UpdateDPI()
221 {
222 	fDPI = 0;
223 
224 	BScreen screen(Window());
225 	monitor_info info;
226 	if (screen.GetMonitorInfo(&info) != B_OK)
227 		return;
228 
229 	double x = info.width / 2.54;
230 	double y = info.height / 2.54;
231 
232 	fDPI = (int32)round((fWidth / x + fHeight / y) / 2);
233 }
234