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
SelectionBox()27 SelectionBox::SelectionBox()
28 :
29 fBounds()
30 {
31 _InitPatterns();
32 }
33
34
~SelectionBox()35 SelectionBox::~SelectionBox()
36 {
37 }
38
39
40 void
SetBounds(ShowImageView * view,BRect bounds)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
Bounds() const64 SelectionBox::Bounds() const
65 {
66 return fBounds;
67 }
68
69
70 void
MouseDown(ShowImageView * view,BPoint where)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
MouseMoved(ShowImageView * view,BPoint where)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
MouseUp(ShowImageView * view,BPoint where)102 SelectionBox::MouseUp(ShowImageView* view, BPoint where)
103 {
104 }
105
106
107 void
Animate()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
Draw(ShowImageView * view,const BRect & updateRect) const142 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
_InitPatterns()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
_RectInView(ShowImageView * view) const187 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