1 /* 2 Copyright (c) by Valery Goryachev (Wal) 3 */ 4 5 6 #include "swl.h" 7 #include <string.h> 8 9 #include <limits.h> 10 11 namespace wal 12 { 13 14 unicode_t ABCString[] = {'A', 'B', 'C', 0}; 15 int ABCStringLen = 3; 16 17 static clPtr<cfont> pSysFont; 18 19 static cfont* guiFont = 0; 20 21 static char uiDefaultRules[] = 22 "* {color: 0; background: 0xD8E9EC; focus-frame-color : 0x00A000; button-color: 0xD8E9EC; }" 23 "*:current-item { color: 0xFFFFFF; background: 0x800000; }" 24 "ScrollBar { button-color: 0xD8E9EC; }" 25 "EditLine:!enabled { background: 0xD8E9EC; }" 26 "EditLine {color: 0; background: 0xFFFFFF; mark-color: 0xFFFFFF; mark-background : 0x800000; }" 27 //"Button {color: 0; background: 0xFFFFFF}" 28 //"ButtonWin { color: 0xFFFFFF; background: 0 }" 29 //"ButtonWin Button {color: 0; background: 0xB0B000 }" 30 ; 31 32 #ifdef _WIN32 BaseInit()33 void BaseInit() 34 { 35 static bool initialized = false; 36 37 if ( initialized ) { return; } 38 39 initialized = true; 40 41 pSysFont = new cfont( ( HFONT )GetStockObject( DEFAULT_GUI_FONT ) ); 42 guiFont = pSysFont.ptr(); 43 44 // winColors[IC_BG] = ::GetSysColor(COLOR_BTNFACE); 45 // winColors[IC_FG] = winColors[IC_TEXT] = ::GetSysColor(COLOR_BTNTEXT); 46 // winColors[IC_GRAY_TEXT] = ::GetSysColor(COLOR_GRAYTEXT); 47 UiReadMem( uiDefaultRules ); 48 } 49 #else 50 BaseInit()51 void BaseInit() 52 { 53 dbg_printf( "BaseInit\n" ); 54 static bool initialized = false; 55 56 if ( initialized ) { return; } 57 58 initialized = true; 59 GC gc( ( Win* )0 ); 60 pSysFont = new cfont( gc, "fixed", 12, cfont::Normal ); // "helvetica",9); 61 guiFont = pSysFont.ptr(); 62 UiReadMem( uiDefaultRules ); 63 } 64 65 #endif 66 _SysGetFont(Win * w,int fontId)67 static cfont* _SysGetFont( Win* w, int fontId ) 68 { 69 return guiFont; 70 } 71 72 cfont* ( *SysGetFont )( Win* w, int fontId ) = _SysGetFont; 73 Draw3DButtonW2(GC & gc,crect r,unsigned bg,bool up)74 void Draw3DButtonW2( GC& gc, crect r, unsigned bg, bool up ) 75 { 76 static unsigned hp1, lp1; 77 static unsigned hp2, lp2; 78 static unsigned lastBg = 0; 79 static bool initialized = false; 80 81 if ( !initialized || lastBg != bg ) 82 { 83 hp1 = ColorTone( bg, -10 ); 84 lp1 = ColorTone( bg, -90 ); 85 hp2 = ColorTone( bg, +150 ); 86 lp2 = ColorTone( bg, -60 ); 87 lastBg = bg; 88 initialized = true; 89 } 90 91 unsigned php1, plp1, php2, plp2; 92 93 if ( up ) 94 { 95 php1 = hp1; 96 plp1 = lp1; 97 php2 = hp2; 98 plp2 = lp2; 99 } 100 else 101 { 102 php1 = lp1; 103 plp1 = hp1; 104 php2 = lp2; 105 plp2 = hp2; 106 } 107 108 gc.SetLine( plp1 ); 109 gc.MoveTo( r.right - 1, r.top ); 110 gc.LineTo( r.right - 1, r.bottom - 1 ); 111 gc.LineTo( r.left, r.bottom - 1 ); 112 gc.SetLine( php1 ); 113 gc.LineTo( r.left, r.top ); 114 gc.LineTo( r.right - 1, r.top ); 115 r.Dec(); 116 gc.MoveTo( r.right - 1, r.top ); 117 gc.SetLine( php2 ); 118 gc.LineTo( r.left, r.top ); 119 gc.LineTo( r.left, r.bottom - 1 ); 120 gc.SetLine( plp2 ); 121 gc.LineTo( r.right - 1, r.bottom - 1 ); 122 gc.LineTo( r.right - 1, r.top ); 123 } 124 125 126 ////////////////////////////////////////// StaticLine 127 StaticTextSize(GC & gc,const unicode_t * s,cfont * font)128 cpoint StaticTextSize( GC& gc, const unicode_t* s, cfont* font ) 129 { 130 cpoint p( 0, 0 ); 131 132 if ( font ) { gc.Set( font ); } 133 134 while ( *s ) 135 { 136 const unicode_t* t = unicode_strchr( s, '\n' ); 137 int len = ( t ? t - s : unicode_strlen( s ) ); 138 139 cpoint c = gc.GetTextExtents( s, len ); 140 s += len; 141 142 if ( t ) { s++; } 143 144 if ( *s == '\r' ) { s++; } 145 146 p.y += c.y; 147 148 if ( p.x < c.x ) { p.x = c.x; } 149 } 150 151 return p; 152 } 153 DrawStaticText(GC & gc,int x,int y,const unicode_t * s,cfont * font,bool transparent)154 void DrawStaticText( GC& gc, int x, int y, const unicode_t* s, cfont* font, bool transparent ) 155 { 156 if ( font ) { gc.Set( font ); } 157 158 while ( *s ) 159 { 160 const unicode_t* t = unicode_strchr( s, '\n' ); 161 int len = ( t ? t - s : unicode_strlen( s ) ); 162 gc.TextOutF( x, y, s, len ); 163 cpoint c = gc.GetTextExtents( s, len ); 164 s += len; 165 166 if ( t ) { s++; } 167 168 if ( *s == '\r' ) { s++; } 169 170 y += c.y; 171 } 172 } 173 GetStaticTextExtent(GC & gc,const unicode_t * s,cfont * font)174 cpoint GetStaticTextExtent( GC& gc, const unicode_t* s, cfont* font ) 175 { 176 cpoint res( 0, 0 ), c; 177 178 if ( font ) { gc.Set( font ); } 179 180 while ( *s ) 181 { 182 const unicode_t* t = unicode_strchr( s, '\n' ); 183 int len = ( t ? t - s : unicode_strlen( s ) ); 184 185 c = gc.GetTextExtents( s, len ); 186 s += len; 187 188 if ( t ) { s++; } 189 190 if ( *s == '\r' ) { s++; } 191 192 res.y += c.y; 193 194 if ( res.x < c.x ) 195 { 196 res.x = c.x; 197 } 198 } 199 200 return res; 201 } 202 203 int uiClassStatic = GetUiID( "Static" ); UiGetClassId()204 int StaticLine::UiGetClassId() { return uiClassStatic;} 205 StaticLine(int nId,Win * parent,const unicode_t * txt,crect * rect,ALIGN al,int w)206 StaticLine::StaticLine( int nId, Win* parent, const unicode_t* txt, crect* rect, ALIGN al, int w ) 207 : Win( Win::WT_CHILD, 0, parent, rect, nId ) 208 , text( txt ? new_unicode_str( txt ) : std::vector<unicode_t>() ) 209 , align( al ) 210 , width( w ) 211 { 212 if ( !rect ) 213 { 214 GC gc( this ); 215 216 if ( w >= 0 ) 217 { 218 static unicode_t t[] = {'A', 'B', 'C', 0}; 219 cpoint p = GetStaticTextExtent( gc, t, GetFont() ); 220 p.x = p.y * w; 221 SetLSize( LSize( p ) ); 222 } 223 else if ( txt ) 224 { 225 SetLSize( LSize( GetStaticTextExtent( gc, txt, GetFont() ) ) ); 226 } 227 else 228 { 229 SetLSize( LSize( cpoint( 0, 0 ) ) ); 230 } 231 } 232 } 233 SetTextUtf8(const std::string & txt)234 void StaticLine::SetTextUtf8( const std::string& txt ) 235 { 236 this->SetText( wal::utf8str_to_unicode(txt).data() ); 237 } 238 SetText(const unicode_t * txt)239 void StaticLine::SetText( const unicode_t* txt ) 240 { 241 text = wal::new_unicode_str(txt); 242 243 LSize NewSize( cpoint(0, 0) ); 244 245 if ( txt ) 246 { 247 GC gc(this); 248 NewSize = LSize(GetStaticTextExtent(gc, txt, GetFont())); 249 } 250 251 if ( NewSize != this->GetLSize( )) 252 { 253 SetLSize( NewSize ); 254 if ( Parent() ) Parent()->RecalcLayouts(); 255 } 256 257 Invalidate(); 258 } 259 Paint(GC & gc,const crect & paintRect)260 void StaticLine::Paint( GC& gc, const crect& paintRect ) 261 { 262 crect rect = ClientRect(); 263 gc.SetFillColor( UiGetColor( uiBackground, 0, 0, 0xFFFFFF )/*GetColor(0)*/ ); 264 gc.FillRect( rect ); //CCC 265 266 if ( !text.data() || !text[0] ) { return; } 267 268 gc.SetTextColor( UiGetColor( uiColor, 0, 0, 0 )/*GetColor(IsEnabled() ? IC_TEXT : IC_GRAY_TEXT)*/ ); //CCC 269 gc.Set( GetFont() ); 270 271 if ( align >= 0 ) 272 { 273 cpoint size = gc.GetTextExtents( text.data() ); 274 275 if ( align ) //right 276 { 277 DrawStaticText( gc, rect.right - size.x, 0, text.data() ); 278 } 279 else //center 280 { 281 DrawStaticText( gc, ( rect.Width() - size.x ) / 2, 0, text.data() ); 282 } 283 } 284 else 285 { 286 DrawStaticText( gc, 0, 0, text.data() ); 287 } 288 } 289 290 //////////////////////////////////// ToolTip 291 292 class TBToolTip: public Win 293 { 294 std::vector<unicode_t> text; 295 public: 296 TBToolTip( Win* parent, int x, int y, const unicode_t* s ); 297 virtual void Paint( wal::GC& gc, const crect& paintRect ); 298 virtual int UiGetClassId(); 299 virtual ~TBToolTip(); 300 }; 301 302 int uiClassToolTip = GetUiID( "ToolTip" ); 303 UiGetClassId()304 int TBToolTip::UiGetClassId() { return uiClassToolTip; } 305 TBToolTip(Win * parent,int x,int y,const unicode_t * s)306 TBToolTip::TBToolTip( Win* parent, int x, int y, const unicode_t* s ) 307 : Win( Win::WT_POPUP, 0, parent ), 308 text( new_unicode_str( s ) ) 309 { 310 wal::GC gc( this ); 311 cpoint p = GetStaticTextExtent( gc, s, GetFont() ); 312 Move( crect( x, y, x + p.x + 4, y + p.y + 2 ) ); 313 } 314 Paint(wal::GC & gc,const crect & paintRect)315 void TBToolTip::Paint( wal::GC& gc, const crect& paintRect ) 316 { 317 gc.SetFillColor( UiGetColor( uiBackground, 0, 0, 0xFFFFFF )/*GetColor(IC_BG)*/ ); //0x80FFFF); 318 crect r = ClientRect(); 319 gc.FillRect( r ); 320 gc.SetTextColor( UiGetColor( uiColor, 0, 0, 0 )/*GetColor(IC_TEXT)*/ ); 321 //gc.TextOutF(0,0,text.ptr()); 322 DrawStaticText( gc, 2, 1, text.data(), GetFont(), false ); 323 } 324 ~TBToolTip()325 TBToolTip::~TBToolTip() {} 326 327 static clPtr<TBToolTip> tip; 328 329 ToolTipShow(Win * w,int x,int y,const unicode_t * s)330 void ToolTipShow( Win* w, int x, int y, const unicode_t* s ) 331 { 332 ToolTipHide(); 333 334 if ( !w ) { return; } 335 336 crect r = w->ScreenRect(); 337 tip = new TBToolTip( w, r.left + x, r.top + y, s ); 338 tip->Enable(); 339 tip->Show( Win::SHOW_INACTIVE ); 340 } 341 ToolTipShow(Win * w,int x,int y,const char * s)342 void ToolTipShow( Win* w, int x, int y, const char* s ) 343 { 344 ToolTipShow( w, x, y, utf8_to_unicode( s ).data() ); 345 } 346 ToolTipHide()347 void ToolTipHide() 348 { 349 tip = 0; 350 } 351 IsValid(const std::vector<unicode_t> & Str) const352 bool clUnsignedInt64Validator::IsValid( const std::vector<unicode_t>& Str ) const 353 { 354 std::string utf8 = unicode_to_utf8( Str.data() ); 355 356 for ( size_t i = 0; i != utf8.size(); i++ ) 357 { 358 if ( !utf8[i] ) { break; } 359 360 if ( !IsDigit( utf8[i] ) ) { return false; } 361 } 362 363 uint64_t Result = strtoull( utf8.data(), nullptr, 10 ); 364 365 if ( Result == ULLONG_MAX ) { return false; } 366 367 return true; 368 } 369 370 /// validate date in format dd.mm.yyyy IsValid(const std::vector<unicode_t> & Str) const371 bool clDateValidator::IsValid( const std::vector<unicode_t>& Str ) const 372 { 373 std::string s = unicode_to_utf8_string( Str.data() ); 374 375 if ( s.empty() ) return false; 376 if ( s.length() > 10 ) return false; 377 378 int Day = 0; 379 int Month = 0; 380 int Year = 0; 381 382 if ( Lsscanf( s.c_str(), "%i.%i.%i", &Day, &Month, &Year ) != 3 ) return false; 383 384 if ( Day <= 0 || Day > 31 ) return false; 385 if ( Month <=0 || Month > 12 ) return false; 386 if ( Year < 1970 || Year > 2100 ) return false; 387 388 return true; 389 } 390 391 /// validate time in format HH:MM:SS,MSC IsValid(const std::vector<unicode_t> & Str) const392 bool clTimeValidator::IsValid( const std::vector<unicode_t>& Str ) const 393 { 394 std::string s = unicode_to_utf8_string( Str.data() ); 395 396 if ( s.empty() ) return false; 397 if ( s.length() > 12 ) return false; 398 399 int Hours = 0; 400 int Minutes = 0; 401 int Seconds = 0; 402 int Milliseconds = 0; 403 404 int NumValues = Lsscanf( s.c_str(), "%i:%i:%i,%i", &Hours, &Minutes, &Seconds, &Milliseconds ); 405 406 if ( NumValues != 3 && NumValues != 4 ) return false; 407 408 if ( Hours < 0 || Hours > 24 ) return false; 409 if ( Minutes < 0 || Minutes > 59 ) return false; 410 if ( Seconds < 0 || Seconds > 59 ) return false; 411 if ( Milliseconds < 0 || Milliseconds > 999 ) return false; 412 413 return true; 414 } 415 416 417 }; //anmespace wal 418