/* name: stk_components.cc info: auxiliary object which handle mechanism of bidirectional linked list features of stk_components - implementation author: Dusan Halicky (dvh.tosomja@post.sk) licence: GNU GPL history: 2005-10-26 - RH 7.2 fixes (bool focus_chaange in Update() was initialized in case block) 2005-09-26 - start of developement 2005-11-06 - last_focused_focusable_component todo: - finish and release this bugs: - */ // external libraries #include #include #include // external stk files #include "stk_constants.h" #include "stk_display.h" #include "stk_mouse.h" #include "stk_keys.h" #include "stk_init.h" #include "stk_callback.h" #include "stk_component.h" // header file #include "stk_components.h" // next one must be after stk_keys.h #include // debugging #ifdef STK_DEBUG #define STK_COMPONENTS_DEBUG #define STK_COMPONENTS_DEBUG_FIND #define STK_COMPONENTS_DEBUG_UPDATE #define STK_COMPONENTS_DEBUG_UPDATE_UNHANDLED #define STK_COMPONENTS_DEBUG_SHORTCUT #define STK_COMPONENTS_DEBUG_ECNF #endif // event variables - not every stkevent variable is set up on every event! XEvent stkevent; // whole event (Xlib style) int stkevent_type; // event type (see X.h - KeyPress, Expose, MapNotify, ...) Window stkevent_window; // window (component) which catch the event (used for Find() ) int stkevent_x, stkevent_y; // coordinates unsigned int stkevent_state; // key or button mask or modifiers or atom property .... KeySym stkevent_keysym; // keysym unsigned int stkevent_button; // mouse button pressed int stkevent_w, stkevent_h; // size Atom stkevent_atom; // atom (client message, propery, selection) StkComponent* stkeventcomponent; // component which call the event, important when you are using dynamicaly created components void stk_next_event() { // this retrieve next event (stkevent) from the server XNextEvent(stkdisplay,&stkevent); } void stk_peek_event() { // this test if any event occure and retrieve it if yes // int i = XPeekEvent(stkdisplay,&stkevent); // printf("i = %d stkevent.type = %d\n",stkevent); } StkComponents::StkComponents () { // constructor #ifdef STK_COMPONENTS_DEBUG printf("StkComponents::StkComponents (this=0x%X)\n",(int)this); #endif first = NULL; last = NULL; focused_last = NULL; } StkComponents::~StkComponents () { // destructor #ifdef STK_COMPONENTS_DEBUG printf("StkComponents::~StkComponents (this=0x%X)\n",(int)this); #endif first = NULL; last = NULL; } void StkComponents::Add (StkComponent * item) { // add component into linked list (at the end) #ifdef STK_COMPONENTS_DEBUG printf("StkComponents::Add (this=0x%X item=0x%X)\n",(int)this,(int)item); #endif // is this first item of the list? if (first == NULL) { // yes, this will be first item #ifdef STK_COMPONENTS_DEBUG printf ("StkComponents: adding FIRST item 0x%X (first=0x%X last=0x%X)\n", (int)item, (int)first, (int)last); #endif first = item; item->SetPrevious(NULL); item->SetNext(NULL); last = item; #ifdef STK_COMPONENTS_DEBUG printf (" done: first=0x%X last=0x%X item=0x%X\n", (int)first, (int)last, (int)item); #endif } else { // is this second item? if (first == last) { // yes, this will be second item #ifdef STK_COMPONENTS_DEBUG printf ("StkComponents: adding SECOND item 0x%X (first=0x%X last=0x%X)\n", (int)item, (int)first, (int)last); #endif first->SetNext(item); item->SetPrevious(first); item->SetNext(NULL); last = item; #ifdef STK_COMPONENTS_DEBUG printf (" done: first=0x%X last=0x%X item=0x%X\n", (int)first, (int)last, (int)item); #endif } else { // no, this will be Xth item, right after the last #ifdef STK_COMPONENTS_DEBUG printf ("StkComponents: adding LAST item 0x%X (first=0x%X last=0x%X)\n", (int)item, (int)first, (int)last); #endif last->SetNext(item); item->SetPrevious(last); item->SetNext(NULL); last = item; #ifdef STK_COMPONENTS_DEBUG printf (" done: first=0x%X last=0x%X item=0x%X\n", (int)first, (int)last, (int)item); #endif } } } void StkComponents::Remove (StkComponent * item) { // remove component from linked list (from its own position) #ifdef STK_COMPONENTS_DEBUG printf("StkComponents::Remove (this=0x%X item=0x%X)\n",(int)this,(int)item); #endif StkComponent *p, *n; // get the previous P and next N ( P -> item -> N ) p = item->GetPrevious (); n = item->GetNext (); // change the previous to point on next p->SetNext (n); // change next to point on previous n->SetPrevious (p); if (focused_last == item) focused_last = first; } void StkComponents::Debug () { // this displays the structure of the bidirection linked list StkComponent *i, *inext; int counter = 0; printf ("StkComponents - debug\n\n index\tprev\t\tthis\t\tnext\t\ttype\twindow\n\n"); for (i = first; i != NULL; i = inext) { counter++; inext = i->GetNext (); printf (" [%d]\t%8X\t%8X\t%8X\t%s\t0x%X\n", counter, (unsigned int)i->GetPrevious (), (unsigned int)i, (unsigned int)i->GetNext (), typeid (*i).name (), (unsigned int)i->GetWindow ()); } } StkComponent * StkComponents::Find (Window w) { // this find the component which has a window w, this is important because XEvent return only window but we need to handle whole component StkComponent *i, *inext; for (i = first; i != NULL; i = inext) { #ifdef STK_COMPONENTS_DEBUG_FIND printf (" i=0x%X\n", (int)i); #endif inext = i->GetNext (); #ifdef STK_COMPONENTS_DEBUG_FIND printf (" inext=0x%X\n", (int)inext); #endif Window ww = i->GetWindow (); #ifdef STK_COMPONENTS_DEBUG_FIND printf (" window=0x%X\n", (int)ww); #endif if (ww == w) { #ifdef STK_COMPONENTS_DEBUG_FIND printf ("StkComponent::Find(0x%X) - found component 0x%X\n",(int) w, (int)i); #endif return i; } } return NULL; } // debug when event component not found void StkComponents::ECNF(Window window) { // debug when EventComponentNotFount #ifdef STK_COMPONENTS_DEBUG_ECNF printf("stk_components: warning - event component not found! (window=0x%X)\n",(unsigned int)window); printf(" stkevent_type = %d\n",stkevent_type); printf(" stkevent_window = %d\n",(int)stkevent_window); printf(" stkevent_x = %d stkevent_y = %d\n",stkevent_x,stkevent_y); printf(" stkevent_w = %d stkevent_h = %d\n",stkevent_w,stkevent_h); printf(" stkevent_button = %d\n",stkevent_button); printf(" stkevent_keysym = %d\n",(int)stkevent_keysym); printf(" stkevent_state = %d\n",stkevent_state); printf(" stkevent_atom = %d\n",(int)stkevent_atom); Debug(); #endif } // this method "decode" event "e" and call all events for components in the bidirectional linked list which is covered by this "components" object void StkComponents::Update() { XEvent e = stkevent; bool change_focus; bool change_focus_forward; bool change_focus_backward; bool force_focus_in; #ifdef STK_COMPONENTS_DEBUG_UPDATE_UNHANDLED printf("Event #%d\n",e.type); #endif switch (e.type) { // prepare the component which will handle the event // MOUSE MOTION case MotionNotify: // retrieve event's variables stkevent_window = e.xmotion.window; stkevent_x = e.xmotion.x; stkevent_y = e.xmotion.y; stkevent_state = e.xmotion.state; // find the event component stkeventcomponent = Find (stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event MotionNotify (window=0x%X component=0x%X='%s' x=%d y=%d state=%d)\n",(int)stkevent_window,(int)stkeventcomponent,typeid(*stkeventcomponent).name(),stkevent_x,stkevent_y,stkevent_state); #endif // call the event if component exist, else debug if (stkeventcomponent) stkeventcomponent->OnMouseMove (stkevent_x, stkevent_y, stkevent_button, stkevent_state); else ECNF(stkevent_window); break; // EXPOSE case Expose: // retrieve event's variables stkevent_window = e.xexpose.window; stkevent_x = e.xexpose.x; stkevent_y = e.xexpose.y; stkevent_w = e.xexpose.width; stkevent_h = e.xexpose.height; // find the event component stkeventcomponent = Find (stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event Expose (window=0x%X component=0x%X='%s' x=%d y=%d w=%d h=%d count=%d)\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name(), stkevent_x, stkevent_y, stkevent_w, stkevent_h, e.xexpose.count); #endif // call the event if exist, else debug if ( (stkeventcomponent)&&(e.xexpose.count==0) ) // only if last expose event?, maybe we should collect this expose events and count maximal rectangle... stkeventcomponent->OnExpose (); else if (!stkeventcomponent) ECNF(stkevent_window); break; // ENTER case EnterNotify: // retrieve event's variables stkevent_window = e.xcrossing.window; stkevent_x = e.xcrossing.x; stkevent_y = e.xcrossing.y; // find the event component stkeventcomponent = Find (stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event EnterNotify (window=0x%X component=0x%X='%s' x=%d y=%d button=%d state=%d)\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name(), stkevent_x, stkevent_y, stkevent_button, stkevent_state); #endif // call the event if exist, else debug if (stkeventcomponent) stkeventcomponent->OnMouseOver (stkevent_x, stkevent_y, stkevent_button, stkevent_state); else ECNF(stkevent_window); break; // LEAVE case LeaveNotify: // retrieve event's variables stkevent_window = e.xcrossing.window; stkevent_x = e.xcrossing.x; stkevent_y = e.xcrossing.y; // find the event component stkeventcomponent = Find (stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event LeaveNotify (window=0x%X component=0x%X='%s' x=%d y=%d button=%d state=%d)\n", (int)stkevent_window, (int)stkeventcomponent,typeid(*stkeventcomponent).name(), stkevent_x, stkevent_y, stkevent_button, stkevent_state); #endif // call the event if exist, else debug if (stkeventcomponent) stkeventcomponent->OnMouseOut (stkevent_x, stkevent_y, stkevent_button, stkevent_state); else ECNF(stkevent_window); break; // KEY PRESS case KeyPress: // retrieve event's variables stkevent_window = e.xkey.window; // this code fix one problem with X dumb focus handling (appear when focused component lost focus when window is moved and then focus // is taken to the main window instead of last focused component) - this code fix this problem force_focus_in = false; if ((focused_last)&&(stkevent_window != focused_last->GetWindow())) { // printf(".... problem: catched input event on not focused window! QQQQQQQQQQQQQQQQQQQQQQQQQQQ\n"); stkevent_window=focused_last->GetWindow(); force_focus_in = true; XSetInputFocus(stkdisplay,stkevent_window,RevertToParent,CurrentTime); } stk_keys_update(e.xkey,true); stkevent_keysym = stkkeys_keysym; stkevent_state = stkkeys_state; // find the component stkeventcomponent = Find (stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event KeyPress (window=0x%X component=0x%X='%s' keysym=%d state=%d) focused_last=0x%X\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name(), (int)stkevent_keysym, stkevent_state, (int)focused_last); #endif // call the event for focused component /* in variable change_focus, component will give information if the focus will be changed after it's event will be called. If the change_focus is false, component may change it to true (to force the change of focus, also if TAB was not pressed) or may it left unchanged. If change_focus is true, component may let it true or component may set it fo false by set it to false. Examples: Component Key change_focus What will component does with change_focus? button any any unchanged vert. slider TAB any unchanged Up true false - because Up is used for focus changing but slider want it use to change slider value Left true unchanged - because vertical slider is controled only by Up/Down keys, so left/right may change focus edit Left true false - because user want to move the cursor in edit memo Tab true false - because user want to write tab key in the text in memo */ change_focus_forward = ((stkkeys_keysym==XK_Tab) ||(stkkeys_keysym==XK_Right) ||(stkkeys_keysym==XK_Down)); change_focus_backward = ((stkkeys_keysym==XK_ISO_Left_Tab) ||(stkkeys_keysym==XK_Left) ||(stkkeys_keysym==XK_Up)); /* bool change_fokus_arrows = ||(stkkeys_keysym==XK_Right) ||(stkkeys_keysym==XK_Down) ||(stkkeys_keysym==XK_Left) ||(stkkeys_keysym==XK_Right); */ change_focus = (change_focus_forward||change_focus_backward); // call the event if exist, else debug if (stkeventcomponent) stkeventcomponent->OnKeyPress (stkevent_keysym, stkevent_state, stkkeys_name, stkkeys_namesize, &change_focus); else ECNF(stkevent_window); // change the focus (if component doesn't block it or if component force it) // TAB, Right, Down - forward focus changing if (change_focus_forward&&change_focus) { #ifdef STK_COMPONENTS_DEBUG printf("stkcomponents: Changing focus: forward\n"); #endif StkComponent *inext, *istart; if (focused_last==NULL) focused_last=first; inext=focused_last; istart=focused_last; // test if pomc is focusable, otherwise we must find focusable compoennt first form right size do { // get the next component inext=inext->GetNext(); // end of linked list? if (inext==NULL) { // yes, must start from begining inext=first; } } while(!( (inext->IsFocusable()==true)||(inext==istart) )); // searching until find focusable item or the same as from we start // set the focus to the next, if it exist and if it is not that from we start if ( (inext!=NULL)&&(inext!=istart) ) { inext->SetFocus(true); } } // SHIFT+TAB, left, up - backward focus changing if (change_focus_backward&&change_focus) { #ifdef STK_COMPONENTS_DEBUG_UPDATE printf("stkcomponents: Changing focus: backward\n"); #endif StkComponent *inext, *istart; inext=stkeventcomponent; istart=stkeventcomponent; #ifdef STK_COMPONENTS_DEBUG_UPDATE printf("stkcomponents: inext=0x%X\n",(int)inext); #endif // test if pomc is focusable, otherwise we must find focusable compoennt first form left size do { // get the previous component inext=inext->GetPrevious(); // printf("stkcomponents: inext=0x%X\n",inext); // end of linked list? if (inext==NULL) // yes, must start from end inext=last; } while(!( (inext->IsFocusable()==true)||(inext==istart) )); // searching until find focusable item or the same as from we start // set the focus to the next, if it exist and if it is not that from we start if ((inext!=NULL)&&(inext!=istart)) { #ifdef STK_COMPONENTS_DEBUG_UPDATE printf("stkcomponents: setting focus from component 0x%X to component 0x%X\n",(int)istart,(int)inext); #endif inext->SetFocus(true); } } // call the shortcuts, this will "propagate" all key press event to the event driver which will test the shortcuts keys for components CallShortcut(); /* if (e.xkey.keycode == 23) { printf ("stkcomponents: TAB pressed, toggling focus\n"); Window fw; int rtr; XGetInputFocus (stkdisplay, &fw, &rtr); printf ("stkcomponents: XGetInputFocus: fw=0x%X rtr=0x%X\n", fw, rtr); } */ break; // key release case KeyRelease: // retrieve event's variables stkevent_window = e.xkey.window; stk_keys_update(e.xkey,true); stkevent_keysym = stkkeys_keysym; stkevent_state = stkkeys_state; // find event component stkeventcomponent = Find (stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event KeyRelease (window=0x%X component=0x%X='%s' keysym=%d state=%d)\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name(), (int)stkevent_keysym, stkevent_state); #endif // call the event if exist, else debug if (stkeventcomponent) stkeventcomponent->OnKeyRelease (stkkeys_keysym, stkkeys_state, stkkeys_name, stkkeys_namesize, &change_focus); else ECNF(stkevent_window); break; // FOCUS IN case FocusIn: // retrieve event's variables // printf("zzz\n"); stkevent_window = e.xfocus.window; if (e.xfocus.send_event==false) { #ifdef STK_COMPONENTS_DEBUG_UPDATE printf("ZZZZ: this is X dumb focus event ... ignored ... se=%d w=0x%X mode=%d detail=%d\n",(int)e.xfocus.send_event,(int)e.xfocus.window,e.xfocus.mode,e.xfocus.detail); #endif } else { #ifdef STK_COMPONENTS_DEBUG_UPDATE printf("FocusIn_____ se=%d w=0x%X mode=%d detail=%d\n",(int)e.xfocus.send_event,(int)e.xfocus.window,e.xfocus.mode,e.xfocus.detail); #endif // find the event component stkeventcomponent = Find(stkevent_window); // debug #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event FocusIn (window=0x%X component=0x%X='%s')\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name() ); #endif // call the event if exist, else debug if (stkeventcomponent) { if (stkeventcomponent->IsFocusable()) { #ifdef STK_COMPONENTS_DEBUG_UPDATE if (focused_last) printf("1: ec=0x%X (focus=%d), fl=0x%X (focus=%d)\n",(int)stkeventcomponent,(int)stkeventcomponent->GetFocus(),(int)focused_last,(int)focused_last->GetFocus()); #endif if (stkeventcomponent!=focused_last) SetFocus(stkeventcomponent); // unset focus for all others focusable component which has focus } else { if (focused_last) { // printf("2: ec=0x%X, fl=0x%X\n",(int)stkeventcomponent,(int)focused_last); SetFocus(focused_last); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf("re-set focus to focused_last = 0x%X\n",(int)focused_last); #endif } } } else ECNF(stkevent_window); } break; // FOCUS OUT case FocusOut: #ifdef STK_COMPONENTS_DEBUG_UPDATE printf("stk_components: FocusOut facility disabled (because of dumb X focus handling...)\n"); #endif // this event is IS NOT NORMAL FOCUS OUT! this event can be passed as semi-normal focusout only if // component has set variable force_focus_out_event = true // - this feature may be obsolete in future /* printf("!!! __FocusOut__ event !!!\n"); { Window tmp_window = e.xfocus.window; StkComponent *tmp_component = Find (tmp_window); if (tmp_component->GetForceFocusOutEvent()) { tmp_component->SetFocus(false); printf("!!! force to __FocusOut__ component 0x%X !!!\n",(int)tmp_component); } }*/ // retrieve event variables /* stkevent_window = e.xfocus.window; // find event component stkeventcomponent = Find (stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event FocusOut (window=0x%X component=0x%X='%s')\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name() ); printf("... here we must do something with focus\n"); printf("... by the way, focused_last=0x%X\n",(int)focused_last); if (focused_last) printf(" focus=%d)\n",(int)focused_last->GetFocus()); #endif // focus is really problematic sometimes, here is few examples of what is catched: // (I=focus in, O=focus out, L=leave notify, E=enter notify, b=manually focused button, w=window) // - when window is moved: wOOII // - when window with focused button lost focus: wOOEOIOIL // - when window is moved and button has focus: bOwOOOII // remember last focused component if it is focusable (window is not focusable (in STK way) so we don't remeber it - that's good) if (stkeventcomponent->GetFocusable()) { last_focused_focusable_component = stkeventcomponent; //printf("... SHOULD WE remember this component because it is FOCUSABLE !!!\n"); } */ break; // MOUSE DOWN case ButtonPress: // retrieve event's variables stkevent_window = e.xbutton.window; stkevent_x = e.xbutton.x; stkevent_y = e.xbutton.y; stkevent_button = e.xbutton.button; stkevent_state = e.xbutton.state; // find the event component stkeventcomponent = Find (e.xbutton.window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event ButtonPress (window=0x%X component=0x%X='%s' x=%d y=%d button=%d state=%d)\n",(int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name(), stkevent_x, stkevent_y, stkevent_button, stkevent_state); #endif // call the event if exist, else debug if (stkeventcomponent) stkeventcomponent->OnMouseDown (stkevent_x, stkevent_y, stkevent_button, stkevent_state); else ECNF(stkevent_window); break; // MOUSE UP case ButtonRelease: // retrieve event's variables stkevent_window = e.xbutton.window; stkevent_x = e.xbutton.x; stkevent_y = e.xbutton.y; stkevent_button = e.xbutton.button; stkevent_state = e.xbutton.state; // find the event component stkeventcomponent = Find (stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event ButtonRelease (window=0x%X component=0x%X='%s' x=%d y=%d button=%d state=%d)\n",(int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name(), stkevent_x, stkevent_y, stkevent_button, stkevent_state); #endif // call the event if exist, else debug if (stkeventcomponent) stkeventcomponent->OnMouseUp (stkevent_x, stkevent_y, stkevent_button, stkevent_state); else ECNF(stkevent_window); // change stkevent_button/state so we need that it will be released stkevent_button = stkevent_button & ~e.xbutton.button; stkevent_state = stkevent_state & ~e.xbutton.state; break; // CREATE EVENT case CreateNotify: // retrieve event's variables stkevent_window = e.xcreatewindow.window; stkevent_x = e.xcreatewindow.x; stkevent_y = e.xcreatewindow.y; stkevent_w = e.xcreatewindow.width; stkevent_h = e.xcreatewindow.height; // find event component stkeventcomponent = Find(stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event CreateNotify (window=0x%X component=0x%X='%s' x=%d y=%d w=%d h=%d)\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name(), stkevent_x, stkevent_y, stkevent_w, stkevent_h); #endif break; // MAPPING NOTIFY case MappingNotify: // retrieve event's variables stkevent_window = e.xmapping.window; // find event component stkeventcomponent = Find(stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event MappingNotify (unhandled) (window=0x%X component=0x%X='%s')\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name()); #endif break; // MAP NOTIFY case MapNotify: // retrieven event's variables stkevent_window = e.xmap.window; // find event component stkeventcomponent = Find(stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event MapNotify (window=0x%X event=0x%X stkeventcomponent=0x%X='%s')\n", (int)stkevent_window, (int)e.xmap.event, (int)stkeventcomponent, typeid(*stkeventcomponent).name()); #endif // call the event if exist, else debug if ( (stkeventcomponent)&&(e.xmap.event==e.xmap.window) ) // don't call the event if window != event in e.xmap (redundant map event?) stkeventcomponent->OnShow(); else if (!stkeventcomponent) ECNF(stkevent_window); break; // UNMAP NOTIFY case UnmapNotify: // retrieven event's variables stkevent_window = e.xunmap.window; // find event component stkeventcomponent = Find(stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event UnmapNotify (window=0x%X event=0x%X stkeventcomponent=0x%X='%s')\n", (int)stkevent_window, (int)e.xunmap.event, (int)stkeventcomponent, typeid(*stkeventcomponent).name()); #endif // call the event if exist, else debug if ( (stkeventcomponent)&&(e.xmap.event==e.xmap.window) ) // don't call the event if window != event in e.xmap (redundant map event?) stkeventcomponent->OnHide(); else if (!stkeventcomponent) ECNF(stkevent_window); break; // RESIZE REQUEST case ResizeRequest: // retrieve event's variables stkevent_window = e.xresizerequest.window; stkevent_w = e.xresizerequest.width; stkevent_h = e.xresizerequest.height; // find the stkeventcomponentn stkeventcomponent = Find(stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event ResizeRequest (window=0x%X stkeventcomponent=0x%X='%s' w=%d h=%d)\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name(), stkevent_w, stkevent_h); #endif // call the event if exists, else debug if (stkeventcomponent) stkeventcomponent->OnResize(stkevent_w,stkevent_h); else ECNF(stkevent_window); break; // PROPERTY NOTIFY case PropertyNotify: // get event variables stkevent_window = e.xproperty.window; // find event component stkeventcomponent = Find(stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event PropertyNotify UNHANDLED (window=0x%X stkeventcomponent=0x%X='%s')\n", (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name()); #endif break; // CLIENT MESSAGE - e.g. locally defined WM_DELETE_WINDOW case ClientMessage: // get event stkevent_window=e.xproperty.window; stkevent_atom=e.xproperty.atom; stkevent_state=e.xproperty.state; // find event component stkeventcomponent = Find (stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE printf ("stk_components: event ClientMessage (window=0x%X atom=0x%X state=0x%X stkeventcomponent=0x%X='%s')\n", (int)stkevent_window, (int)stkevent_atom, (int)stkevent_state, (int)stkeventcomponent, typeid(*stkeventcomponent).name()); #endif // call the events if component exist if (stkeventcomponent) { // internal focus handling // if ( (stkevent_atom==STK_MESSAGE)&&(stkevent_state==STK_MESSAGE_SET_FOCUS) ) // { // printf("_____________ focus message catched _____________\n"); // } // close the window if ( (stkevent_atom==WM_PROTOCOLS)&&(stkevent_state==WM_DELETE_WINDOW) ) { #ifdef STK_COMPONENTS_DEBUG_UPDATE printf (" atom=WM_PROTOCOLS state=WM_DELETE_WINDOW (calling OnClose event)\n"); #endif stkeventcomponent->OnClose(); } } else ECNF(stkevent_window); break; // UNHANDLED EVENTS default: // get event stkevent_window = e.xany.window; // find event compoent stkeventcomponent = Find(stkevent_window); #ifdef STK_COMPONENTS_DEBUG_UPDATE_UNHANDLED printf ("stk_components: event #%d UNHANDLED! (window=0x%X component=0x%X='%s')\n", e.type, (int)stkevent_window, (int)stkeventcomponent, typeid(*stkeventcomponent).name()); #endif break; } } // call the shortcuts - if any match void StkComponents::CallShortcut(void) { #ifdef STK_COMPONENTS_DEBUG_SHORTCUT printf("StkComponents::CallShortcut(keysym=%d mods=%d): \n",(int)stkkeys_keysym, stkkeys_state); #endif StkComponent *i, *inext; for (i = first; i != NULL; i = inext) { int modifs=i->GetModifiers(); inext = i->GetNext (); #ifdef STK_COMPONENTS_DEBUG_SHORTCUT printf(" test: i->shortcut=%d stkkeys_keysym=%d modifs=%d stkkeys_keystate=%d name='%s' enabled=%d ... ", (int)i->GetShortcut(),(int)stkkeys_keysym,modifs,stkkeys_state,typeid(*i).name(),i->GetEnabled()); #endif if ( ( (i->GetShortcut())==stkkeys_keysym ) &&( ( (modifs & stkkeys_state) >0) || (modifs==0) ) &&( i->GetEnabled() ) ) { #ifdef STK_COMPONENTS_DEBUG_SHORTCUT printf(" call: component 0x%X\n",(int)i); #endif i->OnShortcut (stkkeys_keysym, stkkeys_state, stkkeys_name, stkkeys_namesize); } #ifdef STK_COMPONENTS_DEBUG_SHORTCUT else printf("\n"); #endif } } void StkComponents::SetFocus(StkComponent *item) { // unset focus for all focused focusable component except component item and set focus to this item StkComponent *i, *inext; #ifdef STK_COMPONENTS_DEBUG printf("StkComponents::SetFocus (item=0x%X item->window=0x%X)\n",(int)item,(int)item->GetWindow()); #endif // unset focus if (focused_last != item) { for (i=first;i!=NULL;i=inext) { inext=i->GetNext(); if ( (i->GetFocus() ) &&(i!=item) ) { i->OnChangeFocus(false); } } // set focus to item #ifdef STK_COMPONENTS_DEBUG printf(" setting focus to item=0x%X (window=0x%X)\n",(int)item,(int)item->GetWindow()); #endif // item->SetFocus(true); ????????????????????? item->OnChangeFocus(true); focused_last=item; #ifdef STK_COMPONENTS_DEBUG printf(" focused_last=0x%X window=0x%X\n",(int)focused_last,(int)focused_last->GetWindow()); #endif } }