#ifdef INTERFACE CLASS(InputContainer) EXTENDS(Container) METHOD(InputContainer, keyDown, float(entity, float, float, float)) METHOD(InputContainer, mouseMove, float(entity, vector)) METHOD(InputContainer, mousePress, float(entity, vector)) METHOD(InputContainer, mouseRelease, float(entity, vector)) METHOD(InputContainer, mouseDrag, float(entity, vector)) METHOD(InputContainer, focusLeave, void(entity)) METHOD(InputContainer, resizeNotify, void(entity, vector, vector, vector, vector)) METHOD(InputContainer, _changeFocusXY, float(entity, vector)) ATTRIB(InputContainer, mouseFocusedChild, entity, NULL) ATTRIB(InputContainer, isTabRoot, float, 0) ENDCLASS(InputContainer) #endif #ifdef IMPLEMENTATION void InputContainer_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) { SUPER(InputContainer).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); /* if(me.parent.instanceOfInputContainer) me.isTabRoot = 0; else me.isTabRoot = 1; */ } void InputContainer_focusLeave(entity me) { SUPER(InputContainer).focusLeave(me); me.mouseFocusedChild = NULL; } float InputContainer_keyDown(entity me, float scan, float ascii, float shift) { entity f, ff; if(SUPER(InputContainer).keyDown(me, scan, ascii, shift)) return 1; if(scan == K_ESCAPE) { f = me.focusedChild; if(f) { me.setFocus(me, NULL); return 1; } return 0; } if(scan == K_TAB) { f = me.focusedChild; if(shift & S_SHIFT) { if(f) { for(ff = f.prevSibling; ff; ff = ff.prevSibling) { if not(ff.focusable) continue; me.setFocus(me, ff); return 1; } } if(!f || me.isTabRoot) { for(ff = me.lastChild; ff; ff = ff.prevSibling) { if not(ff.focusable) continue; me.setFocus(me, ff); return 1; } return 0; // AIIIIEEEEE! } } else { if(f) { for(ff = f.nextSibling; ff; ff = ff.nextSibling) { if not(ff.focusable) continue; me.setFocus(me, ff); return 1; } } if(!f || me.isTabRoot) { for(ff = me.firstChild; ff; ff = ff.nextSibling) { if not(ff.focusable) continue; me.setFocus(me, ff); return 1; } return 0; // AIIIIEEEEE! } } } return 0; } float InputContainer__changeFocusXY(entity me, vector pos) { entity e, ne; e = me.mouseFocusedChild; ne = me.itemFromPoint(me, pos); if(ne) if not(ne.focusable) ne = NULL; me.mouseFocusedChild = ne; if(ne) if(ne != e) { me.setFocus(me, ne); if(ne.instanceOfInputContainer) { ne.focusedChild = NULL; ne._changeFocusXY(e, globalToBox(pos, ne.Container_origin, ne.Container_size)); } } return (ne != NULL); } float InputContainer_mouseDrag(entity me, vector pos) { if(SUPER(InputContainer).mouseDrag(me, pos)) return 1; if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) return 1; return 0; } float InputContainer_mouseMove(entity me, vector pos) { if(me._changeFocusXY(me, pos)) if(SUPER(InputContainer).mouseMove(me, pos)) return 1; if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) return 1; return 0; } float InputContainer_mousePress(entity me, vector pos) { me.mouseFocusedChild = NULL; // force focusing if(me._changeFocusXY(me, pos)) if(SUPER(InputContainer).mousePress(me, pos)) return 1; if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) return 1; return 0; } float InputContainer_mouseRelease(entity me, vector pos) { float r; r = SUPER(InputContainer).mouseRelease(me, pos); if(me.focused) // am I still eligible for this? (UGLY HACK, but a mouse event could have changed focus away) if(me._changeFocusXY(me, pos)) return 1; if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) return 1; return 0; } #endif