1 /* 2 Copyright (c) by Valery Goryachev (Wal) 3 */ 4 5 6 #include "swl.h" 7 8 namespace wal 9 { 10 11 12 #define SB_WIDTH 16 13 14 int uiClassScrollBar = GetUiID( "ScrollBar" ); UiGetClassId()15 int ScrollBar::UiGetClassId() { return uiClassScrollBar; } 16 Draw3DButtonW1(GC & gc,crect r,unsigned bg,bool up)17 void Draw3DButtonW1( GC& gc, crect r, unsigned bg, bool up ) 18 { 19 static unsigned hp1, lp1; 20 static unsigned lastBg = 0; 21 static bool initialized = false; 22 23 if ( !initialized || lastBg != bg ) 24 { 25 hp1 = ColorTone( bg, 200 ); 26 lp1 = ColorTone( bg, -150 ); 27 lastBg = bg; 28 initialized = true; 29 } 30 31 unsigned php1, plp1; 32 33 if ( up ) 34 { 35 php1 = hp1; 36 plp1 = lp1; 37 } 38 else 39 { 40 php1 = lp1; 41 plp1 = hp1; 42 } 43 44 gc.SetLine( plp1 ); 45 gc.MoveTo( r.right - 1, r.top ); 46 gc.LineTo( r.right - 1, r.bottom - 1 ); 47 gc.LineTo( r.left, r.bottom - 1 ); 48 gc.SetLine( php1 ); 49 gc.LineTo( r.left, r.top ); 50 gc.LineTo( r.right - 1, r.top ); 51 } 52 53 /* 54 types: 55 1 -left 2 - right 3 - horisontal slider 56 4 - up 5 - down 6 - vert. slider 57 */ SBCDrawButton(GC & gc,crect rect,int type,unsigned bg,bool pressed)58 void SBCDrawButton( GC& gc, crect rect, int type, unsigned bg, bool pressed ) 59 { 60 static unsigned short up[] = {6, 0x10, 0x38, 0x7c, 0xee, 0x1c7, 0x82}; 61 static unsigned short down[] = {6, 0x82, 0x1c7, 0xee, 0x7c, 0x38, 0x10,}; 62 static unsigned short left[] = {9, 0x10, 0x38, 0x1c, 0x0e, 0x07, 0x0e, 0x1c, 0x38, 0x10}; 63 static unsigned short right[] = {9, 0x02, 0x07, 0x0E, 0x1c, 0x38, 0x1c, 0x0e, 0x07, 0x02}; 64 DrawBorder( gc, rect, ColorTone( bg, -100 ) ); 65 rect.Dec(); 66 Draw3DButtonW1( gc, rect, bg, !pressed ); 67 //rect.Dec(); 68 rect.Dec(); 69 gc.SetFillColor( bg ); 70 gc.FillRect( rect ); 71 int xPlus = 0; 72 int yPlus = 0; 73 74 if ( pressed ) 75 { 76 // xPlus = 1; 77 yPlus = 1; 78 } 79 80 unsigned color = ColorTone( bg, -200 ); 81 82 switch ( type ) 83 { 84 case 1: 85 DrawPixelList( gc, left, rect.left + ( rect.Width() - 6 ) / 2 + xPlus, rect.top + ( rect.Height() - 9 ) / 2 + yPlus, color ); 86 break; 87 88 case 2: 89 DrawPixelList( gc, right, rect.left + ( rect.Width() - 6 ) / 2 + xPlus, rect.top + ( rect.Height() - 9 ) / 2 + yPlus, color ); 90 break; 91 92 case 4: 93 DrawPixelList( gc, up, rect.left + ( rect.Width() - 9 ) / 2 + xPlus, rect.top + ( rect.Height() - 6 ) / 2 + yPlus, color ); 94 break; 95 96 case 5: 97 DrawPixelList( gc, down, rect.left + ( rect.Width() - 9 ) / 2 + xPlus, rect.top + ( rect.Height() - 6 ) / 2 + yPlus, color ); 98 break; 99 }; 100 } 101 ScrollBar(int nId,Win * parent,bool _vertical,bool _autoHide,crect * rect)102 ScrollBar::ScrollBar( int nId, Win* parent, bool _vertical, bool _autoHide, crect* rect ) 103 : Win( Win::WT_CHILD, 0, parent, rect, nId ), 104 vertical( _vertical ), 105 si( 100, 10, 0 ), 106 len( 0 ), 107 bsize( 0 ), 108 bpos( 0 ), 109 trace( false ), 110 traceBPoint( 0 ), 111 autoHide( _autoHide ), 112 b1Pressed( false ), 113 b2Pressed( false ), 114 managedWin( 0 ) 115 { 116 LSize ls; 117 int l = SB_WIDTH * 2;// + 2;// + 5; 118 int h = SB_WIDTH;// + 2; 119 120 if ( vertical ) 121 { 122 ls.Set( cpoint( h, l ) ); 123 ls.y.maximal = 16000; 124 } 125 else 126 { 127 ls.Set( cpoint( l, h ) ); 128 ls.x.maximal = 16000; 129 } 130 131 SetLSize( ls ); 132 SetScrollInfo( nullptr ); 133 // crect r = ClientRect(); 134 // EventSize(&cevent_size(cpoint(r.Width(),r.Height()))); 135 } 136 Paint(GC & gc,const crect & paintRect)137 void ScrollBar::Paint( GC& gc, const crect& paintRect ) 138 { 139 crect cr = ClientRect(); 140 unsigned bgColor = UiGetColor( uiBackground, 0, 0, 0xD8E9EC );/*GetColor(IC_SCROLL_BG)*/; 141 unsigned btnColor = UiGetColor( uiButtonColor, 0, 0, 0xD8E9EC ); //GetColor(IC_SCROLL_BUTTON); 142 gc.SetFillColor( bgColor ); 143 gc.FillRect( cr ); 144 DrawBorder( gc, cr, UiGetColor( uiColor, 0, 0, 0xD8E9EC )/*GetColor(IC_SCROLL_BORDER)*/ ); 145 146 if ( !b1Rect.IsEmpty() ) { SBCDrawButton( gc, b1Rect, vertical ? 4 : 1, btnColor, b1Pressed ); } 147 148 if ( !b2Rect.IsEmpty() ) { SBCDrawButton( gc, b2Rect, vertical ? 5 : 2, btnColor, b2Pressed ); } 149 150 if ( !b3Rect.IsEmpty() ) { SBCDrawButton( gc, b3Rect, vertical ? 6 : 3, btnColor, false ); } 151 } 152 SetScrollInfo(ScrollInfo * s)153 void ScrollBar::SetScrollInfo( ScrollInfo* s ) 154 { 155 ScrollInfo ns; 156 157 if ( s ) { ns = *s; } 158 else 159 { 160 ns.m_Size = ns.m_PageSize = ns.m_Pos = 0; 161 } 162 163 if ( ns.m_Size < 0 ) { ns.m_Size = 0; } 164 165 if ( ns.m_PageSize < 0 ) { ns.m_PageSize = 0; } 166 167 if ( ns.m_Pos < 0 ) { ns.m_Pos = 0; } 168 169 if ( si == ns ) { return; } 170 171 si = ns; 172 173 Recalc(); 174 175 if ( si.m_AlwaysHidden ) 176 { 177 Hide(); 178 179 if ( Parent() ) { Parent()->RecalcLayouts(); } 180 } 181 else if ( autoHide ) 182 { 183 bool v = IsVisible(); 184 185 if ( si.m_Size <= si.m_PageSize && si.m_Pos <= 0 ) 186 { 187 if ( v ) 188 { 189 Hide(); 190 191 if ( Parent() ) { Parent()->RecalcLayouts(); } 192 } 193 } 194 else 195 { 196 if ( !v ) 197 { 198 Show(); 199 200 if ( Parent() ) { Parent()->RecalcLayouts(); } 201 } 202 } 203 } 204 else 205 { 206 Show(); 207 208 if ( Parent() ) { Parent()->RecalcLayouts(); } 209 } 210 211 Invalidate(); 212 } 213 Recalc(cpoint * newSize)214 void ScrollBar::Recalc( cpoint* newSize ) 215 { 216 cpoint cs; 217 218 if ( newSize ) { cs = *newSize; } 219 else 220 { 221 crect r = ClientRect(); 222 cs.Set( r.Width(), r.Height() ); 223 } 224 225 int s = vertical ? cs.y : cs.x; 226 b1Rect.Set( 0, 0, SB_WIDTH, SB_WIDTH ); 227 228 if ( vertical ) 229 { 230 b2Rect.Set( 0, s - SB_WIDTH, SB_WIDTH, s ); 231 } 232 else 233 { 234 b2Rect.Set( s - SB_WIDTH , 0 , s, SB_WIDTH ); 235 } 236 237 len = s - SB_WIDTH * 2; // - 2; 238 239 b3Rect.Zero(); 240 241 bpos = 0; 242 243 if ( len <= 0 ) { return; } 244 245 if ( si.m_Size <= 0 ) { return; } 246 247 if ( si.m_PageSize <= 0 || si.m_PageSize >= si.m_Size ) { return; } 248 249 bsize = int( ( int64_t( len ) * si.m_PageSize ) / si.m_Size ); 250 251 if ( bsize < 5 ) { bsize = 5; } 252 253 if ( len <= bsize ) { return; } 254 255 int space = ( len - bsize ); 256 257 bpos = int( ( int64_t( space ) * si.m_Pos ) / ( si.m_Size - si.m_PageSize ) ); 258 259 if ( bpos > space ) { bpos = space; } 260 261 int n = SB_WIDTH + bpos; 262 263 if ( vertical ) 264 { 265 b3Rect.Set( 0, n, SB_WIDTH, n + bsize ); 266 } 267 else 268 { 269 b3Rect.Set( n , 0 , n + bsize, SB_WIDTH ); 270 } 271 } 272 EventSize(cevent_size * pEvent)273 void ScrollBar::EventSize( cevent_size* pEvent ) 274 { 275 Recalc( &( pEvent->Size() ) ); 276 } 277 Command(int id,int subId,Win * win,void * data)278 bool ScrollBar::Command( int id, int subId, Win* win, void* data ) 279 { 280 if ( id != CMD_SCROLL_INFO || win != managedWin ) { return false; } 281 282 if ( ( vertical && subId != SCMD_SCROLL_VCHANGE ) || ( !vertical && subId != SCMD_SCROLL_HCHANGE ) ) { return false; } 283 284 SetScrollInfo( ( ScrollInfo* )data ); 285 return true; 286 } 287 SendManagedCmd(int subId,void * data)288 void ScrollBar::SendManagedCmd( int subId, void* data ) 289 { 290 if ( managedWin ) 291 { 292 managedWin->Command( CMD_SCROLL_INFO, subId, this, data ); 293 } 294 else if ( Parent() ) 295 { 296 Parent()->Command( CMD_SCROLL_INFO, subId, this, data ); 297 } 298 } 299 EventTimer(int tid)300 void ScrollBar::EventTimer( int tid ) 301 { 302 SendManagedCmd( tid, 0 ); 303 } 304 EventMouse(cevent_mouse * pEvent)305 bool ScrollBar::EventMouse( cevent_mouse* pEvent ) 306 { 307 switch ( pEvent->Type() ) 308 { 309 310 case EV_MOUSE_MOVE: 311 if ( trace ) 312 { 313 int p = vertical ? ( pEvent->Point().y - b1Rect.bottom ) 314 : ( pEvent->Point().x - b1Rect.right ); 315 p -= traceBPoint; 316 int n = len - bsize; 317 318 if ( n <= 0 ) { break; } 319 320 //if (p>=n) p = n-1; 321 //if (p<0) p = 0; 322 323 int n1 = int( si.m_Size - si.m_PageSize ); 324 int x = ( int64_t( p ) * n1 ) / n; 325 326 if ( x >= n1 ) { x = n1; } 327 328 if ( x < 0 ) { x = 0; } 329 330 SendManagedCmd( SCMD_SCROLL_TRACK, &x ); //(void*)x); 331 } 332 333 break; 334 335 case EV_MOUSE_DOUBLE: 336 case EV_MOUSE_PRESS: 337 if ( pEvent->Button() != MB_L ) 338 { 339 break; 340 } 341 342 { 343 int subId = 0; 344 345 if ( b1Rect.In( pEvent->Point() ) ) 346 { 347 b1Pressed = true; 348 subId = ( vertical ) ? SCMD_SCROLL_LINE_UP : SCMD_SCROLL_LINE_LEFT; 349 } 350 else if ( b2Rect.In( pEvent->Point() ) ) 351 { 352 b2Pressed = true; 353 subId = ( vertical ) ? SCMD_SCROLL_LINE_DOWN : SCMD_SCROLL_LINE_RIGHT; 354 } 355 else if ( b3Rect.In( pEvent->Point() ) ) 356 { 357 traceBPoint = ( vertical ) ? ( pEvent->Point().y - b3Rect.top ) : ( pEvent->Point().x - b3Rect.left ); 358 trace = true; 359 SetCapture( &captureSD ); 360 break; 361 } 362 else if ( !b3Rect.IsEmpty() ) 363 { 364 if ( vertical ) 365 { 366 if ( pEvent->Point().y < b3Rect.top ) 367 { 368 subId = SCMD_SCROLL_PAGE_UP; 369 } 370 else 371 { 372 subId = SCMD_SCROLL_PAGE_DOWN; 373 } 374 } 375 else 376 { 377 if ( pEvent->Point().x < b3Rect.left ) 378 { 379 subId = SCMD_SCROLL_PAGE_LEFT; 380 } 381 else 382 { 383 subId = SCMD_SCROLL_PAGE_RIGHT; 384 } 385 } 386 } 387 388 if ( subId != 0 ) 389 { 390 SetCapture( &captureSD ); 391 SendManagedCmd( subId, 0 ); 392 SetTimer( subId, 100 ); 393 } 394 } 395 396 this->Invalidate(); 397 break; 398 399 case EV_MOUSE_RELEASE: 400 if ( pEvent->Button() != MB_L ) 401 { 402 break; 403 } 404 405 if ( IsCaptured() ) 406 { 407 b1Pressed = false ; 408 b2Pressed = false ; 409 ReleaseCapture( &captureSD ); 410 DelAllTimers(); 411 Invalidate(); 412 trace = false; 413 } 414 415 break; 416 417 default: 418 ; 419 } 420 421 return true; 422 } 423 ~ScrollBar()424 ScrollBar::~ScrollBar() {} 425 426 427 }; //namespace wal 428