xref: /haiku/src/apps/cortex/ValControl/ValControlSegment.cpp (revision 99d027cd0238c1d86da86d7c3f4200509ccc61a6)
1 /*
2  * Copyright (c) 1999-2000, Eric Moon.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions, and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions, and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 // ValControlSegment.cpp
33 // e.moon 20jan99
34 
35 
36 #include "ValControlSegment.h"
37 #include "ValControl.h"
38 
39 #include <Debug.h>
40 
41 #include <cstdio>
42 
43 __USE_CORTEX_NAMESPACE
44 
45 
46 ValControlSegment::ValControlSegment(underline_style underlineStyle)
47 	:BView(BRect(), "ValControlSegment", B_FOLLOW_LEFT|B_FOLLOW_TOP,
48 		B_WILL_DRAW|B_FRAME_EVENTS),
49 	fDragScaleFactor(fDefDragScaleFactor),
50 	fLastClickTime(0LL),
51 	fUnderlineStyle(underlineStyle),
52 	fXUnderlineLeft(0.0),
53 	fXUnderlineRight(0.0)
54 {
55 	_Init();
56 }
57 
58 
59 ValControlSegment::~ValControlSegment()
60 {
61 }
62 
63 
64 void
65 ValControlSegment::_Init()
66 {
67 	//m_pLeft = 0;
68 }
69 
70 
71 const double ValControlSegment::fDefDragScaleFactor = 4;
72 
73 
74 // get parent
75 ValControl*
76 ValControlSegment::parent() const
77 {
78 	return dynamic_cast<ValControl*>(Parent());
79 }
80 
81 
82 //
83 //// send message -> segment to my left
84 //void ValControlSegment::sendMessageLeft(BMessage* pMsg) {
85 //	if(!m_pLeft)
86 //		return;
87 //	BMessenger m(m_pLeft);
88 //	if(!m.IsValid())
89 //		return;
90 //	m.SendMessage(pMsg);
91 //	delete pMsg;
92 //}
93 
94 
95 // init mouse tracking
96 void
97 ValControlSegment::trackMouse(BPoint point, track_flags flags)
98 {
99 	fTrackFlags = flags;
100 	fPrevPoint = point;
101 	setTracking(true);
102 	SetMouseEventMask(B_POINTER_EVENTS,
103 		B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY);
104 }
105 
106 
107 void
108 ValControlSegment::setTracking(bool tracking)
109 {
110 	fTracking = tracking;
111 }
112 
113 
114 bool
115 ValControlSegment::isTracking() const
116 {
117 	return fTracking;
118 }
119 
120 
121 double
122 ValControlSegment::dragScaleFactor() const
123 {
124 	return fDragScaleFactor;
125 }
126 
127 
128 // -------------------------------------------------------- //
129 // default hook implementations
130 // -------------------------------------------------------- //
131 
132 void
133 ValControlSegment::sizeUnderline(float* outLeft, float* outRight)
134 {
135 	*outLeft = 0.0;
136 	*outRight = Bounds().right;
137 }
138 
139 
140 void
141 ValControlSegment::AttachedToWindow()
142 {
143 //	if(parent()->backBuffer())
144 //		SetViewColor(B_TRANSPARENT_COLOR);
145 
146 	// adopt parent's view color
147 	SetViewColor(parent()->ViewColor());
148 }
149 
150 
151 void
152 ValControlSegment::Draw(BRect updateRect)
153 {
154 	if (fUnderlineStyle == NO_UNDERLINE)
155 		return;
156 
157 	// +++++ move to layout function
158 	float fY = parent()->baselineOffset() + 1;
159 
160 	rgb_color white = {255,255,255,255};
161 	rgb_color blue = {0,0,255,255};
162 	rgb_color gray = {140,140,140,255};
163 	rgb_color old = HighColor();
164 
165 	SetLowColor(white);
166 	if(parent()->IsEnabled() && parent()->IsFocus())
167 		SetHighColor(blue);
168 	else
169 		SetHighColor(gray);
170 
171 	if (fXUnderlineRight <= fXUnderlineLeft)
172 		sizeUnderline(&fXUnderlineLeft, &fXUnderlineRight);
173 
174 //	PRINT((
175 //		"### ValControlSegment::Draw(): underline spans %.1f, %.1f\n",
176 //		fXUnderlineLeft, fXUnderlineRight));
177 //
178 	StrokeLine(BPoint(fXUnderlineLeft, fY),
179 		BPoint(fXUnderlineRight, fY),
180 		(fUnderlineStyle == DOTTED_UNDERLINE) ? B_MIXED_COLORS :
181 			B_SOLID_HIGH);
182 	SetHighColor(old);
183 }
184 
185 
186 void
187 ValControlSegment::FrameResized(float width, float height)
188 {
189 	_Inherited::FrameResized(width, height);
190 
191 //	PRINT((
192 //		"### ValControlSegment::FrameResized(%.1f,%.1f)\n",
193 //		fWidth, fHeight));
194 	sizeUnderline(&fXUnderlineLeft, &fXUnderlineRight);
195 }
196 
197 
198 void
199 ValControlSegment::MouseDown(BPoint point)
200 {
201 	if (!parent()->IsEnabled())
202 		return;
203 
204 	parent()->MakeFocus();
205 
206 	// not left button?
207 	uint32 nButton;
208 	GetMouse(&point, &nButton);
209 	if (!(nButton & B_PRIMARY_MOUSE_BUTTON))
210 		return;
211 
212 	// double click?
213 	bigtime_t doubleClickInterval;
214 	if (get_click_speed(&doubleClickInterval) < B_OK) {
215 		PRINT(("* ValControlSegment::MouseDown():\n"
216 			"  get_click_speed() failed."));
217 		return;
218 	}
219 
220 	bigtime_t now = system_time();
221 	if (now - fLastClickTime < doubleClickInterval) {
222 		if(isTracking()) {
223 			setTracking(false);
224 			mouseReleased();
225 		}
226 
227 		// hand off to parent control
228 		parent()->showEditField();
229 		fLastClickTime = 0LL;
230 		return;
231 	}
232 	else
233 		fLastClickTime = now;
234 
235 
236 	// engage tracking
237 	trackMouse(point, TRACK_VERTICAL);
238 }
239 
240 
241 void
242 ValControlSegment::MouseMoved(BPoint point, uint32 transit,
243 	const BMessage* dragMessage)
244 {
245 	if (!parent()->IsEnabled())
246 		return;
247 
248 	if (!isTracking() || fPrevPoint == point)
249 		return;
250 
251 	// float fXDelta = fTrackFlags & TRACK_HORIZONTAL ?
252 	// point.x - fPrevPoint.x : 0.0;
253 	float fYDelta = fTrackFlags & TRACK_VERTICAL ?
254 		point.y - fPrevPoint.y : 0.0;
255 
256 	// printf("MouseMoved(): %2f,%2f\n",
257 	// fXDelta, fYDelta);
258 
259 
260 	// hand off
261 	// +++++ config'able x/y response would be nice...
262 	float fRemaining = handleDragUpdate(fYDelta);
263 
264 	fPrevPoint = point;
265 	fPrevPoint.y -= fRemaining;
266 }
267 
268 
269 void
270 ValControlSegment::MouseUp(BPoint point)
271 {
272 	if (isTracking()) {
273 		setTracking(false);
274 		mouseReleased();
275 	}
276 }
277 
278 
279 void
280 ValControlSegment::MessageReceived(BMessage* message)
281 {
282 	switch(message->what) {
283 		default:
284 			_Inherited::MessageReceived(message);
285 	}
286 }
287 
288 
289 // -------------------------------------------------------- //
290 // archiving/instantiation
291 // -------------------------------------------------------- //
292 
293 ValControlSegment::ValControlSegment(BMessage* archive)
294 	: BView(archive)
295 {
296 	_Init();
297 	archive->FindInt32("ulStyle", (int32*)&fUnderlineStyle);
298 }
299 
300 
301 status_t
302 ValControlSegment::Archive(BMessage* archive, bool deep) const
303 {
304 	_Inherited::Archive(archive, deep);
305 
306 	archive->AddInt32("ulStyle", fUnderlineStyle);
307 	return B_OK;
308 }
309