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