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