From: TimePath Date: Tue, 27 Oct 2015 04:02:26 +0000 (+1100) Subject: Uncrustify menu/{anim,item}/* X-Git-Tag: xonotic-v0.8.2~1780 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=a290ec20cac0a267dc7a6136610c263fc12eebb8;p=xonotic%2Fxonotic-data.pk3dir.git Uncrustify menu/{anim,item}/* --- diff --git a/qcsrc/menu/anim/animation.qc b/qcsrc/menu/anim/animation.qc index d24220fef..09bf77217 100644 --- a/qcsrc/menu/anim/animation.qc +++ b/qcsrc/menu/anim/animation.qc @@ -1,124 +1,117 @@ #ifndef ANIM_ANIMATION_H -#define ANIM_ANIMATION_H -void setterDummy(entity, float); -CLASS(Animation, Object) - METHOD(Animation, configureAnimation, void(entity, entity, void(entity, float), float, float, float, float)); - METHOD(Animation, update, void(entity, float, float, float)); - METHOD(Animation, setTimeStartEnd, void(entity, float, float)); - METHOD(Animation, setTimeStartDuration, void(entity, float, float)); - METHOD(Animation, setValueStartEnd, void(entity, float, float)); - METHOD(Animation, setValueStartDelta, void(entity, float, float)); - METHOD(Animation, setObjectSetter, void(entity, entity, void(entity, float))); - METHOD(Animation, tick, void(entity, float)); - METHOD(Animation, calcValue, float(entity, float, float, float, float)); - METHOD(Animation, isStopped, float(entity)); - METHOD(Animation, stopAnim, void(entity)); - METHOD(Animation, resumeAnim, void(entity)); - METHOD(Animation, isFinished, float(entity)); - METHOD(Animation, finishAnim, void(entity)); - ATTRIB(Animation, object, entity, NULL) - ATTRIB(Animation, setter, void(entity, float), setterDummy) - ATTRIB(Animation, value, float, 0) - ATTRIB(Animation, startTime, float, 0) - ATTRIB(Animation, duration, float, 0) - ATTRIB(Animation, startValue, float, 0) - ATTRIB(Animation, delta, float, 0) - ATTRIB(Animation, stopped, float, false) - ATTRIB(Animation, finished, float, false) -ENDCLASS(Animation) + #define ANIM_ANIMATION_H + CLASS(Animation, Object) + METHOD(Animation, configureAnimation, void(entity, entity, void(entity, float), float, float, float, float)); + METHOD(Animation, update, void(entity, float, float, float)); + METHOD(Animation, setTimeStartEnd, void(entity, float, float)); + METHOD(Animation, setTimeStartDuration, void(entity, float, float)); + METHOD(Animation, setValueStartEnd, void(entity, float, float)); + METHOD(Animation, setValueStartDelta, void(entity, float, float)); + METHOD(Animation, setObjectSetter, void(entity, entity, void(entity, float))); + METHOD(Animation, tick, void(entity, float)); + METHOD(Animation, calcValue, float(entity, float, float, float, float)); + METHOD(Animation, isStopped, float(entity)); + METHOD(Animation, stopAnim, void(entity)); + METHOD(Animation, resumeAnim, void(entity)); + METHOD(Animation, isFinished, float(entity)); + METHOD(Animation, finishAnim, void(entity)); + ATTRIB(Animation, object, entity, NULL) + void setterDummy(entity, float) {} + ATTRIB(Animation, setter, void(entity, float), setterDummy) + ATTRIB(Animation, value, float, 0) + ATTRIB(Animation, startTime, float, 0) + ATTRIB(Animation, duration, float, 0) + ATTRIB(Animation, startValue, float, 0) + ATTRIB(Animation, delta, float, 0) + ATTRIB(Animation, stopped, float, false) + ATTRIB(Animation, finished, float, false) + ENDCLASS(Animation) #endif #ifdef IMPLEMENTATION -void Animation_configureAnimation(entity me, entity obj, void(entity, float) objSetter, float animStartTime, float animDuration, float animStartValue, float animEndValue) -{ - me.setObjectSetter(me, obj, objSetter); - me.setTimeStartDuration(me, animStartTime, animDuration); - me.setValueStartEnd(me, animStartValue, animEndValue); -} - -void Animation_update(entity me, float animDuration, float animStartValue, float animEndValue) -{ - me.setTimeStartDuration(me, time, animDuration); - me.setValueStartEnd(me, animStartValue, animEndValue); -} - -void Animation_setTimeStartEnd(entity me, float s, float e) -{ - me.startTime = s; - me.duration = e - s; -} - -void Animation_setTimeStartDuration(entity me, float s, float d) -{ - me.startTime = s; - me.duration = d; -} - -void Animation_setValueStartEnd(entity me, float s, float e) -{ - me.startValue = s; - me.delta = e - s; -} - -void Animation_setValueStartDelta(entity me, float s, float d) -{ - me.startValue = s; - me.delta = d; -} - -void Animation_setObjectSetter(entity me, entity o, void(entity, float) s) -{ - me.object = o; - me.setter = s; -} - -void Animation_tick(entity me, float tickTime) -{ - if (me.isStopped(me) || me.isFinished(me) || (tickTime < me.startTime)) - return; - - if (tickTime >= (me.startTime + me.duration)) - me.finishAnim(me); - else - me.value = me.calcValue(me, (tickTime - me.startTime), me.duration, me.startValue, me.delta); - - me.setter(me.object, me.value); -} - -float Animation_calcValue(entity me, float tickTime, float animDuration, float animStartValue, float animDelta) -{ - return animStartValue; -} - -float Animation_isStopped(entity me) -{ - return me.stopped; -} - -void Animation_stopAnim(entity me) -{ - me.stopped = true; -} - -void Animation_resumeAnim(entity me) -{ - me.stopped = false; -} - -float Animation_isFinished(entity me) -{ - return me.finished; -} - -void Animation_finishAnim(entity me) -{ - me.value = me.delta + me.startValue; - me.finished = true; - me.setter(me.object, me.value); -} - -void setterDummy(entity obj, float objValue) -{ -} + METHOD(Animation, configureAnimation, void(entity this, entity obj, void(entity, float) objSetter, float animStartTime, float animDuration, float animStartValue, float animEndValue)) + { + this.setObjectSetter(this, obj, objSetter); + this.setTimeStartDuration(this, animStartTime, animDuration); + this.setValueStartEnd(this, animStartValue, animEndValue); + } + + METHOD(Animation, update, void(entity this, float animDuration, float animStartValue, float animEndValue)) + { + this.setTimeStartDuration(this, time, animDuration); + this.setValueStartEnd(this, animStartValue, animEndValue); + } + + METHOD(Animation, setTimeStartEnd, void(entity this, float s, float e)) + { + this.startTime = s; + this.duration = e - s; + } + + METHOD(Animation, setTimeStartDuration, void(entity this, float s, float d)) + { + this.startTime = s; + this.duration = d; + } + + METHOD(Animation, setValueStartEnd, void(entity this, float s, float e)) + { + this.startValue = s; + this.delta = e - s; + } + + METHOD(Animation, setValueStartDelta, void(entity this, float s, float d)) + { + this.startValue = s; + this.delta = d; + } + + METHOD(Animation, setObjectSetter, void(entity this, entity o, void(entity, float) s)) + { + this.object = o; + this.setter = s; + } + + METHOD(Animation, tick, void(entity this, float tickTime)) + { + if (this.isStopped(this) || this.isFinished(this) || (tickTime < this.startTime)) return; + + if (tickTime >= (this.startTime + this.duration)) this.finishAnim(this); + else this.value = this.calcValue(this, (tickTime - this.startTime), this.duration, this.startValue, this.delta); + + this.setter(this.object, this.value); + } + + METHOD(Animation, calcValue, float(entity this, float tickTime, float animDuration, float animStartValue, float animDelta)) + { + return animStartValue; + } + + METHOD(Animation, isStopped, bool(entity this)) + { + return this.stopped; + } + + METHOD(Animation, stopAnim, void(entity this)) + { + this.stopped = true; + } + + METHOD(Animation, resumeAnim, void(entity this)) + { + this.stopped = false; + } + + METHOD(Animation, isFinished, bool(entity this)) + { + return this.finished; + } + + METHOD(Animation, finishAnim, void(entity this)) + { + this.value = this.delta + this.startValue; + this.finished = true; + this.setter(this.object, this.value); + } #endif diff --git a/qcsrc/menu/anim/animhost.qc b/qcsrc/menu/anim/animhost.qc index 55ca901dc..7826a47b7 100644 --- a/qcsrc/menu/anim/animhost.qc +++ b/qcsrc/menu/anim/animhost.qc @@ -1,177 +1,143 @@ #include "../menu.qh" #ifndef ANIM_ANIMHOST_H -#define ANIM_ANIMHOST_H -CLASS(AnimHost, Object) - METHOD(AnimHost, addAnim, void(entity, entity)); - METHOD(AnimHost, removeAnim, void(entity, entity)); - METHOD(AnimHost, removeAllAnim, void(entity)); - METHOD(AnimHost, removeObjAnim, void(entity, entity)); - METHOD(AnimHost, stopAllAnim, void(entity)); - METHOD(AnimHost, stopObjAnim, void(entity, entity)); - METHOD(AnimHost, resumeAllAnim, void(entity)); - METHOD(AnimHost, resumeObjAnim, void(entity, entity)); - METHOD(AnimHost, finishAllAnim, void(entity)); - METHOD(AnimHost, finishObjAnim, void(entity, entity)); - METHOD(AnimHost, tickAll, void(entity)); - ATTRIB(AnimHost, firstChild, entity, NULL) - ATTRIB(AnimHost, lastChild, entity, NULL) -ENDCLASS(AnimHost) -.entity nextSibling; -.entity prevSibling; + #define ANIM_ANIMHOST_H + CLASS(AnimHost, Object) + METHOD(AnimHost, addAnim, void(entity, entity)); + METHOD(AnimHost, removeAnim, void(entity, entity)); + METHOD(AnimHost, removeAllAnim, void(entity)); + METHOD(AnimHost, removeObjAnim, void(entity, entity)); + METHOD(AnimHost, stopAllAnim, void(entity)); + METHOD(AnimHost, stopObjAnim, void(entity, entity)); + METHOD(AnimHost, resumeAllAnim, void(entity)); + METHOD(AnimHost, resumeObjAnim, void(entity, entity)); + METHOD(AnimHost, finishAllAnim, void(entity)); + METHOD(AnimHost, finishObjAnim, void(entity, entity)); + METHOD(AnimHost, tickAll, void(entity)); + ATTRIB(AnimHost, firstChild, entity, NULL) + ATTRIB(AnimHost, lastChild, entity, NULL) + ENDCLASS(AnimHost) + .entity nextSibling; + .entity prevSibling; #endif #ifdef IMPLEMENTATION -void AnimHost_addAnim(entity me, entity other) -{ - if(other.parent) - error("Can't add already added anim!"); - - if(other.isFinished(other)) - error("Can't add finished anim!"); - - other.parent = me; - - entity l; - l = me.lastChild; - - if(l) - l.nextSibling = other; - else - me.firstChild = other; - - other.prevSibling = l; - other.nextSibling = NULL; - me.lastChild = other; -} - -void AnimHost_removeAnim(entity me, entity other) -{ - if(other.parent != me) - error("Can't remove from wrong AnimHost!"); - - other.parent = NULL; - - entity n, p; - n = other.nextSibling; - p = other.prevSibling; - - if(p) - p.nextSibling = n; - else - me.firstChild = n; - - if(n) - n.prevSibling = p; - else - me.lastChild = p; - remove(other); -} - -void AnimHost_removeAllAnim(entity me) -{ - entity e, tmp; - for(e = me.firstChild; e; e = e.nextSibling) + METHOD(AnimHost, addAnim, void(entity this, entity other)) { - tmp = e; - e = tmp.prevSibling; - me.removeAnim(me, tmp); + if (other.parent) error("Can't add already added anim!"); + + if (other.isFinished(other)) error("Can't add finished anim!"); + + other.parent = this; + + entity l = this.lastChild; + + if (l) l.nextSibling = other; + else this.firstChild = other; + + other.prevSibling = l; + other.nextSibling = NULL; + this.lastChild = other; + } + + METHOD(AnimHost, removeAnim, void(entity this, entity other)) + { + if (other.parent != this) error("Can't remove from wrong AnimHost!"); + + other.parent = NULL; + + entity n = other.nextSibling; + entity p = other.prevSibling; + + if (p) p.nextSibling = n; + else this.firstChild = n; + + if (n) n.prevSibling = p; + else this.lastChild = p; + remove(other); } -} -void AnimHost_removeObjAnim(entity me, entity obj) -{ - entity e, tmp; - for(e = me.firstChild; e; e = e.nextSibling) + METHOD(AnimHost, removeAllAnim, void(entity this)) { - if (e.object == obj) + for (entity e = this.firstChild; e; e = e.nextSibling) { - tmp = e; + entity tmp = e; e = tmp.prevSibling; - me.removeAnim(me, tmp); + this.removeAnim(this, tmp); } } -} -void AnimHost_stopAllAnim(entity me) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) + METHOD(AnimHost, removeObjAnim, void(entity this, entity obj)) { - e.stopAnim(e); + for (entity e = this.firstChild; e; e = e.nextSibling) + { + if (e.object == obj) + { + entity tmp = e; + e = tmp.prevSibling; + this.removeAnim(this, tmp); + } + } } -} -void AnimHost_stopObjAnim(entity me, entity obj) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) + METHOD(AnimHost, stopAllAnim, void(entity this)) { - if (e.object == obj) - { + for (entity e = this.firstChild; e; e = e.nextSibling) e.stopAnim(e); - } } -} -void AnimHost_resumeAllAnim(entity me) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) + METHOD(AnimHost, stopObjAnim, void(entity this, entity obj)) { - e.resumeAnim(e); + for (entity e = this.firstChild; e; e = e.nextSibling) + if (e.object == obj) e.stopAnim(e); } -} -void AnimHost_resumeObjAnim(entity me, entity obj) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) + METHOD(AnimHost, resumeAllAnim, void(entity this)) { - if (e.object == obj) - { + for (entity e = this.firstChild; e; e = e.nextSibling) e.resumeAnim(e); - } } -} -void AnimHost_finishAllAnim(entity me) -{ - entity e, tmp; - for(e = me.firstChild; e; e = e.nextSibling) + METHOD(AnimHost, resumeObjAnim, void(entity this, entity obj)) { - tmp = e; - e = tmp.prevSibling; - tmp.finishAnim(tmp); + for (entity e = this.firstChild; e; e = e.nextSibling) + if (e.object == obj) e.resumeAnim(e); } -} -void AnimHost_finishObjAnim(entity me, entity obj) -{ - entity e, tmp; - for(e = me.firstChild; e; e = e.nextSibling) + METHOD(AnimHost, finishAllAnim, void(entity this)) { - if (e.object == obj) + for (entity e = this.firstChild; e; e = e.nextSibling) { - tmp = e; + entity tmp = e; e = tmp.prevSibling; tmp.finishAnim(tmp); } } -} -void AnimHost_tickAll(entity me) -{ - entity e, tmp; - for(e = me.firstChild; e; e = e.nextSibling) + METHOD(AnimHost, finishObjAnim, void(entity this, entity obj)) { - e.tick(e, time); - if (e.isFinished(e)) + for (entity e = this.firstChild; e; e = e.nextSibling) { - tmp = e; - e = tmp.prevSibling; - me.removeAnim(me, tmp); + if (e.object == obj) + { + entity tmp = e; + e = tmp.prevSibling; + tmp.finishAnim(tmp); + } + } + } + + METHOD(AnimHost, tickAll, void(entity this)) + { + for (entity e = this.firstChild; e; e = e.nextSibling) + { + e.tick(e, time); + if (e.isFinished(e)) + { + entity tmp = e; + e = tmp.prevSibling; + this.removeAnim(this, tmp); + } } } -} #endif diff --git a/qcsrc/menu/anim/easing.qc b/qcsrc/menu/anim/easing.qc index f1962719f..080f390ba 100644 --- a/qcsrc/menu/anim/easing.qc +++ b/qcsrc/menu/anim/easing.qc @@ -1,74 +1,66 @@ #ifndef ANIM_EASING_H -#define ANIM_EASING_H -#include "animation.qc" -entity makeHostedEasing(entity, void(entity, float), float(float, float, float, float), float, float, float); -entity makeEasing(entity, void(entity, float), float(float, float, float, float), float, float, float, float); -float easingLinear(float, float, float, float); -float easingQuadIn(float, float, float, float); -float easingQuadOut(float, float, float, float); -float easingQuadInOut(float, float, float, float); -CLASS(Easing, Animation) - METHOD(Easing, calcValue, float(entity, float, float, float, float)); - METHOD(Easing, setMath, void(entity, float(float, float, float, float))); - ATTRIB(Easing, math, float(float, float, float, float), easingLinear) -ENDCLASS(Easing) + #define ANIM_EASING_H + #include "animation.qc" + entity makeHostedEasing(entity, void(entity, float), float(float, float, float, float), float, float, float); + entity makeEasing(entity, void(entity, float), float(float, float, float, float), float, float, float, float); + float easingLinear(float, float, float, float); + float easingQuadIn(float, float, float, float); + float easingQuadOut(float, float, float, float); + float easingQuadInOut(float, float, float, float); + CLASS(Easing, Animation) + METHOD(Easing, calcValue, float(entity, float, float, float, float)); + METHOD(Easing, setMath, void(entity, float(float, float, float, float))); + ATTRIB(Easing, math, float(float, float, float, float), easingLinear) + ENDCLASS(Easing) #endif #ifdef IMPLEMENTATION -entity makeHostedEasing(entity obj, void(entity, float) objSetter, float(float, float, float, float) func, float animDuration, float animStartValue, float animEnd) -{ - entity me; - me = makeEasing(obj, objSetter, func, time, animDuration, animStartValue, animEnd); - anim.addAnim(anim, me); - return me; -} - -entity makeEasing(entity obj, void(entity, float) objSetter, float(float, float, float, float) func, float animStartTime, float animDuration, float animStartValue, float animEnd) -{ - entity me; - me = NEW(Easing); - me.configureAnimation(me, obj, objSetter, animStartTime, animDuration, animStartValue, animEnd); - me.setMath(me, func); - return me; -} + entity makeHostedEasing(entity obj, void(entity, float) objSetter, float(float, float, float, float) func, float animDuration, float animStartValue, float animEnd) + { + entity this = makeEasing(obj, objSetter, func, time, animDuration, animStartValue, animEnd); + anim.addAnim(anim, this); + return this; + } -float Easing_calcValue(entity me, float tickTime, float animDuration, float animStart, float animDelta) -{ - return me.math(tickTime, animDuration, animStart, animDelta); -} + entity makeEasing(entity obj, void(entity, float) objSetter, float(float, float, float, float) func, float animStartTime, float animDuration, float animStartValue, float animEnd) + { + entity this = NEW(Easing); + this.configureAnimation(this, obj, objSetter, animStartTime, animDuration, animStartValue, animEnd); + this.setMath(this, func); + return this; + } -void Easing_setMath(entity me, float(float, float, float, float) func) -{ - me.math = func; -} + METHOD(Easing, calcValue, float(entity this, float tickTime, float animDuration, float animStart, float animDelta)) + { + return this.math(tickTime, animDuration, animStart, animDelta); + } -float easingLinear(float tickTime, float animDuration, float animStart, float animDelta) -{ - return (animDelta * (tickTime / animDuration)) + animStart; -} + METHOD(Easing, setMath, void(entity this, float(float, float, float, float) func)) + { + this.math = func; + } -float easingQuadIn(float tickTime, float animDuration, float animStart, float animDelta) -{ - float frac = tickTime / animDuration; - return (animDelta * frac * frac) + animStart; -} + float easingLinear(float tickTime, float animDuration, float animStart, float animDelta) + { + return (animDelta * (tickTime / animDuration)) + animStart; + } -float easingQuadOut(float tickTime, float animDuration, float animStart, float animDelta) -{ - float frac = tickTime / animDuration; - return (-animDelta * frac * (frac - 2)) + animStart; -} + float easingQuadIn(float tickTime, float animDuration, float animStart, float animDelta) + { + float frac = tickTime / animDuration; + return (animDelta * frac * frac) + animStart; + } -float easingQuadInOut(float tickTime, float animDuration, float animStart, float animDelta) -{ - if (tickTime < (animDuration / 2)) + float easingQuadOut(float tickTime, float animDuration, float animStart, float animDelta) { - return easingQuadIn(tickTime, (animDuration / 2), animStart, (animDelta / 2)); + float frac = tickTime / animDuration; + return (-animDelta * frac * (frac - 2)) + animStart; } - else + + float easingQuadInOut(float tickTime, float animDuration, float animStart, float animDelta) { - return easingQuadOut((tickTime - (animDuration / 2)), (animDuration / 2), (animStart + (animDelta / 2)), (animDelta / 2)); + if (tickTime < (animDuration / 2)) return easingQuadIn(tickTime, (animDuration / 2), animStart, (animDelta / 2)); + else return easingQuadOut((tickTime - (animDuration / 2)), (animDuration / 2), (animStart + (animDelta / 2)), (animDelta / 2)); } -} #endif diff --git a/qcsrc/menu/anim/keyframe.qc b/qcsrc/menu/anim/keyframe.qc index d83a2cbd4..eec5c03ae 100644 --- a/qcsrc/menu/anim/keyframe.qc +++ b/qcsrc/menu/anim/keyframe.qc @@ -1,110 +1,100 @@ #ifndef ANIM_KEYFRAME_H -#define ANIM_KEYFRAME_H -#include "animation.qc" -CLASS(Keyframe, Animation) - METHOD(Keyframe, addEasing, entity(entity, float, float, float(float, float, float, float))); - METHOD(Keyframe, addAnim, void(entity, entity)); - METHOD(Keyframe, calcValue, float(entity, float, float, float, float)); - ATTRIB(Keyframe, currentChild, entity, NULL) - ATTRIB(Keyframe, firstChild, entity, NULL) - ATTRIB(Keyframe, lastChild, entity, NULL) -ENDCLASS(Keyframe) -entity makeHostedKeyframe(entity, void(entity, float), float, float, float); -entity makeKeyframe(entity, void(entity, float), float, float, float); -float getNewChildStart(entity); -float getNewChildDuration(entity, float); -float getNewChildValue(entity); + #define ANIM_KEYFRAME_H + #include "animation.qc" + CLASS(Keyframe, Animation) + METHOD(Keyframe, addEasing, entity(entity, float, float, float(float, float, float, float))); + METHOD(Keyframe, addAnim, void(entity, entity)); + METHOD(Keyframe, calcValue, float(entity, float, float, float, float)); + ATTRIB(Keyframe, currentChild, entity, NULL) + ATTRIB(Keyframe, firstChild, entity, NULL) + ATTRIB(Keyframe, lastChild, entity, NULL) + ENDCLASS(Keyframe) + entity makeHostedKeyframe(entity, void(entity, float), float, float, float); + entity makeKeyframe(entity, void(entity, float), float, float, float); + float getNewChildStart(entity); + float getNewChildDuration(entity, float); + float getNewChildValue(entity); #endif #ifdef IMPLEMENTATION -entity makeHostedKeyframe(entity obj, void(entity, float) objSetter, float animDuration, float animStart, float animEnd) -{ - entity me; - me = makeKeyframe(obj, objSetter, animDuration, animStart, animEnd); - anim.addAnim(anim, me); - return me; -} + entity makeHostedKeyframe(entity obj, void(entity, float) objSetter, float animDuration, float animStart, float animEnd) + { + entity this = makeKeyframe(obj, objSetter, animDuration, animStart, animEnd); + anim.addAnim(anim, this); + return this; + } -entity makeKeyframe(entity obj, void(entity, float) objSetter, float animDuration, float animStart, float animEnd) -{ - entity me; - me = NEW(Keyframe); - me.configureAnimation(me, obj, objSetter, time, animDuration, animStart, animEnd); - return me; -} + entity makeKeyframe(entity obj, void(entity, float) objSetter, float animDuration, float animStart, float animEnd) + { + entity this = NEW(Keyframe); + this.configureAnimation(this, obj, objSetter, time, animDuration, animStart, animEnd); + return this; + } -entity Keyframe_addEasing(entity me, float animDurationTime, float animEnd, float(float, float, float, float) func) -{ - entity other; - other = makeEasing(me.object, me.setter, func, getNewChildStart(me), getNewChildDuration(me, animDurationTime), getNewChildValue(me), animEnd); - me.addAnim(me, other); - return other; -} + METHOD(Keyframe, addEasing, entity(entity this, float animDurationTime, float animEnd, float(float, float, float, float) func)) + { + entity other = makeEasing(this.object, this.setter, func, getNewChildStart(this), getNewChildDuration(this, animDurationTime), getNewChildValue(this), animEnd); + this.addAnim(this, other); + return other; + } + + float getNewChildStart(entity this) + { + if (this.lastChild) return this.lastChild.startTime + this.lastChild.duration; + else return 0; + } -float getNewChildStart(entity me) -{ - if (me.lastChild) - return (me.lastChild.startTime + me.lastChild.duration); - else - return 0; -} + float getNewChildDuration(entity this, float durationTime) + { + float maxDura = this.duration; + if (this.lastChild) maxDura = maxDura - (this.lastChild.startTime + this.lastChild.duration); + float dura = durationTime; + if (0 >= dura || dura > maxDura) dura = maxDura; + return dura; + } -float getNewChildDuration(entity me, float durationTime) -{ - float dura, maxDura; - maxDura = me.duration; - if (me.lastChild) maxDura = maxDura - (me.lastChild.startTime + me.lastChild.duration); - dura = durationTime; - if (0 >= dura || dura > maxDura) dura = maxDura; - return dura; -} + float getNewChildValue(entity this) + { + if (this.lastChild) return this.lastChild.startValue + this.lastChild.delta; + else return this.startValue; + } -float getNewChildValue(entity me) -{ - if (me.lastChild) - return (me.lastChild.startValue + me.lastChild.delta); - else - return me.startValue; -} + METHOD(Keyframe, addAnim, void(entity this, entity other)) + { + if (other.parent) error("Can't add already added anim!"); -void Keyframe_addAnim(entity me, entity other) -{ - if(other.parent) - error("Can't add already added anim!"); + if (other.isFinished(other)) error("Can't add finished anim!"); - if(other.isFinished(other)) - error("Can't add finished anim!"); + other.parent = this; - other.parent = me; + entity l = this.lastChild; - entity l; - l = me.lastChild; + if (l) + { + l.nextSibling = other; + } + else + { + this.currentChild = other; + this.firstChild = other; + } - if(l) - l.nextSibling = other; - else - { - me.currentChild = other; - me.firstChild = other; + other.prevSibling = l; + other.nextSibling = NULL; + this.lastChild = other; } - other.prevSibling = l; - other.nextSibling = NULL; - me.lastChild = other; -} + METHOD(Keyframe, calcValue, float(entity this, float tickTime, float animDuration, float animStartValue, float animDelta)) + { + if (this.currentChild) + if (this.currentChild.isFinished(this.currentChild)) this.currentChild = this.currentChild.nextSibling; -float Keyframe_calcValue(entity me, float tickTime, float animDuration, float animStartValue, float animDelta) -{ - if (me.currentChild) - if (me.currentChild.isFinished(me.currentChild)) - me.currentChild = me.currentChild.nextSibling; + if (this.currentChild) + { + this.currentChild.tick(this.currentChild, tickTime); + return this.currentChild.value; + } - if (me.currentChild) - { - me.currentChild.tick(me.currentChild, tickTime); - return me.currentChild.value; + return animStartValue + animDelta; } - - return animStartValue + animDelta; -} #endif diff --git a/qcsrc/menu/item/borderimage.qc b/qcsrc/menu/item/borderimage.qc index bcbd408ed..4acf33d86 100644 --- a/qcsrc/menu/item/borderimage.qc +++ b/qcsrc/menu/item/borderimage.qc @@ -1,112 +1,111 @@ #ifndef ITEM_BORDERIMAGE_H -#define ITEM_BORDERIMAGE_H -#include "label.qc" -CLASS(BorderImage, Label) - METHOD(BorderImage, configureBorderImage, void(entity, string, float, vector, string, float)); - METHOD(BorderImage, resizeNotify, void(entity, vector, vector, vector, vector)); - METHOD(BorderImage, recalcPositionWithText, void(entity, string)); - ATTRIB(BorderImage, isBold, float, 1) - METHOD(BorderImage, draw, void(entity)); - ATTRIB(BorderImage, src, string, string_null) - ATTRIB(BorderImage, borderHeight, float, 0) - ATTRIB(BorderImage, borderVec, vector, '0 0 0') - ATTRIB(BorderImage, color, vector, '1 1 1') - ATTRIB(BorderImage, closeButton, entity, NULL) - ATTRIB(BorderImage, realFontSize_Nexposeed, vector, '0 0 0') - ATTRIB(BorderImage, realOrigin_Nexposeed, vector, '0 0 0') - ATTRIB(BorderImage, isNexposeeTitleBar, float, 0) - ATTRIB(BorderImage, zoomedOutTitleBarPosition, float, 0) - ATTRIB(BorderImage, zoomedOutTitleBar, float, 0) - ATTRIB(BorderImage, overrideRealOrigin, vector, '0 1 0') - ATTRIB(BorderImage, saveRelOrigin, vector, '0 0 0') - ATTRIB(BorderImage, saveRelSize, vector, '0 0 0') -ENDCLASS(BorderImage) + #define ITEM_BORDERIMAGE_H + #include "label.qc" + CLASS(BorderImage, Label) + METHOD(BorderImage, configureBorderImage, void(entity, string, float, vector, string, float)); + METHOD(BorderImage, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(BorderImage, recalcPositionWithText, void(entity, string)); + ATTRIB(BorderImage, isBold, float, 1) + METHOD(BorderImage, draw, void(entity)); + ATTRIB(BorderImage, src, string, string_null) + ATTRIB(BorderImage, borderHeight, float, 0) + ATTRIB(BorderImage, borderVec, vector, '0 0 0') + ATTRIB(BorderImage, color, vector, '1 1 1') + ATTRIB(BorderImage, closeButton, entity, NULL) + ATTRIB(BorderImage, realFontSize_Nexposeed, vector, '0 0 0') + ATTRIB(BorderImage, realOrigin_Nexposeed, vector, '0 0 0') + ATTRIB(BorderImage, isNexposeeTitleBar, float, 0) + ATTRIB(BorderImage, zoomedOutTitleBarPosition, float, 0) + ATTRIB(BorderImage, zoomedOutTitleBar, float, 0) + ATTRIB(BorderImage, overrideRealOrigin, vector, '0 1 0') + ATTRIB(BorderImage, saveRelOrigin, vector, '0 0 0') + ATTRIB(BorderImage, saveRelSize, vector, '0 0 0') + ENDCLASS(BorderImage) #endif #ifdef IMPLEMENTATION -void BorderImage_recalcPositionWithText(entity me, string t) -{ - if(me.isNexposeeTitleBar) + void BorderImage_recalcPositionWithText(entity me, string t) { - vector scrs; - scrs = eX * conwidth + eY * conheight; - me.resizeNotify(me, me.saveRelOrigin, me.saveRelSize, boxToGlobal(me.parent.Nexposee_smallOrigin, '0 0 0', scrs), boxToGlobalSize(me.parent.Nexposee_smallSize, scrs)); + if (me.isNexposeeTitleBar) + { + vector scrs; + scrs = eX * conwidth + eY * conheight; + me.resizeNotify(me, me.saveRelOrigin, me.saveRelSize, boxToGlobal(me.parent.Nexposee_smallOrigin, '0 0 0', scrs), boxToGlobalSize(me.parent.Nexposee_smallSize, scrs)); + SUPER(BorderImage).recalcPositionWithText(me, t); + me.realOrigin_y = me.realFontSize.y * me.zoomedOutTitleBarPosition; + me.realOrigin_Nexposeed = me.realOrigin; + me.realFontSize_Nexposeed = me.realFontSize; + me.resizeNotify(me, me.saveRelOrigin, me.saveRelSize, boxToGlobal(me.parent.Nexposee_initialOrigin, '0 0 0', scrs), boxToGlobalSize(me.parent.Nexposee_initialSize, scrs)); + } SUPER(BorderImage).recalcPositionWithText(me, t); - me.realOrigin_y = me.realFontSize.y * me.zoomedOutTitleBarPosition; - me.realOrigin_Nexposeed = me.realOrigin; - me.realFontSize_Nexposeed = me.realFontSize; - me.resizeNotify(me, me.saveRelOrigin, me.saveRelSize, boxToGlobal(me.parent.Nexposee_initialOrigin, '0 0 0', scrs), boxToGlobalSize(me.parent.Nexposee_initialSize, scrs)); } - SUPER(BorderImage).recalcPositionWithText(me, t); -} -void BorderImage_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.isNexposeeTitleBar = 0; - if(me.zoomedOutTitleBar) - if(me.parent.parent.instanceOfNexposee) - if(me.parent.instanceOfDialog) - if(me == me.parent.frame) - me.isNexposeeTitleBar = 1; - me.saveRelOrigin = relOrigin; - me.saveRelSize = relSize; - SUPER(BorderImage).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - me.borderVec_x = me.borderHeight / absSize.x; - me.borderVec_y = me.borderHeight / absSize.y; - me.realOrigin_y = 0.5 * (me.borderVec.y - me.realFontSize.y); - if(me.closeButton) + void BorderImage_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) { - // move the close button to the right place - me.closeButton.Container_origin = '1 0 0' * (1 - me.borderVec.x); - me.closeButton.Container_size = me.borderVec; - me.closeButton.color = me.color; - me.closeButton.colorC = me.color; - me.closeButton.colorF = me.color; + me.isNexposeeTitleBar = 0; + if (me.zoomedOutTitleBar) + if (me.parent.parent.instanceOfNexposee) + if (me.parent.instanceOfDialog) + if (me == me.parent.frame) me.isNexposeeTitleBar = 1; + me.saveRelOrigin = relOrigin; + me.saveRelSize = relSize; + SUPER(BorderImage).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + me.borderVec_x = me.borderHeight / absSize.x; + me.borderVec_y = me.borderHeight / absSize.y; + me.realOrigin_y = 0.5 * (me.borderVec.y - me.realFontSize.y); + if (me.closeButton) + { + // move the close button to the right place + me.closeButton.Container_origin = '1 0 0' * (1 - me.borderVec.x); + me.closeButton.Container_size = me.borderVec; + me.closeButton.color = me.color; + me.closeButton.colorC = me.color; + me.closeButton.colorF = me.color; + } } -} -void BorderImage_configureBorderImage(entity me, string theTitle, float sz, vector theColor, string path, float theBorderHeight) -{ - me.configureLabel(me, theTitle, sz, 0.5); - me.src = path; - me.color = theColor; - me.borderHeight = theBorderHeight; -} -void BorderImage_draw(entity me) -{ - if(me.src) - draw_BorderPicture('0 0 0', me.src, '1 1 0', me.color, 1, me.borderVec); - - if(me.fontSize > 0) + void BorderImage_configureBorderImage(entity me, string theTitle, float sz, vector theColor, string path, float theBorderHeight) + { + me.configureLabel(me, theTitle, sz, 0.5); + me.src = path; + me.color = theColor; + me.borderHeight = theBorderHeight; + } + void BorderImage_draw(entity me) { - if(me.recalcPos) - me.recalcPositionWithText(me, me.text); + if (me.src) draw_BorderPicture('0 0 0', me.src, '1 1 0', me.color, 1, me.borderVec); - if(me.isNexposeeTitleBar) + if (me.fontSize > 0) { - vector ro, rf, df; + if (me.recalcPos) me.recalcPositionWithText(me, me.text); - // me.parent.Nexposee_animationFactor 0 (small) or 1 (full) - // default values are for 1 - ro = me.realOrigin; - rf = me.realFontSize; - df = draw_fontscale; - me.realOrigin = ro * me.parent.Nexposee_animationFactor + me.realOrigin_Nexposeed * (1 - me.parent.Nexposee_animationFactor); - me.realFontSize = rf * me.parent.Nexposee_animationFactor + me.realFontSize_Nexposeed * (1 - me.parent.Nexposee_animationFactor); - draw_fontscale = globalToBoxSize(boxToGlobalSize(df, me.realFontSize), rf); + if (me.isNexposeeTitleBar) + { + vector ro, rf, df; - SUPER(BorderImage).draw(me); + // me.parent.Nexposee_animationFactor 0 (small) or 1 (full) + // default values are for 1 + ro = me.realOrigin; + rf = me.realFontSize; + df = draw_fontscale; + me.realOrigin = ro * me.parent.Nexposee_animationFactor + me.realOrigin_Nexposeed * (1 - me.parent.Nexposee_animationFactor); + me.realFontSize = rf * me.parent.Nexposee_animationFactor + me.realFontSize_Nexposeed * (1 - me.parent.Nexposee_animationFactor); + draw_fontscale = globalToBoxSize(boxToGlobalSize(df, me.realFontSize), rf); + + SUPER(BorderImage).draw(me); - // me.Nexposee_animationState 0 (small) or 1 (full) - // default values are for 1 - me.realOrigin = ro; - me.realFontSize = rf; - draw_fontscale = df; + // me.Nexposee_animationState 0 (small) or 1 (full) + // default values are for 1 + me.realOrigin = ro; + me.realFontSize = rf; + draw_fontscale = df; + } + else + { + SUPER(BorderImage).draw(me); + } } else + { SUPER(BorderImage).draw(me); + } } - else - { - SUPER(BorderImage).draw(me); - } -} #endif diff --git a/qcsrc/menu/item/button.qc b/qcsrc/menu/item/button.qc index 934e8cd34..a9112b88f 100644 --- a/qcsrc/menu/item/button.qc +++ b/qcsrc/menu/item/button.qc @@ -1,180 +1,164 @@ #ifndef ITEM_BUTTON_H -#define ITEM_BUTTON_H -#include "label.qc" -CLASS(Button, Label) - METHOD(Button, configureButton, void(entity, string, float, string)); - METHOD(Button, draw, void(entity)); - METHOD(Button, showNotify, void(entity)); - METHOD(Button, resizeNotify, void(entity, vector, vector, vector, vector)); - METHOD(Button, keyDown, float(entity, float, float, float)); - METHOD(Button, mousePress, float(entity, vector)); - METHOD(Button, mouseDrag, float(entity, vector)); - METHOD(Button, mouseRelease, float(entity, vector)); - METHOD(Button, playClickSound, void(entity)); - ATTRIB(Button, onClick, void(entity, entity), func_null) - ATTRIB(Button, onClickEntity, entity, NULL) - ATTRIB(Button, src, string, string_null) - ATTRIB(Button, srcSuffix, string, string_null) - ATTRIB(Button, src2, string, string_null) // is centered, same aspect, and stretched to label size - ATTRIB(Button, src2scale, float, 1) - ATTRIB(Button, srcMulti, float, 1) // 0: button square left, text right; 1: button stretched, text over it - ATTRIB(Button, buttonLeftOfText, float, 0) - ATTRIB(Button, focusable, float, 1) - ATTRIB(Button, allowFocusSound, float, 1) - ATTRIB(Button, pressed, float, 0) - ATTRIB(Button, clickTime, float, 0) - ATTRIB(Button, disabled, float, 0) - ATTRIB(Button, disabledAlpha, float, 0.3) - ATTRIB(Button, forcePressed, float, 0) - ATTRIB(Button, color, vector, '1 1 1') - ATTRIB(Button, colorC, vector, '1 1 1') - ATTRIB(Button, colorF, vector, '1 1 1') - ATTRIB(Button, colorD, vector, '1 1 1') - ATTRIB(Button, color2, vector, '1 1 1') - ATTRIB(Button, alpha2, float, 1) + #define ITEM_BUTTON_H + #include "label.qc" + CLASS(Button, Label) + METHOD(Button, configureButton, void(entity, string, float, string)); + METHOD(Button, draw, void(entity)); + METHOD(Button, showNotify, void(entity)); + METHOD(Button, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Button, keyDown, float(entity, float, float, float)); + METHOD(Button, mousePress, float(entity, vector)); + METHOD(Button, mouseDrag, float(entity, vector)); + METHOD(Button, mouseRelease, float(entity, vector)); + METHOD(Button, playClickSound, void(entity)); + ATTRIB(Button, onClick, void(entity, entity), func_null) + ATTRIB(Button, onClickEntity, entity, NULL) + ATTRIB(Button, src, string, string_null) + ATTRIB(Button, srcSuffix, string, string_null) + ATTRIB(Button, src2, string, string_null) // is centered, same aspect, and stretched to label size + ATTRIB(Button, src2scale, float, 1) + ATTRIB(Button, srcMulti, float, 1) // 0: button square left, text right; 1: button stretched, text over it + ATTRIB(Button, buttonLeftOfText, float, 0) + ATTRIB(Button, focusable, float, 1) + ATTRIB(Button, allowFocusSound, float, 1) + ATTRIB(Button, pressed, float, 0) + ATTRIB(Button, clickTime, float, 0) + ATTRIB(Button, disabled, float, 0) + ATTRIB(Button, disabledAlpha, float, 0.3) + ATTRIB(Button, forcePressed, float, 0) + ATTRIB(Button, color, vector, '1 1 1') + ATTRIB(Button, colorC, vector, '1 1 1') + ATTRIB(Button, colorF, vector, '1 1 1') + ATTRIB(Button, colorD, vector, '1 1 1') + ATTRIB(Button, color2, vector, '1 1 1') + ATTRIB(Button, alpha2, float, 1) - ATTRIB(Button, origin, vector, '0 0 0') - ATTRIB(Button, size, vector, '0 0 0') -ENDCLASS(Button) + ATTRIB(Button, origin, vector, '0 0 0') + ATTRIB(Button, size, vector, '0 0 0') + ENDCLASS(Button) #endif #ifdef IMPLEMENTATION -void Button_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - if(me.srcMulti) - me.keepspaceLeft = 0; - else - me.keepspaceLeft = min(0.8, absSize.x == 0 ? 0 : (absSize.y / absSize.x)); - SUPER(Button).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); -} -void Button_configureButton(entity me, string txt, float sz, string gfx) -{ - SUPER(Button).configureLabel(me, txt, sz, me.srcMulti ? 0.5 : 0); - me.src = gfx; -} -float Button_keyDown(entity me, float key, float ascii, float shift) -{ - if(key == K_ENTER || key == K_SPACE || key == K_KP_ENTER) + void Button_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) { - me.playClickSound(me); - me.clickTime = 0.1; // delayed for effect - return 1; + if (me.srcMulti) me.keepspaceLeft = 0; + else me.keepspaceLeft = min(0.8, absSize.x == 0 ? 0 : (absSize.y / absSize.x)); + SUPER(Button).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + } + void Button_configureButton(entity me, string txt, float sz, string gfx) + { + SUPER(Button).configureLabel(me, txt, sz, me.srcMulti ? 0.5 : 0); + me.src = gfx; } - return 0; -} -float Button_mouseDrag(entity me, vector pos) -{ - me.pressed = 1; - if(pos.x < 0) me.pressed = 0; - if(pos.y < 0) me.pressed = 0; - if(pos.x >= 1) me.pressed = 0; - if(pos.y >= 1) me.pressed = 0; - return 1; -} -float Button_mousePress(entity me, vector pos) -{ - me.mouseDrag(me, pos); // verify coordinates - return 1; -} -float Button_mouseRelease(entity me, vector pos) -{ - me.mouseDrag(me, pos); // verify coordinates - if(me.pressed) + float Button_keyDown(entity me, float key, float ascii, float shift) { - if (!me.disabled) + if (key == K_ENTER || key == K_SPACE || key == K_KP_ENTER) { me.playClickSound(me); - if(me.onClick) - me.onClick(me, me.onClickEntity); + me.clickTime = 0.1; // delayed for effect + return 1; } - me.pressed = 0; + return 0; } - return 1; -} -void Button_showNotify(entity me) -{ - me.focusable = !me.disabled; -} -void Button_draw(entity me) -{ - vector bOrigin, bSize; - float save; - - me.focusable = !me.disabled; - - save = draw_alpha; - if(me.disabled) - draw_alpha *= me.disabledAlpha; - - if(me.src) + float Button_mouseDrag(entity me, vector pos) + { + me.pressed = 1; + if (pos.x < 0) me.pressed = 0; + if (pos.y < 0) me.pressed = 0; + if (pos.x >= 1) me.pressed = 0; + if (pos.y >= 1) me.pressed = 0; + return 1; + } + float Button_mousePress(entity me, vector pos) { - if(me.srcMulti) + me.mouseDrag(me, pos); // verify coordinates + return 1; + } + float Button_mouseRelease(entity me, vector pos) + { + me.mouseDrag(me, pos); // verify coordinates + if (me.pressed) { - bOrigin = '0 0 0'; - bSize = '1 1 0'; - if(me.disabled) - draw_ButtonPicture(bOrigin, strcat(me.src, "_d", me.srcSuffix), bSize, me.colorD, 1); - else if(me.forcePressed || me.pressed || me.clickTime > 0) - draw_ButtonPicture(bOrigin, strcat(me.src, "_c", me.srcSuffix), bSize, me.colorC, 1); - else if(me.focused) - draw_ButtonPicture(bOrigin, strcat(me.src, "_f", me.srcSuffix), bSize, me.colorF, 1); - else - draw_ButtonPicture(bOrigin, strcat(me.src, "_n", me.srcSuffix), bSize, me.color, 1); + if (!me.disabled) + { + me.playClickSound(me); + if (me.onClick) me.onClick(me, me.onClickEntity); + } + me.pressed = 0; } - else + return 1; + } + void Button_showNotify(entity me) + { + me.focusable = !me.disabled; + } + void Button_draw(entity me) + { + vector bOrigin, bSize; + float save; + + me.focusable = !me.disabled; + + save = draw_alpha; + if (me.disabled) draw_alpha *= me.disabledAlpha; + + if (me.src) { - if(me.realFontSize_y == 0) + if (me.srcMulti) { bOrigin = '0 0 0'; bSize = '1 1 0'; + if (me.disabled) draw_ButtonPicture(bOrigin, strcat(me.src, "_d", me.srcSuffix), bSize, me.colorD, 1); + else if (me.forcePressed || me.pressed || me.clickTime > 0) draw_ButtonPicture(bOrigin, strcat(me.src, "_c", me.srcSuffix), bSize, me.colorC, 1); + else if (me.focused) draw_ButtonPicture(bOrigin, strcat(me.src, "_f", me.srcSuffix), bSize, me.colorF, 1); + else draw_ButtonPicture(bOrigin, strcat(me.src, "_n", me.srcSuffix), bSize, me.color, 1); } else { - bOrigin = eY * (0.5 * (1 - me.realFontSize.y)) + eX * (0.5 * (me.keepspaceLeft - me.realFontSize.x)); - bSize = me.realFontSize; + if (me.realFontSize_y == 0) + { + bOrigin = '0 0 0'; + bSize = '1 1 0'; + } + else + { + bOrigin = eY * (0.5 * (1 - me.realFontSize.y)) + eX * (0.5 * (me.keepspaceLeft - me.realFontSize.x)); + bSize = me.realFontSize; + } + if (me.disabled) draw_Picture(bOrigin, strcat(me.src, "_d", me.srcSuffix), bSize, me.colorD, 1); + else if (me.forcePressed || me.pressed || me.clickTime > 0) draw_Picture(bOrigin, strcat(me.src, "_c", me.srcSuffix), bSize, me.colorC, 1); + else if (me.focused) draw_Picture(bOrigin, strcat(me.src, "_f", me.srcSuffix), bSize, me.colorF, 1); + else draw_Picture(bOrigin, strcat(me.src, "_n", me.srcSuffix), bSize, me.color, 1); } - if(me.disabled) - draw_Picture(bOrigin, strcat(me.src, "_d", me.srcSuffix), bSize, me.colorD, 1); - else if(me.forcePressed || me.pressed || me.clickTime > 0) - draw_Picture(bOrigin, strcat(me.src, "_c", me.srcSuffix), bSize, me.colorC, 1); - else if(me.focused) - draw_Picture(bOrigin, strcat(me.src, "_f", me.srcSuffix), bSize, me.colorF, 1); - else - draw_Picture(bOrigin, strcat(me.src, "_n", me.srcSuffix), bSize, me.color, 1); } - } - if(me.src2) - { - bOrigin = me.keepspaceLeft * eX; - bSize = eY + eX * (1 - me.keepspaceLeft); + if (me.src2) + { + bOrigin = me.keepspaceLeft * eX; + bSize = eY + eX * (1 - me.keepspaceLeft); - bOrigin += bSize * (0.5 - 0.5 * me.src2scale); - bSize = bSize * me.src2scale; + bOrigin += bSize * (0.5 - 0.5 * me.src2scale); + bSize = bSize * me.src2scale; - draw_Picture(bOrigin, me.src2, bSize, me.color2, me.alpha2); - } + draw_Picture(bOrigin, me.src2, bSize, me.color2, me.alpha2); + } + + draw_alpha = save; - draw_alpha = save; + if (me.clickTime > 0 && me.clickTime <= frametime) + { + // keyboard click timer expired? Fire the event then. + if (!me.disabled) + if (me.onClick) me.onClick(me, me.onClickEntity); + } + me.clickTime -= frametime; - if(me.clickTime > 0 && me.clickTime <= frametime) + SUPER(Button).draw(me); + } + void Dialog_Close(entity button, entity me); + void Button_playClickSound(entity me) { - // keyboard click timer expired? Fire the event then. - if (!me.disabled) - if(me.onClick) - me.onClick(me, me.onClickEntity); + if (me.onClick == DialogOpenButton_Click) m_play_click_sound(MENU_SOUND_OPEN); + else if (me.onClick == Dialog_Close) m_play_click_sound(MENU_SOUND_CLOSE); + else m_play_click_sound(MENU_SOUND_EXECUTE); } - me.clickTime -= frametime; - - SUPER(Button).draw(me); -} -void Dialog_Close(entity button, entity me); -void Button_playClickSound(entity me) -{ - if(me.onClick == DialogOpenButton_Click) - m_play_click_sound(MENU_SOUND_OPEN); - else if(me.onClick == Dialog_Close) - m_play_click_sound(MENU_SOUND_CLOSE); - else - m_play_click_sound(MENU_SOUND_EXECUTE); -} #endif diff --git a/qcsrc/menu/item/checkbox.qc b/qcsrc/menu/item/checkbox.qc index cda07c518..17bc50103 100644 --- a/qcsrc/menu/item/checkbox.qc +++ b/qcsrc/menu/item/checkbox.qc @@ -1,55 +1,57 @@ #ifndef ITEM_CHECKBOX_H -#define ITEM_CHECKBOX_H -#include "button.qc" -void CheckBox_Click(entity me, entity other); -CLASS(CheckBox, Button) - METHOD(CheckBox, configureCheckBox, void(entity, string, float, string)); - METHOD(CheckBox, draw, void(entity)); - METHOD(CheckBox, playClickSound, void(entity)); - METHOD(CheckBox, toString, string(entity)); - METHOD(CheckBox, setChecked, void(entity, float)); - ATTRIB(CheckBox, useDownAsChecked, float, 0) - ATTRIB(CheckBox, checked, float, 0) - ATTRIB(CheckBox, onClick, void(entity, entity), CheckBox_Click) - ATTRIB(CheckBox, srcMulti, float, 0) - ATTRIB(CheckBox, disabled, float, 0) -ENDCLASS(CheckBox) + #define ITEM_CHECKBOX_H + #include "button.qc" + void CheckBox_Click(entity me, entity other); + CLASS(CheckBox, Button) + METHOD(CheckBox, configureCheckBox, void(entity, string, float, string)); + METHOD(CheckBox, draw, void(entity)); + METHOD(CheckBox, playClickSound, void(entity)); + METHOD(CheckBox, toString, string(entity)); + METHOD(CheckBox, setChecked, void(entity, float)); + ATTRIB(CheckBox, useDownAsChecked, float, 0) + ATTRIB(CheckBox, checked, float, 0) + ATTRIB(CheckBox, onClick, void(entity, entity), CheckBox_Click) + ATTRIB(CheckBox, srcMulti, float, 0) + ATTRIB(CheckBox, disabled, float, 0) + ENDCLASS(CheckBox) #endif #ifdef IMPLEMENTATION -void CheckBox_setChecked(entity me, float val) -{ - me.checked = val; -} -void CheckBox_Click(entity me, entity other) -{ - me.setChecked(me, !me.checked); -} -string CheckBox_toString(entity me) -{ - return strcat(SUPER(CheckBox).toString(me), ", ", me.checked ? "checked" : "unchecked"); -} -void CheckBox_configureCheckBox(entity me, string txt, float sz, string gfx) -{ - me.configureButton(me, txt, sz, gfx); - me.align = 0; -} -void CheckBox_draw(entity me) -{ - float s; - s = me.pressed; - if(me.useDownAsChecked) + void CheckBox_setChecked(entity me, float val) { - me.srcSuffix = string_null; - me.forcePressed = me.checked; + me.checked = val; + } + void CheckBox_Click(entity me, entity other) + { + me.setChecked(me, !me.checked); + } + string CheckBox_toString(entity me) + { + return strcat(SUPER(CheckBox).toString(me), ", ", me.checked ? "checked" : "unchecked"); + } + void CheckBox_configureCheckBox(entity me, string txt, float sz, string gfx) + { + me.configureButton(me, txt, sz, gfx); + me.align = 0; + } + void CheckBox_draw(entity me) + { + float s; + s = me.pressed; + if (me.useDownAsChecked) + { + me.srcSuffix = string_null; + me.forcePressed = me.checked; + } + else + { + me.srcSuffix = (me.checked ? "1" : "0"); + } + me.pressed = s; + SUPER(CheckBox).draw(me); + } + void CheckBox_playClickSound(entity me) + { + m_play_click_sound(MENU_SOUND_SELECT); } - else - me.srcSuffix = (me.checked ? "1" : "0"); - me.pressed = s; - SUPER(CheckBox).draw(me); -} -void CheckBox_playClickSound(entity me) -{ - m_play_click_sound(MENU_SOUND_SELECT); -} #endif diff --git a/qcsrc/menu/item/container.qc b/qcsrc/menu/item/container.qc index cacb0124a..23857dcea 100644 --- a/qcsrc/menu/item/container.qc +++ b/qcsrc/menu/item/container.qc @@ -1,461 +1,426 @@ #ifndef ITEM_CONTAINER_H -#define ITEM_CONTAINER_H -#include "../item.qc" -CLASS(Container, Item) - METHOD(Container, draw, void(entity)); - METHOD(Container, keyUp, float(entity, float, float, float)); - METHOD(Container, keyDown, float(entity, float, float, float)); - METHOD(Container, mouseMove, float(entity, vector)); - METHOD(Container, mousePress, float(entity, vector)); - METHOD(Container, mouseDrag, float(entity, vector)); - METHOD(Container, mouseRelease, float(entity, vector)); - METHOD(Container, focusLeave, void(entity)); - METHOD(Container, resizeNotify, void(entity, vector, vector, vector, vector)); - METHOD(Container, resizeNotifyLie, void(entity, vector, vector, vector, vector, .vector, .vector, .vector)); - METHOD(Container, addItem, void(entity, entity, vector, vector, float)); - METHOD(Container, addItemCentered, void(entity, entity, vector, float)); - METHOD(Container, addItemRightCentered, void(entity, entity, vector, float)); - METHOD(Container, moveItemAfter, void(entity, entity, entity)); - METHOD(Container, removeItem, void(entity, entity)); - METHOD(Container, setFocus, void(entity, entity)); - METHOD(Container, saveFocus, void(entity)); - METHOD(Container, setAlphaOf, void(entity, entity, float)); - METHOD(Container, itemFromPoint, entity(entity, vector)); - METHOD(Container, showNotify, void(entity)); - METHOD(Container, hideNotify, void(entity)); - METHOD(Container, preferredFocusedGrandChild, entity(entity)); - ATTRIB(Container, focusable, float, 0) - ATTRIB(Container, firstChild, entity, NULL) - ATTRIB(Container, lastChild, entity, NULL) - ATTRIB(Container, focusedChild, entity, NULL) - ATTRIB(Container, savedFocus, entity, NULL) - ATTRIB(Container, shown, float, 0) - - METHOD(Container, enterSubitem, void(entity, entity)); - METHOD(Container, enterLieSubitem, void(entity, vector, vector, vector, float)); - METHOD(Container, leaveSubitem, void(entity)); -ENDCLASS(Container) -.entity nextSibling; -.entity prevSibling; -.float resized; -.vector Container_origin; -.vector Container_size; -.vector Container_fontscale; -.float Container_alpha; -.vector Container_save_shift; -.vector Container_save_scale; -.vector Container_save_fontscale; -.float Container_save_alpha; + #define ITEM_CONTAINER_H + #include "../item.qc" + CLASS(Container, Item) + METHOD(Container, draw, void(entity)); + METHOD(Container, keyUp, float(entity, float, float, float)); + METHOD(Container, keyDown, float(entity, float, float, float)); + METHOD(Container, mouseMove, float(entity, vector)); + METHOD(Container, mousePress, float(entity, vector)); + METHOD(Container, mouseDrag, float(entity, vector)); + METHOD(Container, mouseRelease, float(entity, vector)); + METHOD(Container, focusLeave, void(entity)); + METHOD(Container, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Container, resizeNotifyLie, void(entity, vector, vector, vector, vector, .vector, .vector, .vector)); + METHOD(Container, addItem, void(entity, entity, vector, vector, float)); + METHOD(Container, addItemCentered, void(entity, entity, vector, float)); + METHOD(Container, addItemRightCentered, void(entity, entity, vector, float)); + METHOD(Container, moveItemAfter, void(entity, entity, entity)); + METHOD(Container, removeItem, void(entity, entity)); + METHOD(Container, setFocus, void(entity, entity)); + METHOD(Container, saveFocus, void(entity)); + METHOD(Container, setAlphaOf, void(entity, entity, float)); + METHOD(Container, itemFromPoint, entity(entity, vector)); + METHOD(Container, showNotify, void(entity)); + METHOD(Container, hideNotify, void(entity)); + METHOD(Container, preferredFocusedGrandChild, entity(entity)); + ATTRIB(Container, focusable, float, 0) + ATTRIB(Container, firstChild, entity, NULL) + ATTRIB(Container, lastChild, entity, NULL) + ATTRIB(Container, focusedChild, entity, NULL) + ATTRIB(Container, savedFocus, entity, NULL) + ATTRIB(Container, shown, float, 0) + + METHOD(Container, enterSubitem, void(entity, entity)); + METHOD(Container, enterLieSubitem, void(entity, vector, vector, vector, float)); + METHOD(Container, leaveSubitem, void(entity)); + ENDCLASS(Container) + .entity nextSibling; + .entity prevSibling; + .float resized; + .vector Container_origin; + .vector Container_size; + .vector Container_fontscale; + .float Container_alpha; + .vector Container_save_shift; + .vector Container_save_scale; + .vector Container_save_fontscale; + .float Container_save_alpha; #endif #ifdef IMPLEMENTATION -void Container_enterSubitem(entity me, entity sub) -{ - me.enterLieSubitem(me, sub.Container_origin, sub.Container_size, sub.Container_fontscale, sub.Container_alpha); -} - -void Container_enterLieSubitem(entity me, vector o, vector s, vector f, float a) -{ - me.Container_save_shift = draw_shift; - me.Container_save_scale = draw_scale; - me.Container_save_alpha = draw_alpha; - me.Container_save_fontscale = draw_fontscale; - - draw_shift = boxToGlobal(o, draw_shift, draw_scale); - draw_scale = boxToGlobalSize(s, draw_scale); - if(f != '0 0 0') - draw_fontscale = boxToGlobalSize(f, draw_fontscale); - draw_alpha *= a; -} - -void Container_leaveSubitem(entity me) -{ - draw_shift = me.Container_save_shift; - draw_scale = me.Container_save_scale; - draw_alpha = me.Container_save_alpha; - draw_fontscale = me.Container_save_fontscale; -} - -void Container_showNotify(entity me) -{ - entity e; - if(me.shown) - return; - me.shown = 1; - for(e = me.firstChild; e; e = e.nextSibling) - if(e.Container_alpha > 0) - e.showNotify(e); -} - -void Container_hideNotify(entity me) -{ - entity e; - if (!me.shown) - return; - me.shown = 0; - for(e = me.firstChild; e; e = e.nextSibling) - if(e.Container_alpha > 0) - e.hideNotify(e); -} - -void Container_setAlphaOf(entity me, entity other, float theAlpha) -{ - if(theAlpha <= 0) + void Container_enterSubitem(entity me, entity sub) { - if(other.Container_alpha > 0) - other.hideNotify(other); + me.enterLieSubitem(me, sub.Container_origin, sub.Container_size, sub.Container_fontscale, sub.Container_alpha); } - else // value > 0 + + void Container_enterLieSubitem(entity me, vector o, vector s, vector f, float a) { - if(other.Container_alpha <= 0) - other.showNotify(other); + me.Container_save_shift = draw_shift; + me.Container_save_scale = draw_scale; + me.Container_save_alpha = draw_alpha; + me.Container_save_fontscale = draw_fontscale; + + draw_shift = boxToGlobal(o, draw_shift, draw_scale); + draw_scale = boxToGlobalSize(s, draw_scale); + if (f != '0 0 0') draw_fontscale = boxToGlobalSize(f, draw_fontscale); + draw_alpha *= a; } - other.Container_alpha = theAlpha; -} - -void Container_resizeNotifyLie(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize, .vector originField, .vector sizeField, .vector fontScaleField) -{ - entity e; - vector o, s; - float d; - for(e = me.firstChild; e; e = e.nextSibling) + + void Container_leaveSubitem(entity me) { - o = e.(originField); - s = e.(sizeField); - me.enterLieSubitem(me, o, s, e.(fontScaleField), e.Container_alpha); - e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize)); - me.leaveSubitem(me); + draw_shift = me.Container_save_shift; + draw_scale = me.Container_save_scale; + draw_alpha = me.Container_save_alpha; + draw_fontscale = me.Container_save_fontscale; } - do + + void Container_showNotify(entity me) { - d = 0; - for(e = me.firstChild; e; e = e.nextSibling) - if(e.resized) - { - e.resized = 0; - d = 1; - o = e.(originField); - s = e.(sizeField); - me.enterLieSubitem(me, o, s, e.(fontScaleField), e.Container_alpha); - e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize)); - me.leaveSubitem(me); - } + entity e; + if (me.shown) return; + me.shown = 1; + for (e = me.firstChild; e; e = e.nextSibling) + if (e.Container_alpha > 0) e.showNotify(e); + } + + void Container_hideNotify(entity me) + { + entity e; + if (!me.shown) return; + me.shown = 0; + for (e = me.firstChild; e; e = e.nextSibling) + if (e.Container_alpha > 0) e.hideNotify(e); + } + + void Container_setAlphaOf(entity me, entity other, float theAlpha) + { + if (theAlpha <= 0) + { + if (other.Container_alpha > 0) other.hideNotify(other); + } + else // value > 0 + { + if (other.Container_alpha <= 0) other.showNotify(other); + } + other.Container_alpha = theAlpha; } - while(d); - SUPER(Container).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); -} - -void Container_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Container_origin, Container_size, Container_fontscale); -} - -entity Container_itemFromPoint(entity me, vector pos) -{ - entity e; - vector o, s; - for(e = me.lastChild; e; e = e.prevSibling) + + void Container_resizeNotifyLie(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize, .vector originField, .vector sizeField, .vector fontScaleField) { - o = e.Container_origin; - s = e.Container_size; - if(pos.x < o.x) continue; - if(pos.y < o.y) continue; - if(pos.x >= o.x + s.x) continue; - if(pos.y >= o.y + s.y) continue; - return e; + entity e; + vector o, s; + float d; + for (e = me.firstChild; e; e = e.nextSibling) + { + o = e.(originField); + s = e.(sizeField); + me.enterLieSubitem(me, o, s, e.(fontScaleField), e.Container_alpha); + e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize)); + me.leaveSubitem(me); + } + do + { + d = 0; + for (e = me.firstChild; e; e = e.nextSibling) + if (e.resized) + { + e.resized = 0; + d = 1; + o = e.(originField); + s = e.(sizeField); + me.enterLieSubitem(me, o, s, e.(fontScaleField), e.Container_alpha); + e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize)); + me.leaveSubitem(me); + } + } + while (d); + SUPER(Container).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); } - return NULL; -} -void Container_draw(entity me) -{ - entity e; + void Container_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) + { + me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Container_origin, Container_size, Container_fontscale); + } - me.focusable = 0; - for(e = me.firstChild; e; e = e.nextSibling) + entity Container_itemFromPoint(entity me, vector pos) { - if(e.focusable) - me.focusable += 1; - if(e.Container_alpha < 0.003) // can't change color values anyway - continue; - me.enterSubitem(me, e); - e.draw(e); - me.leaveSubitem(me); + entity e; + vector o, s; + for (e = me.lastChild; e; e = e.prevSibling) + { + o = e.Container_origin; + s = e.Container_size; + if (pos.x < o.x) continue; + if (pos.y < o.y) continue; + if (pos.x >= o.x + s.x) continue; + if (pos.y >= o.y + s.y) continue; + return e; + } + return NULL; } - SUPER(Container).draw(me); -} + void Container_draw(entity me) + { + entity e; + + me.focusable = 0; + for (e = me.firstChild; e; e = e.nextSibling) + { + if (e.focusable) me.focusable += 1; + if (e.Container_alpha < 0.003) // can't change color values anyway + continue; + me.enterSubitem(me, e); + e.draw(e); + me.leaveSubitem(me); + } -void Container_focusLeave(entity me) -{ - me.setFocus(me, NULL); -} + SUPER(Container).draw(me); + } -float Container_keyUp(entity me, float scan, float ascii, float shift) -{ - entity f; - float r; - f = me.focusedChild; - if(f) + void Container_focusLeave(entity me) { - me.enterSubitem(me, f); - r = f.keyUp(f, scan, ascii, shift); - me.leaveSubitem(me); - return r; + me.setFocus(me, NULL); } - return 0; -} - -float Container_keyDown(entity me, float scan, float ascii, float shift) -{ - entity f; - float r; - f = me.focusedChild; - if(f) + + float Container_keyUp(entity me, float scan, float ascii, float shift) { - me.enterSubitem(me, f); - r = f.keyDown(f, scan, ascii, shift); - me.leaveSubitem(me); - return r; + entity f; + float r; + f = me.focusedChild; + if (f) + { + me.enterSubitem(me, f); + r = f.keyUp(f, scan, ascii, shift); + me.leaveSubitem(me); + return r; + } + return 0; } - return 0; -} - -float Container_mouseMove(entity me, vector pos) -{ - entity f; - float r; - f = me.focusedChild; - if(f) + + float Container_keyDown(entity me, float scan, float ascii, float shift) { - me.enterSubitem(me, f); - r = f.mouseMove(f, globalToBox(pos, f.Container_origin, f.Container_size)); - me.leaveSubitem(me); - return r; + entity f; + float r; + f = me.focusedChild; + if (f) + { + me.enterSubitem(me, f); + r = f.keyDown(f, scan, ascii, shift); + me.leaveSubitem(me); + return r; + } + return 0; } - return 0; -} -float Container_mousePress(entity me, vector pos) -{ - entity f; - float r; - f = me.focusedChild; - if(f) + + float Container_mouseMove(entity me, vector pos) { - me.enterSubitem(me, f); - r = f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size)); - me.leaveSubitem(me); - return r; + entity f; + float r; + f = me.focusedChild; + if (f) + { + me.enterSubitem(me, f); + r = f.mouseMove(f, globalToBox(pos, f.Container_origin, f.Container_size)); + me.leaveSubitem(me); + return r; + } + return 0; } - return 0; -} -float Container_mouseDrag(entity me, vector pos) -{ - entity f; - float r; - f = me.focusedChild; - if(f) + float Container_mousePress(entity me, vector pos) { - me.enterSubitem(me, f); - r = f.mouseDrag(f, globalToBox(pos, f.Container_origin, f.Container_size)); - me.leaveSubitem(me); - return r; + entity f; + float r; + f = me.focusedChild; + if (f) + { + me.enterSubitem(me, f); + r = f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size)); + me.leaveSubitem(me); + return r; + } + return 0; } - return 0; -} -float Container_mouseRelease(entity me, vector pos) -{ - entity f; - float r; - f = me.focusedChild; - if(f) + float Container_mouseDrag(entity me, vector pos) { - me.enterSubitem(me, f); - r = f.mouseRelease(f, globalToBox(pos, f.Container_origin, f.Container_size)); - me.leaveSubitem(me); - return r; + entity f; + float r; + f = me.focusedChild; + if (f) + { + me.enterSubitem(me, f); + r = f.mouseDrag(f, globalToBox(pos, f.Container_origin, f.Container_size)); + me.leaveSubitem(me); + return r; + } + return 0; + } + float Container_mouseRelease(entity me, vector pos) + { + entity f; + float r; + f = me.focusedChild; + if (f) + { + me.enterSubitem(me, f); + r = f.mouseRelease(f, globalToBox(pos, f.Container_origin, f.Container_size)); + me.leaveSubitem(me); + return r; + } + return 0; } - return 0; -} - -void Container_addItemCentered(entity me, entity other, vector theSize, float theAlpha) -{ - me.addItem(me, other, '0.5 0.5 0' - 0.5 * theSize, theSize, theAlpha); -} - -void Container_addItemRightCentered(entity me, entity other, vector theSize, float theAlpha) -{ - me.addItem(me, other, '1 0.5 0' - 0.5 * theSize, theSize, theAlpha); -} - -void Container_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha) -{ - if(other.parent) - error("Can't add already added item!"); - if(other.focusable) - me.focusable += 1; + void Container_addItemCentered(entity me, entity other, vector theSize, float theAlpha) + { + me.addItem(me, other, '0.5 0.5 0' - 0.5 * theSize, theSize, theAlpha); + } - if(theSize.x > 1) + void Container_addItemRightCentered(entity me, entity other, vector theSize, float theAlpha) { - theOrigin.x -= 0.5 * (theSize.x - 1); - theSize.x = 1; + me.addItem(me, other, '1 0.5 0' - 0.5 * theSize, theSize, theAlpha); } - if(theSize.y > 1) + + void Container_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha) { - theOrigin.y -= 0.5 * (theSize.y - 1); - theSize.y = 1; + if (other.parent) error("Can't add already added item!"); + + if (other.focusable) me.focusable += 1; + + if (theSize.x > 1) + { + theOrigin.x -= 0.5 * (theSize.x - 1); + theSize.x = 1; + } + if (theSize.y > 1) + { + theOrigin.y -= 0.5 * (theSize.y - 1); + theSize.y = 1; + } + theOrigin.x = bound(0, theOrigin.x, 1 - theSize.x); + theOrigin.y = bound(0, theOrigin.y, 1 - theSize.y); + + other.parent = me; + other.Container_origin = theOrigin; + other.Container_size = theSize; + me.setAlphaOf(me, other, theAlpha); + + entity l; + l = me.lastChild; + + if (l) l.nextSibling = other; + else me.firstChild = other; + + other.prevSibling = l; + other.nextSibling = NULL; + me.lastChild = other; } - theOrigin.x = bound(0, theOrigin.x, 1 - theSize.x); - theOrigin.y = bound(0, theOrigin.y, 1 - theSize.y); - - other.parent = me; - other.Container_origin = theOrigin; - other.Container_size = theSize; - me.setAlphaOf(me, other, theAlpha); - - entity l; - l = me.lastChild; - - if(l) - l.nextSibling = other; - else - me.firstChild = other; - - other.prevSibling = l; - other.nextSibling = NULL; - me.lastChild = other; -} - -void Container_removeItem(entity me, entity other) -{ - if(other.parent != me) - error("Can't remove from wrong container!"); - - if(other.focusable) - me.focusable -= 1; - - other.parent = NULL; - - entity n, p; - n = other.nextSibling; - p = other.prevSibling; - - if(p) - p.nextSibling = n; - else - me.firstChild = n; - - if(n) - n.prevSibling = p; - else - me.lastChild = p; -} - -void Container_setFocus(entity me, entity other) -{ - if(me.focusedChild == other) - return; - - if(me.focusedChild) + + void Container_removeItem(entity me, entity other) { - me.focusedChild.focused = 0; - me.focusedChild.focusLeave(me.focusedChild); - me.focusedChild = NULL; + if (other.parent != me) error("Can't remove from wrong container!"); + + if (other.focusable) me.focusable -= 1; + + other.parent = NULL; + + entity n, p; + n = other.nextSibling; + p = other.prevSibling; + + if (p) p.nextSibling = n; + else me.firstChild = n; + + if (n) n.prevSibling = p; + else me.lastChild = p; } - if(other) + void Container_setFocus(entity me, entity other) { - if(!me.focused) - error("Trying to set focus in a non-focused control!"); + if (me.focusedChild == other) return; - if(me.savedFocus) + if (me.focusedChild) { - me.focusedChild = me.savedFocus; - me.savedFocus = NULL; - me.focusedChild.focused = 1; - me.focusedChild.focusEnter(me.focusedChild); - - if(me.focusedChild.instanceOfContainer) - me.focusedChild.setFocus(me.focusedChild, me.focusedChild.savedFocus); + me.focusedChild.focused = 0; + me.focusedChild.focusLeave(me.focusedChild); + me.focusedChild = NULL; } - else + + if (other) { - me.focusedChild = other; - me.focusedChild.focused = 1; - me.focusedChild.focusEnter(me.focusedChild); + if (!me.focused) error("Trying to set focus in a non-focused control!"); + + if (me.savedFocus) + { + me.focusedChild = me.savedFocus; + me.savedFocus = NULL; + me.focusedChild.focused = 1; + me.focusedChild.focusEnter(me.focusedChild); + + if (me.focusedChild.instanceOfContainer) me.focusedChild.setFocus(me.focusedChild, me.focusedChild.savedFocus); + } + else + { + me.focusedChild = other; + me.focusedChild.focused = 1; + me.focusedChild.focusEnter(me.focusedChild); + } } } -} - -void Container_saveFocus(entity me) -{ - me.savedFocus = me.focusedChild; - - if(me.focusedChild.instanceOfContainer) - me.focusedChild.saveFocus(me.focusedChild); -} - -void Container_moveItemAfter(entity me, entity other, entity dest) -{ - // first: remove other from the chain - entity n, p; - - if(other.parent != me) - error("Can't move in wrong container!"); - - n = other.nextSibling; - p = other.prevSibling; - - if(p) - p.nextSibling = n; - else - me.firstChild = n; - - if(n) - n.prevSibling = p; - else - me.lastChild = p; - - // now other got removed. Insert it behind dest now. - other.prevSibling = dest; - if(dest) - other.nextSibling = dest.nextSibling; - else - other.nextSibling = me.firstChild; - - if(dest) - dest.nextSibling = other; - else - me.firstChild = other; - - if(other.nextSibling) - other.nextSibling.prevSibling = other; - else - me.lastChild = other; -} -entity Container_preferredFocusedGrandChild(entity me) -{ - entity e, e2; - entity best; + void Container_saveFocus(entity me) + { + me.savedFocus = me.focusedChild; + + if (me.focusedChild.instanceOfContainer) me.focusedChild.saveFocus(me.focusedChild); + } + + void Container_moveItemAfter(entity me, entity other, entity dest) + { + // first: remove other from the chain + entity n, p; + + if (other.parent != me) error("Can't move in wrong container!"); - best = NULL; + n = other.nextSibling; + p = other.prevSibling; - for(e = me.firstChild; e; e = e.nextSibling) + if (p) p.nextSibling = n; + else me.firstChild = n; + + if (n) n.prevSibling = p; + else me.lastChild = p; + + // now other got removed. Insert it behind dest now. + other.prevSibling = dest; + if (dest) other.nextSibling = dest.nextSibling; + else other.nextSibling = me.firstChild; + + if (dest) dest.nextSibling = other; + else me.firstChild = other; + + if (other.nextSibling) other.nextSibling.prevSibling = other; + else me.lastChild = other; + } + + entity Container_preferredFocusedGrandChild(entity me) { - if(e.instanceOfContainer) + entity e, e2; + entity best; + + best = NULL; + + for (e = me.firstChild; e; e = e.nextSibling) { - e2 = e.preferredFocusedGrandChild(e); - if(e2) - if(!best || best.preferredFocusPriority < e2.preferredFocusPriority) - best = e2; + if (e.instanceOfContainer) + { + e2 = e.preferredFocusedGrandChild(e); + if (e2) + if (!best || best.preferredFocusPriority < e2.preferredFocusPriority) best = e2; + } + if (e) + if (!best || best.preferredFocusPriority < e.preferredFocusPriority) best = e; } - if(e) - if(!best || best.preferredFocusPriority < e.preferredFocusPriority) - best = e; - } - return best; -} + return best; + } #endif diff --git a/qcsrc/menu/item/dialog.qc b/qcsrc/menu/item/dialog.qc index f02be5b53..fc14d9222 100644 --- a/qcsrc/menu/item/dialog.qc +++ b/qcsrc/menu/item/dialog.qc @@ -14,184 +14,177 @@ // a subclass may help with using this as a tab #ifndef ITEM_DIALOG_H -#define ITEM_DIALOG_H -#include "inputcontainer.qc" -CLASS(Dialog, InputContainer) - METHOD(Dialog, configureDialog, void(entity)); // no runtime configuration, all parameters are given in the code! - METHOD(Dialog, fill, void(entity)); // to be overridden by user to fill the dialog with controls - METHOD(Dialog, keyDown, float(entity, float, float, float)); - METHOD(Dialog, close, void(entity)); - METHOD(Dialog, addItemSimple, void(entity, float, float, float, float, entity, vector)); - - METHOD(Dialog, TD, void(entity, float, float, entity)); - METHOD(Dialog, TDNoMargin, void(entity, float, float, entity, vector)); - METHOD(Dialog, TDempty, void(entity, float)); - METHOD(Dialog, setFirstColumn, void(entity, float)); - METHOD(Dialog, TR, void(entity)); - METHOD(Dialog, gotoRC, void(entity, float, float)); - - ATTRIB(Dialog, isTabRoot, float, 1) - ATTRIB(Dialog, closeButton, entity, NULL) - ATTRIB(Dialog, intendedHeight, float, 0) - ATTRIB(Dialog, itemOrigin, vector, '0 0 0') - ATTRIB(Dialog, itemSize, vector, '0 0 0') - ATTRIB(Dialog, itemSpacing, vector, '0 0 0') - ATTRIB(Dialog, currentRow, float, 0) - ATTRIB(Dialog, currentColumn, float, 0) - ATTRIB(Dialog, firstColumn, float, 0) - - // to be customized - ATTRIB(Dialog, closable, float, 1) - ATTRIB(Dialog, title, string, "Form1") // ;) - ATTRIB(Dialog, color, vector, '1 0.5 1') - ATTRIB(Dialog, intendedWidth, float, 0) - ATTRIB(Dialog, rows, float, 3) - ATTRIB(Dialog, columns, float, 2) - - ATTRIB(Dialog, marginTop, float, 0) // pixels - ATTRIB(Dialog, marginBottom, float, 0) // pixels - ATTRIB(Dialog, marginLeft, float, 0) // pixels - ATTRIB(Dialog, marginRight, float, 0) // pixels - ATTRIB(Dialog, columnSpacing, float, 0) // pixels - ATTRIB(Dialog, rowSpacing, float, 0) // pixels - ATTRIB(Dialog, rowHeight, float, 0) // pixels - ATTRIB(Dialog, titleHeight, float, 0) // pixels - ATTRIB(Dialog, titleFontSize, float, 0) // pixels; if 0, title causes no margin - ATTRIB(Dialog, zoomedOutTitleBarPosition, float, 0) - ATTRIB(Dialog, zoomedOutTitleBar, float, 0) - - ATTRIB(Dialog, requiresConnection, float, 0) // set to true if the dialog requires a connection to be opened - - ATTRIB(Dialog, backgroundImage, string, string_null) - ATTRIB(Dialog, borderLines, float, 1) - ATTRIB(Dialog, closeButtonImage, string, string_null) - - ATTRIB(Dialog, frame, entity, NULL) -ENDCLASS(Dialog) + #define ITEM_DIALOG_H + #include "inputcontainer.qc" + CLASS(Dialog, InputContainer) + METHOD(Dialog, configureDialog, void(entity)); // no runtime configuration, all parameters are given in the code! + METHOD(Dialog, fill, void(entity)); // to be overridden by user to fill the dialog with controls + METHOD(Dialog, keyDown, float(entity, float, float, float)); + METHOD(Dialog, close, void(entity)); + METHOD(Dialog, addItemSimple, void(entity, float, float, float, float, entity, vector)); + + METHOD(Dialog, TD, void(entity, float, float, entity)); + METHOD(Dialog, TDNoMargin, void(entity, float, float, entity, vector)); + METHOD(Dialog, TDempty, void(entity, float)); + METHOD(Dialog, setFirstColumn, void(entity, float)); + METHOD(Dialog, TR, void(entity)); + METHOD(Dialog, gotoRC, void(entity, float, float)); + + ATTRIB(Dialog, isTabRoot, float, 1) + ATTRIB(Dialog, closeButton, entity, NULL) + ATTRIB(Dialog, intendedHeight, float, 0) + ATTRIB(Dialog, itemOrigin, vector, '0 0 0') + ATTRIB(Dialog, itemSize, vector, '0 0 0') + ATTRIB(Dialog, itemSpacing, vector, '0 0 0') + ATTRIB(Dialog, currentRow, float, 0) + ATTRIB(Dialog, currentColumn, float, 0) + ATTRIB(Dialog, firstColumn, float, 0) + + // to be customized + ATTRIB(Dialog, closable, float, 1) + ATTRIB(Dialog, title, string, "Form1") // ;) + ATTRIB(Dialog, color, vector, '1 0.5 1') + ATTRIB(Dialog, intendedWidth, float, 0) + ATTRIB(Dialog, rows, float, 3) + ATTRIB(Dialog, columns, float, 2) + + ATTRIB(Dialog, marginTop, float, 0) // pixels + ATTRIB(Dialog, marginBottom, float, 0) // pixels + ATTRIB(Dialog, marginLeft, float, 0) // pixels + ATTRIB(Dialog, marginRight, float, 0) // pixels + ATTRIB(Dialog, columnSpacing, float, 0) // pixels + ATTRIB(Dialog, rowSpacing, float, 0) // pixels + ATTRIB(Dialog, rowHeight, float, 0) // pixels + ATTRIB(Dialog, titleHeight, float, 0) // pixels + ATTRIB(Dialog, titleFontSize, float, 0) // pixels; if 0, title causes no margin + ATTRIB(Dialog, zoomedOutTitleBarPosition, float, 0) + ATTRIB(Dialog, zoomedOutTitleBar, float, 0) + + ATTRIB(Dialog, requiresConnection, float, 0) // set to true if the dialog requires a connection to be opened + + ATTRIB(Dialog, backgroundImage, string, string_null) + ATTRIB(Dialog, borderLines, float, 1) + ATTRIB(Dialog, closeButtonImage, string, string_null) + + ATTRIB(Dialog, frame, entity, NULL) + ENDCLASS(Dialog) #endif #ifdef IMPLEMENTATION -void Dialog_Close(entity button, entity me) -{ - me.close(me); -} - -void Dialog_fill(entity me) -{ -} - -void Dialog_addItemSimple(entity me, float row, float col, float rowspan, float colspan, entity e, vector v) -{ - vector o, s; - o = me.itemOrigin + eX * ( col * me.itemSpacing.x) + eY * ( row * me.itemSpacing.y); - s = me.itemSize + eX * ((colspan - 1) * me.itemSpacing.x) + eY * ((rowspan - 1) * me.itemSpacing.y); - o.x -= 0.5 * (me.itemSpacing.x - me.itemSize.x) * v.x; - s.x += (me.itemSpacing.x - me.itemSize.x) * v.x; - o.y -= 0.5 * (me.itemSpacing.y - me.itemSize.y) * v.y; - s.y += (me.itemSpacing.y - me.itemSize.y) * v.y; - me.addItem(me, e, o, s, 1); -} - -void Dialog_gotoRC(entity me, float row, float col) -{ - me.currentRow = row; - me.currentColumn = col; -} - -void Dialog_TR(entity me) -{ - me.currentRow += 1; - me.currentColumn = me.firstColumn; -} - -void Dialog_TD(entity me, float rowspan, float colspan, entity e) -{ - me.addItemSimple(me, me.currentRow, me.currentColumn, rowspan, colspan, e, '0 0 0'); - me.currentColumn += colspan; -} - -void Dialog_TDNoMargin(entity me, float rowspan, float colspan, entity e, vector v) -{ - me.addItemSimple(me, me.currentRow, me.currentColumn, rowspan, colspan, e, v); - me.currentColumn += colspan; -} - -void Dialog_setFirstColumn(entity me, float col) -{ - me.firstColumn = col; -} - -void Dialog_TDempty(entity me, float colspan) -{ - me.currentColumn += colspan; -} - -void Dialog_configureDialog(entity me) -{ - float absWidth, absHeight; - - if(me.isTabRoot) + void Dialog_Close(entity button, entity me) { - me.frame = NEW(BorderImage); - me.frame.configureBorderImage(me.frame, me.title, me.titleFontSize, me.color, me.backgroundImage, me.borderLines * me.titleHeight); - me.frame.zoomedOutTitleBarPosition = me.zoomedOutTitleBarPosition; - me.frame.zoomedOutTitleBar = me.zoomedOutTitleBar; - me.frame.alpha = me.alpha; - me.addItem(me, me.frame, '0 0 0', '1 1 0', 1); + me.close(me); } - if (!me.titleFontSize) - me.titleHeight = 0; // no title bar - - absWidth = me.intendedWidth * conwidth; - absHeight = me.borderLines * me.titleHeight + me.marginTop + me.rows * me.rowHeight + (me.rows - 1) * me.rowSpacing + me.marginBottom; - me.itemOrigin = eX * (me.marginLeft / absWidth) - + eY * ((me.borderLines * me.titleHeight + me.marginTop) / absHeight); - me.itemSize = eX * ((1 - (me.marginLeft + me.marginRight + me.columnSpacing * (me.columns - 1)) / absWidth) / me.columns) - + eY * (me.rowHeight / absHeight); - me.itemSpacing = me.itemSize - + eX * (me.columnSpacing / absWidth) - + eY * (me.rowSpacing / absHeight); - me.intendedHeight = absHeight / conheight; - me.currentRow = -1; - me.currentColumn = -1; - - me.fill(me); - - if(me.isTabRoot && me.closable && me.borderLines > 0) + void Dialog_fill(entity me) + {} + + void Dialog_addItemSimple(entity me, float row, float col, float rowspan, float colspan, entity e, vector v) + { + vector o, s; + o = me.itemOrigin + eX * (col * me.itemSpacing.x) + eY * (row * me.itemSpacing.y); + s = me.itemSize + eX * ((colspan - 1) * me.itemSpacing.x) + eY * ((rowspan - 1) * me.itemSpacing.y); + o.x -= 0.5 * (me.itemSpacing.x - me.itemSize.x) * v.x; + s.x += (me.itemSpacing.x - me.itemSize.x) * v.x; + o.y -= 0.5 * (me.itemSpacing.y - me.itemSize.y) * v.y; + s.y += (me.itemSpacing.y - me.itemSize.y) * v.y; + me.addItem(me, e, o, s, 1); + } + + void Dialog_gotoRC(entity me, float row, float col) { - entity closebutton; - closebutton = me.closeButton = me.frame.closeButton = NEW(Button); - closebutton.configureButton(closebutton, "", 0, me.closeButtonImage); - closebutton.onClick = Dialog_Close; closebutton.onClickEntity = me; - closebutton.srcMulti = 0; - me.addItem(me, closebutton, '0 0 0', '1 1 0', 1); // put it as LAST + me.currentRow = row; + me.currentColumn = col; } -} -void Dialog_close(entity me) -{ - if(me.parent.instanceOfNexposee) + void Dialog_TR(entity me) { - ExposeeCloseButton_Click(me, me.parent); + me.currentRow += 1; + me.currentColumn = me.firstColumn; } - else if(me.parent.instanceOfModalController) + + void Dialog_TD(entity me, float rowspan, float colspan, entity e) + { + me.addItemSimple(me, me.currentRow, me.currentColumn, rowspan, colspan, e, '0 0 0'); + me.currentColumn += colspan; + } + + void Dialog_TDNoMargin(entity me, float rowspan, float colspan, entity e, vector v) + { + me.addItemSimple(me, me.currentRow, me.currentColumn, rowspan, colspan, e, v); + me.currentColumn += colspan; + } + + void Dialog_setFirstColumn(entity me, float col) + { + me.firstColumn = col; + } + + void Dialog_TDempty(entity me, float colspan) + { + me.currentColumn += colspan; + } + + void Dialog_configureDialog(entity me) + { + float absWidth, absHeight; + + if (me.isTabRoot) + { + me.frame = NEW(BorderImage); + me.frame.configureBorderImage(me.frame, me.title, me.titleFontSize, me.color, me.backgroundImage, me.borderLines * me.titleHeight); + me.frame.zoomedOutTitleBarPosition = me.zoomedOutTitleBarPosition; + me.frame.zoomedOutTitleBar = me.zoomedOutTitleBar; + me.frame.alpha = me.alpha; + me.addItem(me, me.frame, '0 0 0', '1 1 0', 1); + } + + if (!me.titleFontSize) me.titleHeight = 0; // no title bar + + absWidth = me.intendedWidth * conwidth; + absHeight = me.borderLines * me.titleHeight + me.marginTop + me.rows * me.rowHeight + (me.rows - 1) * me.rowSpacing + me.marginBottom; + me.itemOrigin = eX * (me.marginLeft / absWidth) + + eY * ((me.borderLines * me.titleHeight + me.marginTop) / absHeight); + me.itemSize = eX * ((1 - (me.marginLeft + me.marginRight + me.columnSpacing * (me.columns - 1)) / absWidth) / me.columns) + + eY * (me.rowHeight / absHeight); + me.itemSpacing = me.itemSize + + eX * (me.columnSpacing / absWidth) + + eY * (me.rowSpacing / absHeight); + me.intendedHeight = absHeight / conheight; + me.currentRow = -1; + me.currentColumn = -1; + + me.fill(me); + + if (me.isTabRoot && me.closable && me.borderLines > 0) + { + entity closebutton; + closebutton = me.closeButton = me.frame.closeButton = NEW(Button); + closebutton.configureButton(closebutton, "", 0, me.closeButtonImage); + closebutton.onClick = Dialog_Close; + closebutton.onClickEntity = me; + closebutton.srcMulti = 0; + me.addItem(me, closebutton, '0 0 0', '1 1 0', 1); // put it as LAST + } + } + + void Dialog_close(entity me) { - DialogCloseButton_Click(me, me); + if (me.parent.instanceOfNexposee) ExposeeCloseButton_Click(me, me.parent); + else if (me.parent.instanceOfModalController) DialogCloseButton_Click(me, me); } -} -float Dialog_keyDown(entity me, float key, float ascii, float shift) -{ - if(me.closable) + float Dialog_keyDown(entity me, float key, float ascii, float shift) { - if(key == K_ESCAPE) + if (me.closable) { - m_play_click_sound(MENU_SOUND_CLOSE); - me.close(me); - return 1; + if (key == K_ESCAPE) + { + m_play_click_sound(MENU_SOUND_CLOSE); + me.close(me); + return 1; + } } + return SUPER(Dialog).keyDown(me, key, ascii, shift); } - return SUPER(Dialog).keyDown(me, key, ascii, shift); -} #endif diff --git a/qcsrc/menu/item/image.qc b/qcsrc/menu/item/image.qc index baa5d6157..2a28c78b1 100644 --- a/qcsrc/menu/item/image.qc +++ b/qcsrc/menu/item/image.qc @@ -1,233 +1,224 @@ #ifndef ITEM_IMAGE_H -#define ITEM_IMAGE_H -#include "../item.qc" -CLASS(Image, Item) - METHOD(Image, configureImage, void(entity, string)); - METHOD(Image, draw, void(entity)); - METHOD(Image, toString, string(entity)); - METHOD(Image, resizeNotify, void(entity, vector, vector, vector, vector)); - METHOD(Image, updateAspect, void(entity)); - METHOD(Image, initZoom, void(entity)); - METHOD(Image, setZoom, void(entity, float, float)); - METHOD(Image, drag_setStartPos, float(entity, vector)); - METHOD(Image, drag, float(entity, vector)); - ATTRIB(Image, src, string, string_null) - ATTRIB(Image, color, vector, '1 1 1') - ATTRIB(Image, forcedAspect, float, 0) // special values: -1 keep image aspect ratio, -2 keep image size but bound to the containing box, -3 always keep image size - ATTRIB(Image, zoomBox, float, 0) // used by forcedAspect -2 when the image is larger than the containing box - ATTRIB(Image, zoomFactor, float, 1) - ATTRIB(Image, zoomOffset, vector, '0.5 0.5 0') - ATTRIB(Image, zoomSnapToTheBox, float, 1) // snap the zoomed in image to the box borders when zooming/dragging it - ATTRIB(Image, zoomTime, float, 0) - ATTRIB(Image, zoomLimitedByTheBox, float, 0) // forbids zoom if image would be larger than the containing box - ATTRIB(Image, zoomMax, float, 0) - ATTRIB(Image, start_zoomOffset, vector, '0 0 0') - ATTRIB(Image, start_coords, vector, '0 0 0') - ATTRIB(Image, imgOrigin, vector, '0 0 0') - ATTRIB(Image, imgSize, vector, '0 0 0') -ENDCLASS(Image) + #define ITEM_IMAGE_H + #include "../item.qc" + CLASS(Image, Item) + METHOD(Image, configureImage, void(entity, string)); + METHOD(Image, draw, void(entity)); + METHOD(Image, toString, string(entity)); + METHOD(Image, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Image, updateAspect, void(entity)); + METHOD(Image, initZoom, void(entity)); + METHOD(Image, setZoom, void(entity, float, float)); + METHOD(Image, drag_setStartPos, float(entity, vector)); + METHOD(Image, drag, float(entity, vector)); + ATTRIB(Image, src, string, string_null) + ATTRIB(Image, color, vector, '1 1 1') + ATTRIB(Image, forcedAspect, float, 0) // special values: -1 keep image aspect ratio, -2 keep image size but bound to the containing box, -3 always keep image size + ATTRIB(Image, zoomBox, float, 0) // used by forcedAspect -2 when the image is larger than the containing box + ATTRIB(Image, zoomFactor, float, 1) + ATTRIB(Image, zoomOffset, vector, '0.5 0.5 0') + ATTRIB(Image, zoomSnapToTheBox, float, 1) // snap the zoomed in image to the box borders when zooming/dragging it + ATTRIB(Image, zoomTime, float, 0) + ATTRIB(Image, zoomLimitedByTheBox, float, 0) // forbids zoom if image would be larger than the containing box + ATTRIB(Image, zoomMax, float, 0) + ATTRIB(Image, start_zoomOffset, vector, '0 0 0') + ATTRIB(Image, start_coords, vector, '0 0 0') + ATTRIB(Image, imgOrigin, vector, '0 0 0') + ATTRIB(Image, imgSize, vector, '0 0 0') + ENDCLASS(Image) #endif #ifdef IMPLEMENTATION -string Image_toString(entity me) -{ - return me.src; -} -void Image_configureImage(entity me, string path) -{ - me.src = path; -} -void Image_initZoom(entity me) -{ - me.zoomOffset = '0.5 0.5 0'; - me.zoomFactor = 1; - if (me.forcedAspect == -2) - me.zoomBox = -1; // calculate zoomBox at the first updateAspect call - if (me.zoomLimitedByTheBox) - me.zoomMax = -1; // calculate zoomMax at the first updateAspect call -} + string Image_toString(entity me) + { + return me.src; + } + void Image_configureImage(entity me, string path) + { + me.src = path; + } + void Image_initZoom(entity me) + { + me.zoomOffset = '0.5 0.5 0'; + me.zoomFactor = 1; + if (me.forcedAspect == -2) me.zoomBox = -1; // calculate zoomBox at the first updateAspect call + if (me.zoomLimitedByTheBox) me.zoomMax = -1; // calculate zoomMax at the first updateAspect call + } -void Image_draw(entity me) -{ - if(me.imgSize.x > 1 || me.imgSize.y > 1) - draw_SetClip(); - draw_Picture(me.imgOrigin, me.src, me.imgSize, me.color, 1); - if(me.imgSize.x > 1 || me.imgSize.y > 1) - draw_ClearClip(); - SUPER(Image).draw(me); -} -void Image_updateAspect(entity me) -{ - float asp = 0; - if(me.size.x <= 0 || me.size.y <= 0) - return; - if(me.forcedAspect == 0) + void Image_draw(entity me) { - me.imgOrigin = '0 0 0'; - me.imgSize = '1 1 0'; + if (me.imgSize.x > 1 || me.imgSize.y > 1) draw_SetClip(); + draw_Picture(me.imgOrigin, me.src, me.imgSize, me.color, 1); + if (me.imgSize.x > 1 || me.imgSize.y > 1) draw_ClearClip(); + SUPER(Image).draw(me); } - else + void Image_updateAspect(entity me) { - vector sz = '0 0 0'; - if(me.forcedAspect < 0) + float asp = 0; + if (me.size.x <= 0 || me.size.y <= 0) return; + if (me.forcedAspect == 0) { - if (me.src != "") - sz = draw_PictureSize(me.src); - if(sz.x <= 0 || sz.y <= 0) - { - // image is broken or doesn't exist, set the size for the placeholder image - sz.x = me.size.x; - sz.y = me.size.y; - } - asp = sz.x / sz.y; + me.imgOrigin = '0 0 0'; + me.imgSize = '1 1 0'; } else - asp = me.forcedAspect; - - if(me.forcedAspect <= -2) { - me.imgSize_x = sz.x / me.size.x; - me.imgSize_y = sz.y / me.size.y; - if(me.zoomBox < 0 && (me.imgSize.x > 1 || me.imgSize.y > 1)) + vector sz = '0 0 0'; + if (me.forcedAspect < 0) { - // image larger than the containing box, zoom it out to fit into the box - if(me.size.x > asp * me.size.y) - me.zoomBox = (me.size.y * asp / me.size.x) / me.imgSize.x; - else - me.zoomBox = (me.size.x / (asp * me.size.y)) / me.imgSize.y; - me.zoomFactor = me.zoomBox; + if (me.src != "") sz = draw_PictureSize(me.src); + if (sz.x <= 0 || sz.y <= 0) + { + // image is broken or doesn't exist, set the size for the placeholder image + sz.x = me.size.x; + sz.y = me.size.y; + } + asp = sz.x / sz.y; } - } - else - { - if(me.size.x > asp * me.size.y) + else { - // x too large, so center x-wise - me.imgSize = eY + eX * (me.size.y * asp / me.size.x); + asp = me.forcedAspect; + } + + if (me.forcedAspect <= -2) + { + me.imgSize_x = sz.x / me.size.x; + me.imgSize_y = sz.y / me.size.y; + if (me.zoomBox < 0 && (me.imgSize.x > 1 || me.imgSize.y > 1)) + { + // image larger than the containing box, zoom it out to fit into the box + if (me.size.x > asp * me.size.y) me.zoomBox = (me.size.y * asp / me.size.x) / me.imgSize.x; + else me.zoomBox = (me.size.x / (asp * me.size.y)) / me.imgSize.y; + me.zoomFactor = me.zoomBox; + } } else { - // y too large, so center y-wise - me.imgSize = eX + eY * (me.size.x / (asp * me.size.y)); + if (me.size.x > asp * me.size.y) + { + // x too large, so center x-wise + me.imgSize = eY + eX * (me.size.y * asp / me.size.x); + } + else + { + // y too large, so center y-wise + me.imgSize = eX + eY * (me.size.x / (asp * me.size.y)); + } } } - } - if (me.zoomMax < 0) - { - if(me.zoomBox > 0) - me.zoomMax = me.zoomBox; - else + if (me.zoomMax < 0) { - if(me.size.x > asp * me.size.y) - me.zoomMax = (me.size.y * asp / me.size.x) / me.imgSize.x; + if (me.zoomBox > 0) + { + me.zoomMax = me.zoomBox; + } else - me.zoomMax = (me.size.x / (asp * me.size.y)) / me.imgSize.y; + { + if (me.size.x > asp * me.size.y) me.zoomMax = (me.size.y * asp / me.size.x) / me.imgSize.x; + else me.zoomMax = (me.size.x / (asp * me.size.y)) / me.imgSize.y; + } } - } - if (me.zoomMax > 0 && me.zoomFactor > me.zoomMax) - me.zoomFactor = me.zoomMax; - if (me.zoomFactor) - me.imgSize = me.imgSize * me.zoomFactor; + if (me.zoomMax > 0 && me.zoomFactor > me.zoomMax) me.zoomFactor = me.zoomMax; + if (me.zoomFactor) me.imgSize = me.imgSize * me.zoomFactor; - if(me.imgSize.x > 1 || me.imgSize.y > 1) - { - if(me.zoomSnapToTheBox) + if (me.imgSize.x > 1 || me.imgSize.y > 1) { - if(me.imgSize.x > 1) - me.zoomOffset_x = bound(0.5/me.imgSize.x, me.zoomOffset.x, 1 - 0.5/me.imgSize.x); - else - me.zoomOffset_x = bound(1 - 0.5/me.imgSize.x, me.zoomOffset.x, 0.5/me.imgSize.x); + if (me.zoomSnapToTheBox) + { + if (me.imgSize.x > 1) me.zoomOffset_x = bound(0.5 / me.imgSize.x, me.zoomOffset.x, 1 - 0.5 / me.imgSize.x); + else me.zoomOffset_x = bound(1 - 0.5 / me.imgSize.x, me.zoomOffset.x, 0.5 / me.imgSize.x); - if(me.imgSize.y > 1) - me.zoomOffset_y = bound(0.5/me.imgSize.y, me.zoomOffset.y, 1 - 0.5/me.imgSize.y); + if (me.imgSize.y > 1) me.zoomOffset_y = bound(0.5 / me.imgSize.y, me.zoomOffset.y, 1 - 0.5 / me.imgSize.y); + else me.zoomOffset_y = bound(1 - 0.5 / me.imgSize.y, me.zoomOffset.y, 0.5 / me.imgSize.y); + } else - me.zoomOffset_y = bound(1 - 0.5/me.imgSize.y, me.zoomOffset.y, 0.5/me.imgSize.y); + { + me.zoomOffset_x = bound(0, me.zoomOffset.x, 1); + me.zoomOffset_y = bound(0, me.zoomOffset.y, 1); + } } else { - me.zoomOffset_x = bound(0, me.zoomOffset.x, 1); - me.zoomOffset_y = bound(0, me.zoomOffset.y, 1); + me.zoomOffset = '0.5 0.5 0'; } - } - else - me.zoomOffset = '0.5 0.5 0'; - me.imgOrigin_x = 0.5 - me.zoomOffset.x * me.imgSize.x; - me.imgOrigin_y = 0.5 - me.zoomOffset.y * me.imgSize.y; -} -float Image_drag_setStartPos(entity me, vector coords) -{ - //if(me.imgSize_x > 1 || me.imgSize_y > 1) // check disabled: mousewheel zoom may start from a non-zoomed-in image - { - me.start_zoomOffset = me.zoomOffset; - me.start_coords = coords; - } - return 1; -} -float Image_drag(entity me, vector coords) -{ - if(me.imgSize.x > 1 || me.imgSize.y > 1) - { - me.zoomOffset_x = me.start_zoomOffset.x + (me.start_coords.x - coords.x) / me.imgSize.x; - me.zoomOffset_y = me.start_zoomOffset.y + (me.start_coords.y - coords.y) / me.imgSize.y; - me.updateAspect(me); + me.imgOrigin_x = 0.5 - me.zoomOffset.x * me.imgSize.x; + me.imgOrigin_y = 0.5 - me.zoomOffset.y * me.imgSize.y; } - return 1; -} -void Image_setZoom(entity me, float z, float atMousePosition) -{ - float prev_zoomFactor; - prev_zoomFactor = me.zoomFactor; - if (z < 0) // multiply by the current zoomFactor (but can also snap to real dimensions or to box) + float Image_drag_setStartPos(entity me, vector coords) { - me.zoomFactor *= -z; - float realSize_in_the_middle, boxSize_in_the_middle; - realSize_in_the_middle = ((prev_zoomFactor - 1) * (me.zoomFactor - 1) < 0); - boxSize_in_the_middle = (me.zoomBox > 0 && (prev_zoomFactor - me.zoomBox) * (me.zoomFactor - me.zoomBox) < 0); - if (realSize_in_the_middle && boxSize_in_the_middle) + // if(me.imgSize_x > 1 || me.imgSize_y > 1) // check disabled: mousewheel zoom may start from a non-zoomed-in image { - // snap to real dimensions or to box - if (prev_zoomFactor < me.zoomFactor) - me.zoomFactor = min(1, me.zoomBox); - else - me.zoomFactor = max(1, me.zoomBox); + me.start_zoomOffset = me.zoomOffset; + me.start_coords = coords; } - else if (realSize_in_the_middle) - me.zoomFactor = 1; // snap to real dimensions - else if (boxSize_in_the_middle) - me.zoomFactor = me.zoomBox; // snap to box + return 1; } - else if (z == 0) // reset (no zoom) + float Image_drag(entity me, vector coords) { - if (me.zoomBox > 0) - me.zoomFactor = me.zoomBox; - else - me.zoomFactor = 1; + if (me.imgSize.x > 1 || me.imgSize.y > 1) + { + me.zoomOffset_x = me.start_zoomOffset.x + (me.start_coords.x - coords.x) / me.imgSize.x; + me.zoomOffset_y = me.start_zoomOffset.y + (me.start_coords.y - coords.y) / me.imgSize.y; + me.updateAspect(me); + } + return 1; } - else // directly set - me.zoomFactor = z; - me.zoomFactor = bound(1/16, me.zoomFactor, 16); - if (me.zoomMax > 0 && me.zoomFactor > me.zoomMax) - me.zoomFactor = me.zoomMax; - if (prev_zoomFactor != me.zoomFactor) + void Image_setZoom(entity me, float z, float atMousePosition) { - me.zoomTime = time; - if (atMousePosition) + float prev_zoomFactor; + prev_zoomFactor = me.zoomFactor; + if (z < 0) // multiply by the current zoomFactor (but can also snap to real dimensions or to box) + { + me.zoomFactor *= -z; + float realSize_in_the_middle, boxSize_in_the_middle; + realSize_in_the_middle = ((prev_zoomFactor - 1) * (me.zoomFactor - 1) < 0); + boxSize_in_the_middle = (me.zoomBox > 0 && (prev_zoomFactor - me.zoomBox) * (me.zoomFactor - me.zoomBox) < 0); + if (realSize_in_the_middle && boxSize_in_the_middle) + { + // snap to real dimensions or to box + if (prev_zoomFactor < me.zoomFactor) me.zoomFactor = min(1, me.zoomBox); + else me.zoomFactor = max(1, me.zoomBox); + } + else if (realSize_in_the_middle) + { + me.zoomFactor = 1; // snap to real dimensions + } + else if (boxSize_in_the_middle) + { + me.zoomFactor = me.zoomBox; // snap to box + } + } + else if (z == 0) // reset (no zoom) + { + if (me.zoomBox > 0) me.zoomFactor = me.zoomBox; + else me.zoomFactor = 1; + } + else // directly set { - me.zoomOffset_x = me.start_zoomOffset.x + (me.start_coords.x - 0.5) / me.imgSize.x; - me.zoomOffset_y = me.start_zoomOffset.y + (me.start_coords.y - 0.5) / me.imgSize.y; - // updateAspect will reset zoomOffset to '0.5 0.5 0' if - // with this zoomFactor the image will not be zoomed in - // (updateAspect will check the new values of imgSize). + me.zoomFactor = z; } + me.zoomFactor = bound(1 / 16, me.zoomFactor, 16); + if (me.zoomMax > 0 && me.zoomFactor > me.zoomMax) me.zoomFactor = me.zoomMax; + if (prev_zoomFactor != me.zoomFactor) + { + me.zoomTime = time; + if (atMousePosition) + { + me.zoomOffset_x = me.start_zoomOffset.x + (me.start_coords.x - 0.5) / me.imgSize.x; + me.zoomOffset_y = me.start_zoomOffset.y + (me.start_coords.y - 0.5) / me.imgSize.y; + // updateAspect will reset zoomOffset to '0.5 0.5 0' if + // with this zoomFactor the image will not be zoomed in + // (updateAspect will check the new values of imgSize). + } + } + me.updateAspect(me); + } + void Image_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) + { + SUPER(Image).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + me.updateAspect(me); } - me.updateAspect(me); -} -void Image_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(Image).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - me.updateAspect(me); -} #endif diff --git a/qcsrc/menu/item/inputbox.qc b/qcsrc/menu/item/inputbox.qc index 35ffe44d8..89adfaae9 100644 --- a/qcsrc/menu/item/inputbox.qc +++ b/qcsrc/menu/item/inputbox.qc @@ -1,392 +1,401 @@ #ifndef ITEM_INPUTBOX_H -#define ITEM_INPUTBOX_H -#include "label.qc" -CLASS(InputBox, Label) - METHOD(InputBox, configureInputBox, void(entity, string, float, float, string)); - METHOD(InputBox, draw, void(entity)); - METHOD(InputBox, setText, void(entity, string)); - METHOD(InputBox, enterText, void(entity, string)); - METHOD(InputBox, keyDown, float(entity, float, float, float)); - METHOD(InputBox, mouseMove, float(entity, vector)); - METHOD(InputBox, mouseRelease, float(entity, vector)); - METHOD(InputBox, mousePress, float(entity, vector)); - METHOD(InputBox, mouseDrag, float(entity, vector)); - METHOD(InputBox, showNotify, void(entity)); - METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector)); - - ATTRIB(InputBox, src, string, string_null) - - ATTRIB(InputBox, cursorPos, float, 0) // characters - ATTRIB(InputBox, scrollPos, float, 0) // widths - - ATTRIB(InputBox, focusable, float, 1) - ATTRIB(InputBox, allowFocusSound, float, 1) - ATTRIB(InputBox, disabled, float, 0) - ATTRIB(InputBox, lastChangeTime, float, 0) - ATTRIB(InputBox, dragScrollTimer, float, 0) - ATTRIB(InputBox, dragScrollPos, vector, '0 0 0') - ATTRIB(InputBox, pressed, float, 0) - ATTRIB(InputBox, editColorCodes, float, 1) - ATTRIB(InputBox, forbiddenCharacters, string, "") - ATTRIB(InputBox, color, vector, '1 1 1') - ATTRIB(InputBox, colorF, vector, '1 1 1') - ATTRIB(InputBox, maxLength, float, 255) // if negative, it counts bytes, not chars - - ATTRIB(InputBox, enableClearButton, float, 1) - ATTRIB(InputBox, clearButton, entity, NULL) - ATTRIB(InputBox, cb_width, float, 0) - ATTRIB(InputBox, cb_pressed, float, 0) - ATTRIB(InputBox, cb_focused, float, 0) - ATTRIB(InputBox, cb_color, vector, '1 1 1') - ATTRIB(InputBox, cb_colorF, vector, '1 1 1') - ATTRIB(InputBox, cb_colorC, vector, '1 1 1') -ENDCLASS(InputBox) + #define ITEM_INPUTBOX_H + #include "label.qc" + CLASS(InputBox, Label) + METHOD(InputBox, configureInputBox, void(entity, string, float, float, string)); + METHOD(InputBox, draw, void(entity)); + METHOD(InputBox, setText, void(entity, string)); + METHOD(InputBox, enterText, void(entity, string)); + METHOD(InputBox, keyDown, float(entity, float, float, float)); + METHOD(InputBox, mouseMove, float(entity, vector)); + METHOD(InputBox, mouseRelease, float(entity, vector)); + METHOD(InputBox, mousePress, float(entity, vector)); + METHOD(InputBox, mouseDrag, float(entity, vector)); + METHOD(InputBox, showNotify, void(entity)); + METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector)); + + ATTRIB(InputBox, src, string, string_null) + + ATTRIB(InputBox, cursorPos, float, 0) // characters + ATTRIB(InputBox, scrollPos, float, 0) // widths + + ATTRIB(InputBox, focusable, float, 1) + ATTRIB(InputBox, allowFocusSound, float, 1) + ATTRIB(InputBox, disabled, float, 0) + ATTRIB(InputBox, lastChangeTime, float, 0) + ATTRIB(InputBox, dragScrollTimer, float, 0) + ATTRIB(InputBox, dragScrollPos, vector, '0 0 0') + ATTRIB(InputBox, pressed, float, 0) + ATTRIB(InputBox, editColorCodes, float, 1) + ATTRIB(InputBox, forbiddenCharacters, string, "") + ATTRIB(InputBox, color, vector, '1 1 1') + ATTRIB(InputBox, colorF, vector, '1 1 1') + ATTRIB(InputBox, maxLength, float, 255) // if negative, it counts bytes, not chars + + ATTRIB(InputBox, enableClearButton, float, 1) + ATTRIB(InputBox, clearButton, entity, NULL) + ATTRIB(InputBox, cb_width, float, 0) + ATTRIB(InputBox, cb_pressed, float, 0) + ATTRIB(InputBox, cb_focused, float, 0) + ATTRIB(InputBox, cb_color, vector, '1 1 1') + ATTRIB(InputBox, cb_colorF, vector, '1 1 1') + ATTRIB(InputBox, cb_colorC, vector, '1 1 1') + ENDCLASS(InputBox) #endif #ifdef IMPLEMENTATION -void InputBox_configureInputBox(entity me, string theText, float theCursorPos, float theFontSize, string gfx) -{ - SUPER(InputBox).configureLabel(me, theText, theFontSize, 0.0); - me.src = gfx; - me.cursorPos = theCursorPos; -} -void InputBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(InputBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - if (me.enableClearButton) + void InputBox_configureInputBox(entity me, string theText, float theCursorPos, float theFontSize, string gfx) { - me.cb_width = absSize.y / absSize.x; - me.cb_offset = bound(-1, me.cb_offset, 0) * me.cb_width; // bound to range -1, 0 - me.keepspaceRight = me.keepspaceRight - me.cb_offset + me.cb_width; + SUPER(InputBox).configureLabel(me, theText, theFontSize, 0.0); + me.src = gfx; + me.cursorPos = theCursorPos; } -} - -void InputBox_setText(entity me, string txt) -{ - if(me.text) - strunzone(me.text); - SUPER(InputBox).setText(me, strzone(txt)); -} - -float over_ClearButton(entity me, vector pos) -{ - if (pos.x >= 1 + me.cb_offset - me.cb_width) - if (pos.x < 1 + me.cb_offset) - if (pos.y >= 0) - if (pos.y < 1) - return 1; - return 0; -} - -float InputBox_mouseMove(entity me, vector pos) -{ - if (me.enableClearButton) + void InputBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) { - if (over_ClearButton(me, pos)) + SUPER(InputBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + if (me.enableClearButton) { - me.cb_focused = 1; - return 1; + me.cb_width = absSize.y / absSize.x; + me.cb_offset = bound(-1, me.cb_offset, 0) * me.cb_width; // bound to range -1, 0 + me.keepspaceRight = me.keepspaceRight - me.cb_offset + me.cb_width; } - me.cb_focused = 0; } - return 1; -} -float InputBox_mouseDrag(entity me, vector pos) -{ - float p; - if(me.pressed) + void InputBox_setText(entity me, string txt) { - me.dragScrollPos = pos; - p = me.scrollPos + pos.x - me.keepspaceLeft; - me.cursorPos = draw_TextLengthUpToWidth(me.text, p, 0, me.realFontSize); - me.lastChangeTime = time; + if (me.text) strunzone(me.text); + SUPER(InputBox).setText(me, strzone(txt)); } - else if (me.enableClearButton) + + float over_ClearButton(entity me, vector pos) { - if (over_ClearButton(me, pos)) - { - me.cb_pressed = 1; - return 1; - } + if (pos.x >= 1 + me.cb_offset - me.cb_width) + if (pos.x < 1 + me.cb_offset) + if (pos.y >= 0) + if (pos.y < 1) return 1; + return 0; } - me.cb_pressed = 0; - return 1; -} - -float InputBox_mousePress(entity me, vector pos) -{ - if (me.enableClearButton) - if (over_ClearButton(me, pos)) + + float InputBox_mouseMove(entity me, vector pos) { - me.cb_pressed = 1; + if (me.enableClearButton) + { + if (over_ClearButton(me, pos)) + { + me.cb_focused = 1; + return 1; + } + me.cb_focused = 0; + } return 1; } - me.dragScrollTimer = time; - me.pressed = 1; - return InputBox_mouseDrag(me, pos); -} - -float InputBox_mouseRelease(entity me, vector pos) -{ - if(me.cb_pressed) - if (over_ClearButton(me, pos)) + + float InputBox_mouseDrag(entity me, vector pos) { - m_play_click_sound(MENU_SOUND_CLEAR); - me.setText(me, ""); + float p; + if (me.pressed) + { + me.dragScrollPos = pos; + p = me.scrollPos + pos.x - me.keepspaceLeft; + me.cursorPos = draw_TextLengthUpToWidth(me.text, p, 0, me.realFontSize); + me.lastChangeTime = time; + } + else if (me.enableClearButton) + { + if (over_ClearButton(me, pos)) + { + me.cb_pressed = 1; + return 1; + } + } me.cb_pressed = 0; return 1; } - float r = InputBox_mouseDrag(me, pos); - //reset cb_pressed after mouseDrag, mouseDrag could set cb_pressed in this case: - //mouse press out of the clear button, drag and then mouse release over the clear button - me.cb_pressed = 0; - me.pressed = 0; - return r; -} - -void InputBox_enterText(entity me, string ch) -{ - float i; - for(i = 0; i < strlen(ch); ++i) - if(strstrofs(me.forbiddenCharacters, substring(ch, i, 1), 0) > -1) - return; - if(me.maxLength > 0) + + float InputBox_mousePress(entity me, vector pos) { - if(strlen(ch) + strlen(me.text) > me.maxLength) - return; + if (me.enableClearButton) + if (over_ClearButton(me, pos)) + { + me.cb_pressed = 1; + return 1; + } + me.dragScrollTimer = time; + me.pressed = 1; + return InputBox_mouseDrag(me, pos); } - else if(me.maxLength < 0) + + float InputBox_mouseRelease(entity me, vector pos) { - if(u8_strsize(ch) + u8_strsize(me.text) > -me.maxLength) - return; + if (me.cb_pressed) + if (over_ClearButton(me, pos)) + { + m_play_click_sound(MENU_SOUND_CLEAR); + me.setText(me, ""); + me.cb_pressed = 0; + return 1; + } + float r = InputBox_mouseDrag(me, pos); + // reset cb_pressed after mouseDrag, mouseDrag could set cb_pressed in this case: + // mouse press out of the clear button, drag and then mouse release over the clear button + me.cb_pressed = 0; + me.pressed = 0; + return r; } - me.setText(me, strcat(substring(me.text, 0, me.cursorPos), ch, substring(me.text, me.cursorPos, strlen(me.text) - me.cursorPos))); - me.cursorPos += strlen(ch); -} - -float InputBox_keyDown(entity me, float key, float ascii, float shift) -{ - me.lastChangeTime = time; - me.dragScrollTimer = time; - if(ascii >= 32 && ascii != 127) + + void InputBox_enterText(entity me, string ch) { - me.enterText(me, chr(ascii)); - return 1; + float i; + for (i = 0; i < strlen(ch); ++i) + if (strstrofs(me.forbiddenCharacters, substring(ch, i, 1), 0) > -1) return; + if (me.maxLength > 0) + { + if (strlen(ch) + strlen(me.text) > me.maxLength) return; + } + else if (me.maxLength < 0) + { + if (u8_strsize(ch) + u8_strsize(me.text) > -me.maxLength) return; + } + me.setText(me, strcat(substring(me.text, 0, me.cursorPos), ch, substring(me.text, me.cursorPos, strlen(me.text) - me.cursorPos))); + me.cursorPos += strlen(ch); } - switch(key) + + float InputBox_keyDown(entity me, float key, float ascii, float shift) { - case K_KP_LEFTARROW: - case K_LEFTARROW: - me.cursorPos -= 1; - return 1; - case K_KP_RIGHTARROW: - case K_RIGHTARROW: - me.cursorPos += 1; - return 1; - case K_KP_HOME: - case K_HOME: - me.cursorPos = 0; - return 1; - case K_KP_END: - case K_END: - me.cursorPos = strlen(me.text); + me.lastChangeTime = time; + me.dragScrollTimer = time; + if (ascii >= 32 && ascii != 127) + { + me.enterText(me, chr(ascii)); return 1; - case K_BACKSPACE: - if(me.cursorPos > 0) - { + } + switch (key) + { + case K_KP_LEFTARROW: + case K_LEFTARROW: me.cursorPos -= 1; - me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1))); - } - return 1; - case K_KP_DEL: - case K_DEL: - if(shift & S_CTRL) - { - m_play_click_sound(MENU_SOUND_CLEAR); - me.setText(me, ""); - } - else - me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1))); - return 1; + return 1; + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + me.cursorPos += 1; + return 1; + case K_KP_HOME: + case K_HOME: + me.cursorPos = 0; + return 1; + case K_KP_END: + case K_END: + me.cursorPos = strlen(me.text); + return 1; + case K_BACKSPACE: + if (me.cursorPos > 0) + { + me.cursorPos -= 1; + me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1))); + } + return 1; + case K_KP_DEL: + case K_DEL: + if (shift & S_CTRL) + { + m_play_click_sound(MENU_SOUND_CLEAR); + me.setText(me, ""); + } + else + { + me.setText(me, strcat(substring(me.text, 0, me.cursorPos), substring(me.text, me.cursorPos + 1, strlen(me.text) - me.cursorPos - 1))); + } + return 1; + } + return 0; } - return 0; -} -void InputBox_draw(entity me) -{ - string CURSOR = "_"; - float cursorPosInWidths, totalSizeInWidths; + void InputBox_draw(entity me) + { + string CURSOR = "_"; + float cursorPosInWidths, totalSizeInWidths; - if(me.pressed) - me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event + if (me.pressed) me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event - if(me.recalcPos) - me.recalcPositionWithText(me, me.text); + if (me.recalcPos) me.recalcPositionWithText(me, me.text); - me.focusable = !me.disabled; - if(me.disabled) - draw_alpha *= me.disabledAlpha; + me.focusable = !me.disabled; + if (me.disabled) draw_alpha *= me.disabledAlpha; - if(me.src) - { - if(me.focused && !me.disabled) - draw_ButtonPicture('0 0 0', strcat(me.src, "_f"), '1 1 0', me.colorF, 1); - else - draw_ButtonPicture('0 0 0', strcat(me.src, "_n"), '1 1 0', me.color, 1); - } + if (me.src) + { + if (me.focused && !me.disabled) draw_ButtonPicture('0 0 0', strcat(me.src, "_f"), '1 1 0', me.colorF, 1); + else draw_ButtonPicture('0 0 0', strcat(me.src, "_n"), '1 1 0', me.color, 1); + } - me.cursorPos = bound(0, me.cursorPos, strlen(me.text)); - cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0, me.realFontSize); - totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0, me.realFontSize); + me.cursorPos = bound(0, me.cursorPos, strlen(me.text)); + cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0, me.realFontSize); + totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0, me.realFontSize); - if(me.dragScrollTimer < time) - { - float save; - save = me.scrollPos; - me.scrollPos = bound(cursorPosInWidths - (0.875 - me.keepspaceLeft - me.keepspaceRight), me.scrollPos, cursorPosInWidths - 0.125); - if(me.scrollPos != save) - me.dragScrollTimer = time + 0.2; - } - me.scrollPos = min(me.scrollPos, totalSizeInWidths - (1 - me.keepspaceRight - me.keepspaceLeft)); - me.scrollPos = max(0, me.scrollPos); + if (me.dragScrollTimer < time) + { + float save; + save = me.scrollPos; + me.scrollPos = bound(cursorPosInWidths - (0.875 - me.keepspaceLeft - me.keepspaceRight), me.scrollPos, cursorPosInWidths - 0.125); + if (me.scrollPos != save) me.dragScrollTimer = time + 0.2; + } + me.scrollPos = min(me.scrollPos, totalSizeInWidths - (1 - me.keepspaceRight - me.keepspaceLeft)); + me.scrollPos = max(0, me.scrollPos); - draw_SetClipRect(eX * me.keepspaceLeft, eX * (1 - me.keepspaceLeft - me.keepspaceRight) + eY); - if(me.editColorCodes) - { - string ch, ch2; - float i, n; - vector theColor; - float theAlpha; //float theVariableAlpha; - vector p; - vector theTempColor; - float component; - - p = me.realOrigin - eX * me.scrollPos; - theColor = '1 1 1'; - theAlpha = 1; //theVariableAlpha = 1; // changes when ^ax found - - n = strlen(me.text); - for(i = 0; i < n; ++i) + draw_SetClipRect(eX * me.keepspaceLeft, eX * (1 - me.keepspaceLeft - me.keepspaceRight) + eY); + if (me.editColorCodes) { - ch = substring(me.text, i, 1); - if(ch == "^") + string ch, ch2; + float i, n; + vector theColor; + float theAlpha; // float theVariableAlpha; + vector p; + vector theTempColor; + float component; + + p = me.realOrigin - eX * me.scrollPos; + theColor = '1 1 1'; + theAlpha = 1; // theVariableAlpha = 1; // changes when ^ax found + + n = strlen(me.text); + for (i = 0; i < n; ++i) { - float w; - ch2 = substring(me.text, i+1, 1); - w = draw_TextWidth(strcat(ch, ch2), 0, me.realFontSize); - if(ch2 == "^") - { - draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5); - draw_Text(p + eX * 0.25 * w, "^", me.realFontSize, theColor, theAlpha, 0); - } - else if(ch2 == "0" || stof(ch2)) // digit? + ch = substring(me.text, i, 1); + if (ch == "^") { - switch(stof(ch2)) + float w; + ch2 = substring(me.text, i + 1, 1); + w = draw_TextWidth(strcat(ch, ch2), 0, me.realFontSize); + if (ch2 == "^") { - case 0: theColor = '0 0 0'; theAlpha = 1; break; - case 1: theColor = '1 0 0'; theAlpha = 1; break; - case 2: theColor = '0 1 0'; theAlpha = 1; break; - case 3: theColor = '1 1 0'; theAlpha = 1; break; - case 4: theColor = '0 0 1'; theAlpha = 1; break; - case 5: theColor = '0 1 1'; theAlpha = 1; break; - case 6: theColor = '1 0 1'; theAlpha = 1; break; - case 7: theColor = '1 1 1'; theAlpha = 1; break; - case 8: theColor = '1 1 1'; theAlpha = 0.5; break; - case 9: theColor = '0.5 0.5 0.5'; theAlpha = 1; break; + draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5); + draw_Text(p + eX * 0.25 * w, "^", me.realFontSize, theColor, theAlpha, 0); } - draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5); - draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0); - } - else if(ch2 == "x") // ^x found - { - theColor = '1 1 1'; - - component = HEXDIGIT_TO_DEC(substring(me.text, i+2, 1)); - if (component >= 0) // ^xr found + else if (ch2 == "0" || stof(ch2)) // digit? + { + switch (stof(ch2)) + { + case 0: theColor = '0 0 0'; + theAlpha = 1; + break; + case 1: theColor = '1 0 0'; + theAlpha = 1; + break; + case 2: theColor = '0 1 0'; + theAlpha = 1; + break; + case 3: theColor = '1 1 0'; + theAlpha = 1; + break; + case 4: theColor = '0 0 1'; + theAlpha = 1; + break; + case 5: theColor = '0 1 1'; + theAlpha = 1; + break; + case 6: theColor = '1 0 1'; + theAlpha = 1; + break; + case 7: theColor = '1 1 1'; + theAlpha = 1; + break; + case 8: theColor = '1 1 1'; + theAlpha = 0.5; + break; + case 9: theColor = '0.5 0.5 0.5'; + theAlpha = 1; + break; + } + draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5); + draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0); + } + else if (ch2 == "x") // ^x found { - theTempColor.x = component/15; + theColor = '1 1 1'; - component = HEXDIGIT_TO_DEC(substring(me.text, i+3, 1)); - if (component >= 0) // ^xrg found + component = HEXDIGIT_TO_DEC(substring(me.text, i + 2, 1)); + if (component >= 0) // ^xr found { - theTempColor.y = component/15; + theTempColor.x = component / 15; - component = HEXDIGIT_TO_DEC(substring(me.text, i+4, 1)); - if (component >= 0) // ^xrgb found + component = HEXDIGIT_TO_DEC(substring(me.text, i + 3, 1)); + if (component >= 0) // ^xrg found { - theTempColor.z = component/15; - theColor = theTempColor; - w = draw_TextWidth(substring(me.text, i, 5), 0, me.realFontSize); - - draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5); - draw_Text(p, substring(me.text, i, 5), me.realFontSize, theColor, 1, 0); // theVariableAlpha instead of 1 using alpha tags ^ax - i += 3; + theTempColor.y = component / 15; + + component = HEXDIGIT_TO_DEC(substring(me.text, i + 4, 1)); + if (component >= 0) // ^xrgb found + { + theTempColor.z = component / 15; + theColor = theTempColor; + w = draw_TextWidth(substring(me.text, i, 5), 0, me.realFontSize); + + draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5); + draw_Text(p, substring(me.text, i, 5), me.realFontSize, theColor, 1, 0); // theVariableAlpha instead of 1 using alpha tags ^ax + i += 3; + } + else + { + // blue missing + w = draw_TextWidth(substring(me.text, i, 4), 0, me.realFontSize); + draw_Fill(p, eX * w + eY * me.realFontSize.y, eZ, 0.5); + draw_Text(p, substring(me.text, i, 4), me.realFontSize, '1 1 1', theAlpha, 0); + i += 2; + } } else { - // blue missing - w = draw_TextWidth(substring(me.text, i, 4), 0, me.realFontSize); - draw_Fill(p, eX * w + eY * me.realFontSize.y, eZ, 0.5); - draw_Text(p, substring(me.text, i, 4), me.realFontSize, '1 1 1', theAlpha, 0); - i += 2; + // green missing + w = draw_TextWidth(substring(me.text, i, 3), 0, me.realFontSize); + draw_Fill(p, eX * w + eY * me.realFontSize.y, eY, 0.5); + draw_Text(p, substring(me.text, i, 3), me.realFontSize, '1 1 1', theAlpha, 0); + i += 1; } } else { - // green missing - w = draw_TextWidth(substring(me.text, i, 3), 0, me.realFontSize); - draw_Fill(p, eX * w + eY * me.realFontSize.y, eY, 0.5); - draw_Text(p, substring(me.text, i, 3), me.realFontSize, '1 1 1', theAlpha, 0); - i += 1; + // red missing + // w = draw_TextWidth(substring(me.text, i, 2), 0) * me.realFontSize_x; + draw_Fill(p, eX * w + eY * me.realFontSize.y, eX, 0.5); + draw_Text(p, substring(me.text, i, 2), me.realFontSize, '1 1 1', theAlpha, 0); } } else { - // red missing - //w = draw_TextWidth(substring(me.text, i, 2), 0) * me.realFontSize_x; - draw_Fill(p, eX * w + eY * me.realFontSize.y, eX, 0.5); - draw_Text(p, substring(me.text, i, 2), me.realFontSize, '1 1 1', theAlpha, 0); + draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5); + draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0); } + p += w * eX; + ++i; + continue; } - else - { - draw_Fill(p, eX * w + eY * me.realFontSize.y, '1 1 1', 0.5); - draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, theAlpha, 0); - } - p += w * eX; - ++i; - continue; + draw_Text(p, ch, me.realFontSize, theColor, theAlpha, 0); // TODO theVariableAlpha + p += eX * draw_TextWidth(ch, 0, me.realFontSize); } - draw_Text(p, ch, me.realFontSize, theColor, theAlpha, 0); // TODO theVariableAlpha - p += eX * draw_TextWidth(ch, 0, me.realFontSize); } - } - else - draw_Text(me.realOrigin - eX * me.scrollPos, me.text, me.realFontSize, '1 1 1', 1, 0); + else + { + draw_Text(me.realOrigin - eX * me.scrollPos, me.text, me.realFontSize, '1 1 1', 1, 0); + } - if(!me.focused || (time - me.lastChangeTime) < floor(time - me.lastChangeTime) + 0.5) - draw_Text(me.realOrigin + eX * (cursorPosInWidths - me.scrollPos), CURSOR, me.realFontSize, '1 1 1', 1, 0); + if (!me.focused || (time - me.lastChangeTime) < floor(time - me.lastChangeTime) + 0.5) draw_Text(me.realOrigin + eX * (cursorPosInWidths - me.scrollPos), CURSOR, me.realFontSize, '1 1 1', 1, 0); - draw_ClearClip(); + draw_ClearClip(); - if (me.enableClearButton) - if (me.text != "") - { - if(me.focused && me.cb_pressed) - draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_c"), eX * me.cb_width + eY, me.cb_colorC, 1); - else if(me.focused && me.cb_focused) - draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_f"), eX * me.cb_width + eY, me.cb_colorF, 1); - else - draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_n"), eX * me.cb_width + eY, me.cb_color, 1); - } + if (me.enableClearButton) + if (me.text != "") + { + if (me.focused && me.cb_pressed) draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_c"), eX * me.cb_width + eY, me.cb_colorC, 1); + else if (me.focused && me.cb_focused) draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_f"), eX * me.cb_width + eY, me.cb_colorF, 1); + else draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_n"), eX * me.cb_width + eY, me.cb_color, 1); + } - // skipping SUPER(InputBox).draw(me); - Item_draw(me); -} + // skipping SUPER(InputBox).draw(me); + Item_draw(me); + } -void InputBox_showNotify(entity me) -{ - me.focusable = !me.disabled; -} + void InputBox_showNotify(entity me) + { + me.focusable = !me.disabled; + } #endif diff --git a/qcsrc/menu/item/inputcontainer.qc b/qcsrc/menu/item/inputcontainer.qc index 8e7f24f73..45f60854f 100644 --- a/qcsrc/menu/item/inputcontainer.qc +++ b/qcsrc/menu/item/inputcontainer.qc @@ -1,163 +1,152 @@ #ifndef ITEM_INPUTCONTAINER_H -#define ITEM_INPUTCONTAINER_H -#include "container.qc" -CLASS(InputContainer, 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)); + #define ITEM_INPUTCONTAINER_H + #include "container.qc" + CLASS(InputContainer, 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, bool(entity this, vector pos)); - ATTRIB(InputContainer, mouseFocusedChild, entity, NULL) - ATTRIB(InputContainer, isTabRoot, float, 0) -ENDCLASS(InputContainer) + METHOD(InputContainer, _changeFocusXY, bool(entity this, vector pos)); + 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_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; -} + 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) + float InputContainer_keyDown(entity me, float scan, float ascii, float shift) { - f = me.focusedChild; - if(f) + entity f, ff; + if (SUPER(InputContainer).keyDown(me, scan, ascii, shift)) return 1; + if (scan == K_ESCAPE) { - me.setFocus(me, NULL); - return 1; + f = me.focusedChild; + if (f) + { + me.setFocus(me, NULL); + return 1; + } + return 0; } - return 0; - } - if(scan == K_TAB) - { - f = me.focusedChild; - if(shift & S_SHIFT) + if (scan == K_TAB) { - if(f) + f = me.focusedChild; + if (shift & S_SHIFT) { - for(ff = f.prevSibling; ff; ff = ff.prevSibling) + if (f) { - if (!ff.focusable) - continue; - me.setFocus(me, ff); - return 1; + for (ff = f.prevSibling; ff; ff = ff.prevSibling) + { + if (!ff.focusable) continue; + me.setFocus(me, ff); + return 1; + } } - } - if(!f || me.isTabRoot) - { - for(ff = me.lastChild; ff; ff = ff.prevSibling) + if (!f || me.isTabRoot) { - if (!ff.focusable) - continue; - me.setFocus(me, ff); - return 1; + for (ff = me.lastChild; ff; ff = ff.prevSibling) + { + if (!ff.focusable) continue; + me.setFocus(me, ff); + return 1; + } + return 0; // AIIIIEEEEE! } - return 0; // AIIIIEEEEE! } - } - else - { - if(f) + else { - for(ff = f.nextSibling; ff; ff = ff.nextSibling) + if (f) { - if (!ff.focusable) - continue; - me.setFocus(me, ff); - return 1; + for (ff = f.nextSibling; ff; ff = ff.nextSibling) + { + if (!ff.focusable) continue; + me.setFocus(me, ff); + return 1; + } } - } - if(!f || me.isTabRoot) - { - for(ff = me.firstChild; ff; ff = ff.nextSibling) + if (!f || me.isTabRoot) { - if (!ff.focusable) - continue; - me.setFocus(me, ff); - return 1; + for (ff = me.firstChild; ff; ff = ff.nextSibling) + { + if (!ff.focusable) continue; + me.setFocus(me, ff); + return 1; + } + return 0; // AIIIIEEEEE! } - return 0; // AIIIIEEEEE! } } + return 0; } - return 0; -} -bool InputContainer__changeFocusXY(entity this, vector pos) -{ - entity e = this.itemFromPoint(this, pos); - if (e && !e.focusable) e = NULL; - entity prev = this.mouseFocusedChild; - this.mouseFocusedChild = e; - if (!e) return false; // keep focus when hovering over non-focusable elements - if (e != prev) { - this.setFocus(this, e); - if (e.instanceOfInputContainer) { - e.focusedChild = NULL; - e._changeFocusXY(e, globalToBox(pos, e.Container_origin, e.Container_size)); + bool InputContainer__changeFocusXY(entity this, vector pos) + { + entity e = this.itemFromPoint(this, pos); + if (e && !e.focusable) e = NULL; + entity prev = this.mouseFocusedChild; + this.mouseFocusedChild = e; + if (!e) return false; // keep focus when hovering over non-focusable elements + if (e != prev) + { + this.setFocus(this, e); + if (e.instanceOfInputContainer) + { + e.focusedChild = NULL; + e._changeFocusXY(e, globalToBox(pos, e.Container_origin, e.Container_size)); + } } + return true; // have focus } - return true; // have focus -} -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.mouseFocusedChild != me.focusedChild) // if the keyboard moved the focus away - me.mouseFocusedChild = NULL; // force focusing - 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) -{ - SUPER(InputContainer).mouseRelease(me, pos); // return value? - 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; -} + 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.mouseFocusedChild != me.focusedChild) // if the keyboard moved the focus away + me.mouseFocusedChild = NULL; // force focusing + 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) + { + SUPER(InputContainer).mouseRelease(me, pos); // return value? + 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 diff --git a/qcsrc/menu/item/label.qc b/qcsrc/menu/item/label.qc index ea170777e..6d9b9cda1 100644 --- a/qcsrc/menu/item/label.qc +++ b/qcsrc/menu/item/label.qc @@ -1,183 +1,87 @@ #ifndef ITEM_LABEL_H -#define ITEM_LABEL_H -#include "../item.qc" -CLASS(Label, Item) - METHOD(Label, configureLabel, void(entity, string, float, float)); - METHOD(Label, draw, void(entity)); - METHOD(Label, resizeNotify, void(entity, vector, vector, vector, vector)); - METHOD(Label, setText, void(entity, string)); - METHOD(Label, toString, string(entity)); - METHOD(Label, recalcPositionWithText, void(entity, string)); - ATTRIB(Label, isBold, float, 0) - ATTRIB(Label, text, string, string_null) - ATTRIB(Label, currentText, string, string_null) - ATTRIB(Label, fontSize, float, 8) - ATTRIB(Label, align, float, 0.5) - ATTRIB(Label, allowCut, float, 0) - ATTRIB(Label, allowColors, float, 0) - ATTRIB(Label, keepspaceLeft, float, 0) // for use by subclasses (radiobuttons for example) - ATTRIB(Label, keepspaceRight, float, 0) - ATTRIB(Label, marginLeft, float, 0) // alternate way to specify keepspace* (in characters from the font) - ATTRIB(Label, marginRight, float, 0) - ATTRIB(Label, realFontSize, vector, '0 0 0') - ATTRIB(Label, realOrigin, vector, '0 0 0') - ATTRIB(Label, alpha, float, 0.7) - ATTRIB(Label, colorL, vector, SKINCOLOR_TEXT) - ATTRIB(Label, disabled, float, 0) - ATTRIB(Label, disabledAlpha, float, 0.3) - ATTRIB(Label, textEntity, entity, NULL) - ATTRIB(Label, allowWrap, float, 0) - ATTRIB(Label, recalcPos, float, 0) - ATTRIB(Label, condenseFactor, float, 1) - ATTRIB(Label, overrideRealOrigin, vector, '0 0 0') - ATTRIB(Label, overrideCondenseFactor, float, 0) -ENDCLASS(Label) + #define ITEM_LABEL_H + #include "../item.qc" + CLASS(Label, Item) + METHOD(Label, configureLabel, void(entity, string, float, float)); + METHOD(Label, draw, void(entity)); + METHOD(Label, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Label, setText, void(entity, string)); + METHOD(Label, toString, string(entity)); + METHOD(Label, recalcPositionWithText, void(entity, string)); + ATTRIB(Label, isBold, float, 0) + ATTRIB(Label, text, string, string_null) + ATTRIB(Label, currentText, string, string_null) + ATTRIB(Label, fontSize, float, 8) + ATTRIB(Label, align, float, 0.5) + ATTRIB(Label, allowCut, float, 0) + ATTRIB(Label, allowColors, float, 0) + ATTRIB(Label, keepspaceLeft, float, 0) // for use by subclasses (radiobuttons for example) + ATTRIB(Label, keepspaceRight, float, 0) + ATTRIB(Label, marginLeft, float, 0) // alternate way to specify keepspace* (in characters from the font) + ATTRIB(Label, marginRight, float, 0) + ATTRIB(Label, realFontSize, vector, '0 0 0') + ATTRIB(Label, realOrigin, vector, '0 0 0') + ATTRIB(Label, alpha, float, 0.7) + ATTRIB(Label, colorL, vector, SKINCOLOR_TEXT) + ATTRIB(Label, disabled, float, 0) + ATTRIB(Label, disabledAlpha, float, 0.3) + ATTRIB(Label, textEntity, entity, NULL) + ATTRIB(Label, allowWrap, float, 0) + ATTRIB(Label, recalcPos, float, 0) + ATTRIB(Label, condenseFactor, float, 1) + ATTRIB(Label, overrideRealOrigin, vector, '0 0 0') + ATTRIB(Label, overrideCondenseFactor, float, 0) + ENDCLASS(Label) #endif #ifdef IMPLEMENTATION -string Label_toString(entity me) -{ - return me.text; -} -void Label_setText(entity me, string txt) -{ - me.text = txt; - if(txt != me.currentText) + string Label_toString(entity me) { - if(me.currentText) - strunzone(me.currentText); - me.currentText = strzone(txt); - me.recalcPos = 1; + return me.text; } -} -void Label_recalcPositionWithText(entity me, string t) -{ - float spaceAvail; - spaceAvail = 1 - me.keepspaceLeft - me.keepspaceRight; - - if(me.isBold) - draw_beginBoldFont(); - - float spaceUsed; - spaceUsed = draw_TextWidth(t, me.allowColors, me.realFontSize); - - if(spaceUsed <= spaceAvail) + void Label_setText(entity me, string txt) { - if(!me.overrideRealOrigin_x) - me.realOrigin_x = me.align * (spaceAvail - spaceUsed) + me.keepspaceLeft; - if(!me.overrideCondenseFactor) - me.condenseFactor = 1; - } - else if(me.allowCut || me.allowWrap) - { - if(!me.overrideRealOrigin_x) - me.realOrigin_x = me.keepspaceLeft; - if(!me.overrideCondenseFactor) - me.condenseFactor = 1; - } - else - { - if(!me.overrideRealOrigin_x) - me.realOrigin_x = me.keepspaceLeft; - if(!me.overrideCondenseFactor) - me.condenseFactor = spaceAvail / spaceUsed; - LOG_TRACEF("NOTE: label text %s too wide for label, condensed by factor %f\n", t, me.condenseFactor); + me.text = txt; + if (txt != me.currentText) + { + if (me.currentText) strunzone(me.currentText); + me.currentText = strzone(txt); + me.recalcPos = 1; + } } - - if(!me.overrideRealOrigin_y) + void Label_recalcPositionWithText(entity me, string t) { - float lines; - vector dfs; - vector fs; + float spaceAvail; + spaceAvail = 1 - me.keepspaceLeft - me.keepspaceRight; - // set up variables to draw in condensed size, but use hinting for original size - fs = me.realFontSize; - fs.x *= me.condenseFactor; + if (me.isBold) draw_beginBoldFont(); - dfs = draw_fontscale; - draw_fontscale.x *= me.condenseFactor; + float spaceUsed; + spaceUsed = draw_TextWidth(t, me.allowColors, me.realFontSize); - if(me.allowCut) // FIXME allowCut incompatible with align != 0 - lines = 1; - else if(me.allowWrap) // FIXME allowWrap incompatible with align != 0 + if (spaceUsed <= spaceAvail) { - getWrappedLine_remaining = me.text; - lines = 0; - while(getWrappedLine_remaining) - { - if (me.allowColors) - getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), fs, draw_TextWidth_WithColors); - else - getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), fs, draw_TextWidth_WithoutColors); - ++lines; - } + if (!me.overrideRealOrigin_x) me.realOrigin_x = me.align * (spaceAvail - spaceUsed) + me.keepspaceLeft; + if (!me.overrideCondenseFactor) me.condenseFactor = 1; + } + else if (me.allowCut || me.allowWrap) + { + if (!me.overrideRealOrigin_x) me.realOrigin_x = me.keepspaceLeft; + if (!me.overrideCondenseFactor) me.condenseFactor = 1; } else - lines = 1; - - draw_fontscale = dfs; - - me.realOrigin_y = 0.5 * (1 - lines * me.realFontSize.y); - } - - if(me.isBold) - draw_endBoldFont(); - - me.recalcPos = 0; -} -void Label_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(Label).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - // absSize_y is height of label - me.realFontSize_y = absSize.y == 0 ? 0 : (me.fontSize / absSize.y); - me.realFontSize_x = absSize.x == 0 ? 0 : (me.fontSize / absSize.x); - if(me.marginLeft) - me.keepspaceLeft = me.marginLeft * me.realFontSize.x; - if(me.marginRight) - me.keepspaceRight = me.marginRight * me.realFontSize.x; - - me.recalcPos = 1; -} -void Label_configureLabel(entity me, string txt, float sz, float algn) -{ - me.fontSize = sz; - me.align = algn; - me.setText(me, txt); -} -void Label_draw(entity me) -{ - string t; - vector o; - if(me.disabled) - draw_alpha *= me.disabledAlpha; - - if(me.textEntity) - { - t = me.textEntity.toString(me.textEntity); - if(t != me.currentText) { - if(me.currentText) - strunzone(me.currentText); - me.currentText = strzone(t); - me.recalcPos = 1; + if (!me.overrideRealOrigin_x) me.realOrigin_x = me.keepspaceLeft; + if (!me.overrideCondenseFactor) me.condenseFactor = spaceAvail / spaceUsed; + LOG_TRACEF("NOTE: label text %s too wide for label, condensed by factor %f\n", t, me.condenseFactor); } - } - else - t = me.text; - if(me.recalcPos) - me.recalcPositionWithText(me, t); - - if(me.fontSize) - if(t) + if (!me.overrideRealOrigin_y) { + float lines; vector dfs; vector fs; - if(me.isBold) - draw_beginBoldFont(); - // set up variables to draw in condensed size, but use hinting for original size fs = me.realFontSize; fs.x *= me.condenseFactor; @@ -185,31 +89,117 @@ void Label_draw(entity me) dfs = draw_fontscale; draw_fontscale.x *= me.condenseFactor; - if(me.allowCut) // FIXME allowCut incompatible with align != 0 - draw_Text(me.realOrigin, draw_TextShortenToWidth(t, (1 - me.keepspaceLeft - me.keepspaceRight), me.allowColors, fs), fs, me.colorL, me.alpha, me.allowColors); - else if(me.allowWrap) // FIXME allowWrap incompatible with align != 0 + if (me.allowCut) // FIXME allowCut incompatible with align != 0 { - getWrappedLine_remaining = t; - o = me.realOrigin; - while(getWrappedLine_remaining) + lines = 1; + } + else if (me.allowWrap) // FIXME allowWrap incompatible with align != 0 + { + getWrappedLine_remaining = me.text; + lines = 0; + while (getWrappedLine_remaining) { - if (me.allowColors) - t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), fs, draw_TextWidth_WithColors); - else - t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), fs, draw_TextWidth_WithoutColors); - draw_Text(o, t, fs, me.colorL, me.alpha, me.allowColors); - o.y += me.realFontSize.y; + if (me.allowColors) getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), fs, draw_TextWidth_WithColors); + else getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), fs, draw_TextWidth_WithoutColors); + ++lines; } } else - draw_Text(me.realOrigin, t, fs, me.colorL, me.alpha, me.allowColors); + { + lines = 1; + } draw_fontscale = dfs; - if(me.isBold) - draw_endBoldFont(); + me.realOrigin_y = 0.5 * (1 - lines * me.realFontSize.y); } - SUPER(Label).draw(me); -} + if (me.isBold) draw_endBoldFont(); + + me.recalcPos = 0; + } + void Label_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) + { + SUPER(Label).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + // absSize_y is height of label + me.realFontSize_y = absSize.y == 0 ? 0 : (me.fontSize / absSize.y); + me.realFontSize_x = absSize.x == 0 ? 0 : (me.fontSize / absSize.x); + if (me.marginLeft) me.keepspaceLeft = me.marginLeft * me.realFontSize.x; + if (me.marginRight) me.keepspaceRight = me.marginRight * me.realFontSize.x; + + me.recalcPos = 1; + } + void Label_configureLabel(entity me, string txt, float sz, float algn) + { + me.fontSize = sz; + me.align = algn; + me.setText(me, txt); + } + void Label_draw(entity me) + { + string t; + vector o; + if (me.disabled) draw_alpha *= me.disabledAlpha; + + if (me.textEntity) + { + t = me.textEntity.toString(me.textEntity); + if (t != me.currentText) + { + if (me.currentText) strunzone(me.currentText); + me.currentText = strzone(t); + me.recalcPos = 1; + } + } + else + { + t = me.text; + } + + if (me.recalcPos) me.recalcPositionWithText(me, t); + + if (me.fontSize) + if (t) + { + vector dfs; + vector fs; + + if (me.isBold) draw_beginBoldFont(); + + // set up variables to draw in condensed size, but use hinting for original size + fs = me.realFontSize; + fs.x *= me.condenseFactor; + + dfs = draw_fontscale; + draw_fontscale.x *= me.condenseFactor; + + if (me.allowCut) // FIXME allowCut incompatible with align != 0 + { + draw_Text(me.realOrigin, draw_TextShortenToWidth(t, (1 - me.keepspaceLeft - me.keepspaceRight), me.allowColors, fs), fs, me.colorL, me.alpha, me.allowColors); + } + else if (me.allowWrap) // FIXME allowWrap incompatible with align != 0 + { + getWrappedLine_remaining = t; + o = me.realOrigin; + while (getWrappedLine_remaining) + { + if (me.allowColors) t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), fs, draw_TextWidth_WithColors); + else t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), fs, draw_TextWidth_WithoutColors); + draw_Text(o, t, fs, me.colorL, me.alpha, me.allowColors); + o.y += me.realFontSize.y; + } + } + else + { + draw_Text(me.realOrigin, t, fs, me.colorL, me.alpha, me.allowColors); + } + + draw_fontscale = dfs; + + if (me.isBold) draw_endBoldFont(); + } + + SUPER(Label).draw(me); + } #endif diff --git a/qcsrc/menu/item/listbox.qc b/qcsrc/menu/item/listbox.qc index 9210e14b3..7f303fda7 100644 --- a/qcsrc/menu/item/listbox.qc +++ b/qcsrc/menu/item/listbox.qc @@ -1,512 +1,505 @@ #ifndef ITEM_LISTBOX_H -#define ITEM_LISTBOX_H -#include "../item.qc" -CLASS(ListBox, Item) - METHOD(ListBox, resizeNotify, void(entity, vector, vector, vector, vector)); - METHOD(ListBox, configureListBox, void(entity, float, float)); - METHOD(ListBox, draw, void(entity)); - METHOD(ListBox, keyDown, float(entity, float, float, float)); - METHOD(ListBox, mouseMove, float(entity, vector)); - METHOD(ListBox, mousePress, float(entity, vector)); - METHOD(ListBox, mouseDrag, float(entity, vector)); - METHOD(ListBox, mouseRelease, float(entity, vector)); - METHOD(ListBox, focusLeave, void(entity)); - ATTRIB(ListBox, focusable, float, 1) - ATTRIB(ListBox, focusedItem, int, -1) - ATTRIB(ListBox, focusedItemAlpha, float, 0.3) - METHOD(ListBox, setFocusedItem, void(entity, int)); - ATTRIB(ListBox, mouseMoveOffset, float, -1) // let know where the cursor is when the list scrolls without moving the cursor - ATTRIB(ListBox, allowFocusSound, float, 1) - ATTRIB(ListBox, selectedItem, int, 0) - ATTRIB(ListBox, size, vector, '0 0 0') - ATTRIB(ListBox, origin, vector, '0 0 0') - ATTRIB(ListBox, scrollPos, float, 0) // measured in window heights, fixed when needed - ATTRIB(ListBox, scrollPosTarget, float, 0) - METHOD(ListBox, isScrolling, bool(entity)); - ATTRIB(ListBox, needScrollToItem, float, -1) - METHOD(ListBox, scrollToItem, void(entity, int)); - ATTRIB(ListBox, previousValue, float, 0) - ATTRIB(ListBox, pressed, float, 0) // 0 = normal, 1 = scrollbar dragging, 2 = item dragging, 3 = released - ATTRIB(ListBox, pressOffset, float, 0) + #define ITEM_LISTBOX_H + #include "../item.qc" + CLASS(ListBox, Item) + METHOD(ListBox, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(ListBox, configureListBox, void(entity, float, float)); + METHOD(ListBox, draw, void(entity)); + METHOD(ListBox, keyDown, float(entity, float, float, float)); + METHOD(ListBox, mouseMove, float(entity, vector)); + METHOD(ListBox, mousePress, float(entity, vector)); + METHOD(ListBox, mouseDrag, float(entity, vector)); + METHOD(ListBox, mouseRelease, float(entity, vector)); + METHOD(ListBox, focusLeave, void(entity)); + ATTRIB(ListBox, focusable, float, 1) + ATTRIB(ListBox, focusedItem, int, -1) + ATTRIB(ListBox, focusedItemAlpha, float, 0.3) + METHOD(ListBox, setFocusedItem, void(entity, int)); + ATTRIB(ListBox, mouseMoveOffset, float, -1) // let know where the cursor is when the list scrolls without moving the cursor + ATTRIB(ListBox, allowFocusSound, float, 1) + ATTRIB(ListBox, selectedItem, int, 0) + ATTRIB(ListBox, size, vector, '0 0 0') + ATTRIB(ListBox, origin, vector, '0 0 0') + ATTRIB(ListBox, scrollPos, float, 0) // measured in window heights, fixed when needed + ATTRIB(ListBox, scrollPosTarget, float, 0) + METHOD(ListBox, isScrolling, bool(entity)); + ATTRIB(ListBox, needScrollToItem, float, -1) + METHOD(ListBox, scrollToItem, void(entity, int)); + ATTRIB(ListBox, previousValue, float, 0) + ATTRIB(ListBox, pressed, float, 0) // 0 = normal, 1 = scrollbar dragging, 2 = item dragging, 3 = released + ATTRIB(ListBox, pressOffset, float, 0) - METHOD(ListBox, updateControlTopBottom, void(entity)); - ATTRIB(ListBox, controlTop, float, 0) - ATTRIB(ListBox, controlBottom, float, 0) - ATTRIB(ListBox, controlWidth, float, 0) - ATTRIB(ListBox, dragScrollPos, vector, '0 0 0') - ATTRIB(ListBox, selectionDoesntMatter, bool, false) // improves scrolling by keys for lists that don't need to show an active selection + METHOD(ListBox, updateControlTopBottom, void(entity)); + ATTRIB(ListBox, controlTop, float, 0) + ATTRIB(ListBox, controlBottom, float, 0) + ATTRIB(ListBox, controlWidth, float, 0) + ATTRIB(ListBox, dragScrollPos, vector, '0 0 0') + ATTRIB(ListBox, selectionDoesntMatter, bool, false) // improves scrolling by keys for lists that don't need to show an active selection - ATTRIB(ListBox, src, string, string_null) // scrollbar - ATTRIB(ListBox, color, vector, '1 1 1') - ATTRIB(ListBox, color2, vector, '1 1 1') - ATTRIB(ListBox, colorC, vector, '1 1 1') - ATTRIB(ListBox, colorF, vector, '1 1 1') - ATTRIB(ListBox, tolerance, vector, '0 0 0') // drag tolerance - ATTRIB(ListBox, scrollbarWidth, float, 0) // pixels - ATTRIB(ListBox, nItems, float, 42) - ATTRIB(ListBox, itemHeight, float, 0) - ATTRIB(ListBox, colorBG, vector, '0 0 0') - ATTRIB(ListBox, alphaBG, float, 0) + ATTRIB(ListBox, src, string, string_null) // scrollbar + ATTRIB(ListBox, color, vector, '1 1 1') + ATTRIB(ListBox, color2, vector, '1 1 1') + ATTRIB(ListBox, colorC, vector, '1 1 1') + ATTRIB(ListBox, colorF, vector, '1 1 1') + ATTRIB(ListBox, tolerance, vector, '0 0 0') // drag tolerance + ATTRIB(ListBox, scrollbarWidth, float, 0) // pixels + ATTRIB(ListBox, nItems, float, 42) + ATTRIB(ListBox, itemHeight, float, 0) + ATTRIB(ListBox, colorBG, vector, '0 0 0') + ATTRIB(ListBox, alphaBG, float, 0) - ATTRIB(ListBox, lastClickedItem, float, -1) - ATTRIB(ListBox, lastClickedTime, float, 0) + ATTRIB(ListBox, lastClickedItem, float, -1) + ATTRIB(ListBox, lastClickedTime, float, 0) - METHOD(ListBox, drawListBoxItem, void(entity, int, vector, bool, bool)); // item number, width/height, isSelected, isFocused - METHOD(ListBox, clickListBoxItem, void(entity, float, vector)); // item number, relative clickpos - METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector)); // item number, relative clickpos - METHOD(ListBox, setSelected, void(entity, float)); - METHOD(ListBox, focusedItemChangeNotify, void(entity)); + METHOD(ListBox, drawListBoxItem, void(entity, int, vector, bool, bool)); // item number, width/height, isSelected, isFocused + METHOD(ListBox, clickListBoxItem, void(entity, float, vector)); // item number, relative clickpos + METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector)); // item number, relative clickpos + METHOD(ListBox, setSelected, void(entity, float)); + METHOD(ListBox, focusedItemChangeNotify, void(entity)); - METHOD(ListBox, getLastFullyVisibleItemAtScrollPos, float(entity, float)); - METHOD(ListBox, getFirstFullyVisibleItemAtScrollPos, float(entity, float)); + METHOD(ListBox, getLastFullyVisibleItemAtScrollPos, float(entity, float)); + METHOD(ListBox, getFirstFullyVisibleItemAtScrollPos, float(entity, float)); - // NOTE: override these four methods if you want variable sized list items - METHOD(ListBox, getTotalHeight, float(entity)); - METHOD(ListBox, getItemAtPos, float(entity, float)); - METHOD(ListBox, getItemStart, float(entity, float)); - METHOD(ListBox, getItemHeight, float(entity, float)); - // NOTE: if getItemAt* are overridden, it may make sense to cache the - // start and height of the last item returned by getItemAtPos and fast - // track returning their properties for getItemStart and getItemHeight. - // The "hot" code path calls getItemAtPos first, then will query - // getItemStart and getItemHeight on it soon. - // When overriding, the following consistency rules must hold: - // getTotalHeight() == SUM(getItemHeight(i), i, 0, me.nItems-1) - // getItemStart(i+1) == getItemStart(i) + getItemHeight(i) - // for 0 <= i < me.nItems-1 - // getItemStart(0) == 0 - // getItemStart(getItemAtPos(p)) <= p - // if p >= 0 - // getItemAtPos(p) == 0 - // if p < 0 - // getItemStart(getItemAtPos(p)) + getItemHeight(getItemAtPos(p)) > p - // if p < getTotalHeigt() - // getItemAtPos(p) == me.nItems - 1 - // if p >= getTotalHeight() -ENDCLASS(ListBox) + // NOTE: override these four methods if you want variable sized list items + METHOD(ListBox, getTotalHeight, float(entity)); + METHOD(ListBox, getItemAtPos, float(entity, float)); + METHOD(ListBox, getItemStart, float(entity, float)); + METHOD(ListBox, getItemHeight, float(entity, float)); + // NOTE: if getItemAt* are overridden, it may make sense to cache the + // start and height of the last item returned by getItemAtPos and fast + // track returning their properties for getItemStart and getItemHeight. + // The "hot" code path calls getItemAtPos first, then will query + // getItemStart and getItemHeight on it soon. + // When overriding, the following consistency rules must hold: + // getTotalHeight() == SUM(getItemHeight(i), i, 0, me.nItems-1) + // getItemStart(i+1) == getItemStart(i) + getItemHeight(i) + // for 0 <= i < me.nItems-1 + // getItemStart(0) == 0 + // getItemStart(getItemAtPos(p)) <= p + // if p >= 0 + // getItemAtPos(p) == 0 + // if p < 0 + // getItemStart(getItemAtPos(p)) + getItemHeight(getItemAtPos(p)) > p + // if p < getTotalHeigt() + // getItemAtPos(p) == me.nItems - 1 + // if p >= getTotalHeight() + ENDCLASS(ListBox) #endif #ifdef IMPLEMENTATION -bool ListBox_isScrolling(entity me) -{ - return (me.scrollPos != me.scrollPosTarget); -} - -void ListBox_scrollToItem(entity me, int i) -{ - // scroll doesn't work properly until itemHeight is set to the correct value - // at the first resizeNotify call - if(me.itemHeight == 1) // initial temporary value of itemHeight is 1 + bool ListBox_isScrolling(entity me) { - me.needScrollToItem = i; - return; + return me.scrollPos != me.scrollPosTarget; } - i = bound(0, i, me.nItems - 1); + void ListBox_scrollToItem(entity me, int i) + { + // scroll doesn't work properly until itemHeight is set to the correct value + // at the first resizeNotify call + if (me.itemHeight == 1) // initial temporary value of itemHeight is 1 + { + me.needScrollToItem = i; + return; + } + + i = bound(0, i, me.nItems - 1); + + // scroll the list to make sure the selected item is visible + // (even if the selected item doesn't change). + if (i < me.getFirstFullyVisibleItemAtScrollPos(me, me.scrollPos)) + { + // above visible area + me.scrollPosTarget = me.getItemStart(me, i); + } + else if (i > me.getLastFullyVisibleItemAtScrollPos(me, me.scrollPos)) + { + // below visible area + if (i == me.nItems - 1) me.scrollPosTarget = me.getTotalHeight(me) - 1; + else me.scrollPosTarget = me.getItemStart(me, i + 1) - 1; + } + } - // scroll the list to make sure the selected item is visible - // (even if the selected item doesn't change). - if(i < me.getFirstFullyVisibleItemAtScrollPos(me, me.scrollPos)) + void ListBox_setSelected(entity me, float i) { - // above visible area - me.scrollPosTarget = me.getItemStart(me, i); + i = bound(0, i, me.nItems - 1); + me.scrollToItem(me, i); + me.selectedItem = i; } - else if(i > me.getLastFullyVisibleItemAtScrollPos(me, me.scrollPos)) + void ListBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) { - // below visible area - if(i == me.nItems - 1) - me.scrollPosTarget = me.getTotalHeight(me) - 1; - else - me.scrollPosTarget = me.getItemStart(me, i + 1) - 1; + SUPER(ListBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + me.controlWidth = me.scrollbarWidth / absSize.x; + } + void ListBox_configureListBox(entity me, float theScrollbarWidth, float theItemHeight) + { + me.scrollbarWidth = theScrollbarWidth; + me.itemHeight = theItemHeight; } -} - -void ListBox_setSelected(entity me, float i) -{ - i = bound(0, i, me.nItems - 1); - me.scrollToItem(me, i); - me.selectedItem = i; -} -void ListBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(ListBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - me.controlWidth = me.scrollbarWidth / absSize.x; -} -void ListBox_configureListBox(entity me, float theScrollbarWidth, float theItemHeight) -{ - me.scrollbarWidth = theScrollbarWidth; - me.itemHeight = theItemHeight; -} -float ListBox_getTotalHeight(entity me) -{ - return me.nItems * me.itemHeight; -} -float ListBox_getItemAtPos(entity me, float pos) -{ - return floor(pos / me.itemHeight); -} -float ListBox_getItemStart(entity me, float i) -{ - return me.itemHeight * i; -} -float ListBox_getItemHeight(entity me, float i) -{ - return me.itemHeight; -} + float ListBox_getTotalHeight(entity me) + { + return me.nItems * me.itemHeight; + } + float ListBox_getItemAtPos(entity me, float pos) + { + return floor(pos / me.itemHeight); + } + float ListBox_getItemStart(entity me, float i) + { + return me.itemHeight * i; + } + float ListBox_getItemHeight(entity me, float i) + { + return me.itemHeight; + } -float ListBox_getLastFullyVisibleItemAtScrollPos(entity me, float pos) -{ - return me.getItemAtPos(me, pos + 0.999) - 1; -} -float ListBox_getFirstFullyVisibleItemAtScrollPos(entity me, float pos) -{ - return me.getItemAtPos(me, pos + 0.001) + 1; -} -float ListBox_keyDown(entity me, float key, float ascii, float shift) -{ - if(key == K_MWHEELUP) + float ListBox_getLastFullyVisibleItemAtScrollPos(entity me, float pos) { - me.scrollPosTarget = max(me.scrollPosTarget - 0.5, 0); + return me.getItemAtPos(me, pos + 0.999) - 1; } - else if(key == K_MWHEELDOWN) + float ListBox_getFirstFullyVisibleItemAtScrollPos(entity me, float pos) { - me.scrollPosTarget = min(me.scrollPosTarget + 0.5, max(0, me.getTotalHeight(me) - 1)); + return me.getItemAtPos(me, pos + 0.001) + 1; } - else if(key == K_PGUP || key == K_KP_PGUP) + float ListBox_keyDown(entity me, float key, float ascii, float shift) { - if(me.selectionDoesntMatter) + if (key == K_MWHEELUP) { me.scrollPosTarget = max(me.scrollPosTarget - 0.5, 0); - return 1; } + else if (key == K_MWHEELDOWN) + { + me.scrollPosTarget = min(me.scrollPosTarget + 0.5, max(0, me.getTotalHeight(me) - 1)); + } + else if (key == K_PGUP || key == K_KP_PGUP) + { + if (me.selectionDoesntMatter) + { + me.scrollPosTarget = max(me.scrollPosTarget - 0.5, 0); + return 1; + } - float i = me.selectedItem; - float a = me.getItemHeight(me, i); - for (;;) + float i = me.selectedItem; + float a = me.getItemHeight(me, i); + for ( ; ; ) + { + --i; + if (i < 0) break; + a += me.getItemHeight(me, i); + if (a >= 1) break; + } + me.setSelected(me, i + 1); + } + else if (key == K_PGDN || key == K_KP_PGDN) { - --i; - if (i < 0) - break; - a += me.getItemHeight(me, i); - if (a >= 1) - break; + if (me.selectionDoesntMatter) + { + me.scrollPosTarget = min(me.scrollPosTarget + 0.5, me.nItems * me.itemHeight - 1); + return 1; + } + + float i = me.selectedItem; + float a = me.getItemHeight(me, i); + for ( ; ; ) + { + ++i; + if (i >= me.nItems) break; + a += me.getItemHeight(me, i); + if (a >= 1) break; + } + me.setSelected(me, i - 1); } - me.setSelected(me, i + 1); - } - else if(key == K_PGDN || key == K_KP_PGDN) - { - if(me.selectionDoesntMatter) + else if (key == K_UPARROW || key == K_KP_UPARROW) { - me.scrollPosTarget = min(me.scrollPosTarget + 0.5, me.nItems * me.itemHeight - 1); - return 1; + if (me.selectionDoesntMatter) + { + me.scrollPosTarget = max(me.scrollPosTarget - me.itemHeight, 0); + return 1; + } + + me.setSelected(me, me.selectedItem - 1); } + else if (key == K_DOWNARROW || key == K_KP_DOWNARROW) + { + if (me.selectionDoesntMatter) + { + me.scrollPosTarget = min(me.scrollPosTarget + me.itemHeight, me.nItems * me.itemHeight - 1); + return 1; + } - float i = me.selectedItem; - float a = me.getItemHeight(me, i); - for (;;) + me.setSelected(me, me.selectedItem + 1); + } + else if (key == K_HOME || key == K_KP_HOME) { - ++i; - if (i >= me.nItems) - break; - a += me.getItemHeight(me, i); - if (a >= 1) - break; + me.setSelected(me, 0); } - me.setSelected(me, i - 1); - } - else if(key == K_UPARROW || key == K_KP_UPARROW) - { - if(me.selectionDoesntMatter) + else if (key == K_END || key == K_KP_END) { - me.scrollPosTarget = max(me.scrollPosTarget - me.itemHeight, 0); - return 1; + me.setSelected(me, me.nItems - 1); } - - me.setSelected(me, me.selectedItem - 1); - } - else if(key == K_DOWNARROW || key == K_KP_DOWNARROW) - { - if(me.selectionDoesntMatter) + else { - me.scrollPosTarget = min(me.scrollPosTarget + me.itemHeight, me.nItems * me.itemHeight - 1); - return 1; + return 0; } - - me.setSelected(me, me.selectedItem + 1); + return 1; } - else if(key == K_HOME || key == K_KP_HOME) - me.setSelected(me, 0); - else if(key == K_END || key == K_KP_END) - me.setSelected(me, me.nItems - 1); - else - return 0; - return 1; -} -float ListBox_mouseMove(entity me, vector pos) -{ - me.mouseMoveOffset = -1; - if(pos_x < 0) return 0; - if(pos_y < 0) return 0; - if(pos_x >= 1) return 0; - if(pos_y >= 1) return 0; - if(pos_x < 1 - me.controlWidth) - me.mouseMoveOffset = pos.y; - else + float ListBox_mouseMove(entity me, vector pos) { - me.setFocusedItem(me, -1); me.mouseMoveOffset = -1; - } - return 1; -} -float ListBox_mouseDrag(entity me, vector pos) -{ - float hit; - me.updateControlTopBottom(me); - me.dragScrollPos = pos; - if(me.pressed == 1) - { - hit = 1; - if(pos.x < 1 - me.controlWidth - me.tolerance.y * me.controlWidth) hit = 0; - if(pos.y < 0 - me.tolerance.x) hit = 0; - if(pos.x >= 1 + me.tolerance.y * me.controlWidth) hit = 0; - if(pos.y >= 1 + me.tolerance.x) hit = 0; - if(hit) + if (pos_x < 0) return 0; + if (pos_y < 0) return 0; + if (pos_x >= 1) return 0; + if (pos_y >= 1) return 0; + if (pos_x < 1 - me.controlWidth) { - // calculate new pos to v - float d; - d = (pos.y - me.pressOffset) / (1 - (me.controlBottom - me.controlTop)) * (me.getTotalHeight(me) - 1); - me.scrollPosTarget = me.previousValue + d; + me.mouseMoveOffset = pos.y; } else - me.scrollPosTarget = me.previousValue; - me.scrollPosTarget = min(me.scrollPosTarget, me.getTotalHeight(me) - 1); - me.scrollPosTarget = max(me.scrollPosTarget, 0); - } - else if(me.pressed == 2) - { - me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y)); - me.setFocusedItem(me, me.selectedItem); - me.mouseMoveOffset = -1; + { + me.setFocusedItem(me, -1); + me.mouseMoveOffset = -1; + } + return 1; } - return 1; -} -float ListBox_mousePress(entity me, vector pos) -{ - if(pos.x < 0) return 0; - if(pos.y < 0) return 0; - if(pos.x >= 1) return 0; - if(pos.y >= 1) return 0; - me.dragScrollPos = pos; - me.updateControlTopBottom(me); - if(pos.x >= 1 - me.controlWidth) + float ListBox_mouseDrag(entity me, vector pos) { - // if hit, set me.pressed, otherwise scroll by one page - if(pos.y < me.controlTop) + float hit; + me.updateControlTopBottom(me); + me.dragScrollPos = pos; + if (me.pressed == 1) + { + hit = 1; + if (pos.x < 1 - me.controlWidth - me.tolerance.y * me.controlWidth) hit = 0; + if (pos.y < 0 - me.tolerance.x) hit = 0; + if (pos.x >= 1 + me.tolerance.y * me.controlWidth) hit = 0; + if (pos.y >= 1 + me.tolerance.x) hit = 0; + if (hit) + { + // calculate new pos to v + float d; + d = (pos.y - me.pressOffset) / (1 - (me.controlBottom - me.controlTop)) * (me.getTotalHeight(me) - 1); + me.scrollPosTarget = me.previousValue + d; + } + else + { + me.scrollPosTarget = me.previousValue; + } + me.scrollPosTarget = min(me.scrollPosTarget, me.getTotalHeight(me) - 1); + me.scrollPosTarget = max(me.scrollPosTarget, 0); + } + else if (me.pressed == 2) { - // page up - me.scrollPosTarget = max(me.scrollPosTarget - 1, 0); + me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y)); + me.setFocusedItem(me, me.selectedItem); + me.mouseMoveOffset = -1; } - else if(pos.y > me.controlBottom) + return 1; + } + float ListBox_mousePress(entity me, vector pos) + { + if (pos.x < 0) return 0; + if (pos.y < 0) return 0; + if (pos.x >= 1) return 0; + if (pos.y >= 1) return 0; + me.dragScrollPos = pos; + me.updateControlTopBottom(me); + if (pos.x >= 1 - me.controlWidth) { - // page down - me.scrollPosTarget = min(me.scrollPosTarget + 1, me.getTotalHeight(me) - 1); + // if hit, set me.pressed, otherwise scroll by one page + if (pos.y < me.controlTop) + { + // page up + me.scrollPosTarget = max(me.scrollPosTarget - 1, 0); + } + else if (pos.y > me.controlBottom) + { + // page down + me.scrollPosTarget = min(me.scrollPosTarget + 1, me.getTotalHeight(me) - 1); + } + else + { + me.pressed = 1; + me.pressOffset = pos.y; + me.previousValue = me.scrollPos; + } } else { - me.pressed = 1; - me.pressOffset = pos.y; - me.previousValue = me.scrollPos; + // continue doing that while dragging (even when dragging outside). When releasing, forward the click to the then selected item. + me.pressed = 2; + // an item has been clicked. Select it, ... + me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y)); + me.setFocusedItem(me, me.selectedItem); } + return 1; } - else - { - // continue doing that while dragging (even when dragging outside). When releasing, forward the click to the then selected item. - me.pressed = 2; - // an item has been clicked. Select it, ... - me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y)); - me.setFocusedItem(me, me.selectedItem); - } - return 1; -} -void ListBox_setFocusedItem(entity me, int item) -{ - float focusedItem_save = me.focusedItem; - me.focusedItem = (item < me.nItems) ? item : -1; - if(focusedItem_save != me.focusedItem) + void ListBox_setFocusedItem(entity me, int item) { - me.focusedItemChangeNotify(me); - if(me.focusedItem >= 0) - me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED; - } -} -float ListBox_mouseRelease(entity me, vector pos) -{ - if(me.pressed == 1) - { - // slider dragging mode - // in that case, nothing happens on releasing + float focusedItem_save = me.focusedItem; + me.focusedItem = (item < me.nItems) ? item : -1; + if (focusedItem_save != me.focusedItem) + { + me.focusedItemChangeNotify(me); + if (me.focusedItem >= 0) me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED; + } } - else if(me.pressed == 2) + float ListBox_mouseRelease(entity me, vector pos) { - me.pressed = 3; // do that here, so setSelected can know the mouse has been released - // item dragging mode - // select current one one last time... - me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y)); - me.setFocusedItem(me, me.selectedItem); - // and give it a nice click event - if(me.nItems > 0) + if (me.pressed == 1) + { + // slider dragging mode + // in that case, nothing happens on releasing + } + else if (me.pressed == 2) { - vector where = globalToBox(pos, eY * (me.getItemStart(me, me.selectedItem) - me.scrollPos), eX * (1 - me.controlWidth) + eY * me.getItemHeight(me, me.selectedItem)); + me.pressed = 3; // do that here, so setSelected can know the mouse has been released + // item dragging mode + // select current one one last time... + me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y)); + me.setFocusedItem(me, me.selectedItem); + // and give it a nice click event + if (me.nItems > 0) + { + vector where = globalToBox(pos, eY * (me.getItemStart(me, me.selectedItem) - me.scrollPos), eX * (1 - me.controlWidth) + eY * me.getItemHeight(me, me.selectedItem)); - if((me.selectedItem == me.lastClickedItem) && (time < me.lastClickedTime + 0.3)) - me.doubleClickListBoxItem(me, me.selectedItem, where); - else - me.clickListBoxItem(me, me.selectedItem, where); + if ((me.selectedItem == me.lastClickedItem) && (time < me.lastClickedTime + 0.3)) me.doubleClickListBoxItem(me, me.selectedItem, where); + else me.clickListBoxItem(me, me.selectedItem, where); - me.lastClickedItem = me.selectedItem; - me.lastClickedTime = time; + me.lastClickedItem = me.selectedItem; + me.lastClickedTime = time; + } } + me.pressed = 0; + return 1; } - me.pressed = 0; - return 1; -} -void ListBox_focusLeave(entity me) -{ - // Reset the var pressed in case listbox loses focus - // by a mouse click on an item of the list - // for example showing a dialog on right click - me.pressed = 0; - me.setFocusedItem(me, -1); - me.mouseMoveOffset = -1; -} -void ListBox_updateControlTopBottom(entity me) -{ - float f; - // scrollPos is in 0..1 and indicates where the "page" currently shown starts. - if(me.getTotalHeight(me) <= 1) + void ListBox_focusLeave(entity me) { - // we don't need no stinkin' scrollbar, we don't need no view control... - me.controlTop = 0; - me.controlBottom = 1; - me.scrollPos = 0; + // Reset the var pressed in case listbox loses focus + // by a mouse click on an item of the list + // for example showing a dialog on right click + me.pressed = 0; + me.setFocusedItem(me, -1); + me.mouseMoveOffset = -1; } - else + void ListBox_updateControlTopBottom(entity me) { - // if scroll pos is below end of list, fix it - me.scrollPos = min(me.scrollPos, me.getTotalHeight(me) - 1); - // if scroll pos is above beginning of list, fix it - me.scrollPos = max(me.scrollPos, 0); - // now that we know where the list is scrolled to, find out where to draw the control - me.controlTop = max(0, me.scrollPos / me.getTotalHeight(me)); - me.controlBottom = min((me.scrollPos + 1) / me.getTotalHeight(me), 1); - - float minfactor; - minfactor = 2 * me.controlWidth / me.size.y * me.size.x; - f = me.controlBottom - me.controlTop; - if(f < minfactor) // FIXME good default? + float f; + // scrollPos is in 0..1 and indicates where the "page" currently shown starts. + if (me.getTotalHeight(me) <= 1) { - // f * X + 1 * (1-X) = minfactor - // (f - 1) * X + 1 = minfactor - // (f - 1) * X = minfactor - 1 - // X = (minfactor - 1) / (f - 1) - f = (minfactor - 1) / (f - 1); - me.controlTop = me.controlTop * f + 0 * (1 - f); - me.controlBottom = me.controlBottom * f + 1 * (1 - f); + // we don't need no stinkin' scrollbar, we don't need no view control... + me.controlTop = 0; + me.controlBottom = 1; + me.scrollPos = 0; + } + else + { + // if scroll pos is below end of list, fix it + me.scrollPos = min(me.scrollPos, me.getTotalHeight(me) - 1); + // if scroll pos is above beginning of list, fix it + me.scrollPos = max(me.scrollPos, 0); + // now that we know where the list is scrolled to, find out where to draw the control + me.controlTop = max(0, me.scrollPos / me.getTotalHeight(me)); + me.controlBottom = min((me.scrollPos + 1) / me.getTotalHeight(me), 1); + + float minfactor; + minfactor = 2 * me.controlWidth / me.size.y * me.size.x; + f = me.controlBottom - me.controlTop; + if (f < minfactor) // FIXME good default? + { + // f * X + 1 * (1-X) = minfactor + // (f - 1) * X + 1 = minfactor + // (f - 1) * X = minfactor - 1 + // X = (minfactor - 1) / (f - 1) + f = (minfactor - 1) / (f - 1); + me.controlTop = me.controlTop * f + 0 * (1 - f); + me.controlBottom = me.controlBottom * f + 1 * (1 - f); + } } } -} -AUTOCVAR(menu_scroll_averaging_time, float, 0.16, "smooth scroll averaging time"); + AUTOCVAR(menu_scroll_averaging_time, float, 0.16, "smooth scroll averaging time"); // scroll faster while dragging the scrollbar -AUTOCVAR(menu_scroll_averaging_time_pressed, float, 0.06, "smooth scroll averaging time when dragging the scrollbar"); -void ListBox_draw(entity me) -{ - float i; - vector absSize, fillSize = '0 0 0'; - vector oldshift, oldscale; + AUTOCVAR(menu_scroll_averaging_time_pressed, float, 0.06, "smooth scroll averaging time when dragging the scrollbar"); + void ListBox_draw(entity me) + { + float i; + vector absSize, fillSize = '0 0 0'; + vector oldshift, oldscale; - // we can't do this in mouseMove as the list can scroll without moving the cursor - if(me.mouseMoveOffset != -1) - me.setFocusedItem(me, me.getItemAtPos(me, me.scrollPos + me.mouseMoveOffset)); + // we can't do this in mouseMove as the list can scroll without moving the cursor + if (me.mouseMoveOffset != -1) me.setFocusedItem(me, me.getItemAtPos(me, me.scrollPos + me.mouseMoveOffset)); - if(me.needScrollToItem >= 0) - { - me.scrollToItem(me, me.needScrollToItem); - me.needScrollToItem = -1; - } - if(me.scrollPos != me.scrollPosTarget) - { - float averaging_time = (me.pressed == 1) - ? autocvar_menu_scroll_averaging_time_pressed - : autocvar_menu_scroll_averaging_time; - // this formula works with whatever framerate - float f = averaging_time ? exp(-frametime / averaging_time) : 0; - me.scrollPos = me.scrollPos * f + me.scrollPosTarget * (1 - f); - if(fabs(me.scrollPos - me.scrollPosTarget) < 0.001) - me.scrollPos = me.scrollPosTarget; - } + if (me.needScrollToItem >= 0) + { + me.scrollToItem(me, me.needScrollToItem); + me.needScrollToItem = -1; + } + if (me.scrollPos != me.scrollPosTarget) + { + float averaging_time = (me.pressed == 1) + ? autocvar_menu_scroll_averaging_time_pressed + : autocvar_menu_scroll_averaging_time; + // this formula works with whatever framerate + float f = averaging_time ? exp(-frametime / averaging_time) : 0; + me.scrollPos = me.scrollPos * f + me.scrollPosTarget * (1 - f); + if (fabs(me.scrollPos - me.scrollPosTarget) < 0.001) me.scrollPos = me.scrollPosTarget; + } - if(me.pressed == 2) - me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event - me.updateControlTopBottom(me); - fillSize.x = (1 - me.controlWidth); - if(me.alphaBG) - draw_Fill('0 0 0', '0 1 0' + fillSize, me.colorBG, me.alphaBG); - if(me.controlWidth) - { - draw_VertButtonPicture(eX * (1 - me.controlWidth), strcat(me.src, "_s"), eX * me.controlWidth + eY, me.color2, 1); - if(me.getTotalHeight(me) > 1) + if (me.pressed == 2) me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event + me.updateControlTopBottom(me); + fillSize.x = (1 - me.controlWidth); + if (me.alphaBG) draw_Fill('0 0 0', '0 1 0' + fillSize, me.colorBG, me.alphaBG); + if (me.controlWidth) { - vector o, s; - o = eX * (1 - me.controlWidth) + eY * me.controlTop; - s = eX * me.controlWidth + eY * (me.controlBottom - me.controlTop); - if(me.pressed == 1) - draw_VertButtonPicture(o, strcat(me.src, "_c"), s, me.colorC, 1); - else if(me.focused) - draw_VertButtonPicture(o, strcat(me.src, "_f"), s, me.colorF, 1); - else - draw_VertButtonPicture(o, strcat(me.src, "_n"), s, me.color, 1); + draw_VertButtonPicture(eX * (1 - me.controlWidth), strcat(me.src, "_s"), eX * me.controlWidth + eY, me.color2, 1); + if (me.getTotalHeight(me) > 1) + { + vector o, s; + o = eX * (1 - me.controlWidth) + eY * me.controlTop; + s = eX * me.controlWidth + eY * (me.controlBottom - me.controlTop); + if (me.pressed == 1) draw_VertButtonPicture(o, strcat(me.src, "_c"), s, me.colorC, 1); + else if (me.focused) draw_VertButtonPicture(o, strcat(me.src, "_f"), s, me.colorF, 1); + else draw_VertButtonPicture(o, strcat(me.src, "_n"), s, me.color, 1); + } } - } - draw_SetClip(); - oldshift = draw_shift; - oldscale = draw_scale; + draw_SetClip(); + oldshift = draw_shift; + oldscale = draw_scale; - float y; - i = me.getItemAtPos(me, me.scrollPos); - y = me.getItemStart(me, i) - me.scrollPos; - for (; i < me.nItems && y < 1; ++i) - { - draw_shift = boxToGlobal(eY * y, oldshift, oldscale); - vector relSize = eX * (1 - me.controlWidth) + eY * me.getItemHeight(me, i); - absSize = boxToGlobalSize(relSize, me.size); - draw_scale = boxToGlobalSize(relSize, oldscale); - me.drawListBoxItem(me, i, absSize, (me.selectedItem == i), (me.focusedItem == i)); - y += relSize.y; - } - draw_ClearClip(); + float y; + i = me.getItemAtPos(me, me.scrollPos); + y = me.getItemStart(me, i) - me.scrollPos; + for ( ; i < me.nItems && y < 1; ++i) + { + draw_shift = boxToGlobal(eY * y, oldshift, oldscale); + vector relSize = eX * (1 - me.controlWidth) + eY * me.getItemHeight(me, i); + absSize = boxToGlobalSize(relSize, me.size); + draw_scale = boxToGlobalSize(relSize, oldscale); + me.drawListBoxItem(me, i, absSize, (me.selectedItem == i), (me.focusedItem == i)); + y += relSize.y; + } + draw_ClearClip(); - draw_shift = oldshift; - draw_scale = oldscale; - SUPER(ListBox).draw(me); -} + draw_shift = oldshift; + draw_scale = oldscale; + SUPER(ListBox).draw(me); + } -void ListBox_focusedItemChangeNotify(entity me) -{ -} + void ListBox_focusedItemChangeNotify(entity me) + {} -void ListBox_clickListBoxItem(entity me, float i, vector where) -{ - // template method -} + void ListBox_clickListBoxItem(entity me, float i, vector where) + { + // template method + } -void ListBox_doubleClickListBoxItem(entity me, float i, vector where) -{ - // template method -} + void ListBox_doubleClickListBoxItem(entity me, float i, vector where) + { + // template method + } -void ListBox_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused) -{ - draw_Text('0 0 0', sprintf(_("Item %d"), i), eX * (8 / absSize.x) + eY * (8 / absSize.y), (isSelected ? '0 1 0' : '1 1 1'), 1, 0); -} + void ListBox_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused) + { + draw_Text('0 0 0', sprintf(_("Item %d"), i), eX * (8 / absSize.x) + eY * (8 / absSize.y), (isSelected ? '0 1 0' : '1 1 1'), 1, 0); + } #endif diff --git a/qcsrc/menu/item/modalcontroller.qc b/qcsrc/menu/item/modalcontroller.qc index 046d8e194..ed02a0cef 100644 --- a/qcsrc/menu/item/modalcontroller.qc +++ b/qcsrc/menu/item/modalcontroller.qc @@ -1,31 +1,31 @@ #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)); + #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)); - METHOD(ModalController, initializeDialog, void(entity, entity)); + METHOD(ModalController, initializeDialog, void(entity, entity)); - 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) + 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) -.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 + .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 @@ -51,246 +51,238 @@ void DialogCloseButton_Click(entity button, entity tab); // assumes a button has // - 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; + .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 = NULL; - 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; - 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 + 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); + + 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 + { + me.setAlphaOf(me, e, e.Container_alpha * prevFactor); + } + else { - e.Container_origin = e.Container_origin * prevFactor + targetOrigin * targetFactor; - e.Container_size = e.Container_size * prevFactor + targetSize * targetFactor; + 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); } - 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) -} + 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) + } #endif diff --git a/qcsrc/menu/item/nexposee.qc b/qcsrc/menu/item/nexposee.qc index 06616e68f..e35909493 100644 --- a/qcsrc/menu/item/nexposee.qc +++ b/qcsrc/menu/item/nexposee.qc @@ -1,30 +1,30 @@ #ifndef ITEM_NEXPOSEE_H -#define ITEM_NEXPOSEE_H -#include "container.qc" -CLASS(Nexposee, Container) - METHOD(Nexposee, draw, void(entity)); - METHOD(Nexposee, keyDown, float(entity, float, float, float)); - METHOD(Nexposee, keyUp, float(entity, float, float, float)); - METHOD(Nexposee, mousePress, float(entity, vector)); - METHOD(Nexposee, mouseMove, float(entity, vector)); - METHOD(Nexposee, mouseRelease, float(entity, vector)); - METHOD(Nexposee, mouseDrag, float(entity, vector)); - METHOD(Nexposee, resizeNotify, void(entity, vector, vector, vector, vector)); - METHOD(Nexposee, focusEnter, void(entity)); - METHOD(Nexposee, close, void(entity)); - - ATTRIB(Nexposee, animationState, float, -1) - ATTRIB(Nexposee, animationFactor, float, 0) - ATTRIB(Nexposee, selectedChild, entity, NULL) - ATTRIB(Nexposee, mouseFocusedChild, entity, NULL) - METHOD(Nexposee, addItem, void(entity, entity, vector, vector, float)); - METHOD(Nexposee, calc, void(entity)); - METHOD(Nexposee, setNexposee, void(entity, entity, vector, float, float)); - ATTRIB(Nexposee, mousePosition, vector, '0 0 0') - METHOD(Nexposee, pullNexposee, void(entity, entity, vector)); -ENDCLASS(Nexposee) - -void ExposeeCloseButton_Click(entity button, entity other); // un-exposees the current state + #define ITEM_NEXPOSEE_H + #include "container.qc" + CLASS(Nexposee, Container) + METHOD(Nexposee, draw, void(entity)); + METHOD(Nexposee, keyDown, float(entity, float, float, float)); + METHOD(Nexposee, keyUp, float(entity, float, float, float)); + METHOD(Nexposee, mousePress, float(entity, vector)); + METHOD(Nexposee, mouseMove, float(entity, vector)); + METHOD(Nexposee, mouseRelease, float(entity, vector)); + METHOD(Nexposee, mouseDrag, float(entity, vector)); + METHOD(Nexposee, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Nexposee, focusEnter, void(entity)); + METHOD(Nexposee, close, void(entity)); + + ATTRIB(Nexposee, animationState, float, -1) + ATTRIB(Nexposee, animationFactor, float, 0) + ATTRIB(Nexposee, selectedChild, entity, NULL) + ATTRIB(Nexposee, mouseFocusedChild, entity, NULL) + METHOD(Nexposee, addItem, void(entity, entity, vector, vector, float)); + METHOD(Nexposee, calc, void(entity)); + METHOD(Nexposee, setNexposee, void(entity, entity, vector, float, float)); + ATTRIB(Nexposee, mousePosition, vector, '0 0 0') + METHOD(Nexposee, pullNexposee, void(entity, entity, vector)); + ENDCLASS(Nexposee) + + void ExposeeCloseButton_Click(entity button, entity other); // un-exposees the current state // animation states: // 0 = thumbnails seen @@ -32,337 +32,315 @@ void ExposeeCloseButton_Click(entity button, entity other); // un-exposees the c // 2 = zoomed in // 3 = zooming out // animation factor: 0 = minimum theSize, 1 = maximum theSize -.vector Nexposee_initialSize; -.vector Nexposee_initialFontScale; -.vector Nexposee_initialOrigin; -.float Nexposee_initialAlpha; - -.vector Nexposee_smallSize; -.vector Nexposee_smallOrigin; -.float Nexposee_smallAlpha; -.float Nexposee_mediumAlpha; -.vector Nexposee_scaleCenter; -.vector Nexposee_align; -.float Nexposee_animationFactor; + .vector Nexposee_initialSize; + .vector Nexposee_initialFontScale; + .vector Nexposee_initialOrigin; + .float Nexposee_initialAlpha; + + .vector Nexposee_smallSize; + .vector Nexposee_smallOrigin; + .float Nexposee_smallAlpha; + .float Nexposee_mediumAlpha; + .vector Nexposee_scaleCenter; + .vector Nexposee_align; + .float Nexposee_animationFactor; #endif #ifdef IMPLEMENTATION -void Nexposee_close(entity me) -{ - // user must override this -} - -void ExposeeCloseButton_Click(entity button, entity other) -{ - other.selectedChild = other.focusedChild; - other.setFocus(other, NULL); - other.animationState = 3; -} - -void Nexposee_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.calc(me); - me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Nexposee_initialOrigin, Nexposee_initialSize, Nexposee_initialFontScale); -} - -void Nexposee_Calc_Scale(entity me, float scale) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) + void Nexposee_close(entity me) { - e.Nexposee_smallOrigin = (e.Nexposee_initialOrigin - e.Nexposee_scaleCenter) * scale + e.Nexposee_scaleCenter; - e.Nexposee_smallSize = e.Nexposee_initialSize * scale; - if(e.Nexposee_align.x > 0) - e.Nexposee_smallOrigin_x = 1 - e.Nexposee_align.x * scale; - if(e.Nexposee_align.x < 0) - e.Nexposee_smallOrigin_x = -e.Nexposee_smallSize.x + e.Nexposee_align.x * scale; - if(e.Nexposee_align.y > 0) - e.Nexposee_smallOrigin_y = 1 - e.Nexposee_align.y * scale; - if(e.Nexposee_align.y < 0) - e.Nexposee_smallOrigin_y = -e.Nexposee_smallSize.y + e.Nexposee_align.y * scale; + // user must override this } -} - -void Nexposee_calc(entity me) -{ - /* - * patented by Apple - * can't put that here ;) - */ - float scale; - entity e, e2; - vector emins, emaxs, e2mins, e2maxs; - - for(scale = 0.7;; scale *= 0.99) + + void ExposeeCloseButton_Click(entity button, entity other) { - Nexposee_Calc_Scale(me, scale); + other.selectedChild = other.focusedChild; + other.setFocus(other, NULL); + other.animationState = 3; + } - for(e = me.firstChild; e; e = e.nextSibling) + void Nexposee_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) + { + me.calc(me); + me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Nexposee_initialOrigin, Nexposee_initialSize, Nexposee_initialFontScale); + } + + void Nexposee_Calc_Scale(entity me, float scale) + { + entity e; + for (e = me.firstChild; e; e = e.nextSibling) { - emins = e.Nexposee_smallOrigin; - emaxs = emins + e.Nexposee_smallSize; - for(e2 = e.nextSibling; e2; e2 = e2.nextSibling) - { - e2mins = e2.Nexposee_smallOrigin; - e2maxs = e2mins + e2.Nexposee_smallSize; - - // two intervals [amins, amaxs] and [bmins, bmaxs] overlap if: - // amins < bmins < amaxs < bmaxs - // for which suffices - // bmins < amaxs - // amins < bmaxs - if((e2mins.x - emaxs.x) * (emins.x - e2maxs.x) > 0) // x overlap - if((e2mins.y - emaxs.y) * (emins.y - e2maxs.y) > 0) // y overlap - { - goto have_overlap; - } - } + e.Nexposee_smallOrigin = (e.Nexposee_initialOrigin - e.Nexposee_scaleCenter) * scale + e.Nexposee_scaleCenter; + e.Nexposee_smallSize = e.Nexposee_initialSize * scale; + if (e.Nexposee_align.x > 0) e.Nexposee_smallOrigin_x = 1 - e.Nexposee_align.x * scale; + if (e.Nexposee_align.x < 0) e.Nexposee_smallOrigin_x = -e.Nexposee_smallSize.x + e.Nexposee_align.x * scale; + if (e.Nexposee_align.y > 0) e.Nexposee_smallOrigin_y = 1 - e.Nexposee_align.y * scale; + if (e.Nexposee_align.y < 0) e.Nexposee_smallOrigin_y = -e.Nexposee_smallSize.y + e.Nexposee_align.y * scale; } - - break; -:have_overlap } - scale *= 0.95; + void Nexposee_calc(entity me) + { + /* + * patented by Apple + * can't put that here ;) + */ + float scale; + entity e, e2; + vector emins, emaxs, e2mins, e2maxs; + + for (scale = 0.7; ; scale *= 0.99) + { + Nexposee_Calc_Scale(me, scale); - Nexposee_Calc_Scale(me, scale); -} + for (e = me.firstChild; e; e = e.nextSibling) + { + emins = e.Nexposee_smallOrigin; + emaxs = emins + e.Nexposee_smallSize; + for (e2 = e.nextSibling; e2; e2 = e2.nextSibling) + { + e2mins = e2.Nexposee_smallOrigin; + e2maxs = e2mins + e2.Nexposee_smallSize; + + // two intervals [amins, amaxs] and [bmins, bmaxs] overlap if: + // amins < bmins < amaxs < bmaxs + // for which suffices + // bmins < amaxs + // amins < bmaxs + if ((e2mins.x - emaxs.x) * (emins.x - e2maxs.x) > 0) // x overlap + if ((e2mins.y - emaxs.y) * (emins.y - e2maxs.y) > 0) // y overlap + goto have_overlap; + } + } + + break; + : have_overlap + } -void Nexposee_setNexposee(entity me, entity other, vector scalecenter, float a0, float a1) -{ - other.Nexposee_scaleCenter = scalecenter; - other.Nexposee_smallAlpha = a0; - me.setAlphaOf(me, other, a0); - other.Nexposee_mediumAlpha = a1; -} + scale *= 0.95; -void Nexposee_draw(entity me) -{ - float a; - float a0; - entity e; - float f; - vector fs; + Nexposee_Calc_Scale(me, scale); + } - if(me.animationState == -1) + void Nexposee_setNexposee(entity me, entity other, vector scalecenter, float a0, float a1) { - me.animationState = 0; + other.Nexposee_scaleCenter = scalecenter; + other.Nexposee_smallAlpha = a0; + me.setAlphaOf(me, other, a0); + other.Nexposee_mediumAlpha = a1; } - f = min(1, frametime * 5); - switch(me.animationState) + void Nexposee_draw(entity me) { - case 0: - me.animationFactor = 0; - break; - case 1: - me.animationFactor += f; - if(me.animationFactor >= 1) - { + float a; + float a0; + entity e; + float f; + vector fs; + + if (me.animationState == -1) me.animationState = 0; + + f = min(1, frametime * 5); + switch (me.animationState) + { + case 0: + me.animationFactor = 0; + break; + case 1: + me.animationFactor += f; + if (me.animationFactor >= 1) + { + me.animationFactor = 1; + me.animationState = 2; + SUPER(Nexposee).setFocus(me, me.selectedChild); + } + break; + case 2: me.animationFactor = 1; - me.animationState = 2; - SUPER(Nexposee).setFocus(me, me.selectedChild); + break; + case 3: + me.animationFactor -= f; + me.mouseFocusedChild = me.itemFromPoint(me, me.mousePosition); + if (me.animationFactor <= 0) + { + me.animationFactor = 0; + me.animationState = 0; + me.selectedChild = me.mouseFocusedChild; + } + break; + } + + f = min(1, frametime * 10); + for (e = me.firstChild; e; e = e.nextSibling) + { + if (e == me.selectedChild) + { + e.Container_origin = e.Nexposee_smallOrigin * (1 - me.animationFactor) + e.Nexposee_initialOrigin * me.animationFactor; + e.Container_size = e.Nexposee_smallSize * (1 - me.animationFactor) + e.Nexposee_initialSize * me.animationFactor; + e.Nexposee_animationFactor = me.animationFactor; + a0 = e.Nexposee_mediumAlpha; + if (me.animationState == 3) + if (e != me.mouseFocusedChild) a0 = e.Nexposee_smallAlpha; + a = a0 * (1 - me.animationFactor) + me.animationFactor; } - break; - case 2: - me.animationFactor = 1; - break; - case 3: - me.animationFactor -= f; - me.mouseFocusedChild = me.itemFromPoint(me, me.mousePosition); - if(me.animationFactor <= 0) + else { - me.animationFactor = 0; - me.animationState = 0; - me.selectedChild = me.mouseFocusedChild; + // minimum theSize counts + e.Container_origin = e.Nexposee_smallOrigin; + e.Container_size = e.Nexposee_smallSize; + e.Nexposee_animationFactor = 0; + a = e.Nexposee_smallAlpha * (1 - me.animationFactor); } - break; + me.setAlphaOf(me, e, e.Container_alpha * (1 - f) + a * f); + + fs = globalToBoxSize(e.Container_size, e.Nexposee_initialSize); + e.Container_fontscale_x = fs.x * e.Nexposee_initialFontScale.x; + e.Container_fontscale_y = fs.y * e.Nexposee_initialFontScale.y; + } + + SUPER(Nexposee).draw(me); } - f = min(1, frametime * 10); - for(e = me.firstChild; e; e = e.nextSibling) + float Nexposee_mousePress(entity me, vector pos) { - if(e == me.selectedChild) + if (me.animationState == 0) { - e.Container_origin = e.Nexposee_smallOrigin * (1 - me.animationFactor) + e.Nexposee_initialOrigin * me.animationFactor; - e.Container_size = e.Nexposee_smallSize * (1 - me.animationFactor) + e.Nexposee_initialSize * me.animationFactor; - e.Nexposee_animationFactor = me.animationFactor; - a0 = e.Nexposee_mediumAlpha; - if(me.animationState == 3) - if(e != me.mouseFocusedChild) - a0 = e.Nexposee_smallAlpha; - a = a0 * (1 - me.animationFactor) + me.animationFactor; + me.mouseFocusedChild = NULL; + Nexposee_mouseMove(me, pos); + if (me.mouseFocusedChild) + { + m_play_click_sound(MENU_SOUND_OPEN); + me.animationState = 1; + SUPER(Nexposee).setFocus(me, NULL); + } + else + { + me.close(me); + } + return 1; } - else + else if (me.animationState == 2) { - // minimum theSize counts - e.Container_origin = e.Nexposee_smallOrigin; - e.Container_size = e.Nexposee_smallSize; - e.Nexposee_animationFactor = 0; - a = e.Nexposee_smallAlpha * (1 - me.animationFactor); + if (!(SUPER(Nexposee).mousePress(me, pos))) + { + m_play_click_sound(MENU_SOUND_CLOSE); + me.animationState = 3; + SUPER(Nexposee).setFocus(me, NULL); + } + return 1; } - me.setAlphaOf(me, e, e.Container_alpha * (1 - f) + a * f); - - fs = globalToBoxSize(e.Container_size, e.Nexposee_initialSize); - e.Container_fontscale_x = fs.x * e.Nexposee_initialFontScale.x; - e.Container_fontscale_y = fs.y * e.Nexposee_initialFontScale.y; + return 0; } - SUPER(Nexposee).draw(me); -} + float Nexposee_mouseRelease(entity me, vector pos) + { + if (me.animationState == 2) return SUPER(Nexposee).mouseRelease(me, pos); + return 0; + } -float Nexposee_mousePress(entity me, vector pos) -{ - if(me.animationState == 0) + float Nexposee_mouseDrag(entity me, vector pos) { - me.mouseFocusedChild = NULL; - Nexposee_mouseMove(me, pos); - if(me.mouseFocusedChild) - { - m_play_click_sound(MENU_SOUND_OPEN); - me.animationState = 1; - SUPER(Nexposee).setFocus(me, NULL); - } - else - me.close(me); - return 1; + if (me.animationState == 2) return SUPER(Nexposee).mouseDrag(me, pos); + return 0; } - else if(me.animationState == 2) + + float Nexposee_mouseMove(entity me, vector pos) { - if (!(SUPER(Nexposee).mousePress(me, pos))) + entity e; + me.mousePosition = pos; + e = me.mouseFocusedChild; + me.mouseFocusedChild = me.itemFromPoint(me, pos); + if (me.animationState == 2) return SUPER(Nexposee).mouseMove(me, pos); + if (me.animationState == 0) { - m_play_click_sound(MENU_SOUND_CLOSE); - me.animationState = 3; - SUPER(Nexposee).setFocus(me, NULL); + if (me.mouseFocusedChild) + if (me.mouseFocusedChild != e || me.mouseFocusedChild != me.selectedChild) me.selectedChild = me.mouseFocusedChild; + return 1; } - return 1; + return 0; } - return 0; -} - -float Nexposee_mouseRelease(entity me, vector pos) -{ - if(me.animationState == 2) - return SUPER(Nexposee).mouseRelease(me, pos); - return 0; -} - -float Nexposee_mouseDrag(entity me, vector pos) -{ - if(me.animationState == 2) - return SUPER(Nexposee).mouseDrag(me, pos); - return 0; -} - -float Nexposee_mouseMove(entity me, vector pos) -{ - entity e; - me.mousePosition = pos; - e = me.mouseFocusedChild; - me.mouseFocusedChild = me.itemFromPoint(me, pos); - if(me.animationState == 2) - return SUPER(Nexposee).mouseMove(me, pos); - if(me.animationState == 0) + + float Nexposee_keyUp(entity me, float scan, float ascii, float shift) { - if(me.mouseFocusedChild) - if(me.mouseFocusedChild != e || me.mouseFocusedChild != me.selectedChild) - me.selectedChild = me.mouseFocusedChild; - return 1; + if (me.animationState == 2) return SUPER(Nexposee).keyUp(me, scan, ascii, shift); + return 0; } - return 0; -} - -float Nexposee_keyUp(entity me, float scan, float ascii, float shift) -{ - if(me.animationState == 2) - return SUPER(Nexposee).keyUp(me, scan, ascii, shift); - return 0; -} - -float Nexposee_keyDown(entity me, float scan, float ascii, float shift) -{ - float nexposeeKey = 0; - if(me.animationState == 2) - if(SUPER(Nexposee).keyDown(me, scan, ascii, shift)) - return 1; - if(scan == K_TAB) + + float Nexposee_keyDown(entity me, float scan, float ascii, float shift) { - if(me.animationState == 0) + float nexposeeKey = 0; + if (me.animationState == 2) + if (SUPER(Nexposee).keyDown(me, scan, ascii, shift)) return 1; + if (scan == K_TAB) { - if(shift & S_SHIFT) - { - if(me.selectedChild) - me.selectedChild = me.selectedChild.prevSibling; - if (!me.selectedChild) - me.selectedChild = me.lastChild; - } - else + if (me.animationState == 0) { - if(me.selectedChild) - me.selectedChild = me.selectedChild.nextSibling; - if (!me.selectedChild) - me.selectedChild = me.firstChild; + if (shift & S_SHIFT) + { + if (me.selectedChild) me.selectedChild = me.selectedChild.prevSibling; + if (!me.selectedChild) me.selectedChild = me.lastChild; + } + else + { + if (me.selectedChild) me.selectedChild = me.selectedChild.nextSibling; + if (!me.selectedChild) me.selectedChild = me.firstChild; + } } } - } - switch(me.animationState) - { - default: - case 0: - case 3: - nexposeeKey = ((scan == K_SPACE) || (scan == K_ENTER) || (scan == K_KP_ENTER)); - break; - case 1: - case 2: - nexposeeKey = (scan == K_ESCAPE); - break; - } - if(nexposeeKey) - { - switch(me.animationState) + switch (me.animationState) { default: case 0: case 3: - m_play_click_sound(MENU_SOUND_OPEN); - me.animationState = 1; + nexposeeKey = ((scan == K_SPACE) || (scan == K_ENTER) || (scan == K_KP_ENTER)); break; case 1: case 2: - m_play_click_sound(MENU_SOUND_CLOSE); - me.animationState = 3; + nexposeeKey = (scan == K_ESCAPE); break; } - if(me.focusedChild) - me.selectedChild = me.focusedChild; - if (!me.selectedChild) - me.animationState = 0; - SUPER(Nexposee).setFocus(me, NULL); - return 1; + if (nexposeeKey) + { + switch (me.animationState) + { + default: + case 0: + case 3: + m_play_click_sound(MENU_SOUND_OPEN); + me.animationState = 1; + break; + case 1: + case 2: + m_play_click_sound(MENU_SOUND_CLOSE); + me.animationState = 3; + break; + } + if (me.focusedChild) me.selectedChild = me.focusedChild; + if (!me.selectedChild) me.animationState = 0; + SUPER(Nexposee).setFocus(me, NULL); + return 1; + } + return 0; + } + + void Nexposee_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha) + { + SUPER(Nexposee).addItem(me, other, theOrigin, theSize, theAlpha); + other.Nexposee_initialFontScale = other.Container_fontscale; + other.Nexposee_initialSize = other.Container_size; + other.Nexposee_initialOrigin = other.Container_origin; + other.Nexposee_initialAlpha = other.Container_alpha; + if (other.Nexposee_initialFontScale == '0 0 0') other.Nexposee_initialFontScale = '1 1 0'; + } + + void Nexposee_focusEnter(entity me) + { + if (me.animationState == 2) SUPER(Nexposee).setFocus(me, me.selectedChild); + } + + void Nexposee_pullNexposee(entity me, entity other, vector theAlign) + { + other.Nexposee_align = theAlign; } - return 0; -} - -void Nexposee_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha) -{ - SUPER(Nexposee).addItem(me, other, theOrigin, theSize, theAlpha); - other.Nexposee_initialFontScale = other.Container_fontscale; - other.Nexposee_initialSize = other.Container_size; - other.Nexposee_initialOrigin = other.Container_origin; - other.Nexposee_initialAlpha = other.Container_alpha; - if(other.Nexposee_initialFontScale == '0 0 0') - other.Nexposee_initialFontScale = '1 1 0'; -} - -void Nexposee_focusEnter(entity me) -{ - if(me.animationState == 2) - SUPER(Nexposee).setFocus(me, me.selectedChild); -} - -void Nexposee_pullNexposee(entity me, entity other, vector theAlign) -{ - other.Nexposee_align = theAlign; -} #endif diff --git a/qcsrc/menu/item/radiobutton.qc b/qcsrc/menu/item/radiobutton.qc index 4dfadd2d5..dac17b141 100644 --- a/qcsrc/menu/item/radiobutton.qc +++ b/qcsrc/menu/item/radiobutton.qc @@ -1,39 +1,37 @@ #ifndef ITEM_RADIOBUTTON_H -#define ITEM_RADIOBUTTON_H -#include "checkbox.qc" -void RadioButton_Click(entity me, entity other); -CLASS(RadioButton, CheckBox) - METHOD(RadioButton, configureRadioButton, void(entity, string, float, string, float, float)); - ATTRIB(RadioButton, checked, float, 0) - ATTRIB(RadioButton, group, float, 0) - ATTRIB(RadioButton, allowDeselect, float, 0) - ATTRIB(RadioButton, onClick, void(entity, entity), RadioButton_Click) -ENDCLASS(RadioButton) + #define ITEM_RADIOBUTTON_H + #include "checkbox.qc" + void RadioButton_Click(entity me, entity other); + CLASS(RadioButton, CheckBox) + METHOD(RadioButton, configureRadioButton, void(entity, string, float, string, float, float)); + ATTRIB(RadioButton, checked, float, 0) + ATTRIB(RadioButton, group, float, 0) + ATTRIB(RadioButton, allowDeselect, float, 0) + ATTRIB(RadioButton, onClick, void(entity, entity), RadioButton_Click) + ENDCLASS(RadioButton) #endif #ifdef IMPLEMENTATION -void RadioButton_configureRadioButton(entity me, string txt, float sz, string gfx, float theGroup, float doAllowDeselect) -{ - me.configureCheckBox(me, txt, sz, gfx); - me.align = 0; - me.group = theGroup; - me.allowDeselect = doAllowDeselect; -} -void RadioButton_Click(entity me, entity other) -{ - if(me.checked) + void RadioButton_configureRadioButton(entity me, string txt, float sz, string gfx, float theGroup, float doAllowDeselect) { - if(me.allowDeselect) - me.setChecked(me, 0); + me.configureCheckBox(me, txt, sz, gfx); + me.align = 0; + me.group = theGroup; + me.allowDeselect = doAllowDeselect; } - else + void RadioButton_Click(entity me, entity other) { - entity e; - for(e = me.parent.firstChild; e; e = e.nextSibling) - if(e != me) - if(e.group == me.group) - e.setChecked(e, 0); - me.setChecked(me, 1); + if (me.checked) + { + if (me.allowDeselect) me.setChecked(me, 0); + } + else + { + entity e; + for (e = me.parent.firstChild; e; e = e.nextSibling) + if (e != me) + if (e.group == me.group) e.setChecked(e, 0); + me.setChecked(me, 1); + } } -} #endif diff --git a/qcsrc/menu/item/slider.qc b/qcsrc/menu/item/slider.qc index 3bde6565a..f065e34b1 100644 --- a/qcsrc/menu/item/slider.qc +++ b/qcsrc/menu/item/slider.qc @@ -1,322 +1,299 @@ // Note: // to use this, you FIRST call configureSliderVisuals, then configureSliderValues #ifndef ITEM_SLIDER_H -#define ITEM_SLIDER_H -#include "label.qc" -CLASS(Slider, Label) - METHOD(Slider, resizeNotify, void(entity, vector, vector, vector, vector)); - METHOD(Slider, configureSliderVisuals, void(entity, float, float, float, string)); - METHOD(Slider, configureSliderValues, void(entity, float, float, float, float, float, float)); - METHOD(Slider, draw, void(entity)); - METHOD(Slider, keyDown, float(entity, float, float, float)); - METHOD(Slider, keyUp, float(entity, float, float, float)); - METHOD(Slider, mousePress, float(entity, vector)); - METHOD(Slider, mouseDrag, float(entity, vector)); - METHOD(Slider, mouseRelease, float(entity, vector)); - METHOD(Slider, valueToText, string(entity, float)); - METHOD(Slider, toString, string(entity)); - METHOD(Slider, setValue_allowAnim, void(entity, float, bool)); - METHOD(Slider, setValue_noAnim, void(entity, float)); - METHOD(Slider, setValue, void(entity, float)); - METHOD(Slider, setSliderValue, void(entity, float)); - METHOD(Slider, showNotify, void(entity)); - ATTRIB(Slider, src, string, string_null) - ATTRIB(Slider, focusable, float, 1) - ATTRIB(Slider, allowFocusSound, float, 1) - ATTRIB(Slider, value, float, 0) - ATTRIB(Slider, animated, float, 1) - ATTRIB(Slider, sliderValue, float, 0) - ATTRIB(Slider, sliderAnim, entity, NULL) - ATTRIB(Slider, valueMin, float, 0) - ATTRIB(Slider, valueMax, float, 0) - ATTRIB(Slider, valueStep, float, 0) - ATTRIB(Slider, valueDigits, float, 0) - ATTRIB(Slider, valueKeyStep, float, 0) - ATTRIB(Slider, valuePageStep, float, 0) - ATTRIB(Slider, valueDisplayMultiplier, float, 1.0) - ATTRIB(Slider, textSpace, float, 0) - ATTRIB(Slider, controlWidth, float, 0) - ATTRIB(Slider, pressed, float, 0) - ATTRIB(Slider, pressOffset, float, 0) - ATTRIB(Slider, previousValue, float, 0) - ATTRIB(Slider, tolerance, vector, '0 0 0') - ATTRIB(Slider, disabled, float, 0) - ATTRIB(Slider, color, vector, '1 1 1') - ATTRIB(Slider, color2, vector, '1 1 1') - ATTRIB(Slider, colorD, vector, '1 1 1') - ATTRIB(Slider, colorC, vector, '1 1 1') - ATTRIB(Slider, colorF, vector, '1 1 1') - ATTRIB(Slider, disabledAlpha, float, 0.3) -ENDCLASS(Slider) + #define ITEM_SLIDER_H + #include "label.qc" + CLASS(Slider, Label) + METHOD(Slider, resizeNotify, void(entity, vector, vector, vector, vector)); + METHOD(Slider, configureSliderVisuals, void(entity, float, float, float, string)); + METHOD(Slider, configureSliderValues, void(entity, float, float, float, float, float, float)); + METHOD(Slider, draw, void(entity)); + METHOD(Slider, keyDown, float(entity, float, float, float)); + METHOD(Slider, keyUp, float(entity, float, float, float)); + METHOD(Slider, mousePress, float(entity, vector)); + METHOD(Slider, mouseDrag, float(entity, vector)); + METHOD(Slider, mouseRelease, float(entity, vector)); + METHOD(Slider, valueToText, string(entity, float)); + METHOD(Slider, toString, string(entity)); + METHOD(Slider, setValue_allowAnim, void(entity, float, bool)); + METHOD(Slider, setValue_noAnim, void(entity, float)); + METHOD(Slider, setValue, void(entity, float)); + METHOD(Slider, setSliderValue, void(entity, float)); + METHOD(Slider, showNotify, void(entity)); + ATTRIB(Slider, src, string, string_null) + ATTRIB(Slider, focusable, float, 1) + ATTRIB(Slider, allowFocusSound, float, 1) + ATTRIB(Slider, value, float, 0) + ATTRIB(Slider, animated, float, 1) + ATTRIB(Slider, sliderValue, float, 0) + ATTRIB(Slider, sliderAnim, entity, NULL) + ATTRIB(Slider, valueMin, float, 0) + ATTRIB(Slider, valueMax, float, 0) + ATTRIB(Slider, valueStep, float, 0) + ATTRIB(Slider, valueDigits, float, 0) + ATTRIB(Slider, valueKeyStep, float, 0) + ATTRIB(Slider, valuePageStep, float, 0) + ATTRIB(Slider, valueDisplayMultiplier, float, 1.0) + ATTRIB(Slider, textSpace, float, 0) + ATTRIB(Slider, controlWidth, float, 0) + ATTRIB(Slider, pressed, float, 0) + ATTRIB(Slider, pressOffset, float, 0) + ATTRIB(Slider, previousValue, float, 0) + ATTRIB(Slider, tolerance, vector, '0 0 0') + ATTRIB(Slider, disabled, float, 0) + ATTRIB(Slider, color, vector, '1 1 1') + ATTRIB(Slider, color2, vector, '1 1 1') + ATTRIB(Slider, colorD, vector, '1 1 1') + ATTRIB(Slider, colorC, vector, '1 1 1') + ATTRIB(Slider, colorF, vector, '1 1 1') + ATTRIB(Slider, disabledAlpha, float, 0.3) + ENDCLASS(Slider) #endif #ifdef IMPLEMENTATION -void Slider_setValue_allowAnim(entity me, float val, bool allowAnim) -{ - if(allowAnim && me.animated) { - float t = 0.5; - if(!me.sliderAnim) - me.sliderAnim = makeHostedEasing(me, Slider_setSliderValue, easingQuadOut, t, me.sliderValue, val); + void Slider_setValue_allowAnim(entity me, float val, bool allowAnim) + { + if (allowAnim && me.animated) + { + float t = 0.5; + if (!me.sliderAnim) me.sliderAnim = makeHostedEasing(me, Slider_setSliderValue, easingQuadOut, t, me.sliderValue, val); + else me.sliderAnim.update(me.sliderAnim, t, me.sliderValue, val); + } else - me.sliderAnim.update(me.sliderAnim, t, me.sliderValue, val); - } else { - me.setSliderValue(me, val); + { + me.setSliderValue(me, val); + } + me.value = val; } - me.value = val; -} -void Slider_setValue_noAnim(entity me, float val) -{ - Slider_setValue_allowAnim(me, val, false); -} -void Slider_setValue(entity me, float val) -{ - Slider_setValue_allowAnim(me, val, true); -} -void Slider_setSliderValue(entity me, float val) -{ - me.sliderValue = val; -} -string Slider_toString(entity me) -{ - return sprintf("%d (%s)", me.value, me.valueToText(me, me.value)); -} -void Slider_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(Slider).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - me.controlWidth = absSize.x == 0 ? 0 : (absSize.y / absSize.x); -} -string Slider_valueToText(entity me, float val) -{ - if(almost_in_bounds(me.valueMin, val, me.valueMax)) - return ftos_decimals(val * me.valueDisplayMultiplier, me.valueDigits); - return ""; -} -void Slider_configureSliderVisuals(entity me, float sz, float theAlign, float theTextSpace, string gfx) -{ - SUPER(Slider).configureLabel(me, string_null, sz, theAlign); - me.textSpace = theTextSpace; - me.keepspaceLeft = (theTextSpace == 0) ? 0 : (1 - theTextSpace); - me.src = gfx; -} -void Slider_configureSliderValues(entity me, float theValueMin, float theValue, float theValueMax, float theValueStep, float theValueKeyStep, float theValuePageStep) -{ - me.value = theValue; - me.sliderValue = theValue; - me.valueStep = theValueStep; - me.valueMin = theValueMin; - me.valueMax = theValueMax; - me.valueKeyStep = theValueKeyStep; - me.valuePageStep = theValuePageStep; - me.valueDigits = 3; - if(fabs(floor(me.valueStep * 100 + 0.5) - (me.valueStep * 100)) < 0.01) // about a whole number of 100ths - me.valueDigits = 2; - if(fabs(floor(me.valueStep * 10 + 0.5) - (me.valueStep * 10)) < 0.01) // about a whole number of 10ths - me.valueDigits = 1; - if(fabs(floor(me.valueStep * 1 + 0.5) - (me.valueStep * 1)) < 0.01) // about a whole number - me.valueDigits = 0; -} -float Slider_keyDown(entity me, float key, float ascii, float shift) -{ - float inRange; - if(me.disabled) - return 0; - inRange = (almost_in_bounds(me.valueMin, me.value, me.valueMax)); - if(key == K_LEFTARROW || key == K_KP_LEFTARROW || key == K_MWHEELDOWN) + void Slider_setValue_noAnim(entity me, float val) { - if(inRange) - me.setValue(me, median(me.valueMin, me.value - me.valueKeyStep, me.valueMax)); - else - me.setValue(me, me.valueMax); - return 1; + Slider_setValue_allowAnim(me, val, false); } - if(key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_MWHEELUP) + void Slider_setValue(entity me, float val) { - if(inRange) - me.setValue(me, median(me.valueMin, me.value + me.valueKeyStep, me.valueMax)); - else - me.setValue(me, me.valueMin); - return 1; + Slider_setValue_allowAnim(me, val, true); } - if(key == K_PGDN || key == K_KP_PGDN) + void Slider_setSliderValue(entity me, float val) { - if(inRange) - me.setValue(me, median(me.valueMin, me.value - me.valuePageStep, me.valueMax)); - else - me.setValue(me, me.valueMax); - return 1; + me.sliderValue = val; } - if(key == K_PGUP || key == K_KP_PGUP) + string Slider_toString(entity me) { - if(inRange) - me.setValue(me, median(me.valueMin, me.value + me.valuePageStep, me.valueMax)); - else - me.setValue(me, me.valueMin); - return 1; + return sprintf("%d (%s)", me.value, me.valueToText(me, me.value)); } - if(key == K_HOME || key == K_KP_HOME) + void Slider_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) { - me.setValue(me, me.valueMin); - return 1; + SUPER(Slider).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + me.controlWidth = absSize.x == 0 ? 0 : (absSize.y / absSize.x); } - if(key == K_END || key == K_KP_END) + string Slider_valueToText(entity me, float val) { - me.setValue(me, me.valueMax); - return 1; + if (almost_in_bounds(me.valueMin, val, me.valueMax)) return ftos_decimals(val * me.valueDisplayMultiplier, me.valueDigits); + return ""; } - // TODO more keys (NOTE also add them to Slider_keyUp) - return 0; -} -float Slider_keyUp(entity me, float key, float ascii, float shift) -{ - if(me.disabled) - return 0; - switch(key) + void Slider_configureSliderVisuals(entity me, float sz, float theAlign, float theTextSpace, string gfx) { - case K_LEFTARROW: - case K_KP_LEFTARROW: - case K_RIGHTARROW: - case K_KP_RIGHTARROW: - case K_PGUP: - case K_KP_PGUP: - case K_PGDN: - case K_KP_PGDN: - case K_HOME: - case K_KP_HOME: - case K_END: - case K_KP_END: - m_play_click_sound(MENU_SOUND_SLIDE); + SUPER(Slider).configureLabel(me, string_null, sz, theAlign); + me.textSpace = theTextSpace; + me.keepspaceLeft = (theTextSpace == 0) ? 0 : (1 - theTextSpace); + me.src = gfx; } - return 0; -} -float Slider_mouseDrag(entity me, vector pos) -{ - float hit; - float v; - if(me.disabled) - return 0; - - if(me.pressed) + void Slider_configureSliderValues(entity me, float theValueMin, float theValue, float theValueMax, float theValueStep, float theValueKeyStep, float theValuePageStep) { - hit = 1; - if(pos.x < 0 - me.tolerance.x) hit = 0; - if(pos.y < 0 - me.tolerance.y) hit = 0; - if(pos.x >= 1 - me.textSpace + me.tolerance.x) hit = 0; - if(pos.y >= 1 + me.tolerance.y) hit = 0; - if(hit) + me.value = theValue; + me.sliderValue = theValue; + me.valueStep = theValueStep; + me.valueMin = theValueMin; + me.valueMax = theValueMax; + me.valueKeyStep = theValueKeyStep; + me.valuePageStep = theValuePageStep; + me.valueDigits = 3; + if (fabs(floor(me.valueStep * 100 + 0.5) - (me.valueStep * 100)) < 0.01) // about a whole number of 100ths + me.valueDigits = 2; + if (fabs(floor(me.valueStep * 10 + 0.5) - (me.valueStep * 10)) < 0.01) // about a whole number of 10ths + me.valueDigits = 1; + if (fabs(floor(me.valueStep * 1 + 0.5) - (me.valueStep * 1)) < 0.01) // about a whole number + me.valueDigits = 0; + } + float Slider_keyDown(entity me, float key, float ascii, float shift) + { + float inRange; + if (me.disabled) return 0; + inRange = (almost_in_bounds(me.valueMin, me.value, me.valueMax)); + if (key == K_LEFTARROW || key == K_KP_LEFTARROW || key == K_MWHEELDOWN) { - // handle dragging - me.pressed = 2; - - v = median(0, (pos.x - me.pressOffset - 0.5 * me.controlWidth) / (1 - me.textSpace - me.controlWidth), 1) * (me.valueMax - me.valueMin) + me.valueMin; - if(me.valueStep) - v = floor(0.5 + v / me.valueStep) * me.valueStep; - me.setValue_noAnim(me, v); + if (inRange) me.setValue(me, median(me.valueMin, me.value - me.valueKeyStep, me.valueMax)); + else me.setValue(me, me.valueMax); + return 1; } - else - me.setValue(me, me.previousValue); - } - - return 1; -} -float Slider_mousePress(entity me, vector pos) -{ - float controlCenter; - if(me.disabled) + if (key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_MWHEELUP) + { + if (inRange) me.setValue(me, median(me.valueMin, me.value + me.valueKeyStep, me.valueMax)); + else me.setValue(me, me.valueMin); + return 1; + } + if (key == K_PGDN || key == K_KP_PGDN) + { + if (inRange) me.setValue(me, median(me.valueMin, me.value - me.valuePageStep, me.valueMax)); + else me.setValue(me, me.valueMax); + return 1; + } + if (key == K_PGUP || key == K_KP_PGUP) + { + if (inRange) me.setValue(me, median(me.valueMin, me.value + me.valuePageStep, me.valueMax)); + else me.setValue(me, me.valueMin); + return 1; + } + if (key == K_HOME || key == K_KP_HOME) + { + me.setValue(me, me.valueMin); + return 1; + } + if (key == K_END || key == K_KP_END) + { + me.setValue(me, me.valueMax); + return 1; + } + // TODO more keys (NOTE also add them to Slider_keyUp) return 0; - if(pos.x < 0) return 0; - if(pos.y < 0) return 0; - if(pos.x >= 1 - me.textSpace) return 0; - if(pos.y >= 1) return 0; - controlCenter = (me.value - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth) + 0.5 * me.controlWidth; - if(fabs(pos.x - controlCenter) <= 0.5 * me.controlWidth) - { - me.pressed = 1; - me.pressOffset = pos.x - controlCenter; - me.previousValue = me.value; - //me.mouseDrag(me, pos); } - else + float Slider_keyUp(entity me, float key, float ascii, float shift) { - float clickValue, pageValue, inRange; - clickValue = median(0, (pos.x - me.pressOffset - 0.5 * me.controlWidth) / (1 - me.textSpace - me.controlWidth), 1) * (me.valueMax - me.valueMin) + me.valueMin; - inRange = (almost_in_bounds(me.valueMin, me.value, me.valueMax)); - if(pos.x < controlCenter) + if (me.disabled) return 0; + switch (key) { - pageValue = me.value - me.valuePageStep; - if(me.valueStep) - clickValue = floor(clickValue / me.valueStep) * me.valueStep; - pageValue = max(pageValue, clickValue); - if(inRange) - me.setValue(me, median(me.valueMin, pageValue, me.valueMax)); - else - me.setValue(me, me.valueMax); + case K_LEFTARROW: + case K_KP_LEFTARROW: + case K_RIGHTARROW: + case K_KP_RIGHTARROW: + case K_PGUP: + case K_KP_PGUP: + case K_PGDN: + case K_KP_PGDN: + case K_HOME: + case K_KP_HOME: + case K_END: + case K_KP_END: + m_play_click_sound(MENU_SOUND_SLIDE); } - else + return 0; + } + float Slider_mouseDrag(entity me, vector pos) + { + float hit; + float v; + if (me.disabled) return 0; + + if (me.pressed) { - pageValue = me.value + me.valuePageStep; - if(me.valueStep) - clickValue = ceil(clickValue / me.valueStep) * me.valueStep; - pageValue = min(pageValue, clickValue); - if(inRange) - me.setValue(me, median(me.valueMin, pageValue, me.valueMax)); + hit = 1; + if (pos.x < 0 - me.tolerance.x) hit = 0; + if (pos.y < 0 - me.tolerance.y) hit = 0; + if (pos.x >= 1 - me.textSpace + me.tolerance.x) hit = 0; + if (pos.y >= 1 + me.tolerance.y) hit = 0; + if (hit) + { + // handle dragging + me.pressed = 2; + + v = median(0, (pos.x - me.pressOffset - 0.5 * me.controlWidth) / (1 - me.textSpace - me.controlWidth), 1) * (me.valueMax - me.valueMin) + me.valueMin; + if (me.valueStep) v = floor(0.5 + v / me.valueStep) * me.valueStep; + me.setValue_noAnim(me, v); + } else - me.setValue(me, me.valueMax); + { + me.setValue(me, me.previousValue); + } } - if(pageValue == clickValue) + + return 1; + } + float Slider_mousePress(entity me, vector pos) + { + float controlCenter; + if (me.disabled) return 0; + if (pos.x < 0) return 0; + if (pos.y < 0) return 0; + if (pos.x >= 1 - me.textSpace) return 0; + if (pos.y >= 1) return 0; + controlCenter = (me.value - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth) + 0.5 * me.controlWidth; + if (fabs(pos.x - controlCenter) <= 0.5 * me.controlWidth) { - controlCenter = (me.value - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth) + 0.5 * me.controlWidth; me.pressed = 1; me.pressOffset = pos.x - controlCenter; me.previousValue = me.value; - //me.mouseDrag(me, pos); + // me.mouseDrag(me, pos); } + else + { + float clickValue, pageValue, inRange; + clickValue = median(0, (pos.x - me.pressOffset - 0.5 * me.controlWidth) / (1 - me.textSpace - me.controlWidth), 1) * (me.valueMax - me.valueMin) + me.valueMin; + inRange = (almost_in_bounds(me.valueMin, me.value, me.valueMax)); + if (pos.x < controlCenter) + { + pageValue = me.value - me.valuePageStep; + if (me.valueStep) clickValue = floor(clickValue / me.valueStep) * me.valueStep; + pageValue = max(pageValue, clickValue); + if (inRange) me.setValue(me, median(me.valueMin, pageValue, me.valueMax)); + else me.setValue(me, me.valueMax); + } + else + { + pageValue = me.value + me.valuePageStep; + if (me.valueStep) clickValue = ceil(clickValue / me.valueStep) * me.valueStep; + pageValue = min(pageValue, clickValue); + if (inRange) me.setValue(me, median(me.valueMin, pageValue, me.valueMax)); + else me.setValue(me, me.valueMax); + } + if (pageValue == clickValue) + { + controlCenter = (me.value - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth) + 0.5 * me.controlWidth; + me.pressed = 1; + me.pressOffset = pos.x - controlCenter; + me.previousValue = me.value; + // me.mouseDrag(me, pos); + } + } + return 1; } - return 1; -} -float Slider_mouseRelease(entity me, vector pos) -{ - me.pressed = 0; - if(me.disabled) - return 0; - m_play_click_sound(MENU_SOUND_SLIDE); - return 1; -} -void Slider_showNotify(entity me) -{ - me.focusable = !me.disabled; -} -void Slider_draw(entity me) -{ - float controlLeft; - float save; - me.focusable = !me.disabled; - save = draw_alpha; - if(me.disabled) - draw_alpha *= me.disabledAlpha; - draw_ButtonPicture('0 0 0', strcat(me.src, "_s"), eX * (1 - me.textSpace) + eY, me.color2, 1); - if(almost_in_bounds(me.valueMin, me.sliderValue, me.valueMax)) + float Slider_mouseRelease(entity me, vector pos) { - controlLeft = (me.sliderValue - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth); - if(me.disabled) - draw_Picture(eX * controlLeft, strcat(me.src, "_d"), eX * me.controlWidth + eY, me.colorD, 1); - else if(me.pressed) - draw_Picture(eX * controlLeft, strcat(me.src, "_c"), eX * me.controlWidth + eY, me.colorC, 1); - else if(me.focused) - draw_Picture(eX * controlLeft, strcat(me.src, "_f"), eX * me.controlWidth + eY, me.colorF, 1); - else - draw_Picture(eX * controlLeft, strcat(me.src, "_n"), eX * me.controlWidth + eY, me.color, 1); + me.pressed = 0; + if (me.disabled) return 0; + m_play_click_sound(MENU_SOUND_SLIDE); + return 1; } - - if(me.sliderAnim) - if(me.sliderAnim.isFinished(me.sliderAnim)) + void Slider_showNotify(entity me) { - anim.removeObjAnim(anim, me); - me.sliderAnim = NULL; + me.focusable = !me.disabled; } + void Slider_draw(entity me) + { + float controlLeft; + float save; + me.focusable = !me.disabled; + save = draw_alpha; + if (me.disabled) draw_alpha *= me.disabledAlpha; + draw_ButtonPicture('0 0 0', strcat(me.src, "_s"), eX * (1 - me.textSpace) + eY, me.color2, 1); + if (almost_in_bounds(me.valueMin, me.sliderValue, me.valueMax)) + { + controlLeft = (me.sliderValue - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth); + if (me.disabled) draw_Picture(eX * controlLeft, strcat(me.src, "_d"), eX * me.controlWidth + eY, me.colorD, 1); + else if (me.pressed) draw_Picture(eX * controlLeft, strcat(me.src, "_c"), eX * me.controlWidth + eY, me.colorC, 1); + else if (me.focused) draw_Picture(eX * controlLeft, strcat(me.src, "_f"), eX * me.controlWidth + eY, me.colorF, 1); + else draw_Picture(eX * controlLeft, strcat(me.src, "_n"), eX * me.controlWidth + eY, me.color, 1); + } - me.setText(me, me.valueToText(me, me.value)); - draw_alpha = save; - SUPER(Slider).draw(me); - me.text = string_null; // TEMPSTRING! -} + if (me.sliderAnim) + if (me.sliderAnim.isFinished(me.sliderAnim)) + { + anim.removeObjAnim(anim, me); + me.sliderAnim = NULL; + } + + me.setText(me, me.valueToText(me, me.value)); + draw_alpha = save; + SUPER(Slider).draw(me); + me.text = string_null; // TEMPSTRING! + } #endif diff --git a/qcsrc/menu/item/tab.qc b/qcsrc/menu/item/tab.qc index fbbf77668..7564f02cf 100644 --- a/qcsrc/menu/item/tab.qc +++ b/qcsrc/menu/item/tab.qc @@ -1,29 +1,29 @@ #ifndef ITEM_TAB_H -#define ITEM_TAB_H -#include "dialog.qc" -CLASS(Tab, Dialog) - ATTRIB(Tab, isTabRoot, float, 0) - ATTRIB(Tab, closable, float, 0) - ATTRIB(Tab, rootDialog, float, 0) - ATTRIB(Tab, title, string, string_null) - ATTRIB(Tab, titleFontSize, float, 0) // pixels + #define ITEM_TAB_H + #include "dialog.qc" + CLASS(Tab, Dialog) + ATTRIB(Tab, isTabRoot, float, 0) + ATTRIB(Tab, closable, float, 0) + ATTRIB(Tab, rootDialog, float, 0) + ATTRIB(Tab, title, string, string_null) + ATTRIB(Tab, titleFontSize, float, 0) // pixels - // still to be customized - ATTRIB(Tab, intendedWidth, float, 0) - ATTRIB(Tab, rows, float, 3) - ATTRIB(Tab, columns, float, 2) + // still to be customized + ATTRIB(Tab, intendedWidth, float, 0) + ATTRIB(Tab, rows, float, 3) + ATTRIB(Tab, columns, float, 2) - ATTRIB(Tab, marginTop, float, 0) // pixels - ATTRIB(Tab, marginBottom, float, 0) // pixels - ATTRIB(Tab, marginLeft, float, 0) // pixels - ATTRIB(Tab, marginRight, float, 0) // pixels - ATTRIB(Tab, columnSpacing, float, 0) // pixels - ATTRIB(Tab, rowSpacing, float, 0) // pixels - ATTRIB(Tab, rowHeight, float, 0) // pixels - ATTRIB(Tab, titleHeight, float, 0) // pixels + ATTRIB(Tab, marginTop, float, 0) // pixels + ATTRIB(Tab, marginBottom, float, 0) // pixels + ATTRIB(Tab, marginLeft, float, 0) // pixels + ATTRIB(Tab, marginRight, float, 0) // pixels + ATTRIB(Tab, columnSpacing, float, 0) // pixels + ATTRIB(Tab, rowSpacing, float, 0) // pixels + ATTRIB(Tab, rowHeight, float, 0) // pixels + ATTRIB(Tab, titleHeight, float, 0) // pixels - ATTRIB(Tab, backgroundImage, string, string_null) -ENDCLASS(Tab) + ATTRIB(Tab, backgroundImage, string, string_null) + ENDCLASS(Tab) #endif #ifdef IMPLEMENTATION diff --git a/qcsrc/menu/item/textslider.qc b/qcsrc/menu/item/textslider.qc index 30b80c196..4c23ff9a0 100644 --- a/qcsrc/menu/item/textslider.qc +++ b/qcsrc/menu/item/textslider.qc @@ -1,90 +1,86 @@ // Note: // to use this, you FIRST call configureSliderVisuals, then multiple times addValue, then configureTextSlider #ifndef ITEM_TEXTSLIDER_H -#define ITEM_TEXTSLIDER_H -#include "slider.qc" -CLASS(TextSlider, Slider) - METHOD(TextSlider, valueToText, string(entity, float)); - METHOD(TextSlider, valueToIdentifier, string(entity, float)); - METHOD(TextSlider, setValueFromIdentifier_allowAnim, void(entity, string, bool)); - METHOD(TextSlider, setValueFromIdentifier_noAnim, void(entity, string)); - METHOD(TextSlider, setValueFromIdentifier, void(entity, string)); - METHOD(TextSlider, getIdentifier, string(entity)); - METHOD(TextSlider, clearValues, void(entity)); - METHOD(TextSlider, addValue, void(entity, string, string)); - METHOD(TextSlider, insertValue, void(entity, float, string, string)); - METHOD(TextSlider, configureTextSliderValues, void(entity, string)); - ATTRIBARRAY(TextSlider, valueStrings, string, 256) - ATTRIBARRAY(TextSlider, valueIdentifiers, string, 256) - ATTRIB(TextSlider, nValues, int, 0) -ENDCLASS(TextSlider) + #define ITEM_TEXTSLIDER_H + #include "slider.qc" + CLASS(TextSlider, Slider) + METHOD(TextSlider, valueToText, string(entity, float)); + METHOD(TextSlider, valueToIdentifier, string(entity, float)); + METHOD(TextSlider, setValueFromIdentifier_allowAnim, void(entity, string, bool)); + METHOD(TextSlider, setValueFromIdentifier_noAnim, void(entity, string)); + METHOD(TextSlider, setValueFromIdentifier, void(entity, string)); + METHOD(TextSlider, getIdentifier, string(entity)); + METHOD(TextSlider, clearValues, void(entity)); + METHOD(TextSlider, addValue, void(entity, string, string)); + METHOD(TextSlider, insertValue, void(entity, float, string, string)); + METHOD(TextSlider, configureTextSliderValues, void(entity, string)); + ATTRIBARRAY(TextSlider, valueStrings, string, 256) + ATTRIBARRAY(TextSlider, valueIdentifiers, string, 256) + ATTRIB(TextSlider, nValues, int, 0) + ENDCLASS(TextSlider) #endif #ifdef IMPLEMENTATION -string TextSlider_valueToIdentifier(entity me, int val) -{ - if(val >= me.nValues) - return "custom"; - if(val < 0) - return "custom"; - return me.(valueIdentifiers[val]); -} -string TextSlider_valueToText(entity me, int val) -{ - if(val >= me.nValues) - return _("Custom"); - if(val < 0) - return _("Custom"); - return me.(valueStrings[val]); -} -void TextSlider_setValueFromIdentifier_allowAnim(entity me, string id, bool allowAnim) -{ - int i; - for(i = 0; i < me.nValues; ++i) - if(me.valueToIdentifier(me, i) == id) + string TextSlider_valueToIdentifier(entity me, int val) + { + if (val >= me.nValues) return "custom"; + if (val < 0) return "custom"; + return me.(valueIdentifiers[val]); + } + string TextSlider_valueToText(entity me, int val) + { + if (val >= me.nValues) return _("Custom"); + if (val < 0) return _("Custom"); + return me.(valueStrings[val]); + } + void TextSlider_setValueFromIdentifier_allowAnim(entity me, string id, bool allowAnim) + { + int i; + for (i = 0; i < me.nValues; ++i) + if (me.valueToIdentifier(me, i) == id) + { + SUPER(TextSlider).setValue_allowAnim(me, i, allowAnim); + return; + } + SUPER(TextSlider).setValue_allowAnim(me, -1, allowAnim); + } + void TextSlider_setValueFromIdentifier_noAnim(entity me, string id) + { + TextSlider_setValueFromIdentifier_allowAnim(me, id, false); + } + void TextSlider_setValueFromIdentifier(entity me, string id) + { + TextSlider_setValueFromIdentifier_allowAnim(me, id, true); + } + string TextSlider_getIdentifier(entity me) + { + return me.valueToIdentifier(me, me.value); + } + void TextSlider_clearValues(entity me) + { + me.nValues = 0; + } + void TextSlider_addValue(entity me, string theString, string theIdentifier) + { + me.(valueStrings[me.nValues]) = theString; + me.(valueIdentifiers[me.nValues]) = theIdentifier; + me.nValues += 1; + } + void TextSlider_insertValue(entity me, int pos, string theString, string theIdentifier) + { + int i; + for (i = me.nValues; i > pos; --i) { - SUPER(TextSlider).setValue_allowAnim(me, i, allowAnim); - return; + me.(valueStrings[i]) = me.(valueStrings[i - 1]); + me.(valueIdentifiers[i]) = me.(valueIdentifiers[i - 1]); } - SUPER(TextSlider).setValue_allowAnim(me, -1, allowAnim); -} -void TextSlider_setValueFromIdentifier_noAnim(entity me, string id) -{ - TextSlider_setValueFromIdentifier_allowAnim(me, id, false); -} -void TextSlider_setValueFromIdentifier(entity me, string id) -{ - TextSlider_setValueFromIdentifier_allowAnim(me, id, true); -} -string TextSlider_getIdentifier(entity me) -{ - return me.valueToIdentifier(me, me.value); -} -void TextSlider_clearValues(entity me) -{ - me.nValues = 0; -} -void TextSlider_addValue(entity me, string theString, string theIdentifier) -{ - me.(valueStrings[me.nValues]) = theString; - me.(valueIdentifiers[me.nValues]) = theIdentifier; - me.nValues += 1; -} -void TextSlider_insertValue(entity me, int pos, string theString, string theIdentifier) -{ - int i; - for (i = me.nValues; i > pos; --i) + me.(valueStrings[pos]) = theString; + me.(valueIdentifiers[pos]) = theIdentifier; + me.nValues += 1; + } + void TextSlider_configureTextSliderValues(entity me, string theDefault) { - me.(valueStrings[i]) = me.(valueStrings[i-1]); - me.(valueIdentifiers[i]) = me.(valueIdentifiers[i-1]); + me.configureSliderValues(me, 0, 0, me.nValues - 1, 1, 1, 1); + me.setValueFromIdentifier_noAnim(me, theDefault); } - me.(valueStrings[pos]) = theString; - me.(valueIdentifiers[pos]) = theIdentifier; - me.nValues += 1; -} -void TextSlider_configureTextSliderValues(entity me, string theDefault) -{ - me.configureSliderValues(me, 0, 0, me.nValues - 1, 1, 1, 1); - me.setValueFromIdentifier_noAnim(me, theDefault); -} #endif diff --git a/qcsrc/uncrustify.sh b/qcsrc/uncrustify.sh index 2df39aa3a..b36953e36 100755 --- a/qcsrc/uncrustify.sh +++ b/qcsrc/uncrustify.sh @@ -3,7 +3,7 @@ fix_function_types() { # void(void) func; # ) wrong and removes the space between type and variable. Fix this by # a simple sed on ")letter" which should normally not occur. - sed -e 's/)\([A-Za-z0-9]\)/) \1/g' "$@" + sed -e 's/)\([A-Za-z_]\)/) \1/g' "$@" } if [ -z "$UNCRUSTIFY_CONFIG" ]; then @@ -16,7 +16,7 @@ case "$#" in fix_function_types ;; *) - uncrustify --replace --no-backup -c "$UNCRUSTIFY_CONFIG" "$@" &&\ + uncrustify --replace --no-backup -c "$UNCRUSTIFY_CONFIG" "$@" ;\ fix_function_types -i "$@" ;; esac