xref: /haiku/src/apps/cortex/ValControl/ValControlSegment.cpp (revision 2f470aec1c92ce6917b8a903e343795dc77af41f)
1 // ValControlSegment.cpp
2 // e.moon 20jan99
3 
4 
5 #include "ValControlSegment.h"
6 #include "ValControl.h"
7 
8 #include <Debug.h>
9 
10 #include <cstdio>
11 
12 __USE_CORTEX_NAMESPACE
13 
14 // -------------------------------------------------------- //
15 // static stuff
16 // -------------------------------------------------------- //
17 
18 const double ValControlSegment::s_defDragScaleFactor = 4;
19 
20 // -------------------------------------------------------- //
21 // dtor/accessors
22 // -------------------------------------------------------- //
23 
24 ValControlSegment::~ValControlSegment() {}
25 
26 // -------------------------------------------------------- //
27 // ctor/internal operations
28 // -------------------------------------------------------- //
29 
30 ValControlSegment::ValControlSegment(
31 		underline_style							underlineStyle) :
32 
33 	BView(
34 		BRect(),
35 		"ValControlSegment",
36 		B_FOLLOW_LEFT|B_FOLLOW_TOP,
37 		B_WILL_DRAW|B_FRAME_EVENTS),
38 	m_underlineStyle(underlineStyle),
39 	m_dragScaleFactor(s_defDragScaleFactor),
40 	m_lastClickTime(0LL),
41 	m_xUnderlineLeft(0.0),
42 	m_xUnderlineRight(0.0) {
43 
44 	init();
45 }
46 
47 void ValControlSegment::init() {
48 //	m_pLeft = 0;
49 }
50 
51 // get parent
52 ValControl* ValControlSegment::parent() const {
53 	return dynamic_cast<ValControl*>(Parent());
54 }
55 //
56 //// send message -> segment to my left
57 //void ValControlSegment::sendMessageLeft(BMessage* pMsg) {
58 //	if(!m_pLeft)
59 //		return;
60 //	BMessenger m(m_pLeft);
61 //	if(!m.IsValid())
62 //		return;
63 //	m.SendMessage(pMsg);
64 //	delete pMsg;
65 //}
66 
67 // init mouse tracking
68 void ValControlSegment::trackMouse(
69 	BPoint											point,
70 	track_flags									flags) {
71 
72 	m_trackFlags = flags;
73 	m_prevPoint = point;
74 	setTracking(true);
75 	SetMouseEventMask(
76 		B_POINTER_EVENTS,
77 		B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY);
78 }
79 
80 void ValControlSegment::setTracking(
81 	bool												tracking) {
82 
83 	m_tracking = tracking;
84 }
85 
86 bool ValControlSegment::isTracking() const {
87 	return m_tracking;
88 }
89 
90 double ValControlSegment::dragScaleFactor() const {
91 	return m_dragScaleFactor;
92 }
93 
94 // -------------------------------------------------------- //
95 // default hook implementations
96 // -------------------------------------------------------- //
97 
98 void ValControlSegment::sizeUnderline(
99 	float*											outLeft,
100 	float*											outRight) {
101 
102 	*outLeft = 0.0;
103 	*outRight = Bounds().right;
104 }
105 
106 // -------------------------------------------------------- //
107 // BView impl.
108 // -------------------------------------------------------- //
109 
110 void ValControlSegment::AttachedToWindow() {
111 //	if(parent()->backBuffer())
112 //		SetViewColor(B_TRANSPARENT_COLOR);
113 
114 	// adopt parent's view color
115 	SetViewColor(parent()->ViewColor());
116 }
117 
118 void ValControlSegment::Draw(
119 	BRect												updateRect) {
120 
121 	if(m_underlineStyle == NO_UNDERLINE)
122 		return;
123 
124 	// +++++ move to layout function
125 	float fY = parent()->baselineOffset() + 1;
126 
127 	rgb_color white = {255,255,255,255};
128 	rgb_color blue = {0,0,255,255};
129 	rgb_color gray = {140,140,140,255};
130 	rgb_color old = HighColor();
131 
132 	SetLowColor(white);
133 	if(parent()->IsEnabled() && parent()->IsFocus())
134 		SetHighColor(blue);
135 	else
136 		SetHighColor(gray);
137 
138 	if(m_xUnderlineRight <= m_xUnderlineLeft)
139 		sizeUnderline(&m_xUnderlineLeft, &m_xUnderlineRight);
140 
141 //	PRINT((
142 //		"### ValControlSegment::Draw(): underline spans %.1f, %.1f\n",
143 //		m_xUnderlineLeft, m_xUnderlineRight));
144 //
145 	StrokeLine(
146 		BPoint(m_xUnderlineLeft, fY),
147 		BPoint(m_xUnderlineRight, fY),
148 		(m_underlineStyle == DOTTED_UNDERLINE) ? B_MIXED_COLORS :
149 			B_SOLID_HIGH);
150 	SetHighColor(old);
151 }
152 
153 void ValControlSegment::FrameResized(
154 	float												width,
155 	float												height) {
156 	_inherited::FrameResized(width, height);
157 
158 //	PRINT((
159 //		"### ValControlSegment::FrameResized(%.1f,%.1f)\n",
160 //		fWidth, fHeight));
161 	sizeUnderline(&m_xUnderlineLeft, &m_xUnderlineRight);
162 }
163 
164 void ValControlSegment::MouseDown(
165 	BPoint											point) {
166 
167 	if(!parent()->IsEnabled())
168 		return;
169 
170 	parent()->MakeFocus();
171 
172 	// not left button?
173 	uint32 nButton;
174 	GetMouse(&point, &nButton);
175 	if(!(nButton & B_PRIMARY_MOUSE_BUTTON))
176 		return;
177 
178 	// double click?
179 	bigtime_t doubleClickInterval;
180 	if(get_click_speed(&doubleClickInterval) < B_OK) {
181 		PRINT((
182 			"* ValControlSegment::MouseDown():\n"
183 			"  get_click_speed() failed."));
184 		return;
185 	}
186 
187 	bigtime_t now = system_time();
188 	if(now - m_lastClickTime < doubleClickInterval) {
189 		if(isTracking()) {
190 			setTracking(false);
191 			mouseReleased();
192 		}
193 
194 		// hand off to parent control
195 		parent()->showEditField();
196 		m_lastClickTime = 0LL;
197 		return;
198 	}
199 	else
200 		m_lastClickTime = now;
201 
202 
203 	// engage tracking
204 	trackMouse(point, TRACK_VERTICAL);
205 }
206 
207 void ValControlSegment::MouseMoved(
208 	BPoint											point,
209 	uint32											transit,
210 	const BMessage*							dragMessage) {
211 
212 	if(!parent()->IsEnabled())
213 		return;
214 
215 	if(!isTracking() || m_prevPoint == point)
216 		return;
217 
218 //	float fXDelta = m_trackFlags & TRACK_HORIZONTAL ?
219 //		point.x - m_prevPoint.x : 0.0;
220 	float fYDelta = m_trackFlags & TRACK_VERTICAL ?
221 		point.y - m_prevPoint.y : 0.0;
222 
223 //	printf("MouseMoved(): %2f,%2f\n",
224 //		fXDelta, fYDelta);
225 
226 
227 	// hand off
228 	// +++++ config'able x/y response would be nice...
229 	float fRemaining = handleDragUpdate(fYDelta);
230 
231 	m_prevPoint = point;
232 	m_prevPoint.y -= fRemaining;
233 }
234 
235 void ValControlSegment::MouseUp(
236 	BPoint											point) {
237 
238 	if(isTracking()) {
239 		setTracking(false);
240 		mouseReleased();
241 	}
242 }
243 
244 // -------------------------------------------------------- //
245 // BHandler impl.
246 // -------------------------------------------------------- //
247 
248 void ValControlSegment::MessageReceived(
249 	BMessage*										message) {
250 
251 	switch(message->what) {
252 		default:
253 			_inherited::MessageReceived(message);
254 	}
255 }
256 
257 // -------------------------------------------------------- //
258 // archiving/instantiation
259 // -------------------------------------------------------- //
260 
261 ValControlSegment::ValControlSegment(
262 	BMessage*										archive) :
263 	BView(archive) {
264 
265 	init();
266 	archive->FindInt32("ulStyle", (int32*)&m_underlineStyle);
267 }
268 
269 status_t ValControlSegment::Archive(
270 	BMessage*										archive,
271 	bool												deep) const {
272 	_inherited::Archive(archive, deep);
273 
274 	archive->AddInt32("ulStyle", m_underlineStyle);
275 	return B_OK;
276 }
277 
278 // END -- ValControlSegment.cpp --
279