1 /* 2 * Copyright 2003-2010, Haiku, Inc. All Rights Reserved. 3 * Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd. 4 * Copyright 2006 Bernd Korz. All Rights Reserved 5 * Distributed under the terms of the MIT License. 6 * 7 * Authors: 8 * Fernando Francisco de Oliveira 9 * Michael Wilber 10 * Michael Pfeiffer 11 * Ryan Leavengood 12 * yellowTAB GmbH 13 * Bernd Korz 14 * Stephan Aßmus <superstippi@gmx.de> 15 */ 16 17 18 #include "SelectionBox.h" 19 20 #include <math.h> 21 #include <new> 22 #include <stdio.h> 23 24 #include "ShowImageView.h" 25 26 27 SelectionBox::SelectionBox() 28 : 29 fBounds() 30 { 31 _InitPatterns(); 32 } 33 34 35 SelectionBox::~SelectionBox() 36 { 37 } 38 39 40 void 41 SelectionBox::SetBounds(ShowImageView* view, BRect bounds) 42 { 43 view->ConstrainToImage(bounds); 44 45 if (fBounds == bounds) 46 return; 47 48 BRect dirtyOld = _RectInView(view); 49 50 fBounds = bounds; 51 52 BRect dirtyNew = _RectInView(view); 53 54 if (dirtyOld.IsValid() && dirtyNew.IsValid()) 55 view->Invalidate(dirtyOld | dirtyNew); 56 else if (dirtyOld.IsValid()) 57 view->Invalidate(dirtyOld); 58 else if (dirtyNew.IsValid()) 59 view->Invalidate(dirtyNew); 60 } 61 62 63 BRect 64 SelectionBox::Bounds() const 65 { 66 return fBounds; 67 } 68 69 70 void 71 SelectionBox::MouseDown(ShowImageView* view, BPoint where) 72 { 73 // TODO: Allow to re-adjust corners. 74 where = view->ViewToImage(where); 75 SetBounds(view, BRect(where, where)); 76 } 77 78 79 void 80 SelectionBox::MouseMoved(ShowImageView* view, BPoint where) 81 { 82 // TODO: Allow to re-adjust corners. 83 where = view->ViewToImage(where); 84 85 BRect bounds(fBounds); 86 87 if (where.x >= bounds.left) 88 bounds.right = where.x; 89 else 90 bounds.left = where.x; 91 92 if (where.y >= bounds.top) 93 bounds.bottom = where.y; 94 else 95 bounds.top = where.y; 96 97 SetBounds(view, bounds); 98 } 99 100 101 void 102 SelectionBox::MouseUp(ShowImageView* view, BPoint where) 103 { 104 } 105 106 107 void 108 SelectionBox::Animate() 109 { 110 // rotate up 111 uchar p = fPatternUp.data[0]; 112 for (int i = 0; i <= 6; i++) 113 fPatternUp.data[i] = fPatternUp.data[i + 1]; 114 fPatternUp.data[7] = p; 115 116 // rotate down 117 p = fPatternDown.data[7]; 118 for (int i = 7; i >= 1; i--) 119 fPatternDown.data[i] = fPatternDown.data[i - 1]; 120 fPatternDown.data[0] = p; 121 122 // rotate to left 123 p = fPatternLeft.data[0]; 124 bool set = (p & 0x80) != 0; 125 p <<= 1; 126 p &= 0xfe; 127 if (set) 128 p |= 1; 129 memset(fPatternLeft.data, p, 8); 130 131 // rotate to right 132 p = fPatternRight.data[0]; 133 set = (p & 1) != 0; 134 p >>= 1; 135 if (set) 136 p |= 0x80; 137 memset(fPatternRight.data, p, 8); 138 } 139 140 141 void 142 SelectionBox::Draw(ShowImageView* view, const BRect& updateRect) const 143 { 144 BRect r = _RectInView(view); 145 if (!r.IsValid() || !updateRect.Intersects(r)) 146 return; 147 148 view->PushState(); 149 150 view->SetLowColor(255, 255, 255); 151 view->StrokeLine(BPoint(r.left, r.top), BPoint(r.right, r.top), 152 fPatternLeft); 153 view->StrokeLine(BPoint(r.right, r.top + 1), BPoint(r.right, r.bottom - 1), 154 fPatternUp); 155 view->StrokeLine(BPoint(r.left, r.bottom), BPoint(r.right, r.bottom), 156 fPatternRight); 157 view->StrokeLine(BPoint(r.left, r.top + 1), BPoint(r.left, r.bottom - 1), 158 fPatternDown); 159 160 view->PopState(); 161 } 162 163 164 // #pragma mark - 165 166 167 void 168 SelectionBox::_InitPatterns() 169 { 170 uchar p; 171 uchar p1 = 0x33; 172 uchar p2 = 0xCC; 173 for (int i = 0; i <= 7; i++) { 174 fPatternLeft.data[i] = p1; 175 fPatternRight.data[i] = p2; 176 if ((i / 2) % 2 == 0) 177 p = 255; 178 else 179 p = 0; 180 fPatternUp.data[i] = p; 181 fPatternDown.data[i] = ~p; 182 } 183 } 184 185 186 BRect 187 SelectionBox::_RectInView(ShowImageView* view) const 188 { 189 BRect r; 190 if (fBounds.Height() <= 0.0 || fBounds.Width() <= 0.0) 191 return r; 192 193 r = fBounds; 194 // Layout selection rect in view coordinate space 195 view->ConstrainToImage(r); 196 r = view->ImageToView(r); 197 // draw selection box *around* selection 198 r.InsetBy(-1, -1); 199 200 return r; 201 } 202