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