1 /* 2 Copyright (c) by Valery Goryachev (Wal) 3 */ 4 5 #pragma once 6 7 #if defined( _MSC_VER ) 8 # pragma warning( disable:4100 ) // C4100 : unreferenced formal parameter 9 #endif 10 11 #ifdef _WIN32 12 # if !defined( NOMINMAX ) 13 # define NOMINMAX 14 # endif 15 # include <windows.h> 16 typedef HWND WinID; 17 extern HINSTANCE appInstance; 18 #else 19 # include <X11/Xlib.h> 20 # include <X11/keysym.h> 21 # include <wchar.h> 22 typedef Window WinID; 23 #endif 24 25 #include <stdarg.h> 26 #include <unordered_map> 27 28 namespace wal 29 { 30 31 enum CoreCommands 32 { 33 CMD_CHECK = 0, //команда проверки (поддерживается команда или нет) номер команды в этом случае передается в подкоманде 34 CMD_OK = 1, 35 CMD_CANCEL = 2, 36 CMD_YES = 3, 37 CMD_NO = 4, 38 CMD_PUT_RESULTS_TO_TEMP_PANEL = 5 // XXX should be in global CMD_ID space. There is no one yet 39 }; 40 41 struct cpoint; 42 struct crect; 43 class cpen; 44 class cbrush; 45 class cfont; 46 class cevent; 47 //... 48 class crgn; 49 class cicon; 50 class Win; 51 class GC; 52 class Layout; 53 54 struct cpoint 55 { 56 int x, y; cpointcpoint57 cpoint() {} cpointcpoint58 cpoint( int _x, int _y ): x( _x ), y( _y ) {} cpointcpoint59 cpoint( const cpoint& a ): x( a.x ), y( a.y ) {} 60 cpoint& operator = ( const cpoint& a ) {x = a.x; y = a.y; return *this;} Setcpoint61 cpoint& Set( int _x, int _y ) {x = _x; y = _y; return *this;} 62 cpoint& operator + ( const cpoint& a ) { x += a.x; y += a.y; return *this; } 63 cpoint& operator - ( const cpoint& a ) { x -= a.x; y -= a.y; return *this; } 64 bool operator == ( const cpoint& a ) const { return x == a.x && y == a.y; } 65 }; 66 67 struct crect 68 { 69 int left, top; 70 int right, bottom; crectcrect71 crect(): left( 0 ), top( 0 ), right( 0 ), bottom( 0 ) {} crectcrect72 crect( const cpoint& lt, const cpoint& rb ): left( lt.x ), top( lt.y ), right( rb.x ), bottom( rb.y ) {} crectcrect73 crect( int _left, int _top, int _right, int _bottom ): left( _left ), top( _top ), right( _right ), bottom( _bottom ) {} Setcrect74 void Set( int _left, int _top, int _right, int _bottom ) {left = _left; right = _right; top = _top; bottom = _bottom;} 75 Inccrect76 void Inc() { left--; right++; top--; bottom++; } Deccrect77 void Dec() { left++; right--; top++; bottom--; } 78 Inccrect79 void Inc( int n ) { left -= n; right += n; top -= n; bottom += n; } Deccrect80 void Dec( int n ) { left += n; right -= n; top += n; bottom -= n; } 81 Heightcrect82 int Height() const { return bottom - top; } Widthcrect83 int Width()const { return right - left; } Increct84 bool In( cpoint p )const { return p.x >= left && p.x < right && p.y >= top && p.y < bottom; } 85 bool operator == ( const crect& a ) const { return left == a.left && right == a.right && top == a.top && bottom == a.bottom; } 86 bool operator != ( const crect& a ) const { return !( *this == a ); } IsEmptycrect87 bool IsEmpty() const { return bottom <= top || right <= left; } Zerocrect88 void Zero() { left = top = right = bottom = 0; } SetWidthcrect89 void SetWidth( int w ) { right = left + w; } SetHeightcrect90 void SetHeight( int h ) { bottom = top + h; } 91 Crosscrect92 bool Cross( const crect& a ) const 93 { 94 crect b( left > a.left ? left : a.left, top > a.top ? top : a.top, 95 right < a.right ? right : a.right, bottom < a.bottom ? bottom : a.bottom ); 96 return !b.IsEmpty(); 97 } 98 }; 99 100 }; //namespace wal 101 102 #include "swl_layout.h" 103 104 namespace wal 105 { 106 107 void AppInit(); 108 int AppRun(); 109 void AppExit(); 110 111 #ifdef _WIN32 112 enum Keyboard 113 { 114 VK_NUMPAD_CENTER = 0x0C, 115 VK_NUMPAD_RETURN = 0xFFFF, 116 117 VK_LMETA = VK_LWIN, 118 VK_RMETA = VK_RWIN, 119 120 #ifndef VK_SLASH 121 VK_SLASH = 0xBF, 122 #endif 123 124 #ifndef VK_BACKSLASH 125 VK_BACKSLASH = 0xDC, 126 #endif 127 128 #ifndef VK_GRAVE 129 VK_GRAVE = 0xC0, 130 #endif 131 VK_0 = 0x30, 132 VK_1 = 0x31, 133 VK_2 = 0x32, 134 VK_3 = 0x33, 135 VK_4 = 0x34, 136 VK_5 = 0x35, 137 VK_6 = 0x36, 138 VK_7 = 0x37, 139 VK_8 = 0x38, 140 VK_9 = 0x39, 141 142 VK_A = 0x41, 143 VK_B = 0x42, 144 VK_C = 0x43, 145 VK_D = 0x44, 146 VK_E = 0x45, 147 VK_F = 0x46, 148 VK_G = 0x47, 149 VK_H = 0x48, 150 VK_I = 0x49, 151 VK_J = 0x4A, 152 VK_K = 0x4B, 153 VK_L = 0x4C, 154 VK_M = 0x4D, 155 VK_N = 0x4E, 156 VK_O = 0x4F, 157 VK_P = 0x50, 158 VK_Q = 0x51, 159 VK_R = 0x52, 160 VK_S = 0x53, 161 VK_T = 0x54, 162 VK_U = 0x55, 163 VK_V = 0x56, 164 VK_W = 0x57, 165 VK_X = 0x58, 166 VK_Y = 0x59, 167 VK_Z = 0x5A, 168 169 VK_BRACKETLEFT = 219, 170 VK_BRACKETRIGHT = 221, 171 }; 172 173 174 #endif 175 176 177 #ifndef _WIN32 178 enum Keyboard 179 { 180 VK_NUMPAD_CENTER = XK_KP_Begin, 181 182 VK_ESCAPE = XK_Escape, 183 VK_TAB = XK_Tab, 184 VK_RETURN = XK_Return, 185 VK_NUMPAD_RETURN = XK_KP_Enter, 186 VK_BACK = XK_BackSpace, 187 VK_LEFT = XK_Left, 188 VK_RIGHT = XK_Right, 189 VK_HOME = XK_Home, 190 VK_END = XK_End, 191 VK_UP = XK_Up, 192 VK_DOWN = XK_Down, 193 VK_SPACE = XK_space, //XK_KP_Space, 194 VK_DELETE = XK_Delete, 195 VK_NEXT = XK_Next, 196 VK_PRIOR = XK_Prior, 197 VK_OEM_PLUS = XK_equal, 198 199 VK_ADD = XK_KP_Add, 200 VK_SUBTRACT = XK_KP_Subtract, 201 VK_MULTIPLY = XK_KP_Multiply, 202 203 VK_DIVIDE = XK_KP_Divide, 204 VK_SLASH = XK_slash, 205 VK_BACKSLASH = XK_backslash, 206 207 VK_GRAVE = XK_grave, 208 209 VK_INSERT = XK_Insert, 210 211 VK_LMETA = XK_Meta_L, 212 VK_RMETA = XK_Meta_R, 213 214 VK_LCONTROL = XK_Control_L, 215 VK_RCONTROL = XK_Control_R, 216 VK_LSHIFT = XK_Shift_L, 217 VK_RSHIFT = XK_Shift_R, 218 219 VK_LMENU = XK_Alt_L, 220 VK_RMENU = XK_Alt_R, 221 222 VK_F1 = XK_F1, 223 VK_F2 = XK_F2, 224 VK_F3 = XK_F3, 225 VK_F4 = XK_F4, 226 VK_F5 = XK_F5, 227 VK_F6 = XK_F6, 228 VK_F7 = XK_F7, 229 VK_F8 = XK_F8, 230 VK_F9 = XK_F9, 231 VK_F10 = XK_F10, 232 VK_F11 = XK_F11, 233 VK_F12 = XK_F12, 234 235 VK_1 = XK_1, 236 VK_2 = XK_2, 237 VK_3 = XK_3, 238 VK_4 = XK_4, 239 VK_5 = XK_5, 240 VK_6 = XK_6, 241 VK_7 = XK_7, 242 VK_8 = XK_8, 243 VK_9 = XK_9, 244 VK_0 = XK_0, 245 246 VK_BRACKETLEFT = XK_bracketleft, 247 VK_BRACKETRIGHT = XK_bracketright, 248 249 #define S(a) VK_##a = XK_##a 250 S( A ), 251 S( B ), 252 S( C ), 253 S( D ), 254 S( E ), 255 S( F ), 256 S( G ), 257 S( H ), 258 S( I ), 259 S( J ), 260 S( K ), 261 S( L ), 262 S( M ), 263 S( N ), 264 S( O ), 265 S( P ), 266 S( Q ), 267 S( R ), 268 S( S ), 269 S( T ), 270 S( U ), 271 S( V ), 272 S( W ), 273 S( X ), 274 S( Y ), 275 S( Z ) 276 #undef s 277 }; 278 #endif 279 280 enum events 281 { 282 EV_NONE = 0, 283 EV_CLOSE, 284 EV_SHOW, 285 EV_ACTIVATE, 286 287 EV_KEYDOWN = 10, 288 EV_KEYUP, 289 290 EV_MOUSE_MOVE = 20, 291 EV_MOUSE_PRESS, 292 EV_MOUSE_RELEASE, 293 EV_MOUSE_DOUBLE, 294 EV_MOUSE_WHELL, 295 296 EV_ENTER, 297 EV_LEAVE, 298 EV_SETFOCUS = 30, 299 EV_KILLFOCUS, 300 EV_SIZE = 50, 301 EV_MOVE, 302 EV_TIMER = 70, 303 }; 304 305 306 enum KEYMODFLAG 307 { 308 KM_SHIFT = 0x0001, 309 KM_CTRL = 0x0002, 310 KM_ALT = 0x0004, 311 EXT_KM_RSHIFT = 0x0008, 312 EXT_KM_LSHIFT = 0x0010, 313 EXT_KM_RCTRL = 0x0020, 314 EXT_KM_LCTRL = 0x0040, 315 EXT_KM_RALT = 0x00080, 316 EXT_KM_LALT = 0x00100 317 }; 318 319 class cevent//: public iIntrusiveCounter 320 { 321 int type; 322 public: cevent()323 cevent(): type( EV_NONE ) {} cevent(int t)324 cevent( int t ): type( t ) {} Type()325 int Type() const {return type; } 326 virtual ~cevent(); 327 }; 328 329 class cevent_show: public cevent 330 { 331 bool show; 332 public: cevent_show(bool sh)333 cevent_show( bool sh ): cevent( EV_SHOW ), show( sh ) {} Show()334 bool Show() { return show; } 335 virtual ~cevent_show(); 336 }; 337 338 class cevent_activate: public cevent 339 { 340 bool activated; 341 Win* who; 342 public: cevent_activate(bool act,Win * w)343 cevent_activate( bool act, Win* w ): cevent( EV_ACTIVATE ), activated( act ), who( w ) {} Activated()344 bool Activated() { return activated; } Who()345 Win* Who() { return who; } 346 virtual ~cevent_activate(); 347 }; 348 349 class cevent_input: public cevent 350 { 351 unsigned keyMods; 352 public: cevent_input(int t,unsigned km)353 cevent_input( int t, unsigned km ): cevent( t ), keyMods( km ) {} Mod()354 unsigned Mod() { return keyMods & (KM_ALT|KM_CTRL|KM_SHIFT); } ExtMod()355 unsigned ExtMod() { return keyMods; } 356 virtual ~cevent_input(); 357 }; 358 359 enum MOUSEBUTTON 360 { 361 MB_L = 0x01, 362 MB_M = 0x02, 363 MB_R = 0x04, 364 MB_X1 = 0x08, 365 MB_X2 = 0x10 366 }; 367 368 class cevent_mouse: public cevent_input 369 { 370 cpoint point; 371 unsigned buttonFlag; 372 int button; 373 //int whellDistance; 374 public: cevent_mouse(int type,cpoint p,int b,unsigned bf,unsigned km)375 cevent_mouse( int type, cpoint p, int b, unsigned bf, unsigned km ) 376 : cevent_input( type, km ), point( p ), buttonFlag( bf ), button( b ) {}; 377 Point()378 cpoint& Point() { return point; } ButtonFlag()379 unsigned ButtonFlag() { return buttonFlag; } ButtonL()380 bool ButtonL() { return ( buttonFlag & MB_L ) != 0; } ButtonR()381 bool ButtonR() { return ( buttonFlag & MB_R ) != 0; } Button()382 int Button() { return button; } 383 virtual ~cevent_mouse(); 384 }; 385 386 class cevent_key: public cevent_input 387 { 388 int m_Key; // virtual key code (Windows virtual keys are used) 389 int m_Count; 390 unicode_t m_Chr; 391 bool m_FromMouseWheel; 392 public: cevent_key(int type,int k,unsigned km,int cnt,unicode_t ch,bool FromMouseWheel)393 cevent_key( int type, int k, unsigned km, int cnt, unicode_t ch, bool FromMouseWheel ) 394 : cevent_input( type, km ) 395 , m_Key( k ) 396 , m_Count( cnt ) 397 , m_Chr( ch ) 398 , m_FromMouseWheel( FromMouseWheel ) 399 {}; 400 virtual ~cevent_key(); Key()401 int Key() const { return m_Key; } Count()402 int Count() const { return m_Count; } IsFromMouseWheel()403 bool IsFromMouseWheel() const { return m_FromMouseWheel; } Char()404 unicode_t Char() const { return m_Chr; }; 405 }; 406 407 class cevent_size: public cevent 408 { 409 cpoint size; 410 public: cevent_size(cpoint s)411 cevent_size( cpoint s ): cevent( EV_SIZE ), size( s ) {}; Size()412 cpoint& Size() { return size; } 413 virtual ~cevent_size(); 414 }; 415 416 class cevent_move: public cevent 417 { 418 cpoint pos; 419 public: cevent_move(cpoint s)420 cevent_move( cpoint s ): cevent( EV_MOVE ), pos( s ) {}; Pos()421 cpoint& Pos() { return pos; } 422 virtual ~cevent_move(); 423 }; 424 425 426 427 428 #ifdef _WIN32 429 #else 430 unsigned CreateColorFromRGB( unsigned ); 431 #endif 432 433 434 class cfont: public iIntrusiveCounter 435 { cfont()436 cfont() {} cfont(const cfont &)437 cfont( const cfont& ) {} 438 void operator = ( const cfont& ) {} 439 friend class GC; 440 441 #ifdef _WIN32 442 HFONT handle; 443 bool external; //true если внешний хэндл (чтоб не удалять в деструкторе) drop()444 void drop() { if ( handle && !external ) { ::DeleteObject( handle ); } handle = 0; } 445 #else 446 enum { TYPE_X11 = 0, TYPE_FT = 1 }; 447 int type; 448 void* data; 449 450 //XFontStruct *xfs; 451 452 void drop(); 453 #endif 454 455 std::string _uri; 456 std::string _name; 457 public: 458 #ifdef _WIN32 459 static void SetWin32Charset( unsigned ); cfont(HFONT hf)460 cfont( HFONT hf ): handle( hf ), external( true ) {}; Ok()461 bool Ok() { return handle != NULL; } 462 463 static std::vector<char> LogFontToUru( LOGFONT& lf ); 464 static void UriToLogFont( LOGFONT* plf, const char* uri ); 465 #else 466 static void SetWin32Charset( unsigned ) {}; 467 bool Ok() { return data != 0; } 468 #endif 469 470 enum Weight { X3 = 0, Normal, Light, Bold }; 471 enum Flags { Italic = 1, Fixed = 2 }; 472 473 cfont( GC& gc, const char* name, int pointSize, cfont::Weight weight = Normal, unsigned flags = 0 ); 474 cfont( const char* fileName, int pointSize ); //FreeType 475 cfont( const char* uri ); 476 const char* uri(); 477 const char* printable_name(); 478 ~cfont()479 ~cfont() { drop(); } 480 481 static clPtr<cfont> New( GC& gc, const char* name, int pointSize, cfont::Weight weight = Normal, unsigned flags = 0 ) 482 { 483 clPtr<cfont> p = new cfont( gc, name, pointSize, weight, flags ); 484 485 if ( !p->Ok() ) { return clPtr<cfont>(); } 486 487 return p; 488 } 489 New(const char * fileName,int pointSize)490 static clPtr<cfont> New( const char* fileName, int pointSize ) 491 { 492 clPtr<cfont> p = new cfont( fileName, pointSize ); 493 494 if ( !p->Ok( ) ) { return clPtr<cfont>( ); } 495 496 return p; 497 } 498 New(const char * x11string)499 static clPtr<cfont> New( const char* x11string ) 500 { 501 clPtr<cfont> p = new cfont( x11string ); 502 503 if ( !p->Ok( ) ) { return clPtr<cfont>( ); } 504 505 return p; 506 } 507 508 #ifdef USEFREETYPE 509 struct FTInfo: public iIntrusiveCounter 510 { 511 enum {FIXED_WIDTH = 1}; 512 unsigned flags; 513 std::string name; 514 std::string styleName; 515 }; 516 static clPtr<FTInfo> GetFTFileInfo( const char* path ); 517 #endif 518 519 }; 520 521 class XPMImage 522 { 523 int colorCount; 524 std::vector<unsigned> colors; 525 int none; 526 int width, height; 527 std::vector<int> data; 528 public: 529 void Clear(); XPMImage()530 XPMImage(): colorCount( 0 ), none( -1 ), width( 0 ), height( 0 ) {} 531 Width()532 int Width() const { return width; } Height()533 int Height() const { return height; } 534 Colors()535 const unsigned* Colors() const { return colors.data(); } Data()536 const int* Data() const { return data.data(); } 537 538 bool Load( const char** list, int count ); 539 //void Load(InStream &stream); ~XPMImage()540 ~XPMImage() {} 541 }; 542 543 class Image32 544 { 545 int _width; 546 int _height; 547 std::vector<uint32_t> _data; 548 // std::vector<uint32_t*> _lines; 549 Image32(const Image32 &)550 Image32( const Image32& ) {} 551 void operator=( const Image32& ) {} 552 553 public: Image32()554 Image32(): _width( 0 ), _height( 0 ) {} 555 556 void alloc( int w, int c ); 557 558 void fill( int left, int top, int right, int bottom, unsigned c ); fill(const crect & r,unsigned c)559 void fill( const crect& r, unsigned c ) { fill( r.left, r.top, r.right, r.bottom, c ); } 560 561 void copy( const Image32& a ); 562 void copy( const Image32& a, int w, int h ); 563 564 void copy( const XPMImage& xpm ); 565 566 void clear(); 567 get(int x,int y)568 uint32_t get( int x, int y ) 569 { 570 //return ( x >= 0 && x < _width && y >= 0 && y < _height ) ? _lines[y][x] : 0xFF; 571 return ( x >= 0 && x < _width && y >= 0 && y < _height ) ? _data[ y * _width + x ] : 0xFF; 572 } 573 line(int y)574 uint32_t* line( int y ) { return &_data[ y * _width ]; } 575 Image32(int w,int h)576 Image32( int w, int h ) { alloc( w, h ); } 577 width()578 int width() const { return _width; } height()579 int height() const { return _height; } 580 ~Image32()581 ~Image32() {} 582 }; 583 584 585 #ifdef _WIN32 586 587 class Win32CompatibleBitmap: public iIntrusiveCounter 588 { 589 HBITMAP handle; 590 int _w, _h; 591 std::vector<char> mask; 592 void clear(); 593 void init( int w, int h ); 594 public: Win32CompatibleBitmap()595 Win32CompatibleBitmap(): handle( 0 ), _w( 0 ), _h( 0 ) {} Win32CompatibleBitmap(int w,int h)596 Win32CompatibleBitmap( int w, int h ): handle( 0 ) { init( w, h ); } Win32CompatibleBitmap(Image32 & image)597 Win32CompatibleBitmap( Image32& image ) { Set( image ); } 598 void Set( Image32& image ); 599 void Put( wal::GC& gc, int src_x, int src_y, int dest_x, int dest_y, int w, int h ); 600 ~Win32CompatibleBitmap(); 601 }; 602 603 #else 604 //for X 605 class IntXImage 606 { 607 XImage im; 608 std::vector<char> data; 609 std::vector<char> mask; 610 611 void init( int w, int h ); clear()612 void clear() { data.clear(); mask.clear(); } 613 public: IntXImage(int w,int h)614 IntXImage( int w, int h ) { init( w, h ); } 615 IntXImage( Image32& image ); 616 void Set( Image32& image ); 617 void Set( Image32& image, unsigned bgColor ); 618 void Put( wal::GC& gc, int src_x, int src_y, int dest_x, int dest_y, int w, int h ); GetXImage()619 XImage* GetXImage() {return data.data() ? &im : 0; }; 620 ~IntXImage(); 621 }; 622 #endif 623 624 625 //////// Screen compatible image 626 class SCImage 627 { 628 int width; 629 int height; 630 631 #ifdef _WIN32 632 HBITMAP handle; 633 #else 634 Pixmap handle; 635 #endif 636 SCImage(const SCImage &)637 SCImage( const SCImage& ) {}; 638 void operator = ( const SCImage& ) {}; 639 public: 640 SCImage(); 641 void Destroy(); 642 void Create( int w, int h ); Width()643 int Width() const { return width; }; Height()644 int Height()const { return height; }; 645 646 #ifdef _WIN32 GetX11Handle()647 HBITMAP GetX11Handle() { return handle; }; 648 #else GetXDrawable()649 Pixmap GetXDrawable() { return handle; }; 650 #endif 651 652 ~SCImage(); 653 }; 654 655 656 struct IconData 657 { 658 int counter; 659 Image32 image; 660 661 #ifdef _WIN32 662 clPtr<Win32CompatibleBitmap> normal; 663 clPtr<Win32CompatibleBitmap> disabled; 664 665 #else 666 //x11 cache 667 struct Node: public iIntrusiveCounter 668 { 669 SCImage image; 670 std::vector<char> mask; 671 unsigned bgColor; 672 }; 673 674 clPtr<Node> normal; 675 clPtr<Node> disabled; 676 #endif 677 }; 678 679 680 //создавать и копировать можно в любом потоке, а рисовать только в основном 681 class cicon: public iIntrusiveCounter 682 { 683 IconData* data; 684 public: cicon()685 cicon(): data( 0 ) {} 686 687 void Copy( const cicon& ); 688 cicon(const cicon & a)689 cicon( const cicon& a ): data( 0 ) { Copy( a ); } 690 cicon& operator = ( const cicon& a ) { Copy( a ); return *this; } 691 Width()692 int Width() const { return data ? data->image.width() : 0; } Height()693 int Height() const { return data ? data->image.height() : 0; } Valid()694 bool Valid() const { return data != 0; } 695 696 void Draw( wal::GC& gc, int x, int y, bool enabled = true ); 697 void DrawF( wal::GC& gc, int x, int y, bool enabled = true ); 698 void Clear(); 699 700 void Load( int id, int w /*= 16*/, int h /*= 16*/ ); 701 void Load( const Image32&, int w, int h ); 702 void Load( const char** list, int w, int h ); 703 cicon(int id,int w,int h)704 cicon( int id, int w /*= 16*/, int h /*= 16*/ ): data( 0 ) { Load( id, w, h ); } cicon(const char ** xpm,int w,int h)705 cicon( const char** xpm, int w /*= 16*/, int h /*= 16*/ ): data( 0 ) { Load( xpm, w, h ); } 706 707 static void SetCmdIcon( int cmd, const Image32&, int w = 16, int h = 16 ); 708 static void SetCmdIcon( int cmd, const char** s, int w = 16, int h = 16 ); 709 710 static void ClearCmdIcons( int cmd ); ~cicon()711 ~cicon() { Clear(); } 712 private: 713 static Mutex iconCopyMutex; 714 static Mutex iconListMutex; 715 }; 716 717 718 719 720 721 class GC: public iIntrusiveCounter 722 { 723 public: 724 enum LineStyle 725 { 726 SOLID = 0, 727 DOT 728 }; 729 private: GC()730 GC() {}; 731 GC( const GC& ) = delete; 732 GC& operator=( const GC& ) = delete; 733 #ifdef _WIN32 734 friend LRESULT CALLBACK WProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ); 735 friend class cfont; 736 737 struct crgn 738 { 739 HRGN handle; crgncrgn740 crgn(): handle( 0 ) {} dropcrgn741 void drop() { if ( handle ) { ::DeleteObject( handle ); handle = 0; } } 742 void Set( crect* rect = 0 ) { drop(); if ( rect ) { handle = ::CreateRectRgn( rect->left, rect->top, rect->right, rect->bottom ); } } ~crgncrgn743 ~crgn() { drop(); } 744 }; 745 746 HDC handle; 747 bool needDelete; 748 HPEN savedPen; 749 HBRUSH savedBrush; 750 HFONT savedFont; 751 crgn rgn; 752 753 HPEN linePen; 754 HBRUSH fillBrush; 755 unsigned fillRgb; 756 unsigned lineRgb; 757 unsigned lineWidth; 758 int lineStyle; 759 unsigned textRgb; 760 //unsigned textColor; 761 bool textColorSet; 762 bool bkColorSet; 763 764 int bkMode; // -1 - неизвестно 0 - transparent 1 - OPAQUE 765 GC( HDC h, bool needDel ); 766 void Restore(); 767 768 #else 769 ::GC gc; 770 XGCValues gcValues; 771 unsigned long valueMask; 772 static XFontStruct* defaultFontStruct; 773 int lineX, lineY; 774 Window winId; 775 int fontAscent; 776 cfont* curFont; 777 778 unsigned lineRgb, lineColor; 779 unsigned textRgb, textColor; 780 unsigned fillRgb, fillColor; 781 782 void CheckValues(); 783 void SetFg( unsigned ); 784 void SetBg( unsigned ); 785 786 void _Init( Drawable id ); 787 public: GetXDrawable()788 Drawable GetXDrawable() { return winId; } 789 790 #endif 791 792 public: 793 794 GC( Win* win ); 795 GC( SCImage* win ); 796 #ifndef _WIN32 797 GC( Drawable id ); 798 #endif 799 800 void SetFillColor( unsigned rgb ); 801 void SetLine( unsigned rgb, int width = 1, int style = SOLID ); 802 void SetTextColor( unsigned rgb ); 803 TextRgb()804 unsigned TextRgb() const { return textRgb; } FillRgb()805 unsigned FillRgb() const { return fillRgb; } 806 807 808 void Set( cfont* font ); 809 810 void FillRect( crect r ); 811 void FillRectXor( crect r ); 812 void SetClipRgn( crect* r = 0 ); 813 814 void DrawIcon( int x, int y, cicon* ico ); 815 void DrawIconF( int x, int y, cicon* ico ); 816 817 void TextOut( int x, int y, const unicode_t* s, int charCount = -1 ); 818 void TextOutF( int x, int y, const unicode_t* s, int charCount = -1 ); 819 void MoveTo( int x, int y ); 820 void LineTo( int x, int y ); 821 void SetPixel( int x, int y, unsigned rgb ); 822 cpoint GetTextExtents( const unicode_t* s, int charCount = -1 ); 823 void Ellipce( crect r ); 824 825 #ifdef _WIN32 W32Handle()826 HDC W32Handle() { return handle; }; 827 #else XHandle()828 ::GC XHandle() { return gc; } 829 #endif 830 virtual ~GC(); 831 }; 832 833 #define CI_WIN 0 //class ID 834 835 //extern unsigned* (*SysGetColors)(Win *w); 836 //extern unsigned (*SysGetColor)(Win *w, int colorId); 837 extern cfont* ( *SysGetFont )( Win* w, int fontId ); 838 839 ///////////////////////////////// Ui 840 841 extern int GetUiID( const char* name ); 842 843 struct UiValueNode: public iIntrusiveCounter 844 { 845 enum {INT = 1, STR = 2}; 846 int flags; 847 int64_t i; 848 std::string s; 849 UiValueNodeUiValueNode850 UiValueNode( int64_t n ): flags( INT ), i( n ) {}; UiValueNodeUiValueNode851 UiValueNode( const char* a ): flags( STR ), s( a ) {} 852 853 int64_t Int(); 854 const char* Str(); 855 }; 856 857 class UiParzer; 858 859 class UiValue 860 { 861 friend class UiRules; 862 ccollect<clPtr<UiValueNode> > list; 863 UiValue* next; UiValue(UiValue * nx)864 UiValue( UiValue* nx ): next( nx ) {}; Append(int64_t n)865 void Append( int64_t n ) { clPtr<UiValueNode> v = new UiValueNode( n ); list.append( v ); } Append(const char * s)866 void Append( const char* s ) { clPtr<UiValueNode> v = new UiValueNode( s ); list.append( v ); } 867 bool ParzeNode( UiParzer& parzer ); 868 void Parze( UiParzer& parzer ); 869 public: 870 UiValue(); Int(int n)871 int64_t Int( int n ) { return n >= 0 && n < list.count() ? list[n]->Int() : 0 ; } Int()872 int64_t Int() { return Int( 0 ); } Str(int n)873 const char* Str( int n ) { return n >= 0 && n < list.count() ? list[n]->Str() : "" ; } Str()874 const char* Str() { return Str( 0 ); } Count()875 int Count() { return list.count(); } 876 ~UiValue(); 877 }; 878 879 struct UiSelector; 880 class UiRules; 881 882 class UiCache 883 { 884 bool updated; 885 struct Node 886 { 887 UiSelector* s; 888 UiValue* v; NodeNode889 Node(): s( 0 ), v( 0 ) {} NodeNode890 Node( UiSelector* _s, UiValue* _v ): s( _s ), v( _v ) {} 891 }; 892 893 std::unordered_map<int, ccollect<Node> > hash; 894 public: 895 struct ObjNode 896 { 897 int classId; 898 int nameId; ObjNodeObjNode899 ObjNode(): classId( 0 ), nameId( 0 ) {} ObjNodeObjNode900 ObjNode( int c, int n ): classId( c ), nameId( n ) {} 901 }; 902 903 UiCache(); 904 Updated()905 bool Updated() const {return updated;} Clear()906 void Clear() { hash.clear(); updated = false; } 907 void Update( UiRules& rules, ObjNode* list, int listCount ); 908 UiValue* Get( int id, int item, int* condList ); 909 ~UiCache(); 910 }; 911 912 struct UiCondList 913 { 914 enum {N = 16}; 915 int buf[N]; 916 ClearUiCondList917 void Clear() { for ( int i = 0; i < N; i++ ) { buf[i] = 0; } } UiCondListUiCondList918 UiCondList() { Clear(); } 919 void Set( int id, bool yes ); 920 }; 921 922 extern int uiEnabled; 923 extern int uiFocus; 924 extern int uiItem; 925 extern int uiClassWin; 926 extern int uiColor; 927 extern int uiHotkeyColor; 928 extern int uiBackground; 929 extern int uiFrameColor; 930 extern int uiCurrentItem; 931 extern int uiFocusFrameColor; 932 extern int uiButtonColor;//for scrollbar ... 933 extern int uiMarkColor; //marked text color 934 extern int uiMarkBackground; 935 extern int uiCurrentItemFrame; 936 extern int uiLineColor; 937 extern int uiPointerColor; 938 extern int uiOdd; 939 940 extern int uiVariable; 941 extern int uiValue; 942 943 class Win: public iIntrusiveCounter 944 { 945 946 #ifdef _WIN32 947 friend LRESULT CALLBACK WProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ); 948 #else 949 friend int DoEvents( XEvent* event ); 950 friend void DrawExposeRect( Win* w ); 951 #endif 952 friend class Layout; 953 friend struct LItemWin; 954 public: 955 enum WTYPE 956 { 957 WT_MAIN = 1, 958 WT_POPUP = 2, 959 WT_CHILD = 4 960 }; 961 962 enum WHINT 963 { 964 WH_MINBOX = 8, 965 WH_MAXBOX = 0x10, 966 WH_SYSMENU = 0x20, 967 WH_RESIZE = 0x40, 968 WH_TABFOCUS = 0x80, 969 WH_CLICKFOCUS = 0x100, 970 WH_USEDEFPOS = 0x200 //for WT_MAIN (in win32) use default width and height 971 }; 972 973 enum STATE 974 { 975 S_VISIBLE = 1, 976 S_ENABLED = 4 977 }; 978 979 enum SHOW_TYPE 980 { 981 SHOW_ACTIVE = 0, 982 SHOW_INACTIVE = 1, 983 SHOW_MAXIMIZE = 2 984 }; 985 986 private: 987 static WinID focusWinId; 988 989 WinID handle; 990 Win* parent; 991 wal::ccollect<Win*> childList; 992 WTYPE type; 993 994 WinID blockedBy; //Каким модальным окном заблокировано 995 void* modal; //если не 0 то окно в модальном состоянии 996 997 unsigned whint; 998 unsigned state; 999 bool captured; 1000 WinID lastFocusChild; 1001 1002 LSize lSize; 1003 Layout* upLayout, *layout; 1004 int uiNameId; 1005 UiCache uiCache; 1006 SetState(unsigned s)1007 void SetState( unsigned s ) { state |= s; } ClearState(unsigned s)1008 void ClearState( unsigned s ) { state &= ~s; } 1009 1010 bool IsOneParentWith( WinID h ); 1011 void PopupTreeList( ccollect<WinID>& list ); //добавляет в список текущее окно и его попапы 1012 1013 Win* FocusNPChild( bool next ); 1014 1015 #ifdef _WIN32 1016 1017 #else 1018 WinID reparent; //last reparent id 1019 1020 1021 crect position; // in parent coordinates 1022 crect exposeRect; 1023 void AddExposeRect( crect r ); 1024 SHOW_TYPE showType; 1025 1026 friend void KeyEvent( int type, XKeyEvent* event ); 1027 #endif 1028 protected: UiSetNameId(int id)1029 void UiSetNameId( int id ) { uiNameId = id; } 1030 1031 #ifdef _WIN32 1032 class CaptureSD 1033 { 1034 friend class Win; 1035 HWND h; 1036 public: CaptureSD()1037 CaptureSD(): h( 0 ) {}; 1038 }; 1039 #else 1040 class CaptureSD 1041 { 1042 friend class Win; 1043 Window h; 1044 public: CaptureSD()1045 CaptureSD(): h( None ) {}; 1046 }; 1047 #endif 1048 1049 public: 1050 Win( WTYPE t, unsigned hints = 0, Win* _parent = nullptr, const crect* rect = nullptr, int uiNId = 0 ); 1051 GetID()1052 WinID GetID() { return handle; } Parent()1053 Win* Parent() { return parent; } Type()1054 WTYPE Type() { return type; } Blocked()1055 WinID Blocked() { return blockedBy; } ChildCount()1056 int ChildCount() { return childList.count(); } GetChild(int n)1057 Win* GetChild( int n ) { return ( n >= 0 && n < childList.count() ) ? childList[n] : 0; } 1058 FocusNextChild()1059 Win* FocusNextChild() { return FocusNPChild( true ); } FocusPrevChild()1060 Win* FocusPrevChild() { return FocusNPChild( false ); } 1061 1062 crect ClientRect(); 1063 crect ScreenRect(); 1064 crect Rect(); 1065 1066 void ClientToScreen( int* x, int* y ); 1067 SetTabFocusFlag(bool enable)1068 void SetTabFocusFlag( bool enable ) { if ( enable ) { whint |= WH_TABFOCUS; } else { whint &= ~WH_TABFOCUS; } } SetClickFocusFlag(bool enable)1069 void SetClickFocusFlag( bool enable ) { if ( enable ) { whint |= WH_CLICKFOCUS; } else { whint &= ~WH_CLICKFOCUS; } } 1070 Repaint()1071 virtual void Repaint() 1072 { 1073 wal::GC gc( this ); 1074 this->Paint( gc, this->ClientRect() ); 1075 } 1076 1077 void Maximize(); 1078 void Show( SHOW_TYPE type = SHOW_ACTIVE ); 1079 void Hide(); 1080 GetLSize(LSize * ls)1081 void GetLSize( LSize* ls ) { ( state & S_VISIBLE ) ? *ls = lSize : LSize(); } GetLSize()1082 LSize GetLSize() { return ( state & S_VISIBLE ) ? lSize : LSize(); } SetLSize(const LSize & ls)1083 void SetLSize( const LSize& ls ) { lSize = ls; if ( parent && parent->layout ) { parent->layout->valid = false; } } //main and popup ??? 1084 void RecalcLayouts(); SetLayout(Layout * pl)1085 void SetLayout( Layout* pl ) { layout = pl; if ( layout ) { SetLSize( layout->GetLSize() ); } RecalcLayouts(); } 1086 1087 void SetIdealSize(); 1088 void SetTimer( int id, unsigned period ); 1089 void ResetTimer( int id, unsigned period ); 1090 void DelTimer( int id ); 1091 void DelAllTimers(); 1092 1093 void ThreadCreate( int id, void* ( *f )( void* ), void* d ); 1094 virtual void ThreadSignal( int id, int data ); 1095 virtual void ThreadStopped( int id, void* data ); 1096 1097 int DoModal(); IsModal()1098 bool IsModal() { return modal != 0; } 1099 void EndModal( int id ); 1100 1101 void Move( crect rect, bool repaint = true ); 1102 1103 bool IsEnabled(); InFocus()1104 virtual bool InFocus() { return handle == focusWinId; } 1105 bool IsVisible(); 1106 void Enable( bool en = true ); 1107 void Activate(); 1108 bool SetCapture( CaptureSD* sd = nullptr ); 1109 void ReleaseCapture( CaptureSD* sd = nullptr ); 1110 void OnTop(); IsCaptured()1111 bool IsCaptured() { return captured; } 1112 void Invalidate(); 1113 virtual void SetFocus(); 1114 1115 void SetName( const unicode_t* name ); 1116 void SetName( const char* utf8Name ); 1117 UiCacheClear()1118 void UiCacheClear() { uiCache.Clear(); } 1119 virtual int UiGetClassId(); UiGetNameId()1120 int UiGetNameId() { return uiNameId; } 1121 unsigned UiGetColor( int id, int nodeId, UiCondList* cl, unsigned def ); 1122 1123 virtual void Paint( GC& gc, const crect& paintRect ); 1124 1125 virtual bool Event( cevent* pEvent ); 1126 virtual bool EventMouse( cevent_mouse* pEvent ); 1127 virtual bool EventChildKey( Win* child, cevent_key* pEvent ); 1128 // overridden in dialog elements to help dialog winow to find child that matches the hotkey 1129 // returns window to activate on the hotkey, or 0 if the key is unknown IsHisHotKey(cevent_key * pEvent)1130 virtual Win* IsHisHotKey( cevent_key* pEvent ) { return 0; }; 1131 virtual bool EventKey( cevent_key* pEvent ); 1132 virtual bool EventFocus( bool recv ); 1133 virtual bool EventActivate( bool activated, Win* w ); 1134 virtual bool EventShow( bool show ); 1135 virtual bool EventClose(); 1136 virtual void EventEnterLeave( cevent* pEvent ); 1137 virtual void EventTimer( int tid ); 1138 virtual void EventSize( cevent_size* pEvent ); 1139 virtual void EventMove( cevent_move* pEvent ); 1140 1141 // virtual void EventMouseLeave(); 1142 1143 virtual bool Command( int id, int subId, Win* win, void* data ); //control command or info 1144 virtual bool Broadcast( int id, int subId, Win* win, void* data ); 1145 1146 int SendBroadcast( int id, int subId, Win* win, void* data, int level = 1 ); 1147 1148 virtual ~Win(); 1149 1150 //Not for each Block(WinID id)1151 void Block( WinID id ) { if ( !blockedBy ) { blockedBy = id; } } Unblock(WinID id)1152 void Unblock( WinID id ) { if ( blockedBy == id ) { blockedBy = 0; } } 1153 bool UnblockTree( WinID id ); 1154 1155 1156 //Fonts ... 1157 virtual cfont* GetChildFont( Win* w, int fontId ); 1158 1159 cfont* GetFont( int fontId = 0 ) { return parent ? parent->GetChildFont( this, fontId ) : SysGetFont( this, fontId ); } 1160 1161 //вызывается при изменении фонтов или каких то глобальных параметров, которые могут поменять пропорции окон 1162 //в функции нужно пересчитать LSize 1163 virtual void OnChangeStyles(); 1164 1165 //вызывает у всех дочерних окон OnChangeStyles и RecalcLayouts 1166 static void StylesChanged( Win* w ); 1167 1168 #ifndef _WIN32 1169 static void SetIcon( const char** xpm ); 1170 #endif 1171 #if defined _DEBUG 1172 void dbg_dump(int indent=0); 1173 #else dbg_dump()1174 void dbg_dump(){} 1175 #endif 1176 1177 }; 1178 1179 bool WinThreadSignal( int data ); //signalize window from thread 1180 1181 1182 class ClipboardText 1183 { 1184 enum { BUF_SIZE = 1024 }; 1185 ccollect< std::vector<unicode_t>, 0x100 > list; 1186 int count; 1187 void CopyFrom( const ClipboardText& a ); 1188 public: 1189 ClipboardText(); Count()1190 int Count() const { return count; } 1191 void Clear(); 1192 void Append( unicode_t c ); 1193 void AppendUnicodeStr( const unicode_t* c ); 1194 ClipboardText( const ClipboardText& a ); 1195 ClipboardText& operator = ( const ClipboardText& a ); Get(int n)1196 unicode_t Get( int n ) const 1197 { 1198 ASSERT( n >= 0 && n < count ); 1199 return n >= 0 && n < count ? list.const_item( n / BUF_SIZE ).at( n % BUF_SIZE ) : 0; 1200 } 1201 unicode_t operator[]( int n ) const { return Get( n ); } 1202 }; 1203 1204 1205 void ClipboardSetText( Win* w, ClipboardText& text ); 1206 void ClipboardGetText( Win* w, ClipboardText* text ); 1207 void ClipboardClear(); 1208 }; //namespace wal 1209 1210 namespace wal 1211 { 1212 cpoint GetScreenSize(); 1213 cpoint StaticTextSize( GC& gc, const unicode_t* s, cfont* font = 0 ); 1214 void DrawStaticText( GC& gc, int x, int y, const unicode_t* s, cfont* font = 0, bool transparent = true ); 1215 unsigned ColorTone( unsigned color, int tone /*0-255*/ ); 1216 void DrawPixelList( GC& gc, unsigned short* s, int x, int y, unsigned color ); 1217 void Draw3DButtonW2( GC& gc, crect r, unsigned bg, bool up ); 1218 DrawBorder(GC & gc,crect r,unsigned color)1219 inline void DrawBorder( GC& gc, crect r, unsigned color ) 1220 { 1221 gc.SetLine( color ); 1222 gc.MoveTo( r.right - 1, r.top ); 1223 gc.LineTo( r.left, r.top ); 1224 gc.LineTo( r.left, r.bottom - 1 ); 1225 gc.LineTo( r.right - 1, r.bottom - 1 ); 1226 gc.LineTo( r.right - 1, r.top ); 1227 } 1228 1229 extern void UiReadFile( const sys_char_t* fileName ); //can throw 1230 extern void UiReadMem( const char* s ); //can throw 1231 1232 }; //namespace wal 1233