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; }
/* 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; }
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; }
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); } } }
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; }
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; }
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; }
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; }
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; } }
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; } }
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; }
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); }
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; }