xref: /haiku/src/tests/servers/app/copy_bits/main.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 // main.cpp
2 
3 #include <stdio.h>
4 
5 #include "Application.h"
6 #include "Message.h"
7 #include "Button.h"
8 #include "View.h"
9 #include "Window.h"
10 
11 #define MSG_COPY_BITS 'cbts'
12 
13 class TestView : public BView {
14 
15 	enum {
16 		TRACKING_NONE,
17 		TRACKING_SOURCE,
18 		TRACKING_DEST
19 	};
20 
21  public:
22 					TestView(BRect frame, const char* name,
23 							  uint32 resizeFlags, uint32 flags)
24 						: BView(frame, name, resizeFlags, flags),
25 						  fTracking(TRACKING_NONE),
26 						  fCopyBitsJustCalled(false)
27 					{
28 						fSourceRect.Set(frame.left, frame.top,
29 									    (frame.left + frame.right) / 2,
30 									    frame.bottom);
31 						fDestRect.Set((frame.left + frame.right) / 2,
32 									  frame.top,
33 									  frame.right, frame.bottom);
34 						fSourceRect.InsetBy(10.0, 10.0);
35 						fDestRect.InsetBy(10.0, 10.0);
36 
37 						SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
38 						SetLowUIColor(ViewUIColor());
39 					}
40 
41 	virtual	void	MessageReceived(BMessage* message);
42 
43 	virtual	void	Draw(BRect updateRect);
44 
45 	virtual	void	MouseDown(BPoint where);
46 	virtual	void	MouseUp(BPoint where);
47 	virtual	void	MouseMoved(BPoint where, uint32 transit,
48 							   const BMessage* dragMessage);
49 
50  private:
51 			void	_TrackMouse(BPoint where);
52 
53 			BRect	fSourceRect;
54 			BRect	fDestRect;
55 
56 			uint32	fTracking;
57 
58 			bool	fCopyBitsJustCalled;
59 };
60 
61 // MessageReceived
62 void
63 TestView::MessageReceived(BMessage* message)
64 {
65 	if (message->what == MSG_COPY_BITS) {
66 		printf("MSG_COPY_BITS\n");
67 		fSourceRect.PrintToStream();
68 		fDestRect.PrintToStream();
69 		CopyBits(fSourceRect, fDestRect);
70 		fCopyBitsJustCalled = true;
71 	} else
72 		BView::MessageReceived(message);
73 }
74 
75 // Draw
76 void
77 TestView::Draw(BRect updateRect)
78 {
79 	if (fCopyBitsJustCalled) {
80 		printf("TestView::Draw(%.1f, %.1f, %.1f, %.1f) after CopyBits()\n",
81 			   updateRect.left, updateRect.top, updateRect.right, updateRect.bottom);
82 		fCopyBitsJustCalled = false;
83 	}
84 
85 	// background
86 //	SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
87 //	FillRect(updateRect);
88 
89 	BRect r(Bounds());
90 
91 	// draw some pattern with lines
92 	float width = r.Width();
93 	float height = r.Height();
94 	int32 lineCount = 20;
95 	SetPenSize(2.0);
96 	for (int32 i = 0; i < lineCount; i++) {
97 		SetHighColor(255, (255 / lineCount) * i, 255 - (255 / lineCount) * i);
98 		StrokeLine(BPoint(r.left + (width / lineCount) * i, r.top),
99 				   BPoint(r.left, r.top + (height / lineCount) * i));
100 		StrokeLine(BPoint(r.right - (width / lineCount) * i, r.bottom),
101 				   BPoint(r.right, r.bottom - (height / lineCount) * i));
102 	}
103 	StrokeLine(BPoint(r.left, r.bottom), BPoint(r.right, r.top));
104 
105 	// source and dest rect
106 	SetPenSize(1.0);
107 
108 	SetHighColor(0, 255, 0, 255);
109 	StrokeRect(fSourceRect);
110 
111 	SetHighColor(0, 0, 255, 255);
112 	StrokeRect(fDestRect);
113 
114 	// text
115 	SetHighColor(128, 0, 50, 255);
116 
117 	const char* message = "Left-Click and drag";
118 	width = StringWidth(message);
119 	BPoint p(r.left + r.Width() / 2.0 - width / 2.0,
120 			 r.top + r.Height() / 2.0 - 50.0);
121 
122 	DrawString(message, p);
123 
124 	message = "to set source rect!";
125 	width = StringWidth(message);
126 	p.x = r.left + r.Width() / 2.0 - width / 2.0;
127 	p.y += 20;
128 
129 	DrawString(message, p);
130 
131 	message = "Right-Click and drag";
132 	width = StringWidth(message);
133 	p.x = r.left + r.Width() / 2.0 - width / 2.0;
134 	p.y += 30.0;
135 
136 	DrawString(message, p);
137 
138 	message = "to set destination rect!";
139 	width = StringWidth(message);
140 	p.x = r.left + r.Width() / 2.0 - width / 2.0;
141 	p.y += 20;
142 
143 	DrawString(message, p);
144 }
145 
146 // MouseDown
147 void
148 TestView::MouseDown(BPoint where)
149 {
150 	BMessage* message = Window()->CurrentMessage();
151 	uint32 buttons;
152 	if (message && message->FindInt32("buttons", (int32*)&buttons) >= B_OK) {
153 		if (buttons & B_PRIMARY_MOUSE_BUTTON) {
154 			fTracking = TRACKING_SOURCE;
155 			fSourceRect.left = where.x;
156 			fSourceRect.top = where.y;
157 		}
158 		if (buttons & B_SECONDARY_MOUSE_BUTTON) {
159 			fTracking = TRACKING_DEST;
160 			fDestRect.left = where.x;
161 			fDestRect.top = where.y;
162 		}
163 		Invalidate();
164 		_TrackMouse(where);
165 	}
166 }
167 
168 // MouseUp
169 void
170 TestView::MouseUp(BPoint where)
171 {
172 	fTracking = TRACKING_NONE;
173 }
174 
175 // MouseMoved
176 void
177 TestView::MouseMoved(BPoint where, uint32 transit,
178 					 const BMessage* dragMessage)
179 {
180 	if (fTracking > TRACKING_NONE) {
181 		_TrackMouse(where);
182 	}
183 }
184 
185 float
186 min4(float a, float b, float c, float d)
187 {
188 	return min_c(a, min_c(b, min_c(c, d)));
189 }
190 
191 float
192 max4(float a, float b, float c, float d)
193 {
194 	return max_c(a, max_c(b, max_c(c, d)));
195 }
196 
197 // _TrackMouse
198 void
199 TestView::_TrackMouse(BPoint where)
200 {
201 	BRect before;
202 	BRect after;
203 	bool invalidate = false;
204 	switch (fTracking) {
205 		case TRACKING_SOURCE:
206 			before = fSourceRect;
207 			fSourceRect.right = where.x;
208 			fSourceRect.bottom = where.y;
209 			after = fSourceRect;
210 			invalidate = true;
211 			break;
212 		case TRACKING_DEST:
213 			before = fDestRect;
214 			fDestRect.right = where.x;
215 			fDestRect.bottom = where.y;
216 			after = fDestRect;
217 			invalidate = true;
218 			break;
219 	}
220 	if (invalidate) {
221 		BRect dirty(min4(before.left, before.right, after.left, after.right),
222 					min4(before.top, before.bottom, after.top, after.bottom),
223 					max4(before.left, before.right, after.left, after.right),
224 					max4(before.top, before.bottom, after.top, after.bottom));
225 		Invalidate(dirty);
226 	}
227 }
228 
229 
230 // show_window
231 void
232 show_window(BRect frame, const char* name)
233 {
234 	BWindow* window = new BWindow(frame, name,
235 								  B_TITLED_WINDOW,
236 								  B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE);
237 
238 	BView* view = new TestView(window->Bounds(), "test", B_FOLLOW_ALL,
239 							   B_WILL_DRAW/* | B_FULL_UPDATE_ON_RESIZE*/);
240 
241 	window->AddChild(view);
242 	BRect b(0.0, 0.0, 50.0, 15.0);
243 	b.OffsetTo(5.0, view->Bounds().bottom - (b.Height() + 15.0));
244 	BButton* control = new BButton(b, "button", "Copy", new BMessage(MSG_COPY_BITS));
245 	view->AddChild(control);
246 	control->SetTarget(view);
247 
248 	// test CopyBits() on top of children
249 	b = BRect(80, 130, 130, 160);
250 	BView* child = new BView(b, "some child", B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM, 0);
251 	child->SetViewColor(255, 0, 0);
252 	view->AddChild(child);
253 
254 	b = BRect(136, 127, 158, 140);
255 	child = new BView(b, "some other child", B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM, 0);
256 	child->SetViewColor(255, 255, 0);
257 	view->AddChild(child);
258 
259 	window->Show();
260 }
261 
262 // main
263 int
264 main(int argc, char** argv)
265 {
266 	BApplication* app = new BApplication("application/x.vnd-Haiku.CopyBits");
267 
268 	BRect frame(50.0, 50.0, 300.0, 250.0);
269 	show_window(frame, "CopyBits Test");
270 
271 	app->Run();
272 
273 	delete app;
274 	return 0;
275 }
276