xref: /haiku/src/apps/showimage/SelectionBox.cpp (revision 25a7b01d15612846f332751841da3579db313082)
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