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