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 46ValControlSegment::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 59ValControlSegment::~ValControlSegment() 60{ 61} 62 63 64void 65ValControlSegment::_Init() 66{ 67 //m_pLeft = 0; 68} 69 70 71const double ValControlSegment::fDefDragScaleFactor = 4; 72 73 74// get parent 75ValControl* 76ValControlSegment::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 96void 97ValControlSegment::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 107void 108ValControlSegment::setTracking(bool tracking) 109{ 110 fTracking = tracking; 111} 112 113 114bool 115ValControlSegment::isTracking() const 116{ 117 return fTracking; 118} 119 120 121double 122ValControlSegment::dragScaleFactor() const 123{ 124 return fDragScaleFactor; 125} 126 127 128// -------------------------------------------------------- // 129// default hook implementations 130// -------------------------------------------------------- // 131 132void 133ValControlSegment::sizeUnderline(float* outLeft, float* outRight) 134{ 135 *outLeft = 0.0; 136 *outRight = Bounds().right; 137} 138 139 140void 141ValControlSegment::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 151void 152ValControlSegment::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 186void 187ValControlSegment::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 198void 199ValControlSegment::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 241void 242ValControlSegment::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 269void 270ValControlSegment::MouseUp(BPoint point) 271{ 272 if (isTracking()) { 273 setTracking(false); 274 mouseReleased(); 275 } 276} 277 278 279void 280ValControlSegment::MessageReceived(BMessage* message) 281{ 282 switch(message->what) { 283 default: 284 _Inherited::MessageReceived(message); 285 } 286} 287 288 289// -------------------------------------------------------- // 290// archiving/instantiation 291// -------------------------------------------------------- // 292 293ValControlSegment::ValControlSegment(BMessage* archive) 294 : BView(archive) 295{ 296 _Init(); 297 archive->FindInt32("ulStyle", (int32*)&fUnderlineStyle); 298} 299 300 301status_t 302ValControlSegment::Archive(BMessage* archive, bool deep) const 303{ 304 _Inherited::Archive(archive, deep); 305 306 archive->AddInt32("ulStyle", fUnderlineStyle); 307 return B_OK; 308} 309