xref: /haiku/src/preferences/screen/MonitorView.cpp (revision 85fb3e7df81f8d5b6e47a9a64a53873ea906ea6e)
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 	if (Parent())
51 		fBackgroundColor = Parent()->ViewColor();
52 	else
53 		fBackgroundColor = ui_color(B_PANEL_BACKGROUND_COLOR);
54 
55 	_UpdateDPI();
56 }
57 
58 
59 void
60 MonitorView::MouseDown(BPoint point)
61 {
62 	be_roster->Launch(kBackgroundsSignature);
63 }
64 
65 
66 void
67 MonitorView::Draw(BRect updateRect)
68 {
69 	rgb_color darkColor = {160, 160, 160, 255};
70 	rgb_color blackColor = {0, 0, 0, 255};
71 	rgb_color redColor = {228, 0, 0, 255};
72 	rgb_color whiteColor = {255, 255, 255, 255};
73 	BRect outerRect = _MonitorBounds();
74 
75 	SetHighColor(fBackgroundColor);
76 	FillRect(updateRect);
77 
78 	SetDrawingMode(B_OP_OVER);
79 
80 	// frame & background
81 
82 	SetHighColor(darkColor);
83 	FillRoundRect(outerRect, 3.0, 3.0);
84 
85 	SetHighColor(blackColor);
86 	StrokeRoundRect(outerRect, 3.0, 3.0);
87 
88 	SetHighColor(fDesktopColor);
89 
90 	BRect innerRect(outerRect.InsetByCopy(4, 4));
91 	FillRoundRect(innerRect, 2.0, 2.0);
92 
93 	SetHighColor(blackColor);
94 	StrokeRoundRect(innerRect, 2.0, 2.0);
95 
96 	SetDrawingMode(B_OP_COPY);
97 
98 	// power light
99 
100 	SetHighColor(redColor);
101 	BPoint powerPos(outerRect.left + 5, outerRect.bottom - 2);
102 	StrokeLine(powerPos, BPoint(powerPos.x + 2, powerPos.y));
103 
104 	// DPI
105 
106 	if (fDPI == 0)
107 		return;
108 
109 	font_height fontHeight;
110 	GetFontHeight(&fontHeight);
111 	float height = ceilf(fontHeight.ascent + fontHeight.descent);
112 
113 	char text[64];
114 	snprintf(text, sizeof(text), B_TRANSLATE("%ld dpi"), fDPI);
115 
116 	float width = StringWidth(text);
117 	if (width > innerRect.Width() || height > innerRect.Height())
118 		return;
119 
120 	SetLowColor(fDesktopColor);
121 	SetHighColor(whiteColor);
122 
123 	DrawString(text, BPoint(innerRect.left + (innerRect.Width() - width) / 2,
124 		innerRect.top + fontHeight.ascent + (innerRect.Height() - height) / 2));
125 }
126 
127 
128 void
129 MonitorView::SetResolution(int32 width, int32 height)
130 {
131 	if (fWidth == width && fHeight == height)
132 		return;
133 
134 	fWidth = width;
135 	fHeight = height;
136 
137 	_UpdateDPI();
138 	Invalidate();
139 }
140 
141 
142 void
143 MonitorView::SetMaxResolution(int32 width, int32 height)
144 {
145 	if (fMaxWidth == width && fMaxHeight == height)
146 		return;
147 
148 	fMaxWidth = width;
149 	fMaxHeight = height;
150 
151 	Invalidate();
152 }
153 
154 
155 void
156 MonitorView::MessageReceived(BMessage* message)
157 {
158 	switch (message->what) {
159 		case UPDATE_DESKTOP_MSG:
160 		{
161 			int32 width, height;
162 			if (message->FindInt32("width", &width) == B_OK
163 				&& message->FindInt32("height", &height) == B_OK)
164 				SetResolution(width, height);
165 			break;
166 		}
167 
168 		case UPDATE_DESKTOP_COLOR_MSG:
169 		{
170 			BScreen screen(Window());
171 			rgb_color color = screen.DesktopColor(current_workspace());
172 			if (color != fDesktopColor) {
173 				fDesktopColor = color;
174 				Invalidate();
175 			}
176 			break;
177 		}
178 
179 		default:
180 			BView::MessageReceived(message);
181 			break;
182 	}
183 }
184 
185 
186 BRect
187 MonitorView::_MonitorBounds()
188 {
189 	float maxWidth = Bounds().Width();
190 	float maxHeight = Bounds().Height();
191 	if (maxWidth / maxHeight > (float)fMaxWidth / fMaxHeight)
192 		maxWidth = maxHeight / fMaxHeight * fMaxWidth;
193 	else
194 		maxHeight = maxWidth / fMaxWidth * fMaxHeight;
195 
196 	float factorX = (float)fWidth / fMaxWidth;
197 	float factorY = (float)fHeight / fMaxHeight;
198 
199 	if (factorX > factorY && factorX > 1) {
200 		factorY /= factorX;
201 		factorX = 1;
202 	} else if (factorY > factorX && factorY > 1) {
203 		factorX /= factorY;
204 		factorY = 1;
205 	}
206 
207 	float width = maxWidth * factorX;
208 	float height = maxHeight * factorY;
209 
210 	BSize size = Bounds().Size();
211 	return BRect((size.width - width) / 2, (size.height - height) / 2,
212 		(size.width + width) / 2, (size.height + height) / 2);
213 }
214 
215 
216 void
217 MonitorView::_UpdateDPI()
218 {
219 	fDPI = 0;
220 
221 	BScreen screen(Window());
222 	monitor_info info;
223 	if (screen.GetMonitorInfo(&info) != B_OK)
224 		return;
225 
226 	double x = info.width / 2.54;
227 	double y = info.height / 2.54;
228 
229 	fDPI = (int32)round((fWidth / x + fHeight / y) / 2);
230 }
231