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
27SelectionBox::SelectionBox()
28	:
29	fBounds()
30{
31	_InitPatterns();
32}
33
34
35SelectionBox::~SelectionBox()
36{
37}
38
39
40void
41SelectionBox::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
63BRect
64SelectionBox::Bounds() const
65{
66	return fBounds;
67}
68
69
70void
71SelectionBox::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
79void
80SelectionBox::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
101void
102SelectionBox::MouseUp(ShowImageView* view, BPoint where)
103{
104}
105
106
107void
108SelectionBox::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
141void
142SelectionBox::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
167void
168SelectionBox::_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
186BRect
187SelectionBox::_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