home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / pvwin.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-05  |  30.7 KB  |  1,143 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW INTERFACE                 |
  4. // |  File:        PVWIN.CPP                            |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Windows support implementation       |
  8. // |                                                    |
  9. // |  Author:      Emil Dotchevski                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_stdio
  16. #define uses_string
  17. #define uses_app
  18. #define uses_colors
  19. #define uses_dc
  20. #define uses_desk
  21. #define uses_icons
  22. #define uses_label
  23. #define uses_system
  24. #define uses_cmdgen
  25. #define uses_win
  26.  
  27. #define _DECLARE_PVWIN
  28. #include "PVuses.h"
  29. #undef  _DECLARE_PVWIN
  30.  
  31. class Tmoving: public Titem
  32. {
  33.   public:
  34.     Tmoving( boolean _move_or_resize );
  35.  
  36.   protected:
  37.     virtual void set_palette( void );
  38.     virtual void draw( void );
  39.  
  40.   private:
  41.     boolean move_or_resize;
  42. };
  43.  
  44. class Tframe: public Tbox
  45. {
  46.   public:
  47.     Tframe( char *t );
  48.  
  49.   protected:
  50.     virtual void set_palette( void );
  51. };
  52.  
  53.  
  54. //Tclose_icon private:
  55.  
  56. Tmenu *Tclose_icon::init( Twindow *w )
  57. {
  58.   window = w;
  59.   ::menu();
  60.     submenu( i_close );
  61.       w->construct_system_menu();
  62.     endm();
  63.   return endm();
  64. }
  65.  
  66. //Tclose_icon publics:
  67.  
  68. Tclose_icon::Tclose_icon( Twindow *w ):
  69.   Tmenu_bar( init( w ), i_close_len )
  70. {
  71.   client = window;
  72. }
  73.  
  74. uint Tclose_icon::exec( void )
  75. {
  76.   Tcommands *saved_cmd;
  77.   uint result;
  78.  
  79.   saved_cmd = get_cmd();
  80.   set_cmd( &window->commands );
  81.   window->owner->pop_item( window );
  82.   result = Tmenu_bar::exec();
  83.   set_cmd( saved_cmd );
  84.   return result;
  85. }
  86.  
  87. //Tclose_icon protected:
  88.  
  89. void Tclose_icon::set_palette( void )
  90. {
  91.   Tmenu_bar::set_palette();
  92.   if( !window_state( isACTIVE ) )
  93.     text_attr = rolb( pal_windows.frame_normal, 4 );
  94. }
  95.  
  96. #ifndef NOMOUSE
  97. void Tclose_icon::event_handler( Tevent &ev )
  98. {
  99.   if( ( ev.code == evMOUSE_DOWN ) && ev.INSIDE && ev.CLICKS )
  100.   {
  101.     if( state( isMODAL ) ) stop( cmWIN_CLOSE );
  102.     put_command( owner, cmWIN_CLOSE );
  103.     cancelled();
  104.     handled( ev );
  105.   }
  106.   Tmenu_bar::event_handler( ev );
  107. }
  108. #endif
  109.  
  110. Tmenu_item *Tclose_icon::shortcut_ptr( uint ascii )
  111. {
  112.   Tmenu_item *result;
  113.  
  114.   result = Tmenu_bar::shortcut_ptr( ascii );
  115.   if( ( result == NULL ) && ( ascii == kALT_SPACE ) ) result = menu->items;
  116.   return result;
  117. }
  118.  
  119. //Twindow publics:
  120.  
  121. Twindow::Twindow( char *t, int _xl, int _yl ):
  122.   Titem( _xl, _yl ),
  123.   commands( local_commands )
  124. {
  125.   palette = __palette();
  126.   title = NULL;
  127.   if( ( t != NULL ) && ( *t != 0 ) ) title = STRDUP( t );
  128.   xl_min = 0; yl_min = 0; xl_max = 0; yl_max = 0;
  129.   xl_saved = _xl; yl_saved = _yl;
  130.   icon_x = 1000; icon_y = 1000;
  131.   frame_beg_flag = 0;
  132.   local_tools = __context();
  133.   close_icon = NULL;
  134.   maximize_icon = NEW( Ticon( i_maximize, cmWIN_MAXIMIZE, 0 ) );
  135.     put_in( maximize_icon, 0, 0 );
  136.     maximize_icon->drag_mode = dmDRAG_HOR;
  137.   minimize_icon = NEW( Ticon( i_minimize, cmWIN_MINIMIZE, 0 ) );
  138.     minimize_icon->drag_mode = dmDRAG_HOR;
  139.     put_in( minimize_icon, 0, 0 );
  140.   resize_icon = NEW( Ticon( i_resize, 0, 0 ) );
  141.     resize_icon->set_events_mask( ~evCOMMAND, 0 );
  142.     resize_icon->drag_mode = dmDRAG_BOTH;
  143.     put_in( resize_icon, 0, 0 );
  144.   set_flags( ifSELECTABLE+ifICONIZEABLE+ifTILEABLE, 1 );
  145.   grow_mode = gmGROW_REL + gmGROW_BOTH;
  146.   drag_mode = dmDRAG_REL + dmDRAG_BOTH;
  147.   on_top_flag = 0;
  148.   shortcut = 0;
  149.   commands<<0<<cmWIN_ON_TOP;
  150.   resize( xl, yl );
  151. }
  152.  
  153. Twindow::~Twindow( void )
  154. {
  155.   if( shortcut ) win_nums>>shortcut;
  156.   set_context( 0 );
  157.   if( get_cmd() == &commands ) set_cmd( NULL );
  158.   FREE( title );
  159. }
  160.  
  161. void Twindow::set_state( uint _state_word, boolean enable )
  162. {
  163.   uint s;
  164.   int gx, gy, xx, yy;
  165.  
  166.   if( _state_word & isICONIZED )
  167.     if( !flags( ifICONIZEABLE ) )
  168.       _state_word &= ~isICONIZED;
  169.     else
  170.       if( enable && state( wsMAXIMIZED ) ) set_state( wsMAXIMIZED, 0 );
  171.   if( _state_word & wsMAXIMIZED )
  172.     if( !flags( ifRESIZEABLE ) )
  173.       _state_word &= ~wsMAXIMIZED;
  174.     else
  175.       if( enable && state( isICONIZED ) ) set_state( isICONIZED, 0 );
  176.   if( !_state_word ) return;
  177.   s = state_word;
  178.   Titem::set_state( _state_word, enable );
  179.   if( s != state_word )
  180.   {
  181.     if( ( _state_word & isFOCUSED ) && enable ) owner->pop_item( this );
  182.     if( _state_word & ( isHIDDEN ) )
  183.       if( state( isHIDDEN ) )
  184.       {
  185.         commands>>0>>cmWIN_CLOSE;
  186.         if( shortcut )
  187.         {
  188.           win_nums>>shortcut;
  189.           shortcut = 0;
  190.         }
  191.       }
  192.       else
  193.       {
  194.         commands<<0;
  195.         if( flags( ifCLOSEABLE ) ) commands<<cmWIN_CLOSE;
  196.         if( !shortcut && flags( ifSELECTABLE ) && owner==desktop )
  197.           for( char i=1; i<=9; i++ )
  198.             if( !( win_nums & i ) )
  199.             {
  200.               win_nums<<i;
  201.               shortcut = i;
  202.               break;
  203.             }
  204.       }
  205.     desktop->update_commands();
  206.   }
  207.   on_top_flag = state( isON_TOP )? cmWIN_ON_TOP : 0;
  208.   if( (s&(isICONIZED+wsMAXIMIZED)) == (state_word&(isICONIZED+wsMAXIMIZED)) ) return;
  209.   boolean iconized_on   = (s&isICONIZED ) < (state_word&isICONIZED );
  210.   boolean maximized_on  = (s&wsMAXIMIZED) < (state_word&wsMAXIMIZED);
  211.   boolean iconized_off  = (s&isICONIZED ) > (state_word&isICONIZED );
  212.   boolean maximized_off = (s&wsMAXIMIZED) > (state_word&wsMAXIMIZED);
  213.   if( iconized_on || maximized_on )
  214.   {
  215.     x_saved  = x;  y_saved  = y;
  216.     xl_saved = xl; yl_saved = yl;
  217.     commands<<cmWIN_RESTORE;
  218.   }
  219.   if( iconized_off || maximized_off ) commands>>cmWIN_RESTORE;
  220.   redraw();
  221.   if( iconized_on )
  222.   {
  223.     if( xl_min > 0 ) Titem::resize( xl_min, 1 ); else Titem::resize( 23, 1 );
  224.     if( icon_x != 1000 )
  225.       drag( icon_x, icon_y );
  226.     else
  227.       if( owner == desktop ) ( (Tdesktop *) owner )->arrange_one_icon( this );
  228.     commands>>0>>cmWIN_MINIMIZE;
  229.   }
  230.   if( iconized_off )
  231.   {
  232.     icon_x = x; icon_y = y;
  233.     Titem::resize( xl_saved, yl_saved );
  234.     Titem::drag( x_saved, y_saved );
  235.     redraw();
  236.     commands<<cmWIN_MINIMIZE;
  237.     if( state( isALIVE ) ) commands<<0;
  238.   }
  239.   if( maximized_on )
  240.   {
  241.     xx = xl_max; if( !xx ) xx = owner->xl;
  242.     yy = yl_max; if( !yy ) yy = owner->yl;
  243.     direct_resize( xx, yy );
  244.     owner->make_global( x, y, gx, gy );
  245.     if( gx < 0 ) xx = 0; else xx = gx;
  246.     if( ( scr_columns - xx ) < xl ) xx = scr_columns - xl;
  247.     if( gy < desktop_y ) yy = desktop_y; else yy = gy;
  248.     if( ( scr_rows - yy ) < yl ) yy = scr_rows - yl;
  249.     owner->make_local( xx, yy, gx, gy );
  250.     drag( gx, gy );
  251.     commands>>cmWIN_MAXIMIZE;
  252.     maximize_icon->set_cmd( cmWIN_RESTORE );
  253.   }
  254.   if( maximized_off )
  255.   {
  256.     direct_resize( xl_saved, yl_saved );
  257.     Titem::drag( x_saved, y_saved );
  258.     commands<<cmWIN_MAXIMIZE;
  259.     maximize_icon->set_cmd( cmWIN_MAXIMIZE );
  260.   }
  261.   if( state( wsMAXIMIZED ) )
  262.     maximize_icon->set_title( i_maximized );
  263.   else
  264.     maximize_icon->set_title( i_maximize );
  265. }
  266.  
  267. void Twindow::set_flags( uint _flags_word, boolean enable )
  268. {
  269.   Titem::set_flags( _flags_word, enable );
  270.   if( close_icon != NULL )
  271.     close_icon->set_state( isHIDDEN+isDISABLED, !flags( ifCLOSEABLE ) );
  272.   maximize_icon->set_state( isHIDDEN+isDISABLED, !flags( ifRESIZEABLE ) );
  273.   minimize_icon->set_state( isHIDDEN+isDISABLED, !flags( ifICONIZEABLE ) );
  274.   resize_icon->set_state( isHIDDEN+isDISABLED, !flags( ifRESIZEABLE ) );
  275.   flags( ifCLOSEABLE )? commands<<cmWIN_CLOSE : commands>>cmWIN_CLOSE;
  276.   flags( ifMOVABLE )? commands<<cmWIN_MOVE : commands>>cmWIN_MOVE;
  277.   flags( ifRESIZEABLE )? commands<<cmWIN_MAXIMIZE<<cmWIN_SIZE :
  278.                          commands>>cmWIN_MAXIMIZE>>cmWIN_SIZE;
  279.   flags( ifICONIZEABLE )? commands<<cmWIN_MINIMIZE : commands>>cmWIN_MINIMIZE;
  280. }
  281.  
  282. void Twindow::pop_up( void )
  283. {
  284.   if( owner != NULL ) owner->pop_item( this );
  285.   Titem::pop_up();
  286. }
  287.  
  288. void Twindow::drag( int newx, int newy )
  289. {
  290.   int xx, yy, gx, gy;
  291.  
  292.   owner->make_global( newx, newy, gx, gy );
  293.   if( gy < desktop_y ) gy = desktop_y;
  294.   if( gy >= scr_rows ) gy = scr_rows - 1;
  295.   xx = 0;
  296.   if( !state( isICONIZED ) )
  297.   {
  298.     if( flags( ifICONIZEABLE ) ) xx += i_minimize_len;
  299.     if( flags( ifRESIZEABLE ) )  xx += i_maximize_len;
  300.   }
  301.   if( ( gx + xl ) <= xx ) gx = xx - xl + 1;
  302.   xx = 0;
  303.   if( flags( ifCLOSEABLE ) && !state( isICONIZED ) ) xx = i_close_len;
  304.   if( gx >= ( (int) scr_columns - xx ) ) gx = scr_columns - xx - 1;
  305.   owner->make_local( gx, gy, xx, yy );
  306.   Titem::drag( xx, yy );
  307. }
  308.  
  309. void Twindow::resize( int newxl, int newyl )
  310. {
  311.   int xlmax, ylmax;
  312.   boolean was_maximized;
  313.  
  314.   xlmax = xl_max; if( !xlmax ) xlmax = desktop_xl;
  315.   ylmax = yl_max; if( !ylmax ) ylmax = desktop_yl;
  316.   was_maximized = state( wsMAXIMIZED );
  317.   direct_resize( newxl, newyl );
  318.   if( was_maximized && ( ( xl < xlmax ) || ( yl < ylmax ) ) )
  319.   {
  320.     x_saved = x;   y_saved = y;
  321.     xl_saved = xl; yl_saved = yl;
  322.     set_state( wsMAXIMIZED, 0 );
  323.   }
  324. }
  325.  
  326. boolean Twindow::valid( uint command )
  327. {
  328.   static boolean message_flag = 0;
  329.  
  330.   if( Titem::valid( command ) )
  331.     if( ( command != cmVALID ) /*|| !lowmemory */|| message_flag )
  332.       return 1;
  333.     else
  334.     {
  335.       return 1;
  336. //      message_flag = 1;
  337. //      _terror(); ok( "Sorry, memory not enough to complete request." );
  338. //      message_flag = 0;
  339.     }
  340.   return 0;
  341. }
  342.  
  343. void Twindow::put_in( Titem *v, int _x, int _y )
  344. {
  345.   Titem::put_in( v, _x, _y );
  346.   if( ( first() != close_icon ) && ( close_icon != NULL ) )
  347.     pop_item( close_icon );
  348.   if( frame_beg_flag )
  349.   {
  350.     frame_beg_flag = 0;
  351.     beg_frame_item = v;
  352.   }
  353.   end_frame_item = v;
  354. }
  355.  
  356. boolean Twindow::cenabled( uint cmd )
  357. {
  358.   return ( commands & cmd ) != 0;
  359. }
  360.  
  361. boolean Twindow::cdisabled( uint cmd )
  362. {
  363.   return ( commands & cmd ) == 0;
  364. }
  365.  
  366. void Twindow::cenable( uint cmd )
  367. {
  368.   if( commands & cmd ) return;
  369.   commands << cmd;
  370. }
  371.  
  372. void Twindow::cdisable( uint cmd )
  373. {
  374.   if( !( commands & cmd ) ) return;
  375.   commands >> cmd;
  376. }
  377.  
  378. void Twindow::cstate( uint cmd, boolean enable )
  379. {
  380.   if( enable ) cenable( cmd ); else cdisable( cmd );
  381. }
  382.  
  383. void Twindow::set_title( char *t )
  384. {
  385.   if( title != NULL ) FREE( title );
  386.   title = NULL;
  387.   if( ( t != NULL ) && ( *t != 0 ) ) title = STRDUP( t );
  388.   redraw();
  389. }
  390.  
  391. void Twindow::title2str( char *t, int max_len )
  392. {
  393.   if( title != NULL )
  394.     memcpy( t, title, max_len ),
  395.     t[max_len] = 0;
  396.   else
  397.     *t = 0;
  398. }
  399.  
  400. void Twindow::construct_frame( char *fr )
  401. {
  402.   int x_l, y_l;
  403.   char t[256];
  404.   char c1, c2, c3, l1, l2, rt, tl;
  405.  
  406.   x_l = 1;
  407.   if( !state( isICONIZED ) )
  408.   {
  409.     if( flags( ifICONIZEABLE ) ) x_l += i_minimize_len;
  410.     if( flags( ifRESIZEABLE ) ) x_l += i_maximize_len;
  411.   }
  412.   if( x_l < i_close_len+2 ) x_l = i_close_len+2;
  413.   title2str( t, xl - x_l - x_l - 2 );
  414.   x_l = xl - 2; y_l = yl - 2;
  415.   tl = strlen( t )+2;
  416.   l2 = (char) ( (xl-tl) >> 1 ); rt = (char) ( xl-l2-tl-1 );
  417.   l2 -= (l1=i_close_len)+1;
  418.   if( state( isACTIVE ) )
  419.   {
  420.     c1 = '6';
  421.     c2 = '1';
  422.   }
  423.   else
  424.   {
  425.     c1 = '5';
  426.     c2 = '0';
  427.   }
  428.   c3 = shortcut? shortcut+'0' : i_upper_frame;
  429.   if( state( isICONIZED ) )
  430.     sprintf( fr, "|%c|r%c%c%c|r%c%c %s |r%c%c%c",
  431.       c1, l1, i_upper_frame, c3, l2, i_upper_frame, t, rt, i_upper_frame, i_upper_frame_r
  432.     );
  433.   else
  434.     if( *t )
  435.       sprintf( fr, "|%c|r%c%c%c|r%c%c %s |r%c%c%c|n|%c%c|r%c%c%c|l%c%c|r%c%c%c",
  436.         c1, l1, i_upper_frame, c3, l2, i_upper_frame, t, rt, i_upper_frame, i_upper_frame_r,
  437.         c2, frame_normal[3], x_l, frame_normal[4], frame_normal[5], y_l,
  438.         frame_normal[6], x_l, frame_normal[7], frame_normal[8]
  439.       );
  440.     else
  441.       sprintf( fr, "|%c%c|r%c%c%c|n%c|r%c%c%c|l%c%c|r%c%c%c",
  442.         c2, frame_normal[0], x_l, frame_normal[1], frame_normal[2],
  443.         frame_normal[3], x_l, frame_normal[4], frame_normal[5], y_l,
  444.         frame_normal[6], x_l, frame_normal[7], frame_normal[8]
  445.       );
  446. }
  447.  
  448. void Twindow::construct_system_menu( void )
  449. {
  450.   if( flags( ifRESIZEABLE|ifICONIZEABLE ) )
  451. #ifdef CYR
  452.     mitem( "|~é║º▒▓á¡«ó¿", "Ctrl+F5 ", cmWIN_RESTORE );
  453. #else
  454.     mitem( "|~Restore", "Ctrl+F5 ", cmWIN_RESTORE );
  455. #endif
  456.   if( flags( ifMOVABLE ) )
  457. #ifdef CYR
  458.     mitem( "|~Å░ѼÑ▒▓¿", "Ctrl+F7 ", cmWIN_MOVE );
  459. #else
  460.     mitem( "|~Move", "Ctrl+F7 ", cmWIN_MOVE );
  461. #endif
  462.   if( flags( ifRESIZEABLE ) )
  463. #ifdef CYR
  464.     mitem( "|~ÉẼÑ░", "Ctrl+F8 ", cmWIN_SIZE );
  465. #else
  466.     mitem( "|~Size", "Ctrl+F8 ", cmWIN_SIZE );
  467. #endif
  468.   if( flags( ifICONIZEABLE ) )
  469. #ifdef CYR
  470.     mitem( "|~ꬫ¡á", "Ctrl+F9 ", cmWIN_MINIMIZE );
  471. #else
  472.     mitem( "Mi|~nimize", "Ctrl+F9 ", cmWIN_MINIMIZE );
  473. #endif
  474.   if( flags( ifRESIZEABLE ) )
  475. #ifdef CYR
  476.     mitem( "|~û┐½ Ñ¬░á¡", "Ctrl+F10", cmWIN_MAXIMIZE );
  477. #else
  478.     mitem( "Ma|~ximize", "Ctrl+F10", cmWIN_MAXIMIZE );
  479. #endif
  480.   if( flags( ifSELECTABLE ) || !state( isON_TOP ) )
  481. #ifdef CYR
  482.     mitem( "|~ìá ó║░╡á", on_top_flag, cmWIN_ON_TOP );
  483. #else
  484.     mitem( "On |~Top", on_top_flag, cmWIN_ON_TOP );
  485. #endif
  486.   if( flags( ifCLOSEABLE ) )
  487. #ifdef CYR
  488.     mitem( "|~çá▓ó«░¿", "Ctrl+F4 ", cmWIN_CLOSE );
  489. #else
  490.     mitem( "|~Close", "Ctrl+F4 ", cmWIN_CLOSE );
  491. #endif
  492. }
  493.  
  494. static Tframe *win_frame;
  495.  
  496. Titem *Twindow::frame( char *t )
  497. {
  498.   frame_beg_flag = 1;
  499.   win_frame = NEW( Tframe( t ) );
  500.   put_in( win_frame, 0, 0 );
  501.   return win_frame;
  502. }
  503.  
  504. Titem *Twindow::frame( void )
  505. {
  506.   return frame( "" );
  507. }
  508.  
  509. void Twindow::endfr( void )
  510. {
  511.   int n;
  512.   Titem *p;
  513.  
  514.   if( last == NULL ) return;
  515.   p = first();
  516.   while( p != end_frame_item ) p = p->next;
  517.   win_frame->drag( p->x + p->bound_x, p->y + p->bound_y );
  518.   win_frame->resize( p->bound_xl, p->bound_yl );
  519.   while( p != beg_frame_item )
  520.   {
  521.     p = p->next;
  522.     n = win_frame->x - ( p->x + p->bound_x );
  523.     if( n>0 )
  524.     {
  525.       win_frame->resize( win_frame->xl + n, win_frame->yl );
  526.       win_frame->drag( p->x + p->bound_x, win_frame->y );
  527.     }
  528.     n = win_frame->y - ( p->y + p->bound_y );
  529.     if( n>0 )
  530.     {
  531.       win_frame->resize( win_frame->xl, win_frame->yl + n );
  532.       win_frame->drag( win_frame->x, p->y + p->bound_y );
  533.     }
  534.     n = ( ( p->x + p->bound_x ) + p->bound_xl ) -
  535.           ( win_frame->x + win_frame->xl );
  536.     if( n>0 ) win_frame->resize( win_frame->xl + n, win_frame->yl );
  537.     n = ( ( p->y + p->bound_y ) + p->bound_yl ) -
  538.           ( win_frame->y + win_frame->yl );
  539.     if( n>0 ) win_frame->resize( win_frame->xl, win_frame->yl + n );
  540.   }
  541.   win_frame->resize( win_frame->xl + 2, win_frame->yl + 2 );
  542.   win_frame->drag( win_frame->x - 1, win_frame->y - 1 );
  543. }
  544.  
  545. //Twindow protected:
  546.  
  547. void Twindow::calc_bounds( int delta_xl, int delta_yl )
  548. {
  549.   int oxl, oyl, nxl, nyl, xx, yy;
  550.   boolean was_iconized, was_maximized;
  551.  
  552.   was_maximized = state( wsMAXIMIZED );
  553.   was_iconized  = state( isICONIZED );
  554.   set_state( wsMAXIMIZED+isICONIZED, 0 );
  555.   if( flags( ifRESIZEABLE ) )
  556.   {
  557.     maximize_icon->set_title( i_maximize );
  558.     maximize_icon->drag( xl - i_maximize_len, 0 );
  559.     resize_icon->drag( xl - i_resize_len, yl - 1 );
  560.   }
  561.   if( flags( ifICONIZEABLE ) )
  562.   {
  563.     nxl = xl-i_minimize_len;
  564.     if( flags( ifRESIZEABLE ) ) nxl -= i_maximize_len;
  565.     minimize_icon->drag( nxl, 0 );
  566.   }
  567.   if( delta_xl || delta_yl )
  568.   {
  569.     oxl = owner->xl; oyl = owner->yl;
  570.     nxl = oxl - delta_xl; nyl = oyl - delta_yl;
  571.     if( drag_mode & dmDRAG_REL )
  572.     {
  573.       xx = ( x * oxl ) / nxl;
  574.       yy = ( y * oyl ) / nyl;
  575.       if( !( drag_mode & dmDRAG_HOR ) )
  576.         xx = x,
  577.         icon_x = ( icon_x * oxl ) / nxl;
  578.       if( !( drag_mode & dmDRAG_VER ) )
  579.         yy = y,
  580.         icon_y = ( icon_y * oyl ) / nyl;
  581.       drag( xx, yy );
  582.     }
  583.     nxl = xl; nyl = yl;
  584.     if( grow_mode & gmGROW_REL )
  585.     {
  586.       if( !( grow_mode & gmGROW_HOR ) )
  587.         xl_saved = ( xl_saved * oxl ) / nxl,
  588.         nxl = ( xl * oxl ) / nxl;
  589.       if( !( grow_mode & gmGROW_VER ) )
  590.         yl_saved = ( yl_saved * oyl ) / nyl,
  591.         nyl = ( yl * oyl ) / nyl;
  592.       if( ( ( x + xl ) <= nxl ) && ( ( x + nxl ) > oxl ) ) nxl = oxl - x;
  593.       if( ( ( y + yl ) <= nyl ) && ( ( y + nyl ) > oyl ) ) nyl = oyl - y;
  594.     }
  595.     resize( nxl,nyl );
  596.   }
  597.   if( was_maximized ) set_state( wsMAXIMIZED, 1 );
  598.   if( was_iconized  ) set_state( isICONIZED, 1 );
  599. }
  600.  
  601. void Twindow::set_palette( void )
  602. {
  603.   switch( palette )
  604.   {
  605.     case wpSTANDARD:
  606.       text_attr = pal_windows.standard_normal;
  607.       bold_attr = pal_windows.standard_bold;
  608.       selected_attr = pal_windows.standard_selected;
  609.       disabled_attr = pal_windows.standard_disabled;
  610.       break;
  611.     case wpEDITOR:
  612.       text_attr = pal_windows.editor_normal;
  613.       bold_attr = pal_windows.editor_bold;
  614.       selected_attr = pal_windows.editor_selected;
  615.       disabled_attr = pal_windows.editor_disabled;
  616.       break;
  617.     case wpTOOL:
  618.       text_attr = pal_windows.tool_normal;
  619.       bold_attr = pal_windows.tool_bold;
  620.       selected_attr = pal_windows.tool_selected;
  621.       disabled_attr = pal_windows.tool_disabled;
  622.       break;
  623.     case wpHELP:
  624.       text_attr = pal_windows.help_normal;
  625.       bold_attr = pal_windows.help_bold;
  626.       selected_attr = pal_windows.help_selected;
  627.       disabled_attr = pal_windows.help_disabled;
  628.       break;
  629.     case wpALERT:
  630.       text_attr = pal_windows.alert_normal;
  631.       bold_attr = pal_windows.alert_bold;
  632.       selected_attr = pal_windows.alert_selected;
  633.       disabled_attr = pal_windows.alert_disabled;
  634.       break;
  635.   }
  636.   shortcut_attr = pal_windows.shortcut;
  637.   attr[0] = (char) ( ( text_attr & 0xF0 ) | pal_windows.frame_normal );
  638.   attr[1] = (char) ( ( text_attr & 0xF0 ) | pal_windows.frame_selected );
  639.   attr[2] = pal_windows.icon_normal;
  640.   attr[3] = pal_windows.icon_selected;
  641.   attr[4] = pal_windows.icon_pressed;
  642.   attr[5] = pal_windows.title_normal;
  643.   attr[6] = pal_windows.title_selected;
  644. }
  645.  
  646. void Twindow::draw( void )
  647. {
  648.   char window_frame[256];
  649.  
  650.   construct_frame( window_frame );
  651.   txt( window_frame );
  652. }
  653.  
  654. void Twindow::initialize( void )
  655. {
  656.   Titem::initialize();
  657.   close_icon = NEW( Tclose_icon( this ) );
  658.   put_in( close_icon, 0, 0 );
  659.   if( !shortcut && owner==desktop && flags( ifSELECTABLE ) && !state( isHIDDEN ) )
  660.     for( char i=1; i<=9; i++ )
  661.       if( !( win_nums & i ) )
  662.       {
  663.         win_nums<<i;
  664.         shortcut = i;
  665.         break;
  666.       }
  667. }
  668.  
  669. void Twindow::get_focused( void )
  670. {
  671.   Titem::get_focused();
  672.   set_cmd( &commands );
  673.   set_context( local_tools );
  674. }
  675.  
  676. boolean Twindow::release_focus( void )
  677. {
  678.   if( Titem::release_focus() )
  679.   {
  680.     set_cmd( NULL );
  681.     set_context( 0 );
  682.     return 1;
  683.   }
  684.   return 0;
  685. }
  686.  
  687. void Twindow::event_handler( Tevent &ev )
  688. {
  689.   int restore_x, restore_y, restore_xl, restore_yl, tmpx, tmpy;
  690.   Tevent ev1;
  691.   boolean selected, iconized, moved;
  692.   Tmoving *mv_ptr;
  693.   uint mask_svd, old_shifts;
  694.  
  695.   Titem::event_handler( ev );
  696.   iconized = state( isICONIZED );
  697.   selected = state( isSELECTED|isMODAL ) && !state( isHIDDEN );
  698.   switch( ev.code )
  699.   {
  700.     case evCOMMAND:
  701.       if( ( ev.destination == this ) || selected )
  702.       {
  703.         switch( ev.CMD_CODE )
  704.         {
  705.           case cmWIN_CLOSE:
  706.             if( flags( ifCLOSEABLE ) ) put_command( this, cmDONE );
  707.             break;
  708.           case cmWIN_MOVE:
  709.             if( !flags( ifMOVABLE ) ) break;
  710.           case cmWIN_SIZE:
  711.             moved = 1;
  712.             if( ev.CMD_CODE == cmWIN_SIZE )
  713.             {
  714.               moved = 0;
  715.               if( !flags( ifRESIZEABLE ) ) break;
  716.             }
  717.             mv_ptr = NEW( Tmoving( moved ) );
  718.             owner->put_in( mv_ptr, xCENTER, owner->yl - 6 );
  719.             old_shifts = get_shifts();
  720.             put_shifts( old_shifts & ~smNUM );
  721.             restore_x  = x;  restore_y  = y;
  722.             restore_xl = xl; restore_yl = yl;
  723.             do
  724.             {
  725.               get_key( ev, evKEY_PRESS );
  726.               if( moved )
  727.                 switch( ev.ASCII )
  728.                 {
  729.                   case kUP:
  730.                     drag( x, y - 1 ); break;
  731.                   case kDOWN:
  732.                     drag( x, y + 1 ); break;
  733.                   case kLEFT:
  734.                     drag( x - 1, y ); break;
  735.                   case kRIGHT:
  736.                     drag( x + 1, y ); break;
  737.                   case kPG_UP:
  738.                     drag( x, 0 ); break;
  739.                   case kPG_DN:
  740.                     drag( x, owner->yl - yl ); break;
  741.                   case kHOME:
  742.                     drag( 0, y ); break;
  743.                   case kEND:
  744.                     drag( owner->xl - xl, y ); break;
  745.                   case kESC:
  746.                     drag( restore_x, restore_y );
  747.                 }
  748.               else
  749.                 switch( ev.ASCII )
  750.                 {
  751.                   case kUP:
  752.                     direct_resize( xl, yl - 1 ); break;
  753.                   case kDOWN:
  754.                     direct_resize( xl, yl + 1 ); break;
  755.                   case kLEFT:
  756.                     direct_resize( xl - 1, yl ); break;
  757.                   case kRIGHT:
  758.                     direct_resize( xl + 1, yl ); break;
  759.                   case kESC:
  760.                     direct_resize( restore_xl, restore_yl );
  761.                 }
  762.             }
  763.             while( ( ev.ASCII != kENTER ) && ( ev.ASCII != kESC ) );
  764.           _break:
  765.             tmpx = xl; tmpy = yl;
  766.             direct_resize( restore_xl, restore_yl );
  767.             resize( tmpx, tmpy );
  768.             DELETE( mv_ptr );
  769.             put_shifts( old_shifts & ~( smSCROLL+smCTRL+smLCTRL ) );
  770.             break;
  771.           case cmWIN_MAXIMIZE:
  772.             if( flags( ifRESIZEABLE ) ) set_state( wsMAXIMIZED, 1 );
  773.             break;
  774.           case cmWIN_MINIMIZE:
  775.             if( flags( ifICONIZEABLE ) ) set_state( isICONIZED, 1 );
  776.             break;
  777.           case cmWIN_RESTORE:
  778.             set_state( isICONIZED, 0 );
  779.             set_state( wsMAXIMIZED, 0 );
  780.             break;
  781.           case cmWIN_ON_TOP:
  782.             set_state( isON_TOP, !state( isON_TOP ) );
  783.             break;
  784.           default:
  785.             goto hot1;
  786.         }
  787.         handled( ev );
  788.       }
  789.     hot1:
  790.       break;
  791.     case evKEY_PRESS:
  792.       if( state( isFOCUSED ) )
  793.       {
  794.         switch( ev.ASCII )
  795.         {
  796.           case kCTRL_F4:
  797.             message( this, cmWIN_CLOSE ); break;
  798.           case kENTER:
  799.             if( !iconized ) goto hot;
  800.           case kCTRL_F5:
  801.             message( this, cmWIN_RESTORE ); break;
  802.           case kCTRL_F7:
  803.             message( this, cmWIN_MOVE ); break;
  804.           case kCTRL_F8:
  805.             message( this, cmWIN_SIZE ); break;
  806.           case kCTRL_F9:
  807.             message( this, cmWIN_MINIMIZE );
  808.             owner->tab_next( 0 );
  809.             while( owner->current!=NULL &&
  810.                    owner->current!=this &&
  811.                    owner->current->state( isICONIZED ) ) owner->tab_next( 0 );
  812.             break;
  813.           case kCTRL_F10:
  814.             message( this, cmWIN_MAXIMIZE ); break;
  815.           default:
  816.             goto hot;
  817.         }
  818.         handled( ev );
  819.         break;
  820.       }
  821.     hot:
  822.       if( shortcut && ev.ASCII==kALT_1+((shortcut-1)<<8) )
  823.       {
  824.         set_state( isICONIZED, 0 );
  825.         focus();
  826.         handled( ev );
  827.         break;
  828.       }
  829.       if( iconized )
  830.       {
  831.         if( ev.ASCII==kALT_SPACE )
  832.         {
  833.           do_system_menu();
  834.           handled( ev );
  835.         }
  836.         break;
  837.       }
  838.       if( selected )
  839.       {
  840.         if( ev.ASCII <= 255 )
  841.         {
  842.           ev1 = ev;
  843.           if( ( ev1.ASCII = lat2alt( ev1.ASCII ) ) != 0 )
  844.           {
  845.             mask_svd = event_mask; event_mask = 0;
  846.             handle_event( ev1 );
  847.             event_mask = mask_svd;
  848.             if( ev1.code == evNOTHING ) handled( ev );
  849.           }
  850.         }
  851.         if( ev.code != evNOTHING )
  852.         {
  853.           switch ( ev.ASCII )
  854.           {
  855.             case kTAB:
  856.             case kSHIFT_TAB:
  857.               tab_next( ev.ASCII == kSHIFT_TAB ); break;
  858.             case kUP:
  859.             case kLEFT:
  860.             case kDOWN:
  861.             case kRIGHT:
  862.               local_next( ( ev.ASCII == kUP ) || ( ev.ASCII == kLEFT ) ); break;
  863.             default:
  864.               goto hot2;
  865.           }
  866.           handled( ev );
  867.         }
  868.       }
  869.     hot2:
  870.       break;
  871. #ifndef NOMOUSE
  872.       case evMOUSE_DOWN:
  873.         if( ev.INSIDE )
  874.         {
  875.           handled( ev );
  876.           owner->pop_item( this );
  877.           if( !ev.LOCAL_Y )
  878.             if( ev.CLICKS )
  879.               if( !state( isICONIZED ) && !state( wsMAXIMIZED ) )
  880.                 message( this, cmWIN_MAXIMIZE );
  881.               else
  882.                 message( this, cmWIN_RESTORE );
  883.             else
  884.             {
  885.               int delta_x = ev.LOCAL_X;
  886.               moved = 0;
  887.               while( get_mouse( ev, evMOUSE_DRAG ) )
  888.               {
  889.                 owner->make_local( ev.GLOBAL_X, ev.GLOBAL_Y, tmpx, tmpy );
  890.                 drag( tmpx - delta_x, tmpy );
  891.                 moved = 1;
  892.               }
  893.               if( !moved ) do_system_menu();
  894.             }
  895.           else
  896.             if( !iconized && flags( ifRESIZEABLE ) &&
  897.                 ( ev.LOCAL_Y == ( yl - 1 ) ) &&
  898.                 ( ev.LOCAL_X >= xl - i_resize_len ) )
  899.             {
  900.               restore_xl = xl; restore_yl = yl;
  901.               resize_icon->pressed = 1;
  902.               resize_icon->redraw();
  903.               while( get_mouse( ev, evMOUSE_DRAG ) )
  904.                 direct_resize( ev.LOCAL_X + 1, ev.LOCAL_Y + 1 );
  905.               resize_icon->pressed = 0;
  906.               resize_icon->redraw();
  907.               tmpx = xl; tmpy = yl;
  908.               direct_resize( restore_xl, restore_yl );
  909.               resize( tmpx, tmpy );
  910.             }
  911.         }
  912.         break;
  913. #endif
  914.     }
  915. }
  916.  
  917. void Twindow::direct_resize( int newxl, int newyl )
  918. {
  919.   int xlmin, ylmin, xlmax, ylmax;
  920.  
  921.   if( state( isICONIZED ) ) return;
  922.   xlmin = xl_min; ylmin = yl_min; xlmax = xl_max; ylmax = yl_max;
  923.   if( !xlmin ) xlmin = 23;
  924.   if( !ylmin ) ylmin = 5;
  925.   if( !xlmax ) xlmax = desktop_xl;
  926.   if( !ylmax ) ylmax = desktop_yl;
  927.   if( newyl < ylmin ) newyl = ylmin;
  928.   if( newyl > ylmax ) newyl = ylmax;
  929.   if( newxl < xlmin ) newxl = xlmin;
  930.   if( newxl > xlmax ) newxl = xlmax;
  931.   Titem::resize( newxl, newyl );
  932. }
  933.  
  934. void Twindow::do_system_menu( void )
  935. {
  936.   Tmenu_box *m;
  937.   int xx,yy;
  938.   Tcommands *saved_cmd;
  939.  
  940.   if( state( isICONIZED ) )
  941.   {
  942.     saved_cmd = get_cmd();
  943.     set_cmd( &commands );
  944.     m = construct_menu_box( close_icon->menu->items->what.submenu );
  945.     m->client = this;
  946.     make_global( 0, -m->yl, xx, yy );
  947.     if( yy < 0 ) yy += m->yl + 1;
  948.     application->make_local( xx, yy, xx, yy );
  949.     application->put_in( m, xx, yy );
  950.     show_menu_cursor( m->menu );
  951.     m->exec();
  952.     m->menu = NULL;
  953.     set_cmd( saved_cmd );
  954.   }
  955. }
  956.  
  957. //Tmoving publics:
  958.  
  959. Tmoving::Tmoving( boolean _move_or_resize ):
  960.   Titem( 40, 4 )
  961. {
  962.   set_events_mask( (uint)-1, 0 );
  963.   set_flags( (uint)-1, 0 ); set_flags( ifVISIBLE, 1 );
  964.   set_state( isON_TOP, 1 );
  965.   move_or_resize = _move_or_resize;
  966. }
  967.  
  968. //Tmoving protected:
  969.  
  970. void Tmoving::set_palette( void )
  971. {
  972.   text_attr = pal_windows.help_normal;
  973.   bold_attr = pal_windows.help_bold;
  974.   selected_attr = (char) ( pal_windows.frame_selected | ( text_attr & 0xF0 ) );
  975. }
  976.  
  977. void Tmoving::draw( void )
  978. {
  979. #ifdef CYR
  980.   static char m[] = "»░ѼÑ▒▓Ñ▓Ñ";
  981.   static char s[] = "»░«¼Ñ¡Ñ▓Ñ ";
  982. #else
  983.   static char m[] = "move";
  984.   static char s[] = "size";
  985. #endif
  986.   char *what;
  987.  
  988.   what = s;
  989.   if( move_or_resize ) what = m;
  990. #ifdef CYR
  991.   txtf( "|s%c|r\046%c%c|n%c|t ù░Ѻ ▒▓░ѽ¬¿▓Ñ %s »░«º«░Ñ╢á, |s%c|n%c|t      ¡á▓¿▒¡Ñ▓Ñ <|bEnter|t> ºá ¬░á⌐.      |s%c|n%c|r\046%c%c",
  992. #else
  993.   txtf( "|s%c|r\046%c%c|n%c|t  Use arrow keys to %s the window,  |s%c|n%c|t       press <|bEnter|t> when done.       |s%c|n%c|r\046%c%c",
  994. #endif
  995.   frame_normal[0],frame_normal[1],frame_normal[2],frame_normal[3],
  996.   what,
  997.   frame_normal[5],frame_normal[3],frame_normal[5],frame_normal[6],
  998.   frame_normal[7],frame_normal[8] );
  999. }
  1000.  
  1001. //Tframe publics:
  1002.  
  1003. Tframe::Tframe( char *t ):
  1004.   Tbox( t, NULL )
  1005. {
  1006.   set_events_mask( (uint)-1, 0 );
  1007. }
  1008.  
  1009. //Tframe protected:
  1010.  
  1011. void Tframe::set_palette( void )
  1012. {
  1013.   Tbox::set_palette();
  1014.   bold_attr = text_attr;
  1015. }
  1016.  
  1017. //Tscroll_window publics:
  1018.  
  1019. Tscroll_window::Tscroll_window( uint &hbeg_print, uint &hcount,
  1020.                                 uint &vbeg_print, uint &vcount,
  1021.                                 int delta_h,
  1022.                                 char *t, Titem *item ):
  1023.   Twindow( t, item->xl + i_sb_up_len + 1, item->yl + 2 )
  1024. {
  1025.   vbar = NEW( Tvscroll_bar( item->yl, vcount, vbeg_print ) );
  1026.     vbar->set_flags( sfHIDEABLE+sfHANDLE_KEYBOARD, 0 );
  1027.     item->put_in( vbar, item->xl, 0 );
  1028.   hbar = NEW( Thscroll_bar( item->xl - delta_h + 1, hcount, hbeg_print ) );
  1029.     hbar->set_flags( sfHIDEABLE+sfHANDLE_KEYBOARD, 0 );
  1030.     item->put_in( hbar, delta_h - 1, item->yl );
  1031.   commands<<cmUP_ARROW<<cmDOWN_ARROW<<cmLEFT_ARROW<<cmRIGHT_ARROW;
  1032.   put_in( item, 1, 1 );
  1033.   palette = wpEDITOR;
  1034. }
  1035.  
  1036. //Tfile_window publics:
  1037.  
  1038. Tfile_window::Tfile_window( uint &hbeg_print, uint &hcount,
  1039.                             uint &vbeg_print, uint &vcount,
  1040.                             int delta_h,
  1041.                             char *t, Titem *item ):
  1042.   Tscroll_window( hbeg_print, hcount, vbeg_print, vcount, delta_h, t, item )
  1043. {
  1044. }
  1045.  
  1046. void Tfile_window::title2str( char *t, int max_len )
  1047. {
  1048.   if( ( title == NULL ) || ( *title == 0 ) ||
  1049.       ( title[1] != ':' ) || ( title[2] != '\\' ) )
  1050.     Tscroll_window::title2str( t, max_len );
  1051.   else
  1052.   {
  1053.     strcpy( t, title );
  1054.     min_path( t );
  1055.     short_path( t, max_len );
  1056.   }
  1057. }
  1058.  
  1059. //PREFIXES
  1060.  
  1061. static char palette_ = 0;
  1062. static int context_ = 0;
  1063.  
  1064. /*
  1065.   Description:
  1066.     Specify standard palette for dialog box. Call just before a call to
  1067.     'dialog'.
  1068. */
  1069. void _pstandard( void )
  1070. {
  1071.   if( !palette_ ) palette_ = wpSTANDARD;
  1072. }
  1073.  
  1074. /*
  1075.   Description:
  1076.     Specify editor palette for dialog box. Call just before a call to
  1077.     'dialog'.
  1078. */
  1079.  
  1080. void _peditor( void )
  1081. {
  1082.   if( !palette_ ) palette_ = wpEDITOR;
  1083. }
  1084.  
  1085. /*
  1086.   Description:
  1087.     Specify help palette for dialog box. Call just before a call to
  1088.     'dialog'.
  1089. */
  1090. void _ptool( void )
  1091. {
  1092.   if( !palette_ ) palette_ = wpTOOL;
  1093. }
  1094.  
  1095. /*
  1096.   Description:
  1097.     Specify help palette for dialog box. Call just before a call to
  1098.     'dialog'.
  1099. */
  1100. void _phelp( void )
  1101. {
  1102.   if( !palette_ ) palette_ = wpHELP;
  1103. }
  1104.  
  1105. /*
  1106.   Description:
  1107.     Specify alert palette for dialog box. Call just before a call to
  1108.     'dialog'.
  1109. */
  1110. void _palert( void )
  1111. {
  1112.   if( !palette_ ) palette_ = wpALERT;
  1113. }
  1114.  
  1115. char __palette( void )
  1116. {
  1117.   char result = wpSTANDARD;
  1118.  
  1119.   if( palette_ ) result = palette_;
  1120.   palette_ = 0;
  1121.   return result;
  1122. }
  1123.  
  1124. /*
  1125.   Description:
  1126.     Specify toolbox number of the window that is about to be constructed.
  1127.   Entry:
  1128.     tools_num - toolbox number.
  1129. */
  1130. void _context( int context )
  1131. {
  1132.   if( !context_ ) context_ = context;
  1133. }
  1134.  
  1135. int __context( void )
  1136. {
  1137.   int result;
  1138.  
  1139.   result = context_;
  1140.   context_ = 0;
  1141.   return result;
  1142. }
  1143.