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