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:
TestView(BRect frame,const char * name,uint32 resizeFlags,uint32 flags)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
MessageReceived(BMessage * message)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
Draw(BRect updateRect)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
MouseDown(BPoint where)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
MouseUp(BPoint where)170 TestView::MouseUp(BPoint where)
171 {
172 fTracking = TRACKING_NONE;
173 }
174
175 // MouseMoved
176 void
MouseMoved(BPoint where,uint32 transit,const BMessage * dragMessage)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
min4(float a,float b,float c,float d)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
max4(float a,float b,float c,float d)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
_TrackMouse(BPoint where)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
show_window(BRect frame,const char * name)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
main(int argc,char ** argv)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