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