X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fmenu%2Fitem%2Fmodalcontroller.qc;h=660431d60dd5cdd5a90a99cbc8c93b70cb0bae6d;hb=26693a3ac060825ce6c7f170d4e65f7ac2a1fb25;hp=a13fcdd69f5706d663ea529072735ae0a85c4dcc;hpb=263c592e468eeeffb2755d204b21eb13e398adac;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/menu/item/modalcontroller.qc b/qcsrc/menu/item/modalcontroller.qc index a13fcdd69..660431d60 100644 --- a/qcsrc/menu/item/modalcontroller.qc +++ b/qcsrc/menu/item/modalcontroller.qc @@ -1,296 +1,238 @@ -#ifndef ITEM_MODALCONTROLLER_H -#define ITEM_MODALCONTROLLER_H -#include "container.qc" -CLASS(ModalController, Container) - METHOD(ModalController, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(ModalController, draw, void(entity)) - METHOD(ModalController, showChild, void(entity, entity, vector, vector, float)) - METHOD(ModalController, hideChild, void(entity, entity, float)) - METHOD(ModalController, hideAll, void(entity, float)) - METHOD(ModalController, addItem, void(entity, entity, vector, vector, float)) - METHOD(ModalController, addTab, void(entity, entity, entity)) +#include "modalcontroller.qh" - METHOD(ModalController, initializeDialog, void(entity, entity)) +#include "button.qh" - METHOD(ModalController, switchState, void(entity, entity, float, float)) - ATTRIB(ModalController, origin, vector, '0 0 0') - ATTRIB(ModalController, size, vector, '0 0 0') - ATTRIB(ModalController, previousButton, entity, NULL) - ATTRIB(ModalController, fadedAlpha, float, 0.3) -ENDCLASS(ModalController) + .vector ModalController_initialSize; + .vector ModalController_initialOrigin; + .vector ModalController_initialFontScale; + .float ModalController_initialAlpha; + .vector ModalController_buttonSize; + .vector ModalController_buttonOrigin; + .float ModalController_state; + .float ModalController_factor; + .entity ModalController_controllingButton; -.entity tabSelectingButton; -.vector origin; -.vector size; -void TabButton_Click(entity button, entity tab); // assumes a button has set the above fields to its own absolute origin, its size, and the tab to activate -void DialogOpenButton_Click(entity button, entity tab); // assumes a button has set the above fields to its own absolute origin, its size, and the tab to activate -void DialogOpenButton_Click_withCoords(entity button, entity tab, vector theOrigin, vector theSize); -void DialogCloseButton_Click(entity button, entity tab); // assumes a button has set the above fields to the tab to close -#endif - -#ifdef IMPLEMENTATION - -// modal dialog controller -// handles a stack of dialog elements -// each element can have one of the following states: -// 0: hidden (fading out) -// 1: visible (zooming in) -// 2: greyed out (inactive) -// While an animation is running, no item has focus. When an animation is done, -// the topmost item gets focus. -// The items are assumed to be added in overlapping order, that is, the lowest -// window must get added first. -// -// Possible uses: -// - to control a modal dialog: -// - show modal dialog: me.showChild(me, childItem, buttonAbsOrigin, buttonAbsSize, 0) // childItem also gets focus -// - dismiss modal dialog: me.hideChild(me, childItem, 0) // childItem fades out and relinquishes focus -// - show first screen in m_show: me.hideAll(me, 1); me.showChild(me, me.firstChild, '0 0 0', '0 0 0', 1); -// - to show a temporary dialog instead of the menu (teamselect): me.hideAll(me, 1); me.showChild(me, teamSelectDialog, '0 0 0', '0 0 0', 1); -// - as a tabbed dialog control: -// - to initialize: me.hideAll(me, 1); me.showChild(me, me.firstChild, '0 0 0', '0 0 0', 1); -// - to show a tab: me.hideChild(me, currentTab, 0); me.showChild(me, newTab, buttonAbsOrigin, buttonAbsSize, 0); - -.vector ModalController_initialSize; -.vector ModalController_initialOrigin; -.vector ModalController_initialFontScale; -.float ModalController_initialAlpha; -.vector ModalController_buttonSize; -.vector ModalController_buttonOrigin; -.float ModalController_state; -.float ModalController_factor; -.entity ModalController_controllingButton; - -void ModalController_initializeDialog(entity me, entity root) -{ - me.hideAll(me, 1); - me.showChild(me, root, '0 0 0', '0 0 0', 1); // someone else animates for us -} - -void TabButton_Click(entity button, entity tab) -{ - if(tab.ModalController_state == 1) - return; - tab.parent.hideAll(tab.parent, 0); - button.forcePressed = 1; - tab.ModalController_controllingButton = button; - tab.parent.showChild(tab.parent, tab, button.origin, button.size, 0); -} - -void DialogOpenButton_Click(entity button, entity tab) -{ - DialogOpenButton_Click_withCoords(button, tab, button.origin, button.size); -} + void ModalController_initializeDialog(entity me, entity root) + { + me.hideAll(me, 1); + me.showChild(me, root, '0 0 0', '0 0 0', 1); // someone else animates for us + } -void DialogOpenButton_Click_withCoords(entity button, entity tab, vector theOrigin, vector theSize) -{ - if(tab.ModalController_state) - return; - if(button) + void TabButton_Click(entity button, entity tab) + { + if (tab.ModalController_state == 1) return; + tab.parent.hideAll(tab.parent, 0); button.forcePressed = 1; - if(tab.parent.focusedChild) - tab.parent.focusedChild.saveFocus(tab.parent.focusedChild); - tab.ModalController_controllingButton = button; - tab.parent.showChild(tab.parent, tab, theOrigin, theSize, 0); -} + tab.ModalController_controllingButton = button; + tab.parent.showChild(tab.parent, tab, button.origin, button.size, 0); + } -void DialogCloseButton_Click(entity button, entity tab) -{ - tab.parent.hideChild(tab.parent, tab, 0); -} + void DialogOpenButton_Click(entity button, entity tab) + { + DialogOpenButton_Click_withCoords(button, tab, button.origin, button.size); + } -void ModalController_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, ModalController_initialOrigin, ModalController_initialSize, ModalController_initialFontScale); -} + void DialogOpenButton_Click_withCoords(entity button, entity tab, vector theOrigin, vector theSize) + { + if (tab.ModalController_state) return; + if (button) button.forcePressed = 1; + if (tab.parent.focusedChild) tab.parent.focusedChild.saveFocus(tab.parent.focusedChild); + tab.ModalController_controllingButton = button; + tab.parent.showChild(tab.parent, tab, theOrigin, theSize, 0); + } -void ModalController_switchState(entity me, entity other, float state, float skipAnimation) -{ - float previousState; - previousState = other.ModalController_state; - if(state == previousState && !skipAnimation) - return; - other.ModalController_state = state; - switch(state) + void DialogCloseButton_Click(entity button, entity tab) { - case 0: - other.ModalController_factor = 1 - other.Container_alpha / other.ModalController_initialAlpha; - // fading out - break; - case 1: - other.ModalController_factor = other.Container_alpha / other.ModalController_initialAlpha; - if(previousState == 0 && !skipAnimation) - { - other.Container_origin = other.ModalController_buttonOrigin; - other.Container_size = other.ModalController_buttonSize; - } - // zooming in - break; - case 2: - other.ModalController_factor = bound(0, (1 - other.Container_alpha / other.ModalController_initialAlpha) / me.fadedAlpha, 1); - // fading out halfway - break; + tab.parent.hideChild(tab.parent, tab, 0); } - if(skipAnimation) - other.ModalController_factor = 1; -} -void ModalController_draw(entity me) -{ - entity e; - entity front; - float animating; - float f; // animation factor - float df; // animation step size - float prevFactor, targetFactor; - vector targetOrigin, targetSize; float targetAlpha; - vector fs; - animating = 0; + void ModalController_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) + { + me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, ModalController_initialOrigin, ModalController_initialSize, ModalController_initialFontScale); + } - front = world; - for(e = me.firstChild; e; e = e.nextSibling) - if(e.ModalController_state) + void ModalController_switchState(entity me, entity other, float state, float skipAnimation) + { + float previousState; + previousState = other.ModalController_state; + if (state == previousState && !skipAnimation) return; + other.ModalController_state = state; + switch (state) { - if(front) - me.switchState(me, front, 2, 0); - front = e; + case 0: + other.ModalController_factor = 1 - other.Container_alpha / other.ModalController_initialAlpha; + // fading out + break; + case 1: + other.ModalController_factor = other.Container_alpha / other.ModalController_initialAlpha; + if (previousState == 0 && !skipAnimation) + { + other.Container_origin = other.ModalController_buttonOrigin; + other.Container_size = other.ModalController_buttonSize; + } + // zooming in + break; + case 2: + other.ModalController_factor = bound(0, (1 - other.Container_alpha / other.ModalController_initialAlpha) / me.fadedAlpha, 1); + // fading out halfway + break; } - if(front) - me.switchState(me, front, 1, 0); - - df = frametime * 3; // animation speed + if (skipAnimation) other.ModalController_factor = 1; + } - for(e = me.firstChild; e; e = e.nextSibling) + void ModalController_draw(entity me) { - if(e.ModalController_state == 2) - { - // fading out partially - targetOrigin = e.Container_origin; // stay as is - targetSize = e.Container_size; // stay as is - targetAlpha = me.fadedAlpha * e.ModalController_initialAlpha; - } - else if(e.ModalController_state == 1) - { - // zooming in - targetOrigin = e.ModalController_initialOrigin; - targetSize = e.ModalController_initialSize; - targetAlpha = e.ModalController_initialAlpha; - } - else - { - // fading out - targetOrigin = e.Container_origin; // stay as is - targetSize = e.Container_size; // stay as is - targetAlpha = 0; - } + entity e; + entity front; + float animating; + float f; // animation factor + float df; // animation step size + float prevFactor, targetFactor; + vector targetOrigin, targetSize; + float targetAlpha; + vector fs; + animating = 0; + + front = NULL; + for (e = me.firstChild; e; e = e.nextSibling) + if (e.ModalController_state) + { + if (front) me.switchState(me, front, 2, 0); + front = e; + } + if (front) me.switchState(me, front, 1, 0); - f = (e.ModalController_factor = min(1, e.ModalController_factor + df)); - if(f == 1) - { - prevFactor = 0; - targetFactor = 1; - e.Container_origin = targetOrigin; - e.Container_size = targetSize; - me.setAlphaOf(me, e, targetAlpha); - } - else + df = frametime * 3; // animation speed + + for (e = me.firstChild; e; e = e.nextSibling) { - prevFactor = (1 - f) / (1 - f + df); - if(!e.ModalController_state) // optimize code and avoid precision errors - me.setAlphaOf(me, e, e.Container_alpha * prevFactor); + if (e.ModalController_state == 2) + { + // fading out partially + targetOrigin = e.Container_origin; // stay as is + targetSize = e.Container_size; // stay as is + targetAlpha = me.fadedAlpha * e.ModalController_initialAlpha; + } + else if (e.ModalController_state == 1) + { + // zooming in + targetOrigin = e.ModalController_initialOrigin; + targetSize = e.ModalController_initialSize; + targetAlpha = e.ModalController_initialAlpha; + } else { - animating = 1; - targetFactor = df / (1 - f + df); + // fading out + targetOrigin = e.Container_origin; // stay as is + targetSize = e.Container_size; // stay as is + targetAlpha = 0; + } - if(e.ModalController_state == 1) + f = (e.ModalController_factor = min(1, e.ModalController_factor + df)); + if (f == 1) + { + prevFactor = 0; + targetFactor = 1; + e.Container_origin = targetOrigin; + e.Container_size = targetSize; + me.setAlphaOf(me, e, targetAlpha); + } + else + { + prevFactor = (1 - f) / (1 - f + df); + if (!e.ModalController_state) // optimize code and avoid precision errors { - e.Container_origin = e.Container_origin * prevFactor + targetOrigin * targetFactor; - e.Container_size = e.Container_size * prevFactor + targetSize * targetFactor; + me.setAlphaOf(me, e, e.Container_alpha * prevFactor); } - me.setAlphaOf(me, e, e.Container_alpha * prevFactor + targetAlpha * targetFactor); + else + { + animating = 1; + targetFactor = df / (1 - f + df); + + if (e.ModalController_state == 1) + { + e.Container_origin = e.Container_origin * prevFactor + targetOrigin * targetFactor; + e.Container_size = e.Container_size * prevFactor + targetSize * targetFactor; + } + me.setAlphaOf(me, e, e.Container_alpha * prevFactor + targetAlpha * targetFactor); + } + } + // assume: o == to * f_prev + X * (1 - f_prev) + // make: o' = to * f + X * (1 - f) + // --> + // X == (o - to * f_prev) / (1 - f_prev) + // o' = to * f + (o - to * f_prev) / (1 - f_prev) * (1 - f) + // --> (maxima) + // o' = (to * (f - f_prev) + o * (1 - f)) / (1 - f_prev) + + if (e.ModalController_state == 1) + { + fs = globalToBoxSize(e.Container_size, e.ModalController_initialSize); + e.Container_fontscale_x = fs.x * e.ModalController_initialFontScale.x; + e.Container_fontscale_y = fs.y * e.ModalController_initialFontScale.y; } } - // assume: o == to * f_prev + X * (1 - f_prev) - // make: o' = to * f + X * (1 - f) - // --> - // X == (o - to * f_prev) / (1 - f_prev) - // o' = to * f + (o - to * f_prev) / (1 - f_prev) * (1 - f) - // --> (maxima) - // o' = (to * (f - f_prev) + o * (1 - f)) / (1 - f_prev) - if(e.ModalController_state == 1) + if (animating || !me.focused) me.setFocus(me, NULL); + else me.setFocus(me, front); + SUPER(ModalController).draw(me); + } + + void ModalController_addTab(entity me, entity other, entity tabButton) + { + me.addItem(me, other, '0 0 0', '1 1 1', 1); + tabButton.onClick = TabButton_Click; + tabButton.onClickEntity = other; + other.tabSelectingButton = tabButton; + if (other == me.firstChild) { - fs = globalToBoxSize(e.Container_size, e.ModalController_initialSize); - e.Container_fontscale_x = fs.x * e.ModalController_initialFontScale.x; - e.Container_fontscale_y = fs.y * e.ModalController_initialFontScale.y; + tabButton.forcePressed = 1; + other.ModalController_controllingButton = tabButton; + me.showChild(me, other, '0 0 0', '0 0 0', 1); } } - if(animating || !me.focused) - me.setFocus(me, NULL); - else - me.setFocus(me, front); - SUPER(ModalController).draw(me); -} - -void ModalController_addTab(entity me, entity other, entity tabButton) -{ - me.addItem(me, other, '0 0 0', '1 1 1', 1); - tabButton.onClick = TabButton_Click; - tabButton.onClickEntity = other; - other.tabSelectingButton = tabButton; - if(other == me.firstChild) + void ModalController_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha) { - tabButton.forcePressed = 1; - other.ModalController_controllingButton = tabButton; - me.showChild(me, other, '0 0 0', '0 0 0', 1); + SUPER(ModalController).addItem(me, other, theOrigin, theSize, (other == me.firstChild) ? theAlpha : 0); + other.ModalController_initialFontScale = other.Container_fontscale; + other.ModalController_initialSize = other.Container_size; + other.ModalController_initialOrigin = other.Container_origin; + other.ModalController_initialAlpha = theAlpha; // hope Container never modifies this + if (other.ModalController_initialFontScale == '0 0 0') other.ModalController_initialFontScale = '1 1 0'; } -} -void ModalController_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha) -{ - SUPER(ModalController).addItem(me, other, theOrigin, theSize, (other == me.firstChild) ? theAlpha : 0); - other.ModalController_initialFontScale = other.Container_fontscale; - other.ModalController_initialSize = other.Container_size; - other.ModalController_initialOrigin = other.Container_origin; - other.ModalController_initialAlpha = theAlpha; // hope Container never modifies this - if(other.ModalController_initialFontScale == '0 0 0') - other.ModalController_initialFontScale = '1 1 0'; -} - -void ModalController_showChild(entity me, entity other, vector theOrigin, vector theSize, float skipAnimation) -{ - if(other.ModalController_state == 0 || skipAnimation) + void ModalController_showChild(entity me, entity other, vector theOrigin, vector theSize, float skipAnimation) { - me.setFocus(me, NULL); - if(!skipAnimation) + if (other.ModalController_state == 0 || skipAnimation) { - other.ModalController_buttonOrigin = globalToBox(theOrigin, me.origin, me.size); - other.ModalController_buttonSize = globalToBoxSize(theSize, me.size); - } - me.switchState(me, other, 1, skipAnimation); - } // zoom in from button (factor increases) -} + me.setFocus(me, NULL); + if (!skipAnimation) + { + other.ModalController_buttonOrigin = globalToBox(theOrigin, me.origin, me.size); + other.ModalController_buttonSize = globalToBoxSize(theSize, me.size); + } + me.switchState(me, other, 1, skipAnimation); + } // zoom in from button (factor increases) + } -void ModalController_hideAll(entity me, float skipAnimation) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) - me.hideChild(me, e, skipAnimation); -} + void ModalController_hideAll(entity me, float skipAnimation) + { + entity e; + for (e = me.firstChild; e; e = e.nextSibling) + me.hideChild(me, e, skipAnimation); + } -void ModalController_hideChild(entity me, entity other, float skipAnimation) -{ - if(other.ModalController_state || skipAnimation) + void ModalController_hideChild(entity me, entity other, float skipAnimation) { - me.setFocus(me, NULL); - me.switchState(me, other, 0, skipAnimation); - if(other.ModalController_controllingButton) + if (other.ModalController_state || skipAnimation) { - other.ModalController_controllingButton.forcePressed = 0; - other.ModalController_controllingButton = NULL; - } - } // just alpha fade out (factor increases and decreases alpha) -} -#endif + me.setFocus(me, NULL); + me.switchState(me, other, 0, skipAnimation); + if (other.ModalController_controllingButton) + { + other.ModalController_controllingButton.forcePressed = 0; + other.ModalController_controllingButton = NULL; + } + } // just alpha fade out (factor increases and decreases alpha) + }