Beispiel #1
0
Handle
Application_top_frame( Handle self, Handle from)
{
   while ( from) {
      if ( kind_of( from, CWindow) &&
             (( PWidget( from)-> owner == application) || !CWidget( from)-> get_clipOwner(from))
         )
         return from;
      from = PWidget( from)-> owner;
   }
   return application;
}
Beispiel #2
0
/* checks if Handle in is allowed to be a master for self -
   used for gt::Pack */
static Handle
Widget_check_in( Handle self, Handle in, Bool barf)
{
   Handle h = in;

   /* check overall validity */
   if ( !in || !kind_of( in, CWidget)) {
      if ( barf)
         croak("%s: invalid 'in': not a widget", "RTC008F: Prima::Widget::pack");
      else
         return nilHandle;
   }

   /* check direct inheritance */
   while ( h) {
      if ( h == self) {
         if ( barf)
            croak("%s: invalid 'in': is already a child", "RTC008F: Prima::Widget::pack");
         else
            return nilHandle;
      }
      h = PWidget( h)-> owner;
   }

   /* check slaves chain */
   h = PWidget( in)-> packSlaves;
   while ( h) {
      if ( h == in) {
         if ( barf)
            croak("%s: invalid 'in': already a pack slave", "RTC008F: Prima::Widget::pack");
         else
            return nilHandle;
      }
      h = PWidget( h)-> geomInfo. next;
   }
   
   h = PWidget( in)-> placeSlaves;
   while ( h) {
      if ( h == in) {
         if ( barf)
            croak("%s: invalid 'in': already a place slave", "RTC008F: Prima::Widget::pack");
         else
            return nilHandle;
      }
      h = PWidget( h)-> geomInfo. next;
   }

   /* place to check other chains if needed */

   return in;
}
Beispiel #3
0
static int
do_taborder_candidates( Handle level, Handle who,
                        int (*compareProc)(const void *, const void *),
                        int * stage, Handle * result)
{
    int i, fsel = -1;
    PList w = &(PWidget( level)-> widgets);
    Handle * ordered;

    if ( w-> count == 0) return true;

    ordered = ( Handle *) malloc( w-> count * sizeof( Handle));
    if ( !ordered) return true;

    memcpy( ordered, w-> items, w-> count * sizeof( Handle));
    qsort( ordered, w-> count, sizeof( Handle), compareProc);

    /* finding current widget in the group */
    for ( i = 0; i < w-> count; i++) {
        Handle x = ordered[i];
        if ( CWidget( x)-> get_current( x)) {
            fsel = i;
            break;
        }
    }
    if ( fsel < 0) fsel = 0;

    for ( i = 0; i < w-> count; i++) {
        int j;
        Handle x;

        j = i + fsel;
        if ( j >= w-> count) j -= w-> count;

        x = ordered[j];
        if ( CWidget( x)-> get_visible( x) && CWidget( x)-> get_enabled( x)) {
            if ( CWidget( x)-> get_selectable( x) && CWidget( x)-> get_tabStop( x)) {
                if ( *result == nilHandle) *result = x;
                switch( *stage) {
                case 0: /* nothing found yet */
                    if ( x == who) *stage = 1;
                    break;
                default:
                    /* next widget after 'who' is ours */
                    *result = x;
                    free( ordered);
                    return false;
                }
            }
            if ( !do_taborder_candidates( x, who, compareProc, stage, result)) {
                free( ordered);
                return false; /* fall through */
            }
        }
    }
    free( ordered);
    return true;
}
Beispiel #4
0
void
Application_set_hint_action( Handle self, Handle view, Bool show, Bool byMouse)
{
   if ( show && !is_opt( optShowHint)) return;
   if ( show)
   {
      var->  hintUnder = view;
      if ( var->  hintActive == -1)
      {
         Event ev = {cmHint};
         ev. gen. B = true;
         ev. gen. H = view;
         ((( PTimer) var->  hintTimer)-> self)-> stop( var-> hintTimer);
         var->  hintVisible = 1;
         if (( PWidget( view)-> stage == csNormal) &&
             ( CWidget( view)-> message( view, &ev)))
             hshow( self);
      } else {
         if ( !byMouse && var->  hintActive == 1) return;
         CTimer( var->  hintTimer)-> start( var-> hintTimer);
      }
      var->  hintActive = 1;
   } else {
      int oldHA = var->  hintActive;
      int oldHV = var->  hintVisible;
      if ( oldHA != -1)
         ((( PTimer) var-> hintTimer)-> self)-> stop( var-> hintTimer);
      if ( var->  hintVisible)
      {
         Event ev = {cmHint};
         ev. gen. B = false;
         ev. gen. H = view;
         var->  hintVisible = 0;
         if (( PWidget( view)-> stage != csNormal) ||
              ( CWidget( view)-> message( view, &ev)))
            CWidget( var->  hintWidget)-> hide( var->  hintWidget);
      }
      if ( oldHA != -1) var->  hintActive = 0;
      if ( byMouse && oldHV) {
         var->  hintActive = -1;
         CTimer( var->  hintTimer)-> start( var->  hintTimer);
      }
   }
}
Beispiel #5
0
Handle
Widget_currentWidget( Handle self, Bool set, Handle widget)
{
    enter_method;
    if ( var-> stage > csFrozen) return nilHandle;
    if ( !set)
        return var-> currentWidget;
    if ( widget) {
        if ( !widget || ( PWidget( widget)-> stage > csFrozen) ||
                ( PWidget( widget)-> owner != self)
           ) return nilHandle;
        var-> currentWidget = widget;
    } else
        var-> currentWidget = nilHandle;

    /* adjust selection if we're in currently selected chain */
    if ( my-> get_selected( self))
        my-> set_selectedWidget( self, widget);
    return nilHandle;
}
Beispiel #6
0
Handle
Widget_selectedWidget( Handle self, Bool set, Handle widget)
{
    if ( var-> stage > csFrozen) return nilHandle;

    if ( !set) {
        if ( var-> stage <= csNormal) {
            Handle foc = apc_widget_get_focused();
            PWidget  f = ( PWidget) foc;
            while( f) {
                if (( Handle) f == self) return foc;
                f = ( PWidget) f-> owner;
            }
        }
        return nilHandle;

        /* classic solution should be recursive and inheritant call */
        /* of get_selected() here, when Widget would return state of */
        /* child-group selected state until Widget::selected() called; */
        /* thus, each of them would call apc_widget_get_focused - that's expensive, */
        /* so that's the reason not to use classic object model here. */
    }

    if ( widget) {
        if ( PWidget( widget)-> owner == self)
            CWidget( widget)-> set_selected( widget, true);
    } else {
        /* give selection up to hierarchy chain */
        Handle s = self;
        while ( s) {
            if ( CWidget( s)-> get_selectable( s)) {
                CWidget( s)-> set_selected( s, true);
                break;
            }
            s = PWidget( s)-> owner;
        }
    }
    return nilHandle;
}
Beispiel #7
0
Handle
Widget_next_tab( Handle self, Bool forward)
{
    Handle horizon = self, result = nilHandle;
    int stage = 0;

    while ( PWidget( horizon)-> owner) {
        if (
            ( PWidget( horizon)-> options. optSystemSelectable) || /* fast check for CWindow */
            ( PWidget( horizon)-> options. optModalHorizon)
        ) break;
        horizon = PWidget( horizon)-> owner;
    }

    if ( !CWidget( horizon)-> get_visible( horizon) ||
            !CWidget( horizon)-> get_enabled( horizon)) return nilHandle;

    do_taborder_candidates( horizon, self,
                            forward ? compare_taborders_forward : compare_taborders_backward,
                            &stage, &result);
    if ( result == self) result = nilHandle;
    return result;
}
Beispiel #8
0
static int
get_cursor( Handle self, Pixmap *source, Pixmap *mask, Point *hot_spot, Cursor *cursor)
{
	int id = X(self)-> pointer_id;

	while ( self && ( id = X(self)-> pointer_id) == crDefault)
		self = PWidget(self)-> owner;
	if ( id == crDefault) {
		id = crArrow;
	} else if ( id == crUser) {
		if (source)       *source   = X(self)-> user_p_source;
		if (mask)         *mask     = X(self)-> user_p_mask;
		if (hot_spot)     *hot_spot = X(self)-> pointer_hot_spot;
		if (cursor)       *cursor   = X(self)-> user_pointer;
	}

	return id;
}
Beispiel #9
0
static void
perform_pending_paints( void)
{
   PDrawableSysData selfxx, next;

   for ( XX = TAILQ_FIRST( &guts.paintq); XX != nil; ) {
      next = TAILQ_NEXT( XX, paintq_link);
      if ( XX-> flags. paint_pending && (guts. appLock == 0) &&
         (PWidget( XX->self)-> stage == csNormal)) {
         TAILQ_REMOVE( &guts.paintq, XX, paintq_link);
         XX-> flags. paint_pending = false;
         prima_simple_message( XX-> self, cmPaint, false);
         /* handle the case where this widget is locked */
         if (XX->invalid_region) {
            XDestroyRegion(XX->invalid_region);
            XX->invalid_region = nil;
         }
      } 
      XX = next;
   }
}
Beispiel #10
0
void
Application_HintTimer_handle_event( Handle timer, PEvent event)
{
   CComponent-> handle_event( timer, event);
   if ( event-> cmd == cmTimer) {
      Handle self = application;
      CTimer(timer)-> stop( timer);
      if ( var->  hintActive == 1) {
         Event ev = {cmHint};
         if (   !var->hintUnder
             || apc_application_get_widget_from_point( self,
                   my-> get_pointerPos(self)) != var->hintUnder
             || PObject( var-> hintUnder)-> stage != csNormal)
            return;
         ev. gen. B = true;
         ev. gen. H = var->  hintUnder;
         var->  hintVisible = 1;
         if (( PWidget( var->  hintUnder)-> stage == csNormal) &&
             ( CWidget( var->  hintUnder)-> message( var->  hintUnder, &ev)))
             hshow( self);
      } else if ( var->  hintActive == -1)
         var->  hintActive = 0;
   }
}
Beispiel #11
0
LRESULT CALLBACK generic_view_handler( HWND win, UINT  msg, WPARAM mp1, LPARAM mp2)
{
   LRESULT ret = 0;
   Handle  self   = GetWindowLongPtr( win, GWLP_USERDATA);
   PWidget v      = ( PWidget) self;
   UINT    orgMsg = msg;
   Event   ev;
   Bool    hiStage   = false;
   int     i, orgCmd;
   Bool    message_result = true;

   if ( !self || appDead)
      return DefWindowProcW( win, msg, mp1, mp2);

   memset( &ev, 0, sizeof (ev));
   ev. gen. source = self;

   switch ( msg) {
   case WM_NCACTIVATE:
        // if activation or deactivation is concerned with declipped window ( e.g.self),
        // notify its top level frame so that it will have the chance to redraw itself correspondingly
        if ( is_declipped_child( self) && !Widget_is_child( hwnd_to_view(( HWND) mp2), hwnd_top_level( self))) {
           Handle x = hwnd_top_level( self);
           if ( x) SendMessage( DHANDLE( x), WM_NCACTIVATE, mp1, mp2);
        }   
        break;
   case WM_MOUSEACTIVATE:
       // if pointing to non-active frame, but its declipped child is active at the moment,
       // cancel activation - it could produce unwilling focus changes
       if ( sys className == WC_FRAME) {
          Handle x = hwnd_to_view( GetActiveWindow());
          if ( is_declipped_child(x) && Widget_is_child( x, self))
             return MA_NOACTIVATE;
       }
       break;
   case WM_CLOSE:
      if ( sys className != WC_FRAME)
         return 0;
      break;
   case WM_COMMAND:
      if (( HIWORD( mp1) == 0 /* menu source */) && ( mp2 == 0)) {
          if ( LOWORD( mp1) <= MENU_ID_AUTOSTART) {
             HWND active = GetFocus();
             if ( active != nil) SendMessage( active, LOWORD( mp1), 0, 0);
          } else if ( sys lastMenu) {
             PAbstractMenu a = ( PAbstractMenu) sys lastMenu;
             if ( a-> stage <= csNormal)
                a-> self-> sub_call_id(( Handle) a, LOWORD( mp1) - MENU_ID_AUTOSTART);
          }
      }
      break;
   case WM_CONTEXTMENU:
      {
         POINT a;
	 a. x = ( short)LOWORD( mp2);
	 a. y = ( short)HIWORD( mp2);
         ev. cmd       = cmPopup;
         // mouse event
         ev. gen. B    = ( GetKeyState( VK_LBUTTON) < 0) | ( GetKeyState( VK_RBUTTON) < 0);
         if ( !ev. gen. B && GetSystemMetrics( SM_MOUSEPRESENT))
            GetCursorPos(( POINT*) &a);

         MapWindowPoints( NULL, win, &a, 1);
         ev. gen. P. x = a. x;
         ev. gen. P. y = sys lastSize. y - a. y - 1;
      }
      break;
   case WM_ENABLE:
      ev. cmd = mp1 ? cmEnable : cmDisable;
      hiStage = true;
      break;
   case WM_ERASEBKGND:
      return 1;
   case WM_FORCEFOCUS:
      if ( mp2)
         ((( PWidget) mp2)-> self)-> set_selected(( Handle) mp2, 1);
      return 0;
   case WM_HASMATE:
      *(( Handle*) mp2) = self;
      return HASMATE_MAGIC;
   case WM_IME_CHAR:
      if ( apc_widget_is_responsive( self)) {
         ev. cmd = cmKeyDown;
         ev. key. mod  = kmUnicode;
         ev. key. key  = kbNoKey;
         ev. key. code = mp1;
      }
      break;
   case WM_SYSKEYDOWN:
   case WM_SYSKEYUP:
      if ( mp2 & ( 1 << 29)) ev. key. mod = kmAlt;
   case WM_KEYDOWN:
   case WM_KEYUP:
      if ( apc_widget_is_responsive( self)) {
          BYTE * keyState;
          Bool up = ( msg == WM_KEYUP) || ( msg == WM_SYSKEYUP);
          Bool extended = mp2 & ( 1 << 24);
          UINT scan = ( HIWORD( mp2) & 0xFF) | ( up ? 0x80000000 : 0);
          int deadPollCount = 0;
          HKL kl = GetKeyboardLayout(0);

          // basic assignments
          ev. cmd = up ? cmKeyUp : cmKeyDown;
          ev. key. key    = ctx_remap_def( mp1, ctx_kb2VK, false, kbNoKey);
          ev. key. code   = mp1;
          ev. key. repeat = mp2 & 0x000000FF;

          // VK validations
          if ( extended) {
             int ks = ev. key. key;
             ev. key. key = ctx_remap_def( ks, ctx_kb2VK3, true, ks);
             if ( ev. key. key != ks)
                extended = false; // avoid (Ctrl|Alt)R+KeyPad combinations
          } else if ( mp1 >= VK_NUMPAD0 && mp1 <= VK_DIVIDE)
             extended = true; // include numpads

          ev. key. mod   = 0 |
             ( extended ? kmKeyPad : 0) |
             (( GetKeyState( VK_SHIFT)   < 0) ? kmShift : 0) |
             (( GetKeyState( VK_CONTROL) < 0) ? kmCtrl  : 0) |
             (( GetKeyState( VK_MENU)    < 0) ? kmAlt   : 0);

          keyState = guts. keyState;
AGAIN:             
          if ( PApplication(application)-> wantUnicodeInput) {
             WCHAR keys[ 2];
             // unicode mapping
             switch ( ToUnicodeEx( mp1, scan, keyState, keys, 2, 0, kl)) {
             case 1: // char
	     	if ( lastDeadKey ) {
 		   WCHAR wcBuffer[3];
 		   WCHAR out[3];
 		   wcBuffer[0] = keys[0];
 		   wcBuffer[1] = lastDeadKey;
 		   wcBuffer[2] = '\0';
 		   if ( FoldStringW(MAP_PRECOMPOSED, (LPWSTR) wcBuffer, 3, (LPWSTR) out, 3) )
 		      keys[0] = out[0];
		}
                if ( !deadPollCount && ( GetKeyState( VK_MENU) < 0) && ( GetKeyState( VK_SHIFT) >= 0)) {
                   WCHAR keys2[2];
                   if (( ToUnicodeEx( mp1, scan, guts. emptyKeyState, keys2, 2, 0, kl) == 1) &&
                       ( keys2[0] != keys[0])) {
                       /* example - (AltGr+2) == '@' on danish keyboard.
                          this hack is to tell whether the key without mods
                          will give same character code ...  */
                       ev. key. mod &= ~(kmAlt|kmCtrl|kmShift);
                   }
                }   
                if (!up) lastDeadKey = 0;
                break;
             case 2: { // dead key
                   lastDeadKey = ctx_remap_def( keys[0], ctx_deadkeys, true, keys[0]);
                   keys[ 0] = 0;
               	   ev. key. mod |= kmDeadKey;
                }
                break;
             case 0: // virtual key
                if ( deadPollCount == 0) {
                /* can't have character code - maybe fish out without mods? */
                   keyState = guts. emptyKeyState;
                   deadPollCount = 1;
                   goto AGAIN;
                } else {
                /* same meaning without mods, no code anyway */
                   keys[ 0] = 0;
                }
                if (!up) lastDeadKey = 0;
                break;
             default:
               	ev. key. mod |= kmDeadKey;
                if (!up) lastDeadKey = 0;
             }
             ev. key. code = keys[ 0];
	     ev. key. mod |= kmUnicode;
          } else {
             BYTE keys[ 4];
             switch ( ToAsciiEx( mp1, scan, keyState, (LPWORD) keys, 0, kl)) {
             case 1: // char
	     	if ( lastDeadKey ) {
 		   BYTE cBuffer[3];
 		   BYTE out[3];
 		   cBuffer[0] = keys[0];
 		   cBuffer[1] = lastDeadKey;
 		   cBuffer[2] = '\0';
 		   if ( FoldStringA(MAP_PRECOMPOSED, (LPSTR) cBuffer, 3, (LPSTR) out, 3) )
 		      keys[0] = out[0];
		}
                if ( !deadPollCount && ( GetKeyState( VK_MENU) < 0) && ( GetKeyState( VK_SHIFT) >= 0)) {
                   BYTE keys2[4];
                   if (( ToAsciiEx( mp1, scan, guts. emptyKeyState, (LPWORD) keys2, 0, kl) == 1) &&
                       ( keys2[0] != keys[0])) {
                       /* example - (AltGr+2) == '@' on danish keyboard.
                          this hack is to tell whether the key without mods
                          will give same character code ...  */
                       ev. key. mod &= ~(kmAlt|kmCtrl|kmShift);
                   }
                }   
                break;
             case 2: { // dead key
                   lastDeadKey = keys[0];
                   keys[ 0] = 0;
               	   ev. key. mod |= kmDeadKey;
                }
                break;
             case 0: // virtual key
                if ( deadPollCount == 0) {
                /* can't have character code - maybe fish out without mods? */
                   keyState = guts. emptyKeyState;
                   deadPollCount = 1;
                   goto AGAIN;
                } else {
                /* same meaning without mods, no code anyway */
                   keys[ 0] = 0;
                }   
                if (!up) lastDeadKey = 0;
                break;
             default:
                ev. key. mod |= kmDeadKey;
                if (!up) lastDeadKey = 0;
             }
             ev. key. code = keys[ 0];
          }

          // simulated key codes
          if ( ev. key. key == kbTab && ( ev. key. mod & kmShift))
             ev. key. key = kbBackTab;
          
          if ( ev. key. code >= 'A' && ev. key. code <= 'z' && ev. key. mod & kmCtrl) {
             ev. key. code = toupper(ev. key. code & 0xFF) - '@';
             if (!( ev. key. mod & kmShift)) ev. key. code = tolower( ev. key. code);
          }
      }
      break;
   case WM_INITMENUPOPUP:
      if ( HIWORD( mp2)) break; // do not use system popup
   case WM_INITMENU:
      {
         PMenuWndData mwd = ( PMenuWndData) hash_fetch( menuMan, &mp1, sizeof( void*));
         PMenuItemReg m = nil;
         sys lastMenu = mwd ? mwd-> menu : nilHandle;
         if ( mwd && mwd-> menu && ( PAbstractMenu(mwd-> menu)->stage <= csNormal)) {
            m = ( PMenuItemReg) AbstractMenu_first_that( mwd-> menu, find_oid, INT2PTR(void*,mwd->id), true);
            hiStage    = true;
            ev. cmd    = cmMenu;
            ev. gen. H = mwd-> menu;
            ev. gen. i = m ? m-> id : 0;
         }
         if (( msg == WM_INITMENUPOPUP) && ( m == nil))
            ev. cmd = 0;
      }
      break;
   case WM_KILLFOCUS:
      if (( HWND) mp1 != win) {
        ev. cmd = cmReleaseFocus;
        hiStage = true;
        apt_assign( aptFocused, 0);
        DestroyCaret();
      }
      break;
   case WM_LBUTTONDOWN:
      ev. pos. button = mbLeft;
      goto MB_DOWN;
   case WM_RBUTTONDOWN:
      ev. pos. button = mbRight;
      goto MB_DOWN;
   case WM_MBUTTONDOWN:
      ev. pos. button = mbMiddle;
      goto MB_DOWN;
   case WM_LBUTTONUP:
      ev. pos. button = mbLeft;
      goto MB_UP;
   case WM_RBUTTONUP:
      ev. pos. button = mbRight;
      goto MB_UP;
   case WM_MBUTTONUP:
      ev. pos. button = mbMiddle;
      goto MB_UP;
   case WM_LBUTTONDBLCLK:
      ev. pos. button = mbLeft;
      goto MB_DBLCLK;
   case WM_RBUTTONDBLCLK:
      ev. pos. button = mbRight;
      goto MB_DBLCLK;
   case WM_MBUTTONDBLCLK:
      ev. pos. button = mbMiddle;
      goto MB_DBLCLK;
   case WM_LMOUSECLICK:
      ev. pos. button = mbLeft;
      goto MB_CLICK;
   case WM_RMOUSECLICK:
      ev. pos. button = mbRight;
      goto MB_CLICK;
   case WM_MMOUSECLICK:
      ev. pos. button = mbMiddle;
      goto MB_CLICK;
   case WM_MOUSEWHEEL:
      {
         POINT p;
	 p. x = (short)LOWORD( mp2);
	 p. y = (short)HIWORD( mp2);
         ev. cmd         = cmMouseWheel;
         ev. pos. button = ( short) HIWORD( mp1);
         MapWindowPoints( nil, win, &p, 1);
         ev. pos. where. x = p. x;
         ev. pos. where. y = sys lastSize. y - p. y - 1;
      }
      goto MB_MAIN_NOPOS;
   case WM_MOUSEMOVE:
      ev. cmd = cmMouseMove;
      if ( self != lastMouseOver) {
         Handle old = lastMouseOver;
         lastMouseOver = self;
         if ( old && ( PWidget( old)-> stage == csNormal))
            SendMessage(( HWND)(( PWidget) old)-> handle, WM_MOUSEEXIT, mp1, mp2);
         SendMessage( win, WM_MOUSEENTER, mp1, mp2);
         if ( !guts. mouseTimer) {
            guts. mouseTimer = 1;
            if ( !SetTimer( dsys(application)handle, TID_USERMAX, 100, nil)) apiErr;
         }
      }
      goto MB_MAIN;
   case WM_MOUSEENTER:
      ev. cmd = cmMouseEnter;
      goto MB_MAIN;
   case WM_MOUSEEXIT:
      ev. cmd = cmMouseLeave;
      goto MB_MAIN;
   MB_DOWN:
      ev. cmd = cmMouseDown;
      goto MB_MAINACT;
   MB_UP:
      ev. cmd = cmMouseUp;
      goto MB_MAINACT;
   MB_DBLCLK:
      ev. pos. dblclk = 1;
   MB_CLICK:
      ev. cmd = cmMouseClick;
      goto MB_MAINACT;
   MB_MAINACT:
      if ( !is_apt( aptEnabled) || !apc_widget_is_responsive( self))
      {
         if ( ev. cmd == cmMouseDown || (ev. cmd == cmMouseClick && ev. pos. dblclk))
            MessageBeep( MB_OK);
         return 0;
      }
      goto MB_MAIN;
   MB_MAIN:
      if ( ev. cmd == cmMouseDown && !is_apt( aptFirstClick)) {
         Handle x = self;
         while ( dsys(x) className != WC_FRAME && ( x != application)) x = (( PWidget) x)-> owner;
         if ( x != application && !local_wnd( GetActiveWindow(), DHANDLE( x)))
         {
             ev. cmd = 0; // yes, we abandon mousedown but we should force selection:
             if ((( PApplication) application)-> hintUnder == self) v-> self-> set_hintVisible( self, 0);
             if (( v-> options. optSelectable) && ( v-> selectingButtons & ev. pos. button))
                apc_widget_set_focused( self);
         }
      }
      ev. pos. where. x = (short)LOWORD( mp2);
      ev. pos. where. y = sys lastSize. y - (short)HIWORD( mp2) - 1;
   MB_MAIN_NOPOS:
      ev. pos. mod      = 0 |
        (( mp1 & MK_CONTROL ) ? kmCtrl   : 0) |
        (( mp1 & MK_SHIFT   ) ? kmShift  : 0) |
        (( GetKeyState( VK_MENU) < 0) ? kmAlt : 0) |
	apc_pointer_get_state(self)
      ;
      break;
   case WM_MENUCHAR:
       {
          int key;
          ev. key. key    = ctx_remap_def( mp1, ctx_kb2VK2, false, kbNoKey);
          ev. key. code   = mp1;
          ev. key. mod   |=
             (( GetKeyState( VK_SHIFT)   < 0) ? kmShift : 0) |
             (( GetKeyState( VK_CONTROL) < 0) ? kmCtrl  : 0) |
             (( GetKeyState( VK_MENU)    < 0) ? kmAlt   : 0);
          if (( ev. key. mod & kmCtrl) && ( ev. key. code <= 'z'))
             ev. key. code += 'A' - 1;
          key = CAbstractMenu-> translate_key( nilHandle, ev. key. code, ev. key. key, ev. key. mod);
          if ( v-> self-> process_accel( self, key))
             return MAKELONG( 0, MNC_CLOSE);
       }
       break;
   case WM_SYNCMOVE:
       {
          Handle parent = v-> self-> get_parent(( Handle) v);
          if ( parent) {
             Point pos  = var self-> get_origin( self);
             ev. cmd    = cmMove;
             ev. gen. P = pos;
             if ( pos. x == var pos. x && pos. y == var pos. y) ev. cmd = 0;
          }
       }
       break;
   case WM_MOVE:
      {
          Handle parent = v-> self-> get_parent(( Handle) v);
          if ( parent) {
             Point sz = CWidget(parent)-> get_size( parent);
             ev. cmd = cmMove;
             ev. gen . P. x = ( short) LOWORD( mp2);
             ev. gen . P. y = sz. y - ( short) HIWORD( mp2) - sys yOverride;
             if ( is_apt( aptTransparent))
                InvalidateRect( win, nil, false);
          }
      }
      break;
   case WM_NCHITTEST:
      if ( guts. focSysDialog) return HTERROR;
      // dlg protect code - protecting from user actions
      if ( !guts. focSysDisabled && ( Application_map_focus( application, self) != self))
         return HTERROR;
      break;
   case WM_PAINT:
   	ev. cmd = cmPaint;
      if (
           ( sys className == WC_CUSTOM) &&
           ( var stage == csNormal) &&
           ( list_index_of( &guts. transp, self) >= 0)
         )
         return 0;
      break;
   case WM_QUERYNEWPALETTE:
      return palette_change( self);
   case WM_PALETTECHANGED:
      if (( HWND) mp1 != win) {
         Handle mp = hwnd_to_view(( HWND) mp1);
         if ( mp && ( hwnd_top_level( mp) == hwnd_top_level( self)))
            return 0;
         palette_change( self);
      }
      break;
   case WM_POSTAL:
      ev. cmd    = cmPost;
      ev. gen. H = ( Handle) mp1;
      ev. gen. p = ( void *) mp2;
      break;
   case WM_PRIMA_CREATE:
      ev. cmd = cmSetup;
      break;
   case WM_SETFOCUS:
      if ( guts. focSysDialog) return 1;
      // dlg protect code - general case
      if ( !guts. focSysDisabled && !guts. focSysGranted) {
         Handle hf = Application_map_focus( application, self);
         if ( hf != self) {
            PostMessage( win, WM_FORCEFOCUS, 0, ( LPARAM) hf);
            return 1;
         }
      }
      if (( HWND) mp1 != win) {
         ev. cmd = cmReceiveFocus;
         hiStage = true;
         apt_assign( aptFocused, 1);
         cursor_update( self);
      }
      break;
   case WM_SETVISIBLE:
     if ( list_index_of( &guts. transp, self) < 0) {
        if ( v-> stage <= csNormal) ev. cmd = mp1 ? cmShow : cmHide;
        hiStage = true;
        apt_assign( aptVisible, mp1);
     }
     break;
   case WM_SIZE:
      ev. cmd = cmSize;
      ev. gen. R. left   = sys lastSize. x;
      ev. gen. R. bottom = sys lastSize. y;
      sys lastSize. x    = ev. gen. R. right  = ev. gen . P. x = ( short) LOWORD( mp2);
      sys lastSize. y    = ev. gen. R. top    = ev. gen . P. y = ( short) HIWORD( mp2);
      if ( ev. gen. R. top != ev. gen. R. bottom) {
         int delta = ev. gen. R. top - ev. gen. R. bottom;
         Widget_first_that( self, move_back, &delta);
         if ( is_apt( aptFocused)) cursor_update(( Handle) self);
      }
      if ( sys sizeLockLevel == 0 && var stage <= csNormal)
         var virtualSize = sys lastSize;
      break;
   case WM_TIMER:
      {
         int id = mp1 - 1;
         if ( id >= 0 && id < sys timeDefsCount) ev. gen. H = ( Handle) sys timeDefs[ id]. item;
         if ( ev. gen. H) {
             v = ( PWidget)( self = ev. gen. H);
             ev. cmd = cmTimer;
         }
      }
      break;
   case WM_WINDOWPOSCHANGING:
      {
         LPWINDOWPOS l = ( LPWINDOWPOS) mp2;
         if ( sys className == WC_CUSTOM) {
            if (( l-> flags & SWP_NOSIZE) == 0) {
               ev. cmd = cmCalcBounds;
               ev. gen. R. right = l-> cx;
               ev. gen. R. top   = l-> cy;
            }
         }
         if (( l-> flags & SWP_NOZORDER) == 0)
            zorder_sync( self, win, l);
      }
      break;
   case WM_WINDOWPOSCHANGED:
      {
          LPWINDOWPOS l = ( LPWINDOWPOS) mp2;
          if (( l-> flags & SWP_NOZORDER) == 0)
             PostMessage( win, WM_ZORDERSYNC, 0, 0);
          if (( l-> flags & SWP_NOSIZE) == 0) {
             sys yOverride = l-> cy;
             SendMessage( win, WM_SYNCMOVE, 0, 0);
          }
          if ( l-> flags & SWP_HIDEWINDOW) SendMessage( win, WM_SETVISIBLE, 0, 0);
          if ( l-> flags & SWP_SHOWWINDOW) SendMessage( win, WM_SETVISIBLE, 1, 0);
      }
      break;
   case WM_ZORDERSYNC:
      ev. cmd = cmZOrderChanged;
      break;
   }
Beispiel #12
0
void Window_handle_event( Handle self, PEvent event)
{
#define evOK ( var-> evStack[ var-> evPtr - 1])
#define objCheck if ( var-> stage > csNormal) return
   switch (event-> cmd)
   {
   case cmColorChanged:
      if ( event-> gen. source == var-> menu) {
         var-> menuColor[ event-> gen. i] = apc_menu_get_color( var-> menu, event-> gen. i);
         return;
      }
      break;
   case cmFontChanged:
      if ( event-> gen. source == var-> menu)
      {
         apc_menu_get_font( var-> menu, &var-> menuFont);
         return;
      }
      break;
   case cmExecute:
      my-> notify( self, "<s", "Execute");
      break;
   case cmEndModal:
      my-> notify( self, "<s", "EndModal");
      break;
   case cmActivate:
      if ( var-> owner)
         PWidget( var-> owner)-> currentWidget = self;
      my-> notify( self, "<s", "Activate");
      break;
   case cmDeactivate:
      my-> notify( self, "<s", "Deactivate");
      break;
   case cmWindowState:
      my-> notify( self, "<si", "WindowState", event-> gen. i);
      break;
   case cmDelegateKey:
      #define leave { my-> clear_event( self); return; }
      if ( var-> modal && event-> key. subcmd == 0)
      {
          Event ev = *event;
          ev. key. cmd   = cmTranslateAccel;
          if ( !my-> message( self, &ev)) leave;
          if ( my-> first_that( self, (void*)accel_notify, &ev)) leave;
          ev. key. cmd    = cmDelegateKey;
          ev. key. subcmd = 1;
          if ( my-> first_that( self, (void*)accel_notify, &ev)) leave;
      }
      objCheck;
      break;
   case cmTranslateAccel:
      if ( event-> key. key == kbEsc && var-> modal)
      {
         my-> cancel( self);
         my-> clear_event( self);
         return;
      }
      break;
   }
   inherited handle_event ( self, event);
}
Beispiel #13
0
Handle
Widget_next_positional( Handle self, int dx, int dy)
{
    Handle horizon = self;

    int i, maxDiff = INT_MAX;
    Handle max = nilHandle;
    List candidates;
    Point p[2];

    int minor[2], major[2], axis, extraDiff, ir[4];

    /*
       In order to compute positional difference, using four penalties.
       To simplify algorithm, Rect will be translated to int[4] and
       minor, major and extraDiff assigned to array indices for those
       steps - minor for first and third, major for second and extraDiff for last one.
     */

    axis = ( dx == 0) ? dy : dx;
    minor[0] = ( dx == 0) ? 0 : 1;
    minor[1] = minor[0] + 2;
    extraDiff = major[(axis < 0) ? 0 : 1] = ( dx == 0) ? 1 : 0;
    major[(axis < 0) ? 1 : 0] = extraDiff + 2;
    extraDiff = ( dx == 0) ? (( axis < 0) ? 0 : 2) : (( axis < 0) ? 1 : 3);

    while ( PWidget( horizon)-> owner) {
        if (
            ( PWidget( horizon)-> options. optSystemSelectable) || /* fast check for CWindow */
            ( PWidget( horizon)-> options. optModalHorizon)
        ) break;
        horizon = PWidget( horizon)-> owner;
    }

    if ( !CWidget( horizon)-> get_visible( horizon) ||
            !CWidget( horizon)-> get_enabled( horizon)) return nilHandle;

    list_create( &candidates, 64, 64);
    fill_tab_candidates( &candidates, horizon);

    p[0].x = p[0].y = 0;
    p[1] = CWidget( self)-> get_size( self);
    apc_widget_map_points( self, true, 2, p);
    apc_widget_map_points( horizon, false, 2, p);
    ir[0] = p[0].x;
    ir[1] = p[0].y;
    ir[2] = p[1].x;
    ir[3] = p[1].y;

    for ( i = 0; i < candidates. count; i++) {
        int    diff, ix[4];
        Handle x = candidates. items[i];

        if ( x == self) continue;

        p[0].x = p[0].y = 0;
        p[1] = CWidget( x)-> get_size( x);
        apc_widget_map_points( x, true, 2, p);
        apc_widget_map_points( horizon, false, 2, p);
        ix[0] = p[0].x;
        ix[1] = p[0].y;
        ix[2] = p[1].x;
        ix[3] = p[1].y;

        /* First step - checking if the widget is subject to comparison. It is not,
           if it's minor axis is not contiguous with self's */

        if ( ix[ minor[0]] > ir[ minor[1]] || ix[ minor[1]] < ir[ minor[0]])
            continue;

        /* Using x100 penalty for distance in major axis - and discarding those that
           of different sign */
        diff = ( ix[ major[ 1]] - ir[ major[0]]) * 100 * axis;
        if ( diff < 0)
            continue;

        /* Adding x10 penalty for incomplete minor axis congruence. Addition goes in tenths,
           in a way to not allow congruence overweight major axis distance */
        if ( ix[ minor[0]] > ir[ minor[0]])
            diff += ( ix[ minor[0]] - ir[ minor[0]]) * 100 / ( ir[ minor[1]] - ir[ minor[0]]);
        if ( ix[ minor[1]] < ir[ minor[1]])
            diff += ( ir[ minor[1]] - ix[ minor[1]]) * 100 / ( ir[ minor[1]] - ir[ minor[0]]);

        /* Adding 'distance from level' x1 penalty */
        if (( ix[ extraDiff] - ir[ extraDiff]) * axis < 0)
            diff += abs( ix[ extraDiff] - ir[ extraDiff]);

        if ( diff < maxDiff) {
            max = x;
            maxDiff = diff;
        }
    }

    list_destroy( &candidates);

    return max;
}