From: TimePath Date: Sun, 25 Jan 2015 04:02:50 +0000 (+1100) Subject: Rename menu files to be consistent X-Git-Tag: xonotic-v0.8.1~133^2~33 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=d99a102842ced06e6e1a0c9358c07c3b64523968;p=xonotic%2Fxonotic-data.pk3dir.git Rename menu files to be consistent *.h -> *.qh *.c -> *.qc --- diff --git a/qcsrc/menu/anim/animation.c b/qcsrc/menu/anim/animation.c deleted file mode 100644 index 99ccc7896..000000000 --- a/qcsrc/menu/anim/animation.c +++ /dev/null @@ -1,116 +0,0 @@ -#ifdef INTERFACE -CLASS(Animation) EXTENDS(Object) - METHOD(Animation, configureAnimation, void(entity, entity, void(entity, float), float, 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) -void setterDummy(entity, float); -#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_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) -{ -} - -#endif diff --git a/qcsrc/menu/anim/animation.qc b/qcsrc/menu/anim/animation.qc new file mode 100644 index 000000000..99ccc7896 --- /dev/null +++ b/qcsrc/menu/anim/animation.qc @@ -0,0 +1,116 @@ +#ifdef INTERFACE +CLASS(Animation) EXTENDS(Object) + METHOD(Animation, configureAnimation, void(entity, entity, void(entity, float), float, 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) +void setterDummy(entity, float); +#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_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) +{ +} + +#endif diff --git a/qcsrc/menu/anim/animhost.c b/qcsrc/menu/anim/animhost.c deleted file mode 100644 index ae84e0957..000000000 --- a/qcsrc/menu/anim/animhost.c +++ /dev/null @@ -1,174 +0,0 @@ -#ifdef INTERFACE -CLASS(AnimHost) EXTENDS(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) - { - tmp = e; - e = tmp.prevSibling; - me.removeAnim(me, tmp); - } -} - -void AnimHost_removeObjAnim(entity me, entity obj) -{ - entity e, tmp; - for(e = me.firstChild; e; e = e.nextSibling) - { - if (e.object == obj) - { - tmp = e; - e = tmp.prevSibling; - me.removeAnim(me, tmp); - } - } -} - -void AnimHost_stopAllAnim(entity me) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) - { - e.stopAnim(e); - } -} - -void AnimHost_stopObjAnim(entity me, entity obj) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) - { - if (e.object == obj) - { - e.stopAnim(e); - } - } -} - -void AnimHost_resumeAllAnim(entity me) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) - { - e.resumeAnim(e); - } -} - -void AnimHost_resumeObjAnim(entity me, entity obj) -{ - entity e; - for(e = me.firstChild; e; e = e.nextSibling) - { - if (e.object == obj) - { - e.resumeAnim(e); - } - } -} - -void AnimHost_finishAllAnim(entity me) -{ - entity e, tmp; - for(e = me.firstChild; e; e = e.nextSibling) - { - tmp = e; - e = tmp.prevSibling; - tmp.finishAnim(tmp); - } -} - -void AnimHost_finishObjAnim(entity me, entity obj) -{ - entity e, tmp; - for(e = me.firstChild; e; e = e.nextSibling) - { - if (e.object == obj) - { - tmp = e; - e = tmp.prevSibling; - tmp.finishAnim(tmp); - } - } -} - -void AnimHost_tickAll(entity me) -{ - entity e, tmp; - for(e = me.firstChild; e; e = e.nextSibling) - { - e.tick(e, time); - if (e.isFinished(e)) - { - tmp = e; - e = tmp.prevSibling; - me.removeAnim(me, tmp); - } - } -} -#endif diff --git a/qcsrc/menu/anim/animhost.qc b/qcsrc/menu/anim/animhost.qc new file mode 100644 index 000000000..ae84e0957 --- /dev/null +++ b/qcsrc/menu/anim/animhost.qc @@ -0,0 +1,174 @@ +#ifdef INTERFACE +CLASS(AnimHost) EXTENDS(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) + { + tmp = e; + e = tmp.prevSibling; + me.removeAnim(me, tmp); + } +} + +void AnimHost_removeObjAnim(entity me, entity obj) +{ + entity e, tmp; + for(e = me.firstChild; e; e = e.nextSibling) + { + if (e.object == obj) + { + tmp = e; + e = tmp.prevSibling; + me.removeAnim(me, tmp); + } + } +} + +void AnimHost_stopAllAnim(entity me) +{ + entity e; + for(e = me.firstChild; e; e = e.nextSibling) + { + e.stopAnim(e); + } +} + +void AnimHost_stopObjAnim(entity me, entity obj) +{ + entity e; + for(e = me.firstChild; e; e = e.nextSibling) + { + if (e.object == obj) + { + e.stopAnim(e); + } + } +} + +void AnimHost_resumeAllAnim(entity me) +{ + entity e; + for(e = me.firstChild; e; e = e.nextSibling) + { + e.resumeAnim(e); + } +} + +void AnimHost_resumeObjAnim(entity me, entity obj) +{ + entity e; + for(e = me.firstChild; e; e = e.nextSibling) + { + if (e.object == obj) + { + e.resumeAnim(e); + } + } +} + +void AnimHost_finishAllAnim(entity me) +{ + entity e, tmp; + for(e = me.firstChild; e; e = e.nextSibling) + { + tmp = e; + e = tmp.prevSibling; + tmp.finishAnim(tmp); + } +} + +void AnimHost_finishObjAnim(entity me, entity obj) +{ + entity e, tmp; + for(e = me.firstChild; e; e = e.nextSibling) + { + if (e.object == obj) + { + tmp = e; + e = tmp.prevSibling; + tmp.finishAnim(tmp); + } + } +} + +void AnimHost_tickAll(entity me) +{ + entity e, tmp; + for(e = me.firstChild; e; e = e.nextSibling) + { + e.tick(e, time); + if (e.isFinished(e)) + { + tmp = e; + e = tmp.prevSibling; + me.removeAnim(me, tmp); + } + } +} +#endif diff --git a/qcsrc/menu/anim/easing.c b/qcsrc/menu/anim/easing.c deleted file mode 100644 index 94ea9cf08..000000000 --- a/qcsrc/menu/anim/easing.c +++ /dev/null @@ -1,72 +0,0 @@ -#ifdef INTERFACE -CLASS(Easing) EXTENDS(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) -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); -#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 = spawnEasing(); - me.configureAnimation(me, obj, objSetter, animStartTime, animDuration, animStartValue, animEnd); - me.setMath(me, func); - return me; -} - -float Easing_calcValue(entity me, float tickTime, float animDuration, float animStart, float animDelta) -{ - return me.math(tickTime, animDuration, animStart, animDelta); -} - -void Easing_setMath(entity me, float(float, float, float, float) func) -{ - me.math = func; -} - -float easingLinear(float tickTime, float animDuration, float animStart, float animDelta) -{ - return (animDelta * (tickTime / animDuration)) + animStart; -} - -float easingQuadIn(float tickTime, float animDuration, float animStart, float animDelta) -{ - float frac = tickTime / animDuration; - return (animDelta * frac * frac) + animStart; -} - -float easingQuadOut(float tickTime, float animDuration, float animStart, float animDelta) -{ - float frac = tickTime / animDuration; - return (-animDelta * frac * (frac - 2)) + animStart; -} - -float easingQuadInOut(float tickTime, float animDuration, float animStart, float animDelta) -{ - 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/easing.qc b/qcsrc/menu/anim/easing.qc new file mode 100644 index 000000000..94ea9cf08 --- /dev/null +++ b/qcsrc/menu/anim/easing.qc @@ -0,0 +1,72 @@ +#ifdef INTERFACE +CLASS(Easing) EXTENDS(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) +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); +#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 = spawnEasing(); + me.configureAnimation(me, obj, objSetter, animStartTime, animDuration, animStartValue, animEnd); + me.setMath(me, func); + return me; +} + +float Easing_calcValue(entity me, float tickTime, float animDuration, float animStart, float animDelta) +{ + return me.math(tickTime, animDuration, animStart, animDelta); +} + +void Easing_setMath(entity me, float(float, float, float, float) func) +{ + me.math = func; +} + +float easingLinear(float tickTime, float animDuration, float animStart, float animDelta) +{ + return (animDelta * (tickTime / animDuration)) + animStart; +} + +float easingQuadIn(float tickTime, float animDuration, float animStart, float animDelta) +{ + float frac = tickTime / animDuration; + return (animDelta * frac * frac) + animStart; +} + +float easingQuadOut(float tickTime, float animDuration, float animStart, float animDelta) +{ + float frac = tickTime / animDuration; + return (-animDelta * frac * (frac - 2)) + animStart; +} + +float easingQuadInOut(float tickTime, float animDuration, float animStart, float animDelta) +{ + 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.c b/qcsrc/menu/anim/keyframe.c deleted file mode 100644 index 3bcda94e6..000000000 --- a/qcsrc/menu/anim/keyframe.c +++ /dev/null @@ -1,108 +0,0 @@ -#ifdef INTERFACE -CLASS(Keyframe) EXTENDS(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 makeKeyframe(entity obj, void(entity, float) objSetter, float animDuration, float animStart, float animEnd) -{ - entity me; - me = spawnKeyframe(); - me.configureAnimation(me, obj, objSetter, time, animDuration, animStart, animEnd); - return me; -} - -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; -} - -float getNewChildStart(entity me) -{ - if (me.lastChild) - return (me.lastChild.startTime + me.lastChild.duration); - else - return 0; -} - -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 me) -{ - if (me.lastChild) - return (me.lastChild.startValue + me.lastChild.delta); - else - return me.startValue; -} - -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!"); - - other.parent = me; - - entity l; - l = me.lastChild; - - if(l) - l.nextSibling = other; - else - { - me.currentChild = other; - me.firstChild = other; - } - - other.prevSibling = l; - other.nextSibling = NULL; - me.lastChild = other; -} - -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 (me.currentChild) - { - me.currentChild.tick(me.currentChild, tickTime); - return me.currentChild.value; - } - - return animStartValue + animDelta; -} -#endif diff --git a/qcsrc/menu/anim/keyframe.qc b/qcsrc/menu/anim/keyframe.qc new file mode 100644 index 000000000..3bcda94e6 --- /dev/null +++ b/qcsrc/menu/anim/keyframe.qc @@ -0,0 +1,108 @@ +#ifdef INTERFACE +CLASS(Keyframe) EXTENDS(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 makeKeyframe(entity obj, void(entity, float) objSetter, float animDuration, float animStart, float animEnd) +{ + entity me; + me = spawnKeyframe(); + me.configureAnimation(me, obj, objSetter, time, animDuration, animStart, animEnd); + return me; +} + +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; +} + +float getNewChildStart(entity me) +{ + if (me.lastChild) + return (me.lastChild.startTime + me.lastChild.duration); + else + return 0; +} + +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 me) +{ + if (me.lastChild) + return (me.lastChild.startValue + me.lastChild.delta); + else + return me.startValue; +} + +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!"); + + other.parent = me; + + entity l; + l = me.lastChild; + + if(l) + l.nextSibling = other; + else + { + me.currentChild = other; + me.firstChild = other; + } + + other.prevSibling = l; + other.nextSibling = NULL; + me.lastChild = other; +} + +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 (me.currentChild) + { + me.currentChild.tick(me.currentChild, tickTime); + return me.currentChild.value; + } + + return animStartValue + animDelta; +} +#endif diff --git a/qcsrc/menu/classes.c b/qcsrc/menu/classes.c deleted file mode 100644 index 9f01ee3fb..000000000 --- a/qcsrc/menu/classes.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "anim/animhost.c" -#include "anim/animation.c" -#include "anim/easing.c" -#include "anim/keyframe.c" -#include "item.c" -#include "item/container.c" -#include "item/inputcontainer.c" -#include "item/nexposee.c" -#include "item/modalcontroller.c" -#include "item/image.c" -#include "item/label.c" -#include "item/button.c" -#include "item/checkbox.c" -#include "item/radiobutton.c" -#include "item/borderimage.c" -#include "item/slider.c" -#include "item/dialog.c" -#include "item/tab.c" -#include "item/textslider.c" -#include "item/listbox.c" -#include "item/inputbox.c" -#include "xonotic/dialog.c" -#include "xonotic/tab.c" -#include "xonotic/mainwindow.c" -#include "xonotic/button.c" -#include "xonotic/bigbutton.c" -#include "xonotic/commandbutton.c" -#include "xonotic/bigcommandbutton.c" -#include "xonotic/textlabel.c" -#include "xonotic/dialog_firstrun.c" -#include "xonotic/dialog_teamselect.c" -#include "xonotic/dialog_sandboxtools.c" -#include "xonotic/dialog_monstertools.c" -#include "xonotic/dialog_settings.c" -#include "xonotic/dialog_settings_video.c" -#include "xonotic/dialog_settings_effects.c" -#include "xonotic/dialog_settings_audio.c" -#include "xonotic/dialog_settings_game.c" -#include "xonotic/dialog_settings_user.c" -#include "xonotic/dialog_settings_user_languagewarning.c" -#include "xonotic/dialog_settings_misc.c" -#include "xonotic/dialog_multiplayer.c" -#include "xonotic/dialog_multiplayer_profile.c" -#include "xonotic/tabcontroller.c" -#include "xonotic/slider.c" -#include "xonotic/slider_resolution.c" -#include "xonotic/checkbox.c" -#include "xonotic/checkbox_string.c" -#include "xonotic/weaponarenacheckbox.c" -#include "xonotic/radiobutton.c" -#include "xonotic/nexposee.c" -#include "xonotic/rootdialog.c" -#include "xonotic/textslider.c" -#include "xonotic/colorbutton.c" -#include "xonotic/dialog_multiplayer_join.c" -#include "xonotic/dialog_multiplayer_join_serverinfo.c" -#include "xonotic/playerlist.c" -#include "xonotic/listbox.c" -#include "xonotic/serverlist.c" -#include "xonotic/inputbox.c" -#include "xonotic/dialog_quit.c" -#include "xonotic/dialog_multiplayer_create.c" -#include "xonotic/dialog_multiplayer_create_mutators.c" -#include "xonotic/dialog_multiplayer_create_mapinfo.c" -#include "xonotic/gametypelist.c" -#include "xonotic/maplist.c" -#include "xonotic/skinlist.c" -#include "xonotic/languagelist.c" -#include "xonotic/image.c" -#include "xonotic/crosshairbutton.c" -#include "xonotic/playermodel.c" -#include "xonotic/checkbox_slider_invalid.c" -#include "xonotic/charmap.c" -#include "xonotic/keybinder.c" -#include "xonotic/dialog_settings_input.c" -#include "xonotic/dialog_settings_input_userbind.c" -#include "xonotic/slider_decibels.c" -#include "xonotic/dialog_singleplayer.c" -#include "xonotic/campaign.c" -#include "xonotic/dialog_singleplayer_winner.c" -#include "xonotic/dialog_credits.c" -#include "xonotic/credits.c" -#include "xonotic/dialog_settings_game_crosshair.c" -#include "xonotic/dialog_settings_game_hud.c" -#include "xonotic/dialog_settings_game_hudconfirm.c" -#include "xonotic/dialog_settings_game_model.c" -#include "xonotic/dialog_settings_game_messages.c" -#include "xonotic/dialog_settings_game_view.c" -#include "xonotic/dialog_settings_game_weapons.c" -#include "xonotic/weaponslist.c" -#include "xonotic/dialog_multiplayer_media.c" -#include "xonotic/dialog_multiplayer_media_demo.c" -#include "xonotic/dialog_multiplayer_media_demo_startconfirm.c" -#include "xonotic/dialog_multiplayer_media_demo_timeconfirm.c" -#include "xonotic/demolist.c" -#include "xonotic/screenshotimage.c" -#include "xonotic/dialog_multiplayer_media_screenshot.c" -#include "xonotic/dialog_multiplayer_media_screenshot_viewer.c" -#include "xonotic/screenshotlist.c" -#include "xonotic/statslist.c" -#include "xonotic/dialog_multiplayer_media_musicplayer.c" -#include "xonotic/soundlist.c" -#include "xonotic/playlist.c" -#include "xonotic/colorpicker.c" -#include "xonotic/colorpicker_string.c" -#include "xonotic/cvarlist.c" -#include "xonotic/dialog_settings_misc_cvars.c" -#include "xonotic/dialog_hudsetup_exit.c" -#include "xonotic/dialog_hudpanel_notification.c" -#include "xonotic/dialog_hudpanel_ammo.c" -#include "xonotic/dialog_hudpanel_healtharmor.c" -#include "xonotic/dialog_hudpanel_powerups.c" -#include "xonotic/dialog_hudpanel_racetimer.c" -#include "xonotic/dialog_hudpanel_pressedkeys.c" -#include "xonotic/dialog_hudpanel_radar.c" -#include "xonotic/dialog_hudpanel_score.c" -#include "xonotic/dialog_hudpanel_timer.c" -#include "xonotic/dialog_hudpanel_vote.c" -#include "xonotic/dialog_hudpanel_modicons.c" -#include "xonotic/dialog_hudpanel_chat.c" -#include "xonotic/dialog_hudpanel_engineinfo.c" -#include "xonotic/dialog_hudpanel_infomessages.c" -#include "xonotic/dialog_hudpanel_weapons.c" -#include "xonotic/dialog_hudpanel_physics.c" -#include "xonotic/dialog_hudpanel_centerprint.c" -#include "xonotic/dialog_hudpanel_buffs.c" -#include "xonotic/slider_picmip.c" -#include "xonotic/slider_particles.c" -#include "xonotic/slider_sbfadetime.c" -#include "xonotic/dialog_settings_misc_reset.c" diff --git a/qcsrc/menu/classes.qc b/qcsrc/menu/classes.qc new file mode 100644 index 000000000..9b4bb4dab --- /dev/null +++ b/qcsrc/menu/classes.qc @@ -0,0 +1,130 @@ +#include "anim/animhost.qc" +#include "anim/animation.qc" +#include "anim/easing.qc" +#include "anim/keyframe.qc" +#include "item.qc" +#include "item/container.qc" +#include "item/inputcontainer.qc" +#include "item/nexposee.qc" +#include "item/modalcontroller.qc" +#include "item/image.qc" +#include "item/label.qc" +#include "item/button.qc" +#include "item/checkbox.qc" +#include "item/radiobutton.qc" +#include "item/borderimage.qc" +#include "item/slider.qc" +#include "item/dialog.qc" +#include "item/tab.qc" +#include "item/textslider.qc" +#include "item/listbox.qc" +#include "item/inputbox.qc" +#include "xonotic/dialog.qc" +#include "xonotic/tab.qc" +#include "xonotic/mainwindow.qc" +#include "xonotic/button.qc" +#include "xonotic/bigbutton.qc" +#include "xonotic/commandbutton.qc" +#include "xonotic/bigcommandbutton.qc" +#include "xonotic/textlabel.qc" +#include "xonotic/dialog_firstrun.qc" +#include "xonotic/dialog_teamselect.qc" +#include "xonotic/dialog_sandboxtools.qc" +#include "xonotic/dialog_monstertools.qc" +#include "xonotic/dialog_settings.qc" +#include "xonotic/dialog_settings_video.qc" +#include "xonotic/dialog_settings_effects.qc" +#include "xonotic/dialog_settings_audio.qc" +#include "xonotic/dialog_settings_game.qc" +#include "xonotic/dialog_settings_user.qc" +#include "xonotic/dialog_settings_user_languagewarning.qc" +#include "xonotic/dialog_settings_misc.qc" +#include "xonotic/dialog_multiplayer.qc" +#include "xonotic/dialog_multiplayer_profile.qc" +#include "xonotic/tabcontroller.qc" +#include "xonotic/slider.qc" +#include "xonotic/slider_resolution.qc" +#include "xonotic/checkbox.qc" +#include "xonotic/checkbox_string.qc" +#include "xonotic/weaponarenacheckbox.qc" +#include "xonotic/radiobutton.qc" +#include "xonotic/nexposee.qc" +#include "xonotic/rootdialog.qc" +#include "xonotic/textslider.qc" +#include "xonotic/colorbutton.qc" +#include "xonotic/dialog_multiplayer_join.qc" +#include "xonotic/dialog_multiplayer_join_serverinfo.qc" +#include "xonotic/playerlist.qc" +#include "xonotic/listbox.qc" +#include "xonotic/serverlist.qc" +#include "xonotic/inputbox.qc" +#include "xonotic/dialog_quit.qc" +#include "xonotic/dialog_multiplayer_create.qc" +#include "xonotic/dialog_multiplayer_create_mutators.qc" +#include "xonotic/dialog_multiplayer_create_mapinfo.qc" +#include "xonotic/gametypelist.qc" +#include "xonotic/maplist.qc" +#include "xonotic/skinlist.qc" +#include "xonotic/languagelist.qc" +#include "xonotic/image.qc" +#include "xonotic/crosshairbutton.qc" +#include "xonotic/playermodel.qc" +#include "xonotic/checkbox_slider_invalid.qc" +#include "xonotic/charmap.qc" +#include "xonotic/keybinder.qc" +#include "xonotic/dialog_settings_input.qc" +#include "xonotic/dialog_settings_input_userbind.qc" +#include "xonotic/slider_decibels.qc" +#include "xonotic/dialog_singleplayer.qc" +#include "xonotic/campaign.qc" +#include "xonotic/dialog_singleplayer_winner.qc" +#include "xonotic/dialog_credits.qc" +#include "xonotic/credits.qc" +#include "xonotic/dialog_settings_game_crosshair.qc" +#include "xonotic/dialog_settings_game_hud.qc" +#include "xonotic/dialog_settings_game_hudconfirm.qc" +#include "xonotic/dialog_settings_game_model.qc" +#include "xonotic/dialog_settings_game_messages.qc" +#include "xonotic/dialog_settings_game_view.qc" +#include "xonotic/dialog_settings_game_weapons.qc" +#include "xonotic/weaponslist.qc" +#include "xonotic/dialog_multiplayer_media.qc" +#include "xonotic/dialog_multiplayer_media_demo.qc" +#include "xonotic/dialog_multiplayer_media_demo_startconfirm.qc" +#include "xonotic/dialog_multiplayer_media_demo_timeconfirm.qc" +#include "xonotic/demolist.qc" +#include "xonotic/screenshotimage.qc" +#include "xonotic/dialog_multiplayer_media_screenshot.qc" +#include "xonotic/dialog_multiplayer_media_screenshot_viewer.qc" +#include "xonotic/screenshotlist.qc" +#include "xonotic/statslist.qc" +#include "xonotic/dialog_multiplayer_media_musicplayer.qc" +#include "xonotic/soundlist.qc" +#include "xonotic/playlist.qc" +#include "xonotic/colorpicker.qc" +#include "xonotic/colorpicker_string.qc" +#include "xonotic/cvarlist.qc" +#include "xonotic/dialog_settings_misc_cvars.qc" +#include "xonotic/dialog_hudsetup_exit.qc" +#include "xonotic/dialog_hudpanel_notification.qc" +#include "xonotic/dialog_hudpanel_ammo.qc" +#include "xonotic/dialog_hudpanel_healtharmor.qc" +#include "xonotic/dialog_hudpanel_powerups.qc" +#include "xonotic/dialog_hudpanel_racetimer.qc" +#include "xonotic/dialog_hudpanel_pressedkeys.qc" +#include "xonotic/dialog_hudpanel_radar.qc" +#include "xonotic/dialog_hudpanel_score.qc" +#include "xonotic/dialog_hudpanel_timer.qc" +#include "xonotic/dialog_hudpanel_vote.qc" +#include "xonotic/dialog_hudpanel_modicons.qc" +#include "xonotic/dialog_hudpanel_chat.qc" +#include "xonotic/dialog_hudpanel_engineinfo.qc" +#include "xonotic/dialog_hudpanel_infomessages.qc" +#include "xonotic/dialog_hudpanel_weapons.qc" +#include "xonotic/dialog_hudpanel_physics.qc" +#include "xonotic/dialog_hudpanel_centerprint.qc" +#include "xonotic/dialog_hudpanel_buffs.qc" +#include "xonotic/slider_picmip.qc" +#include "xonotic/slider_particles.qc" +#include "xonotic/slider_sbfadetime.qc" +#include "xonotic/dialog_settings_misc_reset.qc" diff --git a/qcsrc/menu/item.c b/qcsrc/menu/item.c deleted file mode 100644 index d055b1a05..000000000 --- a/qcsrc/menu/item.c +++ /dev/null @@ -1,134 +0,0 @@ -#ifdef INTERFACE -CLASS(Item) EXTENDS(Object) - METHOD(Item, draw, void(entity)) - METHOD(Item, keyDown, float(entity, float, float, float)) - METHOD(Item, keyUp, float(entity, float, float, float)) - METHOD(Item, mouseMove, float(entity, vector)) - METHOD(Item, mousePress, float(entity, vector)) - METHOD(Item, mouseDrag, float(entity, vector)) - METHOD(Item, mouseRelease, float(entity, vector)) - METHOD(Item, focusEnter, void(entity)) - METHOD(Item, focusLeave, void(entity)) - METHOD(Item, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(Item, relinquishFocus, void(entity)) - METHOD(Item, showNotify, void(entity)) - METHOD(Item, hideNotify, void(entity)) - METHOD(Item, toString, string(entity)) - METHOD(Item, destroy, void(entity)) - ATTRIB(Item, focused, float, 0) - ATTRIB(Item, focusable, float, 0) - ATTRIB(Item, parent, entity, NULL) - ATTRIB(Item, preferredFocusPriority, float, 0) - ATTRIB(Item, origin, vector, '0 0 0') - ATTRIB(Item, size, vector, '0 0 0') - ATTRIB(Item, tooltip, string, string_null) -ENDCLASS(Item) -#endif - -#ifdef IMPLEMENTATION -void Item_destroy(entity me) -{ - // free memory associated with me -} - -void Item_relinquishFocus(entity me) -{ - if(me.parent) - if(me.parent.instanceOfContainer) - me.parent.setFocus(me.parent, NULL); -} - -void Item_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.origin = absOrigin; - me.size = absSize; -} - -float autocvar_menu_showboxes; -void Item_draw(entity me) -{ - if(autocvar_menu_showboxes) - { - vector rgb = '1 0 1'; - float a = fabs(autocvar_menu_showboxes); - - // don't draw containers and border images - if(me.instanceOfContainer || me.instanceOfBorderImage) - { - rgb = '0 0 0'; - a = 0; - } - -#if 0 - // hack to detect multi drawing - float r = random() * 3; - if(r >= 2) - rgb = '1 0 0'; - else if(r >= 1) - rgb = '0 1 0'; - else - rgb = '0 0 1'; -#endif - if(autocvar_menu_showboxes < 0) - { - draw_Fill('0 0 0', '0.5 0.5 0', rgb, a); - draw_Fill('0.5 0.5 0', '0.5 0.5 0', rgb, a); - } - if(autocvar_menu_showboxes > 0) - { - draw_Fill('0 0 0', '1 1 0', rgb, a); - } - } -} - -void Item_showNotify(entity me) -{ -} - -void Item_hideNotify(entity me) -{ -} - -float Item_keyDown(entity me, float scan, float ascii, float shift) -{ - return 0; // unhandled -} - -float Item_keyUp(entity me, float scan, float ascii, float shift) -{ - return 0; // unhandled -} - -float Item_mouseMove(entity me, vector pos) -{ - return 0; // unhandled -} - -float Item_mousePress(entity me, vector pos) -{ - return 0; // unhandled -} - -float Item_mouseDrag(entity me, vector pos) -{ - return 0; // unhandled -} - -float Item_mouseRelease(entity me, vector pos) -{ - return 0; // unhandled -} - -void Item_focusEnter(entity me) -{ -} - -void Item_focusLeave(entity me) -{ -} - -string Item_toString(entity me) -{ - return string_null; -} -#endif diff --git a/qcsrc/menu/item.qc b/qcsrc/menu/item.qc new file mode 100644 index 000000000..d055b1a05 --- /dev/null +++ b/qcsrc/menu/item.qc @@ -0,0 +1,134 @@ +#ifdef INTERFACE +CLASS(Item) EXTENDS(Object) + METHOD(Item, draw, void(entity)) + METHOD(Item, keyDown, float(entity, float, float, float)) + METHOD(Item, keyUp, float(entity, float, float, float)) + METHOD(Item, mouseMove, float(entity, vector)) + METHOD(Item, mousePress, float(entity, vector)) + METHOD(Item, mouseDrag, float(entity, vector)) + METHOD(Item, mouseRelease, float(entity, vector)) + METHOD(Item, focusEnter, void(entity)) + METHOD(Item, focusLeave, void(entity)) + METHOD(Item, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(Item, relinquishFocus, void(entity)) + METHOD(Item, showNotify, void(entity)) + METHOD(Item, hideNotify, void(entity)) + METHOD(Item, toString, string(entity)) + METHOD(Item, destroy, void(entity)) + ATTRIB(Item, focused, float, 0) + ATTRIB(Item, focusable, float, 0) + ATTRIB(Item, parent, entity, NULL) + ATTRIB(Item, preferredFocusPriority, float, 0) + ATTRIB(Item, origin, vector, '0 0 0') + ATTRIB(Item, size, vector, '0 0 0') + ATTRIB(Item, tooltip, string, string_null) +ENDCLASS(Item) +#endif + +#ifdef IMPLEMENTATION +void Item_destroy(entity me) +{ + // free memory associated with me +} + +void Item_relinquishFocus(entity me) +{ + if(me.parent) + if(me.parent.instanceOfContainer) + me.parent.setFocus(me.parent, NULL); +} + +void Item_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.origin = absOrigin; + me.size = absSize; +} + +float autocvar_menu_showboxes; +void Item_draw(entity me) +{ + if(autocvar_menu_showboxes) + { + vector rgb = '1 0 1'; + float a = fabs(autocvar_menu_showboxes); + + // don't draw containers and border images + if(me.instanceOfContainer || me.instanceOfBorderImage) + { + rgb = '0 0 0'; + a = 0; + } + +#if 0 + // hack to detect multi drawing + float r = random() * 3; + if(r >= 2) + rgb = '1 0 0'; + else if(r >= 1) + rgb = '0 1 0'; + else + rgb = '0 0 1'; +#endif + if(autocvar_menu_showboxes < 0) + { + draw_Fill('0 0 0', '0.5 0.5 0', rgb, a); + draw_Fill('0.5 0.5 0', '0.5 0.5 0', rgb, a); + } + if(autocvar_menu_showboxes > 0) + { + draw_Fill('0 0 0', '1 1 0', rgb, a); + } + } +} + +void Item_showNotify(entity me) +{ +} + +void Item_hideNotify(entity me) +{ +} + +float Item_keyDown(entity me, float scan, float ascii, float shift) +{ + return 0; // unhandled +} + +float Item_keyUp(entity me, float scan, float ascii, float shift) +{ + return 0; // unhandled +} + +float Item_mouseMove(entity me, vector pos) +{ + return 0; // unhandled +} + +float Item_mousePress(entity me, vector pos) +{ + return 0; // unhandled +} + +float Item_mouseDrag(entity me, vector pos) +{ + return 0; // unhandled +} + +float Item_mouseRelease(entity me, vector pos) +{ + return 0; // unhandled +} + +void Item_focusEnter(entity me) +{ +} + +void Item_focusLeave(entity me) +{ +} + +string Item_toString(entity me) +{ + return string_null; +} +#endif diff --git a/qcsrc/menu/item/borderimage.c b/qcsrc/menu/item/borderimage.c deleted file mode 100644 index 3a345a43d..000000000 --- a/qcsrc/menu/item/borderimage.c +++ /dev/null @@ -1,110 +0,0 @@ -#ifdef INTERFACE -CLASS(BorderImage) EXTENDS(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) - { - 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); -} -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) - { - // 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) - { - if(me.recalcPos) - me.recalcPositionWithText(me, me.text); - - if(me.isNexposeeTitleBar) - { - vector ro, rf, df; - - // 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; - } - else - SUPER(BorderImage).draw(me); - } - else - { - SUPER(BorderImage).draw(me); - } -} -#endif diff --git a/qcsrc/menu/item/borderimage.qc b/qcsrc/menu/item/borderimage.qc new file mode 100644 index 000000000..3a345a43d --- /dev/null +++ b/qcsrc/menu/item/borderimage.qc @@ -0,0 +1,110 @@ +#ifdef INTERFACE +CLASS(BorderImage) EXTENDS(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) + { + 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); +} +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) + { + // 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) + { + if(me.recalcPos) + me.recalcPositionWithText(me, me.text); + + if(me.isNexposeeTitleBar) + { + vector ro, rf, df; + + // 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; + } + else + SUPER(BorderImage).draw(me); + } + else + { + SUPER(BorderImage).draw(me); + } +} +#endif diff --git a/qcsrc/menu/item/button.c b/qcsrc/menu/item/button.c deleted file mode 100644 index 8bbdfa704..000000000 --- a/qcsrc/menu/item/button.c +++ /dev/null @@ -1,173 +0,0 @@ -#ifdef INTERFACE -CLASS(Button) EXTENDS(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, focusEnter, 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, 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) -#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_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) - { - me.clickTime = 0.1; // delayed for effect - return 1; - } - 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) - { - if (!me.disabled) - { - if(cvar("menu_sounds")) - localsound("sound/misc/menu2.wav"); - if(me.onClick) - me.onClick(me, me.onClickEntity); - } - me.pressed = 0; - } - return 1; -} -void Button_showNotify(entity me) -{ - me.focusable = !me.disabled; -} -void Button_focusEnter(entity me) -{ - if(cvar("menu_sounds") > 1) - localsound("sound/misc/menu1.wav"); - SUPER(Button).focusEnter(me); -} -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.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 - { - 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.src2) - { - bOrigin = me.keepspaceLeft * eX; - bSize = eY + eX * (1 - me.keepspaceLeft); - - bOrigin += bSize * (0.5 - 0.5 * me.src2scale); - bSize = bSize * me.src2scale; - - draw_Picture(bOrigin, me.src2, bSize, me.color2, me.alpha2); - } - - 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; - - SUPER(Button).draw(me); -} -#endif diff --git a/qcsrc/menu/item/button.qc b/qcsrc/menu/item/button.qc new file mode 100644 index 000000000..8bbdfa704 --- /dev/null +++ b/qcsrc/menu/item/button.qc @@ -0,0 +1,173 @@ +#ifdef INTERFACE +CLASS(Button) EXTENDS(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, focusEnter, 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, 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) +#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_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) + { + me.clickTime = 0.1; // delayed for effect + return 1; + } + 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) + { + if (!me.disabled) + { + if(cvar("menu_sounds")) + localsound("sound/misc/menu2.wav"); + if(me.onClick) + me.onClick(me, me.onClickEntity); + } + me.pressed = 0; + } + return 1; +} +void Button_showNotify(entity me) +{ + me.focusable = !me.disabled; +} +void Button_focusEnter(entity me) +{ + if(cvar("menu_sounds") > 1) + localsound("sound/misc/menu1.wav"); + SUPER(Button).focusEnter(me); +} +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.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 + { + 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.src2) + { + bOrigin = me.keepspaceLeft * eX; + bSize = eY + eX * (1 - me.keepspaceLeft); + + bOrigin += bSize * (0.5 - 0.5 * me.src2scale); + bSize = bSize * me.src2scale; + + draw_Picture(bOrigin, me.src2, bSize, me.color2, me.alpha2); + } + + 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; + + SUPER(Button).draw(me); +} +#endif diff --git a/qcsrc/menu/item/checkbox.c b/qcsrc/menu/item/checkbox.c deleted file mode 100644 index 94f67ba70..000000000 --- a/qcsrc/menu/item/checkbox.c +++ /dev/null @@ -1,48 +0,0 @@ -#ifdef INTERFACE -void CheckBox_Click(entity me, entity other); -CLASS(CheckBox) EXTENDS(Button) - METHOD(CheckBox, configureCheckBox, void(entity, string, float, string)) - METHOD(CheckBox, draw, 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) - { - me.srcSuffix = string_null; - me.forcePressed = me.checked; - } - else - me.srcSuffix = (me.checked ? "1" : "0"); - me.pressed = s; - SUPER(CheckBox).draw(me); -} -#endif diff --git a/qcsrc/menu/item/checkbox.qc b/qcsrc/menu/item/checkbox.qc new file mode 100644 index 000000000..94f67ba70 --- /dev/null +++ b/qcsrc/menu/item/checkbox.qc @@ -0,0 +1,48 @@ +#ifdef INTERFACE +void CheckBox_Click(entity me, entity other); +CLASS(CheckBox) EXTENDS(Button) + METHOD(CheckBox, configureCheckBox, void(entity, string, float, string)) + METHOD(CheckBox, draw, 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) + { + me.srcSuffix = string_null; + me.forcePressed = me.checked; + } + else + me.srcSuffix = (me.checked ? "1" : "0"); + me.pressed = s; + SUPER(CheckBox).draw(me); +} +#endif diff --git a/qcsrc/menu/item/container.c b/qcsrc/menu/item/container.c deleted file mode 100644 index 8bc925f1c..000000000 --- a/qcsrc/menu/item/container.c +++ /dev/null @@ -1,453 +0,0 @@ -#ifdef INTERFACE -CLASS(Container) EXTENDS(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, 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) - { - if(other.Container_alpha > 0) - other.hideNotify(other); - } - else // value > 0 - { - if(other.Container_alpha <= 0) - other.showNotify(other); - } - 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) - { - 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); -} - -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) - { - 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; -} - -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); - } - - SUPER(Container).draw(me); -} - -void Container_focusLeave(entity me) -{ - me.setFocus(me, NULL); -} - -float Container_keyUp(entity me, float scan, float ascii, float shift) -{ - 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; -} - -float Container_keyDown(entity me, float scan, float ascii, float shift) -{ - 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; -} - -float Container_mouseMove(entity me, vector pos) -{ - 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; -} -float Container_mousePress(entity me, vector pos) -{ - 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; -} -float Container_mouseDrag(entity me, vector pos) -{ - 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; -} - -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_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; - - 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; -} - -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) - { - me.focusedChild.focused = 0; - me.focusedChild.focusLeave(me.focusedChild); - me.focusedChild = NULL; - } - - if(other) - { - 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; - - best = NULL; - - for(e = me.firstChild; e; e = e.nextSibling) - { - 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; - } - - return best; -} -#endif diff --git a/qcsrc/menu/item/container.qc b/qcsrc/menu/item/container.qc new file mode 100644 index 000000000..8bc925f1c --- /dev/null +++ b/qcsrc/menu/item/container.qc @@ -0,0 +1,453 @@ +#ifdef INTERFACE +CLASS(Container) EXTENDS(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, 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) + { + if(other.Container_alpha > 0) + other.hideNotify(other); + } + else // value > 0 + { + if(other.Container_alpha <= 0) + other.showNotify(other); + } + 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) + { + 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); +} + +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) + { + 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; +} + +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); + } + + SUPER(Container).draw(me); +} + +void Container_focusLeave(entity me) +{ + me.setFocus(me, NULL); +} + +float Container_keyUp(entity me, float scan, float ascii, float shift) +{ + 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; +} + +float Container_keyDown(entity me, float scan, float ascii, float shift) +{ + 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; +} + +float Container_mouseMove(entity me, vector pos) +{ + 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; +} +float Container_mousePress(entity me, vector pos) +{ + 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; +} +float Container_mouseDrag(entity me, vector pos) +{ + 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; +} + +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_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; + + 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; +} + +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) + { + me.focusedChild.focused = 0; + me.focusedChild.focusLeave(me.focusedChild); + me.focusedChild = NULL; + } + + if(other) + { + 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; + + best = NULL; + + for(e = me.firstChild; e; e = e.nextSibling) + { + 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; + } + + return best; +} +#endif diff --git a/qcsrc/menu/item/dialog.c b/qcsrc/menu/item/dialog.c deleted file mode 100644 index 383578781..000000000 --- a/qcsrc/menu/item/dialog.c +++ /dev/null @@ -1,191 +0,0 @@ -// Note: this class is called Dialog, but it can also handle a tab under the following conditions: -// - isTabRoot is 0 -// - backgroundImage is the tab's background -// - closable is 0 -// - rootDialog is 0 -// - title is "" -// - marginTop is -// - intendedHeight ends up to be the tab's actual height, or at least close -// - titleFontSize is 0 -// - marginTop cancels out as much of titleHeight as needed (that is, it should be actualMarginTop - titleHeight) -// To ensure the latter, you best create all tabs FIRST and insert the tabbed -// control to your dialog THEN - with the right height -// -// a subclass may help with using this as a tab - -#ifdef INTERFACE -CLASS(Dialog) EXTENDS(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; - - me.frame = spawnBorderImage(); - 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.closable && me.borderLines > 0) - { - entity closebutton; - closebutton = me.closeButton = me.frame.closeButton = spawnButton(); - 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) -{ - 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) - { - if(key == K_ESCAPE) - { - me.close(me); - return 1; - } - } - return SUPER(Dialog).keyDown(me, key, ascii, shift); -} -#endif diff --git a/qcsrc/menu/item/dialog.qc b/qcsrc/menu/item/dialog.qc new file mode 100644 index 000000000..383578781 --- /dev/null +++ b/qcsrc/menu/item/dialog.qc @@ -0,0 +1,191 @@ +// Note: this class is called Dialog, but it can also handle a tab under the following conditions: +// - isTabRoot is 0 +// - backgroundImage is the tab's background +// - closable is 0 +// - rootDialog is 0 +// - title is "" +// - marginTop is +// - intendedHeight ends up to be the tab's actual height, or at least close +// - titleFontSize is 0 +// - marginTop cancels out as much of titleHeight as needed (that is, it should be actualMarginTop - titleHeight) +// To ensure the latter, you best create all tabs FIRST and insert the tabbed +// control to your dialog THEN - with the right height +// +// a subclass may help with using this as a tab + +#ifdef INTERFACE +CLASS(Dialog) EXTENDS(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; + + me.frame = spawnBorderImage(); + 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.closable && me.borderLines > 0) + { + entity closebutton; + closebutton = me.closeButton = me.frame.closeButton = spawnButton(); + 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) +{ + 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) + { + if(key == K_ESCAPE) + { + me.close(me); + return 1; + } + } + return SUPER(Dialog).keyDown(me, key, ascii, shift); +} +#endif diff --git a/qcsrc/menu/item/image.c b/qcsrc/menu/item/image.c deleted file mode 100644 index 8d1a6de86..000000000 --- a/qcsrc/menu/item/image.c +++ /dev/null @@ -1,231 +0,0 @@ -#ifdef INTERFACE -CLASS(Image) EXTENDS(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 -} - -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) - { - me.imgOrigin = '0 0 0'; - me.imgSize = '1 1 0'; - } - else - { - vector sz = '0 0 0'; - 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; - } - 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)) - { - // 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 - { - 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.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.imgSize_x > 1 || me.imgSize_y > 1) - { - 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); - else - me.zoomOffset_y = bound(1 - 0.5/me.imgSize_y, me.zoomOffset_y, 0.5/me.imgSize_y); - } - else - { - me.zoomOffset_x = bound(0, me.zoomOffset_x, 1); - me.zoomOffset_y = bound(0, me.zoomOffset_y, 1); - } - } - 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); - } - 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) - { - 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.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); -} -#endif diff --git a/qcsrc/menu/item/image.qc b/qcsrc/menu/item/image.qc new file mode 100644 index 000000000..8d1a6de86 --- /dev/null +++ b/qcsrc/menu/item/image.qc @@ -0,0 +1,231 @@ +#ifdef INTERFACE +CLASS(Image) EXTENDS(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 +} + +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) + { + me.imgOrigin = '0 0 0'; + me.imgSize = '1 1 0'; + } + else + { + vector sz = '0 0 0'; + 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; + } + 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)) + { + // 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 + { + 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.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.imgSize_x > 1 || me.imgSize_y > 1) + { + 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); + else + me.zoomOffset_y = bound(1 - 0.5/me.imgSize_y, me.zoomOffset_y, 0.5/me.imgSize_y); + } + else + { + me.zoomOffset_x = bound(0, me.zoomOffset_x, 1); + me.zoomOffset_y = bound(0, me.zoomOffset_y, 1); + } + } + 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); + } + 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) + { + 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.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); +} +#endif diff --git a/qcsrc/menu/item/inputbox.c b/qcsrc/menu/item/inputbox.c deleted file mode 100644 index 7708a0d7f..000000000 --- a/qcsrc/menu/item/inputbox.c +++ /dev/null @@ -1,391 +0,0 @@ -#ifdef INTERFACE -CLASS(InputBox) EXTENDS(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, 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) -void InputBox_Clear_Click(entity btn, entity me); -#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) - { - 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; - } -} - -void InputBox_setText(entity me, string txt) -{ - if(me.text) - strunzone(me.text); - SUPER(InputBox).setText(me, strzone(txt)); -} - -void InputBox_Clear_Click(entity btn, entity me) -{ - me.setText(me, ""); -} - -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) - { - if (over_ClearButton(me, pos)) - { - me.cb_focused = 1; - return 1; - } - me.cb_focused = 0; - } - return 1; -} - -float InputBox_mouseDrag(entity me, vector pos) -{ - 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 InputBox_mousePress(entity me, vector pos) -{ - 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); -} - -float InputBox_mouseRelease(entity me, vector pos) -{ - if(me.cb_pressed) - if (over_ClearButton(me, pos)) - { - me.cb_pressed = 0; - InputBox_Clear_Click(world, me); - 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) - { - 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); -} - -float InputBox_keyDown(entity me, float key, float ascii, float shift) -{ - me.lastChangeTime = time; - me.dragScrollTimer = time; - if(ascii >= 32 && ascii != 127) - { - me.enterText(me, chr(ascii)); - return 1; - } - switch(key) - { - 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); - 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) - 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; -} - -void InputBox_draw(entity me) -{ - string CURSOR = "_"; - float cursorPosInWidths, totalSizeInWidths; - - if(me.pressed) - me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event - - if(me.recalcPos) - me.recalcPositionWithText(me, me.text); - - 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); - } - - 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); - - 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) - { - ch = substring(me.text, i, 1); - if(ch == "^") - { - 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? - { - 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 - { - theColor = '1 1 1'; - - component = HEXDIGIT_TO_DEC(substring(me.text, i+2, 1)); - if (component >= 0) // ^xr found - { - theTempColor_x = component/15; - - component = HEXDIGIT_TO_DEC(substring(me.text, i+3, 1)); - if (component >= 0) // ^xrg found - { - 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 - { - // 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 - { - // 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 - { - 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); - } - } - 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); - - 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); - } - - // skipping SUPER(InputBox).draw(me); - Item_draw(me); -} - -void InputBox_showNotify(entity me) -{ - me.focusable = !me.disabled; -} -#endif diff --git a/qcsrc/menu/item/inputbox.qc b/qcsrc/menu/item/inputbox.qc new file mode 100644 index 000000000..7708a0d7f --- /dev/null +++ b/qcsrc/menu/item/inputbox.qc @@ -0,0 +1,391 @@ +#ifdef INTERFACE +CLASS(InputBox) EXTENDS(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, 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) +void InputBox_Clear_Click(entity btn, entity me); +#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) + { + 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; + } +} + +void InputBox_setText(entity me, string txt) +{ + if(me.text) + strunzone(me.text); + SUPER(InputBox).setText(me, strzone(txt)); +} + +void InputBox_Clear_Click(entity btn, entity me) +{ + me.setText(me, ""); +} + +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) + { + if (over_ClearButton(me, pos)) + { + me.cb_focused = 1; + return 1; + } + me.cb_focused = 0; + } + return 1; +} + +float InputBox_mouseDrag(entity me, vector pos) +{ + 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 InputBox_mousePress(entity me, vector pos) +{ + 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); +} + +float InputBox_mouseRelease(entity me, vector pos) +{ + if(me.cb_pressed) + if (over_ClearButton(me, pos)) + { + me.cb_pressed = 0; + InputBox_Clear_Click(world, me); + 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) + { + 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); +} + +float InputBox_keyDown(entity me, float key, float ascii, float shift) +{ + me.lastChangeTime = time; + me.dragScrollTimer = time; + if(ascii >= 32 && ascii != 127) + { + me.enterText(me, chr(ascii)); + return 1; + } + switch(key) + { + 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); + 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) + 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; +} + +void InputBox_draw(entity me) +{ + string CURSOR = "_"; + float cursorPosInWidths, totalSizeInWidths; + + if(me.pressed) + me.mouseDrag(me, me.dragScrollPos); // simulate mouseDrag event + + if(me.recalcPos) + me.recalcPositionWithText(me, me.text); + + 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); + } + + 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); + + 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) + { + ch = substring(me.text, i, 1); + if(ch == "^") + { + 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? + { + 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 + { + theColor = '1 1 1'; + + component = HEXDIGIT_TO_DEC(substring(me.text, i+2, 1)); + if (component >= 0) // ^xr found + { + theTempColor_x = component/15; + + component = HEXDIGIT_TO_DEC(substring(me.text, i+3, 1)); + if (component >= 0) // ^xrg found + { + 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 + { + // 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 + { + // 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 + { + 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); + } + } + 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); + + 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); + } + + // skipping SUPER(InputBox).draw(me); + Item_draw(me); +} + +void InputBox_showNotify(entity me) +{ + me.focusable = !me.disabled; +} +#endif diff --git a/qcsrc/menu/item/inputcontainer.c b/qcsrc/menu/item/inputcontainer.c deleted file mode 100644 index 0f80c2b50..000000000 --- a/qcsrc/menu/item/inputcontainer.c +++ /dev/null @@ -1,166 +0,0 @@ -#ifdef INTERFACE -CLASS(InputContainer) EXTENDS(Container) - METHOD(InputContainer, keyDown, float(entity, float, float, float)) - METHOD(InputContainer, mouseMove, float(entity, vector)) - METHOD(InputContainer, mousePress, float(entity, vector)) - METHOD(InputContainer, mouseRelease, float(entity, vector)) - METHOD(InputContainer, mouseDrag, float(entity, vector)) - METHOD(InputContainer, focusLeave, void(entity)) - METHOD(InputContainer, resizeNotify, void(entity, vector, vector, vector, vector)) - - METHOD(InputContainer, _changeFocusXY, float(entity, vector)) - ATTRIB(InputContainer, mouseFocusedChild, entity, NULL) - ATTRIB(InputContainer, isTabRoot, float, 0) -ENDCLASS(InputContainer) -#endif - -#ifdef IMPLEMENTATION -void InputContainer_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(InputContainer).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - /* - if(me.parent.instanceOfInputContainer) - me.isTabRoot = 0; - else - me.isTabRoot = 1; - */ -} - -void InputContainer_focusLeave(entity me) -{ - SUPER(InputContainer).focusLeave(me); - me.mouseFocusedChild = NULL; -} - -float InputContainer_keyDown(entity me, float scan, float ascii, float shift) -{ - entity f, ff; - if(SUPER(InputContainer).keyDown(me, scan, ascii, shift)) - return 1; - if(scan == K_ESCAPE) - { - f = me.focusedChild; - if(f) - { - me.setFocus(me, NULL); - return 1; - } - return 0; - } - if(scan == K_TAB) - { - f = me.focusedChild; - if(shift & S_SHIFT) - { - if(f) - { - for(ff = f.prevSibling; ff; ff = ff.prevSibling) - { - if (!ff.focusable) - continue; - me.setFocus(me, ff); - return 1; - } - } - if(!f || me.isTabRoot) - { - for(ff = me.lastChild; ff; ff = ff.prevSibling) - { - if (!ff.focusable) - continue; - me.setFocus(me, ff); - return 1; - } - return 0; // AIIIIEEEEE! - } - } - else - { - if(f) - { - 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 (!ff.focusable) - continue; - me.setFocus(me, ff); - return 1; - } - return 0; // AIIIIEEEEE! - } - } - } - return 0; -} - -float InputContainer__changeFocusXY(entity me, vector pos) -{ - entity e, ne; - e = me.mouseFocusedChild; - ne = me.itemFromPoint(me, pos); - if(ne) - if (!ne.focusable) - ne = NULL; - me.mouseFocusedChild = ne; - if(ne) - if(ne != e) - { - me.setFocus(me, ne); - if(ne.instanceOfInputContainer) - { - ne.focusedChild = NULL; - ne._changeFocusXY(e, globalToBox(pos, ne.Container_origin, ne.Container_size)); - } - } - return (ne != NULL); -} - -float InputContainer_mouseDrag(entity me, vector pos) -{ - if(SUPER(InputContainer).mouseDrag(me, pos)) - return 1; - if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) - return 1; - return 0; -} -float InputContainer_mouseMove(entity me, vector pos) -{ - if(me.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/inputcontainer.qc b/qcsrc/menu/item/inputcontainer.qc new file mode 100644 index 000000000..0f80c2b50 --- /dev/null +++ b/qcsrc/menu/item/inputcontainer.qc @@ -0,0 +1,166 @@ +#ifdef INTERFACE +CLASS(InputContainer) EXTENDS(Container) + METHOD(InputContainer, keyDown, float(entity, float, float, float)) + METHOD(InputContainer, mouseMove, float(entity, vector)) + METHOD(InputContainer, mousePress, float(entity, vector)) + METHOD(InputContainer, mouseRelease, float(entity, vector)) + METHOD(InputContainer, mouseDrag, float(entity, vector)) + METHOD(InputContainer, focusLeave, void(entity)) + METHOD(InputContainer, resizeNotify, void(entity, vector, vector, vector, vector)) + + METHOD(InputContainer, _changeFocusXY, float(entity, vector)) + ATTRIB(InputContainer, mouseFocusedChild, entity, NULL) + ATTRIB(InputContainer, isTabRoot, float, 0) +ENDCLASS(InputContainer) +#endif + +#ifdef IMPLEMENTATION +void InputContainer_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(InputContainer).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + /* + if(me.parent.instanceOfInputContainer) + me.isTabRoot = 0; + else + me.isTabRoot = 1; + */ +} + +void InputContainer_focusLeave(entity me) +{ + SUPER(InputContainer).focusLeave(me); + me.mouseFocusedChild = NULL; +} + +float InputContainer_keyDown(entity me, float scan, float ascii, float shift) +{ + entity f, ff; + if(SUPER(InputContainer).keyDown(me, scan, ascii, shift)) + return 1; + if(scan == K_ESCAPE) + { + f = me.focusedChild; + if(f) + { + me.setFocus(me, NULL); + return 1; + } + return 0; + } + if(scan == K_TAB) + { + f = me.focusedChild; + if(shift & S_SHIFT) + { + if(f) + { + for(ff = f.prevSibling; ff; ff = ff.prevSibling) + { + if (!ff.focusable) + continue; + me.setFocus(me, ff); + return 1; + } + } + if(!f || me.isTabRoot) + { + for(ff = me.lastChild; ff; ff = ff.prevSibling) + { + if (!ff.focusable) + continue; + me.setFocus(me, ff); + return 1; + } + return 0; // AIIIIEEEEE! + } + } + else + { + if(f) + { + 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 (!ff.focusable) + continue; + me.setFocus(me, ff); + return 1; + } + return 0; // AIIIIEEEEE! + } + } + } + return 0; +} + +float InputContainer__changeFocusXY(entity me, vector pos) +{ + entity e, ne; + e = me.mouseFocusedChild; + ne = me.itemFromPoint(me, pos); + if(ne) + if (!ne.focusable) + ne = NULL; + me.mouseFocusedChild = ne; + if(ne) + if(ne != e) + { + me.setFocus(me, ne); + if(ne.instanceOfInputContainer) + { + ne.focusedChild = NULL; + ne._changeFocusXY(e, globalToBox(pos, ne.Container_origin, ne.Container_size)); + } + } + return (ne != NULL); +} + +float InputContainer_mouseDrag(entity me, vector pos) +{ + if(SUPER(InputContainer).mouseDrag(me, pos)) + return 1; + if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) + return 1; + return 0; +} +float InputContainer_mouseMove(entity me, vector pos) +{ + if(me.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.c b/qcsrc/menu/item/label.c deleted file mode 100644 index 592c3a7ac..000000000 --- a/qcsrc/menu/item/label.c +++ /dev/null @@ -1,213 +0,0 @@ -#ifdef INTERFACE -CLASS(Label) EXTENDS(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) - { - if(me.currentText) - strunzone(me.currentText); - me.currentText = strzone(txt); - me.recalcPos = 1; - } -} -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) - { - 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; - dprintf("NOTE: label text %s too wide for label, condensed by factor %f\n", t, me.condenseFactor); - } - - if(!me.overrideRealOrigin_y) - { - float lines; - vector dfs; - vector fs; - - // 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 - lines = 1; - else if(me.allowWrap) // FIXME allowWrap incompatible with align != 0 - { - 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; - } - } - 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 = me.fontSize / absSize_y; - me.realFontSize_x = 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/label.qc b/qcsrc/menu/item/label.qc new file mode 100644 index 000000000..592c3a7ac --- /dev/null +++ b/qcsrc/menu/item/label.qc @@ -0,0 +1,213 @@ +#ifdef INTERFACE +CLASS(Label) EXTENDS(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) + { + if(me.currentText) + strunzone(me.currentText); + me.currentText = strzone(txt); + me.recalcPos = 1; + } +} +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) + { + 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; + dprintf("NOTE: label text %s too wide for label, condensed by factor %f\n", t, me.condenseFactor); + } + + if(!me.overrideRealOrigin_y) + { + float lines; + vector dfs; + vector fs; + + // 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 + lines = 1; + else if(me.allowWrap) // FIXME allowWrap incompatible with align != 0 + { + 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; + } + } + 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 = me.fontSize / absSize_y; + me.realFontSize_x = 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.c b/qcsrc/menu/item/listbox.c deleted file mode 100644 index 275b99735..000000000 --- a/qcsrc/menu/item/listbox.c +++ /dev/null @@ -1,402 +0,0 @@ -#ifdef INTERFACE -CLASS(ListBox) EXTENDS(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, 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, selectedItem, float, 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, 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, dragScrollTimer, float, 0) - ATTRIB(ListBox, dragScrollPos, vector, '0 0 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) - - METHOD(ListBox, drawListBoxItem, void(entity, float, vector, float)) // item number, width/height, selected - 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, 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) -#endif - -#ifdef IMPLEMENTATION -void ListBox_setSelected(entity me, float i) -{ - me.selectedItem = bound(0, i, me.nItems - 1); -} -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_getLastFullyVisibleItemAtScrollPos(entity me, float pos) -{ - return me.getItemAtPos(me, pos + 1.001) - 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) -{ - me.dragScrollTimer = time; - if(key == K_MWHEELUP) - { - me.scrollPos = max(me.scrollPos - 0.5, 0); - me.setSelected(me, min(me.selectedItem, me.getLastFullyVisibleItemAtScrollPos(me, me.scrollPos))); - } - else if(key == K_MWHEELDOWN) - { - me.scrollPos = min(me.scrollPos + 0.5, me.getTotalHeight(me) - 1); - me.setSelected(me, max(me.selectedItem, me.getFirstFullyVisibleItemAtScrollPos(me, me.scrollPos))); - } - else if(key == K_PGUP || key == K_KP_PGUP) - { - 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) - { - 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); - } - else if(key == K_UPARROW || key == K_KP_UPARROW) - me.setSelected(me, me.selectedItem - 1); - else if(key == K_DOWNARROW || key == K_KP_DOWNARROW) - me.setSelected(me, me.selectedItem + 1); - else if(key == K_HOME || key == K_KP_HOME) - { - me.scrollPos = 0; - me.setSelected(me, 0); - } - else if(key == K_END || key == K_KP_END) - { - me.scrollPos = max(0, me.getTotalHeight(me) - 1); - me.setSelected(me, me.nItems - 1); - } - else - return 0; - return 1; -} -float ListBox_mouseDrag(entity me, vector pos) -{ - float hit; - float i; - 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.scrollPos = me.previousValue + d; - } - else - me.scrollPos = me.previousValue; - me.scrollPos = min(me.scrollPos, me.getTotalHeight(me) - 1); - me.scrollPos = max(me.scrollPos, 0); - i = min(me.selectedItem, me.getLastFullyVisibleItemAtScrollPos(me, me.scrollPos)); - i = max(i, ListBox_getFirstFullyVisibleItemAtScrollPos(me, me.scrollPos)); - me.setSelected(me, i); - } - else if(me.pressed == 2) - { - me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos_y)); - } - 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); - me.dragScrollTimer = time; - if(pos_x >= 1 - me.controlWidth) - { - // if hit, set me.pressed, otherwise scroll by one page - if(pos_y < me.controlTop) - { - // page up - me.scrollPos = max(me.scrollPos - 1, 0); - me.setSelected(me, min(me.selectedItem, ListBox_getLastFullyVisibleItemAtScrollPos(me, me.scrollPos))); - } - else if(pos_y > me.controlBottom) - { - // page down - me.scrollPos = min(me.scrollPos + 1, me.getTotalHeight(me) - 1); - me.setSelected(me, max(me.selectedItem, ListBox_getFirstFullyVisibleItemAtScrollPos(me, me.scrollPos))); - } - else - { - me.pressed = 1; - me.pressOffset = pos_y; - me.previousValue = me.scrollPos; - } - } - 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)); - } - return 1; -} -float ListBox_mouseRelease(entity me, vector pos) -{ - if(me.pressed == 1) - { - // slider dragging mode - // in that case, nothing happens on releasing - } - else if(me.pressed == 2) - { - 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)); - // 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); - - me.lastClickedItem = me.selectedItem; - me.lastClickedTime = time; - } - } - 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; -} -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) - { - // 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(frametime) // only do this in draw frames - { - if(me.dragScrollTimer < time) - { - float save; - save = me.scrollPos; - // if selected item is below listbox, increase scrollpos so it is in - me.scrollPos = max(me.scrollPos, me.getItemStart(me, me.selectedItem) + me.getItemHeight(me, me.selectedItem) - 1); - // if selected item is above listbox, decrease scrollpos so it is in - me.scrollPos = min(me.scrollPos, me.getItemStart(me, me.selectedItem)); - if(me.scrollPos != save) - me.dragScrollTimer = time + 0.2; - } - } - // 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); - } - } -} -void ListBox_draw(entity me) -{ - float i; - vector absSize, fillSize = '0 0 0'; - vector oldshift, oldscale; - 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) - { - 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; - 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)); - y += relSize_y; - } - draw_ClearClip(); - - draw_shift = oldshift; - draw_scale = oldscale; - SUPER(ListBox).draw(me); -} - -void ListBox_clickListBoxItem(entity me, float i, vector where) -{ - // template method -} - -void ListBox_doubleClickListBoxItem(entity me, float i, vector where) -{ - // template method -} - -void ListBox_drawListBoxItem(entity me, float i, vector absSize, float selected) -{ - draw_Text('0 0 0', sprintf(_("Item %d"), i), eX * (8 / absSize_x) + eY * (8 / absSize_y), (selected ? '0 1 0' : '1 1 1'), 1, 0); -} -#endif diff --git a/qcsrc/menu/item/listbox.qc b/qcsrc/menu/item/listbox.qc new file mode 100644 index 000000000..275b99735 --- /dev/null +++ b/qcsrc/menu/item/listbox.qc @@ -0,0 +1,402 @@ +#ifdef INTERFACE +CLASS(ListBox) EXTENDS(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, 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, selectedItem, float, 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, 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, dragScrollTimer, float, 0) + ATTRIB(ListBox, dragScrollPos, vector, '0 0 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) + + METHOD(ListBox, drawListBoxItem, void(entity, float, vector, float)) // item number, width/height, selected + 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, 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) +#endif + +#ifdef IMPLEMENTATION +void ListBox_setSelected(entity me, float i) +{ + me.selectedItem = bound(0, i, me.nItems - 1); +} +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_getLastFullyVisibleItemAtScrollPos(entity me, float pos) +{ + return me.getItemAtPos(me, pos + 1.001) - 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) +{ + me.dragScrollTimer = time; + if(key == K_MWHEELUP) + { + me.scrollPos = max(me.scrollPos - 0.5, 0); + me.setSelected(me, min(me.selectedItem, me.getLastFullyVisibleItemAtScrollPos(me, me.scrollPos))); + } + else if(key == K_MWHEELDOWN) + { + me.scrollPos = min(me.scrollPos + 0.5, me.getTotalHeight(me) - 1); + me.setSelected(me, max(me.selectedItem, me.getFirstFullyVisibleItemAtScrollPos(me, me.scrollPos))); + } + else if(key == K_PGUP || key == K_KP_PGUP) + { + 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) + { + 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); + } + else if(key == K_UPARROW || key == K_KP_UPARROW) + me.setSelected(me, me.selectedItem - 1); + else if(key == K_DOWNARROW || key == K_KP_DOWNARROW) + me.setSelected(me, me.selectedItem + 1); + else if(key == K_HOME || key == K_KP_HOME) + { + me.scrollPos = 0; + me.setSelected(me, 0); + } + else if(key == K_END || key == K_KP_END) + { + me.scrollPos = max(0, me.getTotalHeight(me) - 1); + me.setSelected(me, me.nItems - 1); + } + else + return 0; + return 1; +} +float ListBox_mouseDrag(entity me, vector pos) +{ + float hit; + float i; + 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.scrollPos = me.previousValue + d; + } + else + me.scrollPos = me.previousValue; + me.scrollPos = min(me.scrollPos, me.getTotalHeight(me) - 1); + me.scrollPos = max(me.scrollPos, 0); + i = min(me.selectedItem, me.getLastFullyVisibleItemAtScrollPos(me, me.scrollPos)); + i = max(i, ListBox_getFirstFullyVisibleItemAtScrollPos(me, me.scrollPos)); + me.setSelected(me, i); + } + else if(me.pressed == 2) + { + me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos_y)); + } + 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); + me.dragScrollTimer = time; + if(pos_x >= 1 - me.controlWidth) + { + // if hit, set me.pressed, otherwise scroll by one page + if(pos_y < me.controlTop) + { + // page up + me.scrollPos = max(me.scrollPos - 1, 0); + me.setSelected(me, min(me.selectedItem, ListBox_getLastFullyVisibleItemAtScrollPos(me, me.scrollPos))); + } + else if(pos_y > me.controlBottom) + { + // page down + me.scrollPos = min(me.scrollPos + 1, me.getTotalHeight(me) - 1); + me.setSelected(me, max(me.selectedItem, ListBox_getFirstFullyVisibleItemAtScrollPos(me, me.scrollPos))); + } + else + { + me.pressed = 1; + me.pressOffset = pos_y; + me.previousValue = me.scrollPos; + } + } + 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)); + } + return 1; +} +float ListBox_mouseRelease(entity me, vector pos) +{ + if(me.pressed == 1) + { + // slider dragging mode + // in that case, nothing happens on releasing + } + else if(me.pressed == 2) + { + 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)); + // 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); + + me.lastClickedItem = me.selectedItem; + me.lastClickedTime = time; + } + } + 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; +} +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) + { + // 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(frametime) // only do this in draw frames + { + if(me.dragScrollTimer < time) + { + float save; + save = me.scrollPos; + // if selected item is below listbox, increase scrollpos so it is in + me.scrollPos = max(me.scrollPos, me.getItemStart(me, me.selectedItem) + me.getItemHeight(me, me.selectedItem) - 1); + // if selected item is above listbox, decrease scrollpos so it is in + me.scrollPos = min(me.scrollPos, me.getItemStart(me, me.selectedItem)); + if(me.scrollPos != save) + me.dragScrollTimer = time + 0.2; + } + } + // 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); + } + } +} +void ListBox_draw(entity me) +{ + float i; + vector absSize, fillSize = '0 0 0'; + vector oldshift, oldscale; + 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) + { + 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; + 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)); + y += relSize_y; + } + draw_ClearClip(); + + draw_shift = oldshift; + draw_scale = oldscale; + SUPER(ListBox).draw(me); +} + +void ListBox_clickListBoxItem(entity me, float i, vector where) +{ + // template method +} + +void ListBox_doubleClickListBoxItem(entity me, float i, vector where) +{ + // template method +} + +void ListBox_drawListBoxItem(entity me, float i, vector absSize, float selected) +{ + draw_Text('0 0 0', sprintf(_("Item %d"), i), eX * (8 / absSize_x) + eY * (8 / absSize_y), (selected ? '0 1 0' : '1 1 1'), 1, 0); +} +#endif diff --git a/qcsrc/menu/item/modalcontroller.c b/qcsrc/menu/item/modalcontroller.c deleted file mode 100644 index 8a025cb33..000000000 --- a/qcsrc/menu/item/modalcontroller.c +++ /dev/null @@ -1,293 +0,0 @@ -#ifdef INTERFACE -CLASS(ModalController) EXTENDS(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, 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 -#endif - -#ifdef IMPLEMENTATION - -// modal dialog controller -// handles a stack of dialog elements -// each element can have one of the following states: -// 0: hidden (fading out) -// 1: visible (zooming in) -// 2: greyed out (inactive) -// While an animation is running, no item has focus. When an animation is done, -// the topmost item gets focus. -// The items are assumed to be added in overlapping order, that is, the lowest -// window must get added first. -// -// Possible uses: -// - to control a modal dialog: -// - show modal dialog: me.showChild(me, childItem, buttonAbsOrigin, buttonAbsSize, 0) // childItem also gets focus -// - dismiss modal dialog: me.hideChild(me, childItem, 0) // childItem fades out and relinquishes focus -// - show first screen in m_show: me.hideAll(me, 1); me.showChild(me, me.firstChild, '0 0 0', '0 0 0', 1); -// - to show a temporary dialog instead of the menu (teamselect): me.hideAll(me, 1); me.showChild(me, teamSelectDialog, '0 0 0', '0 0 0', 1); -// - as a tabbed dialog control: -// - to initialize: me.hideAll(me, 1); me.showChild(me, me.firstChild, '0 0 0', '0 0 0', 1); -// - to show a tab: me.hideChild(me, currentTab, 0); me.showChild(me, newTab, buttonAbsOrigin, buttonAbsSize, 0); - -.vector ModalController_initialSize; -.vector ModalController_initialOrigin; -.vector ModalController_initialFontScale; -.float ModalController_initialAlpha; -.vector ModalController_buttonSize; -.vector ModalController_buttonOrigin; -.float ModalController_state; -.float ModalController_factor; -.entity ModalController_controllingButton; - -void ModalController_initializeDialog(entity me, entity root) -{ - me.hideAll(me, 1); - me.showChild(me, root, '0 0 0', '0 0 0', 1); // someone else animates for us -} - -void TabButton_Click(entity button, entity tab) -{ - if(tab.ModalController_state == 1) - return; - tab.parent.hideAll(tab.parent, 0); - button.forcePressed = 1; - tab.ModalController_controllingButton = button; - tab.parent.showChild(tab.parent, tab, button.origin, button.size, 0); -} - -void DialogOpenButton_Click(entity button, entity tab) -{ - DialogOpenButton_Click_withCoords(button, tab, button.origin, button.size); -} - -void 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 DialogCloseButton_Click(entity button, entity tab) -{ - tab.parent.hideChild(tab.parent, tab, 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); -} - -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) - { - 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(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; - - front = world; - 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) - { - f = (e.ModalController_factor = min(1, e.ModalController_factor + df)); - if(e.ModalController_state) - if(f < 1) - animating = 1; - - if(f < 1) - { - prevFactor = (1 - f) / (1 - f + df); - targetFactor = df / (1 - f + df); - } - else - { - prevFactor = 0; - targetFactor = 1; - } - - 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 - if(f < 1) - animating = 1; - targetOrigin = e.Container_origin; // stay as is - targetSize = e.Container_size; // stay as is - targetAlpha = 0; - } - - if(f == 1) - { - e.Container_origin = targetOrigin; - e.Container_size = targetSize; - me.setAlphaOf(me, e, targetAlpha); - } - else - { - e.Container_origin = e.Container_origin * prevFactor + targetOrigin * targetFactor; - e.Container_size = e.Container_size * prevFactor + targetSize * targetFactor; - me.setAlphaOf(me, e, e.Container_alpha * prevFactor + targetAlpha * targetFactor); - } - // assume: o == to * f_prev + X * (1 - f_prev) - // make: o' = to * f + X * (1 - f) - // --> - // X == (o - to * f_prev) / (1 - f_prev) - // o' = to * f + (o - to * f_prev) / (1 - f_prev) * (1 - f) - // --> (maxima) - // o' = (to * (f - f_prev) + o * (1 - f)) / (1 - f_prev) - - 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; - } - 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) - { - tabButton.forcePressed = 1; - other.ModalController_controllingButton = tabButton; - me.showChild(me, other, '0 0 0', '0 0 0', 1); - } -} - -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) - { - 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_hideChild(entity me, entity other, float skipAnimation) -{ - if(other.ModalController_state || skipAnimation) - { - 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/modalcontroller.qc b/qcsrc/menu/item/modalcontroller.qc new file mode 100644 index 000000000..8a025cb33 --- /dev/null +++ b/qcsrc/menu/item/modalcontroller.qc @@ -0,0 +1,293 @@ +#ifdef INTERFACE +CLASS(ModalController) EXTENDS(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, 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 +#endif + +#ifdef IMPLEMENTATION + +// modal dialog controller +// handles a stack of dialog elements +// each element can have one of the following states: +// 0: hidden (fading out) +// 1: visible (zooming in) +// 2: greyed out (inactive) +// While an animation is running, no item has focus. When an animation is done, +// the topmost item gets focus. +// The items are assumed to be added in overlapping order, that is, the lowest +// window must get added first. +// +// Possible uses: +// - to control a modal dialog: +// - show modal dialog: me.showChild(me, childItem, buttonAbsOrigin, buttonAbsSize, 0) // childItem also gets focus +// - dismiss modal dialog: me.hideChild(me, childItem, 0) // childItem fades out and relinquishes focus +// - show first screen in m_show: me.hideAll(me, 1); me.showChild(me, me.firstChild, '0 0 0', '0 0 0', 1); +// - to show a temporary dialog instead of the menu (teamselect): me.hideAll(me, 1); me.showChild(me, teamSelectDialog, '0 0 0', '0 0 0', 1); +// - as a tabbed dialog control: +// - to initialize: me.hideAll(me, 1); me.showChild(me, me.firstChild, '0 0 0', '0 0 0', 1); +// - to show a tab: me.hideChild(me, currentTab, 0); me.showChild(me, newTab, buttonAbsOrigin, buttonAbsSize, 0); + +.vector ModalController_initialSize; +.vector ModalController_initialOrigin; +.vector ModalController_initialFontScale; +.float ModalController_initialAlpha; +.vector ModalController_buttonSize; +.vector ModalController_buttonOrigin; +.float ModalController_state; +.float ModalController_factor; +.entity ModalController_controllingButton; + +void ModalController_initializeDialog(entity me, entity root) +{ + me.hideAll(me, 1); + me.showChild(me, root, '0 0 0', '0 0 0', 1); // someone else animates for us +} + +void TabButton_Click(entity button, entity tab) +{ + if(tab.ModalController_state == 1) + return; + tab.parent.hideAll(tab.parent, 0); + button.forcePressed = 1; + tab.ModalController_controllingButton = button; + tab.parent.showChild(tab.parent, tab, button.origin, button.size, 0); +} + +void DialogOpenButton_Click(entity button, entity tab) +{ + DialogOpenButton_Click_withCoords(button, tab, button.origin, button.size); +} + +void 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 DialogCloseButton_Click(entity button, entity tab) +{ + tab.parent.hideChild(tab.parent, tab, 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); +} + +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) + { + 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(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; + + front = world; + 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) + { + f = (e.ModalController_factor = min(1, e.ModalController_factor + df)); + if(e.ModalController_state) + if(f < 1) + animating = 1; + + if(f < 1) + { + prevFactor = (1 - f) / (1 - f + df); + targetFactor = df / (1 - f + df); + } + else + { + prevFactor = 0; + targetFactor = 1; + } + + 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 + if(f < 1) + animating = 1; + targetOrigin = e.Container_origin; // stay as is + targetSize = e.Container_size; // stay as is + targetAlpha = 0; + } + + if(f == 1) + { + e.Container_origin = targetOrigin; + e.Container_size = targetSize; + me.setAlphaOf(me, e, targetAlpha); + } + else + { + e.Container_origin = e.Container_origin * prevFactor + targetOrigin * targetFactor; + e.Container_size = e.Container_size * prevFactor + targetSize * targetFactor; + me.setAlphaOf(me, e, e.Container_alpha * prevFactor + targetAlpha * targetFactor); + } + // assume: o == to * f_prev + X * (1 - f_prev) + // make: o' = to * f + X * (1 - f) + // --> + // X == (o - to * f_prev) / (1 - f_prev) + // o' = to * f + (o - to * f_prev) / (1 - f_prev) * (1 - f) + // --> (maxima) + // o' = (to * (f - f_prev) + o * (1 - f)) / (1 - f_prev) + + 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; + } + 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) + { + tabButton.forcePressed = 1; + other.ModalController_controllingButton = tabButton; + me.showChild(me, other, '0 0 0', '0 0 0', 1); + } +} + +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) + { + 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_hideChild(entity me, entity other, float skipAnimation) +{ + if(other.ModalController_state || skipAnimation) + { + 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.c b/qcsrc/menu/item/nexposee.c deleted file mode 100644 index ca7ab8fc3..000000000 --- a/qcsrc/menu/item/nexposee.c +++ /dev/null @@ -1,363 +0,0 @@ -#ifdef INTERFACE -CLASS(Nexposee) EXTENDS(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 -#endif - -// animation states: -// 0 = thumbnails seen -// 1 = zooming in -// 2 = zoomed in -// 3 = zooming out -// animation factor: 0 = minimum theSize, 1 = maximum theSize - -#ifdef IMPLEMENTATION - -.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; - -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) - { - 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; - } -} - -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); - - 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 - } - - scale *= 0.95; - - Nexposee_Calc_Scale(me, scale); -} - -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; -} - -void Nexposee_draw(entity me) -{ - 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; - 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; - } - else - { - // 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); - } - 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); -} - -float Nexposee_mousePress(entity me, vector pos) -{ - if(me.animationState == 0) - { - me.mouseFocusedChild = NULL; - Nexposee_mouseMove(me, pos); - if(me.mouseFocusedChild) - { - me.animationState = 1; - SUPER(Nexposee).setFocus(me, NULL); - } - else - me.close(me); - return 1; - } - else if(me.animationState == 2) - { - if (!(SUPER(Nexposee).mousePress(me, pos))) - { - me.animationState = 3; - SUPER(Nexposee).setFocus(me, NULL); - } - return 1; - } - 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) - { - if(me.mouseFocusedChild) - if(me.mouseFocusedChild != e || me.mouseFocusedChild != me.selectedChild) - me.selectedChild = me.mouseFocusedChild; - return 1; - } - 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) - { - if(me.animationState == 0) - { - 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) - { - default: - case 0: - case 3: - me.animationState = 1; - break; - case 1: - case 2: - 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; -} -#endif diff --git a/qcsrc/menu/item/nexposee.qc b/qcsrc/menu/item/nexposee.qc new file mode 100644 index 000000000..ca7ab8fc3 --- /dev/null +++ b/qcsrc/menu/item/nexposee.qc @@ -0,0 +1,363 @@ +#ifdef INTERFACE +CLASS(Nexposee) EXTENDS(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 +#endif + +// animation states: +// 0 = thumbnails seen +// 1 = zooming in +// 2 = zoomed in +// 3 = zooming out +// animation factor: 0 = minimum theSize, 1 = maximum theSize + +#ifdef IMPLEMENTATION + +.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; + +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) + { + 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; + } +} + +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); + + 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 + } + + scale *= 0.95; + + Nexposee_Calc_Scale(me, scale); +} + +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; +} + +void Nexposee_draw(entity me) +{ + 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; + 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; + } + else + { + // 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); + } + 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); +} + +float Nexposee_mousePress(entity me, vector pos) +{ + if(me.animationState == 0) + { + me.mouseFocusedChild = NULL; + Nexposee_mouseMove(me, pos); + if(me.mouseFocusedChild) + { + me.animationState = 1; + SUPER(Nexposee).setFocus(me, NULL); + } + else + me.close(me); + return 1; + } + else if(me.animationState == 2) + { + if (!(SUPER(Nexposee).mousePress(me, pos))) + { + me.animationState = 3; + SUPER(Nexposee).setFocus(me, NULL); + } + return 1; + } + 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) + { + if(me.mouseFocusedChild) + if(me.mouseFocusedChild != e || me.mouseFocusedChild != me.selectedChild) + me.selectedChild = me.mouseFocusedChild; + return 1; + } + 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) + { + if(me.animationState == 0) + { + 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) + { + default: + case 0: + case 3: + me.animationState = 1; + break; + case 1: + case 2: + 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; +} +#endif diff --git a/qcsrc/menu/item/radiobutton.c b/qcsrc/menu/item/radiobutton.c deleted file mode 100644 index 80fd5329b..000000000 --- a/qcsrc/menu/item/radiobutton.c +++ /dev/null @@ -1,37 +0,0 @@ -#ifdef INTERFACE -void RadioButton_Click(entity me, entity other); -CLASS(RadioButton) EXTENDS(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) - { - 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/radiobutton.qc b/qcsrc/menu/item/radiobutton.qc new file mode 100644 index 000000000..80fd5329b --- /dev/null +++ b/qcsrc/menu/item/radiobutton.qc @@ -0,0 +1,37 @@ +#ifdef INTERFACE +void RadioButton_Click(entity me, entity other); +CLASS(RadioButton) EXTENDS(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) + { + 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.c b/qcsrc/menu/item/slider.c deleted file mode 100644 index c92db27e9..000000000 --- a/qcsrc/menu/item/slider.c +++ /dev/null @@ -1,285 +0,0 @@ -// Note: -// to use this, you FIRST call configureSliderVisuals, then configureSliderValues -#ifdef INTERFACE -CLASS(Slider) EXTENDS(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, mousePress, float(entity, vector)) - METHOD(Slider, mouseDrag, float(entity, vector)) - METHOD(Slider, mouseRelease, float(entity, vector)) - METHOD(Slider, focusEnter, void(entity)) - METHOD(Slider, valueToText, string(entity, float)) - METHOD(Slider, toString, string(entity)) - 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, value, float, 0) - ATTRIB(Slider, animated, float, 1) - ATTRIB(Slider, sliderValue, float, 0) - 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(entity me, float val) -{ - if (me.animated) { - anim.removeObjAnim(anim, me); - makeHostedEasing(me, Slider_setSliderValue, easingQuadInOut, 1, me.sliderValue, val); - } else { - me.setSliderValue(me, val); - } - me.value = val; -} -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_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) - { - if(inRange) - me.setValue(me, median(me.valueMin, me.value - me.valueKeyStep, me.valueMax)); - else - me.setValue(me, me.valueMax); - return 1; - } - 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 - return 0; -} -float Slider_mouseDrag(entity me, vector pos) -{ - float hit; - float v, animed; - if(me.disabled) - return 0; - - anim.removeObjAnim(anim, me); - animed = me.animated; - me.animated = false; - - if(me.pressed) - { - 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) - { - 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(me, v); - } - else - me.setValue(me, me.previousValue); - } - - me.animated = animed; - - 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) - { - me.pressed = 1; - me.pressOffset = pos_x - controlCenter; - me.previousValue = me.value; - //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; -} -float Slider_mouseRelease(entity me, vector pos) -{ - me.pressed = 0; - if(me.disabled) - return 0; - if(cvar("menu_sounds")) - localsound("sound/misc/menu2.wav"); - return 1; -} -void Slider_showNotify(entity me) -{ - me.focusable = !me.disabled; -} -void Slider_focusEnter(entity me) -{ - if(cvar("menu_sounds") > 1) - localsound("sound/misc/menu1.wav"); - SUPER(Slider).focusEnter(me); -} -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! -} -#endif diff --git a/qcsrc/menu/item/slider.qc b/qcsrc/menu/item/slider.qc new file mode 100644 index 000000000..c92db27e9 --- /dev/null +++ b/qcsrc/menu/item/slider.qc @@ -0,0 +1,285 @@ +// Note: +// to use this, you FIRST call configureSliderVisuals, then configureSliderValues +#ifdef INTERFACE +CLASS(Slider) EXTENDS(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, mousePress, float(entity, vector)) + METHOD(Slider, mouseDrag, float(entity, vector)) + METHOD(Slider, mouseRelease, float(entity, vector)) + METHOD(Slider, focusEnter, void(entity)) + METHOD(Slider, valueToText, string(entity, float)) + METHOD(Slider, toString, string(entity)) + 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, value, float, 0) + ATTRIB(Slider, animated, float, 1) + ATTRIB(Slider, sliderValue, float, 0) + 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(entity me, float val) +{ + if (me.animated) { + anim.removeObjAnim(anim, me); + makeHostedEasing(me, Slider_setSliderValue, easingQuadInOut, 1, me.sliderValue, val); + } else { + me.setSliderValue(me, val); + } + me.value = val; +} +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_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) + { + if(inRange) + me.setValue(me, median(me.valueMin, me.value - me.valueKeyStep, me.valueMax)); + else + me.setValue(me, me.valueMax); + return 1; + } + 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 + return 0; +} +float Slider_mouseDrag(entity me, vector pos) +{ + float hit; + float v, animed; + if(me.disabled) + return 0; + + anim.removeObjAnim(anim, me); + animed = me.animated; + me.animated = false; + + if(me.pressed) + { + 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) + { + 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(me, v); + } + else + me.setValue(me, me.previousValue); + } + + me.animated = animed; + + 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) + { + me.pressed = 1; + me.pressOffset = pos_x - controlCenter; + me.previousValue = me.value; + //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; +} +float Slider_mouseRelease(entity me, vector pos) +{ + me.pressed = 0; + if(me.disabled) + return 0; + if(cvar("menu_sounds")) + localsound("sound/misc/menu2.wav"); + return 1; +} +void Slider_showNotify(entity me) +{ + me.focusable = !me.disabled; +} +void Slider_focusEnter(entity me) +{ + if(cvar("menu_sounds") > 1) + localsound("sound/misc/menu1.wav"); + SUPER(Slider).focusEnter(me); +} +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! +} +#endif diff --git a/qcsrc/menu/item/tab.c b/qcsrc/menu/item/tab.c deleted file mode 100644 index 8cd72ba9c..000000000 --- a/qcsrc/menu/item/tab.c +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef INTERFACE -CLASS(Tab) EXTENDS(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) - - 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) -#endif - -#ifdef IMPLEMENTATION -#endif diff --git a/qcsrc/menu/item/tab.qc b/qcsrc/menu/item/tab.qc new file mode 100644 index 000000000..8cd72ba9c --- /dev/null +++ b/qcsrc/menu/item/tab.qc @@ -0,0 +1,28 @@ +#ifdef INTERFACE +CLASS(Tab) EXTENDS(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) + + 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) +#endif + +#ifdef IMPLEMENTATION +#endif diff --git a/qcsrc/menu/item/textslider.c b/qcsrc/menu/item/textslider.c deleted file mode 100644 index 59d8c10db..000000000 --- a/qcsrc/menu/item/textslider.c +++ /dev/null @@ -1,78 +0,0 @@ -// Note: -// to use this, you FIRST call configureSliderVisuals, then multiple times addValue, then configureTextSlider -#ifdef INTERFACE -CLASS(TextSlider) EXTENDS(Slider) - METHOD(TextSlider, valueToText, string(entity, float)) - METHOD(TextSlider, valueToIdentifier, string(entity, float)) - 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, float, 0) -ENDCLASS(TextSlider) -#endif - -#ifdef IMPLEMENTATION -string TextSlider_valueToIdentifier(entity me, float val) -{ - if(val >= me.nValues) - return "custom"; - if(val < 0) - return "custom"; - return me.(valueIdentifiers[val]); -} -string TextSlider_valueToText(entity me, float val) -{ - if(val >= me.nValues) - return _("Custom"); - if(val < 0) - return _("Custom"); - return me.(valueStrings[val]); -} -void TextSlider_setValueFromIdentifier(entity me, string id) -{ - float i; - for(i = 0; i < me.nValues; ++i) - if(me.valueToIdentifier(me, i) == id) - { - SUPER(TextSlider).setValue( me, i ); - return; - } - SUPER(TextSlider).setValue( me, -1 ); -} -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, float pos, string theString, string theIdentifier) -{ - float i; - for (i = me.nValues; i > pos; --i) - { - me.(valueStrings[i]) = me.(valueStrings[i-1]); - me.(valueIdentifiers[i]) = me.(valueIdentifiers[i-1]); - } - 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(me, theDefault); -} -#endif diff --git a/qcsrc/menu/item/textslider.qc b/qcsrc/menu/item/textslider.qc new file mode 100644 index 000000000..59d8c10db --- /dev/null +++ b/qcsrc/menu/item/textslider.qc @@ -0,0 +1,78 @@ +// Note: +// to use this, you FIRST call configureSliderVisuals, then multiple times addValue, then configureTextSlider +#ifdef INTERFACE +CLASS(TextSlider) EXTENDS(Slider) + METHOD(TextSlider, valueToText, string(entity, float)) + METHOD(TextSlider, valueToIdentifier, string(entity, float)) + 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, float, 0) +ENDCLASS(TextSlider) +#endif + +#ifdef IMPLEMENTATION +string TextSlider_valueToIdentifier(entity me, float val) +{ + if(val >= me.nValues) + return "custom"; + if(val < 0) + return "custom"; + return me.(valueIdentifiers[val]); +} +string TextSlider_valueToText(entity me, float val) +{ + if(val >= me.nValues) + return _("Custom"); + if(val < 0) + return _("Custom"); + return me.(valueStrings[val]); +} +void TextSlider_setValueFromIdentifier(entity me, string id) +{ + float i; + for(i = 0; i < me.nValues; ++i) + if(me.valueToIdentifier(me, i) == id) + { + SUPER(TextSlider).setValue( me, i ); + return; + } + SUPER(TextSlider).setValue( me, -1 ); +} +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, float pos, string theString, string theIdentifier) +{ + float i; + for (i = me.nValues; i > pos; --i) + { + me.(valueStrings[i]) = me.(valueStrings[i-1]); + me.(valueIdentifiers[i]) = me.(valueIdentifiers[i-1]); + } + 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(me, theDefault); +} +#endif diff --git a/qcsrc/menu/oo/base.h b/qcsrc/menu/oo/base.h deleted file mode 100644 index ed4eba5a1..000000000 --- a/qcsrc/menu/oo/base.h +++ /dev/null @@ -1,27 +0,0 @@ -.string classname; -entity Object_vtbl; -.string vtblname; -.entity vtblbase; -// THIS LINE INTENTIONALLY LEFT BLANK -entity spawnVtbl(entity e, entity b) -{ - entity v; - v = spawn(); - copyentity(e, v); - v.vtblname = v.classname; - v.classname = "vtbl"; - if(b) - v.vtblbase = b; - else - v.vtblbase = v; - return v; -} -entity spawnObject() -{ - entity e; - e = spawn(); - e.classname = "Object"; - if(!Object_vtbl) - Object_vtbl = spawnVtbl(e, null_entity); - return e; -} diff --git a/qcsrc/menu/oo/base.qh b/qcsrc/menu/oo/base.qh new file mode 100644 index 000000000..ed4eba5a1 --- /dev/null +++ b/qcsrc/menu/oo/base.qh @@ -0,0 +1,27 @@ +.string classname; +entity Object_vtbl; +.string vtblname; +.entity vtblbase; +// THIS LINE INTENTIONALLY LEFT BLANK +entity spawnVtbl(entity e, entity b) +{ + entity v; + v = spawn(); + copyentity(e, v); + v.vtblname = v.classname; + v.classname = "vtbl"; + if(b) + v.vtblbase = b; + else + v.vtblbase = v; + return v; +} +entity spawnObject() +{ + entity e; + e = spawn(); + e.classname = "Object"; + if(!Object_vtbl) + Object_vtbl = spawnVtbl(e, null_entity); + return e; +} diff --git a/qcsrc/menu/oo/implementation.h b/qcsrc/menu/oo/implementation.h deleted file mode 100644 index 28b7f08e4..000000000 --- a/qcsrc/menu/oo/implementation.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef INTERFACE -#define INTERFACE -#endif - -#ifndef IMPLEMENTATION -#define IMPLEMENTATION -#endif - -#ifdef CLASS -#undef CLASS -#undef EXTENDS -#undef METHOD -#undef ATTRIB -#undef ATTRIBARRAY -#undef ENDCLASS -#undef SUPER -#endif - -// for the constructor -#define CLASS(cname) entity spawn##cname() { entity me; -#define EXTENDS(base) me = spawn##base (); entity basevtbl; basevtbl = base##_vtbl; -#define METHOD(cname,name,prototype) me.name = cname##_##name; -#define ATTRIB(cname,name,type,val) me.name = val; -#define ATTRIBARRAY(cname,name,type,cnt) -#define ENDCLASS(cname) me.instanceOf##cname = 1; me.classname = #cname; if(!cname##_vtbl) cname##_vtbl = spawnVtbl(me, basevtbl); return me; } - -// for the implementation -#define SUPER(cname) (cname##_vtbl.vtblbase) diff --git a/qcsrc/menu/oo/implementation.qh b/qcsrc/menu/oo/implementation.qh new file mode 100644 index 000000000..28b7f08e4 --- /dev/null +++ b/qcsrc/menu/oo/implementation.qh @@ -0,0 +1,28 @@ +#ifndef INTERFACE +#define INTERFACE +#endif + +#ifndef IMPLEMENTATION +#define IMPLEMENTATION +#endif + +#ifdef CLASS +#undef CLASS +#undef EXTENDS +#undef METHOD +#undef ATTRIB +#undef ATTRIBARRAY +#undef ENDCLASS +#undef SUPER +#endif + +// for the constructor +#define CLASS(cname) entity spawn##cname() { entity me; +#define EXTENDS(base) me = spawn##base (); entity basevtbl; basevtbl = base##_vtbl; +#define METHOD(cname,name,prototype) me.name = cname##_##name; +#define ATTRIB(cname,name,type,val) me.name = val; +#define ATTRIBARRAY(cname,name,type,cnt) +#define ENDCLASS(cname) me.instanceOf##cname = 1; me.classname = #cname; if(!cname##_vtbl) cname##_vtbl = spawnVtbl(me, basevtbl); return me; } + +// for the implementation +#define SUPER(cname) (cname##_vtbl.vtblbase) diff --git a/qcsrc/menu/oo/interface.h b/qcsrc/menu/oo/interface.h deleted file mode 100644 index 1e122066c..000000000 --- a/qcsrc/menu/oo/interface.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef INTERFACE -#define INTERFACE -#endif - -#ifdef IMPLEMENTATION -#undef IMPLEMENTATION -#endif - -#ifdef CLASS -#undef CLASS -#undef EXTENDS -#undef METHOD -#undef ATTRIB -#undef ATTRIBARRAY -#undef ENDCLASS -#undef SUPER -#endif - -#define CLASS(cname) entity spawn##cname(); entity cname##_vtbl; -#define EXTENDS(base) -#define METHOD(cname,name,prototype) prototype cname##_##name; .prototype name; -#define ATTRIB(cname,name,type,val) .type name; -#define ATTRIBARRAY(cname,name,type,cnt) .type name[cnt]; -#define ENDCLASS(cname) .float instanceOf##cname; -#define SUPER(cname) diff --git a/qcsrc/menu/oo/interface.qh b/qcsrc/menu/oo/interface.qh new file mode 100644 index 000000000..1e122066c --- /dev/null +++ b/qcsrc/menu/oo/interface.qh @@ -0,0 +1,25 @@ +#ifndef INTERFACE +#define INTERFACE +#endif + +#ifdef IMPLEMENTATION +#undef IMPLEMENTATION +#endif + +#ifdef CLASS +#undef CLASS +#undef EXTENDS +#undef METHOD +#undef ATTRIB +#undef ATTRIBARRAY +#undef ENDCLASS +#undef SUPER +#endif + +#define CLASS(cname) entity spawn##cname(); entity cname##_vtbl; +#define EXTENDS(base) +#define METHOD(cname,name,prototype) prototype cname##_##name; .prototype name; +#define ATTRIB(cname,name,type,val) .type name; +#define ATTRIBARRAY(cname,name,type,cnt) .type name[cnt]; +#define ENDCLASS(cname) .float instanceOf##cname; +#define SUPER(cname) diff --git a/qcsrc/menu/progs.src b/qcsrc/menu/progs.src index 79b0f9023..3b1e46944 100644 --- a/qcsrc/menu/progs.src +++ b/qcsrc/menu/progs.src @@ -12,7 +12,7 @@ config.qh ../common/util.qh ../common/test.qh -oo/base.h +oo/base.qh ../common/playerstats.qh ../common/teams.qh @@ -34,10 +34,10 @@ draw.qh skin.qh xonotic/util.qh -oo/interface.h - classes.c -oo/implementation.h - classes.c +oo/interface.qh + classes.qc +oo/implementation.qh + classes.qc ../common/util.qc ../common/test.qc diff --git a/qcsrc/menu/xonotic/bigbutton.c b/qcsrc/menu/xonotic/bigbutton.c deleted file mode 100644 index a63189b63..000000000 --- a/qcsrc/menu/xonotic/bigbutton.c +++ /dev/null @@ -1,23 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticBigButton) EXTENDS(XonoticButton) - METHOD(XonoticBigButton, configureXonoticBigButton, void(entity, string, vector)) - ATTRIB(XonoticBigButton, image, string, SKINGFX_BUTTON_BIG) - ATTRIB(XonoticBigButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY) -ENDCLASS(XonoticBigButton) -entity makeXonoticButton(string theText, vector theColor); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticBigButton(string theText, vector theColor) -{ - entity me; - me = spawnXonoticBigButton(); - me.configureXonoticBigButton(me, theText, theColor); - return me; -} - -void XonoticBigButton_configureXonoticBigButton(entity me, string theText, vector theColor) -{ - me.configureXonoticButton(me, theText, theColor); -} -#endif diff --git a/qcsrc/menu/xonotic/bigbutton.qc b/qcsrc/menu/xonotic/bigbutton.qc new file mode 100644 index 000000000..a63189b63 --- /dev/null +++ b/qcsrc/menu/xonotic/bigbutton.qc @@ -0,0 +1,23 @@ +#ifdef INTERFACE +CLASS(XonoticBigButton) EXTENDS(XonoticButton) + METHOD(XonoticBigButton, configureXonoticBigButton, void(entity, string, vector)) + ATTRIB(XonoticBigButton, image, string, SKINGFX_BUTTON_BIG) + ATTRIB(XonoticBigButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY) +ENDCLASS(XonoticBigButton) +entity makeXonoticButton(string theText, vector theColor); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticBigButton(string theText, vector theColor) +{ + entity me; + me = spawnXonoticBigButton(); + me.configureXonoticBigButton(me, theText, theColor); + return me; +} + +void XonoticBigButton_configureXonoticBigButton(entity me, string theText, vector theColor) +{ + me.configureXonoticButton(me, theText, theColor); +} +#endif diff --git a/qcsrc/menu/xonotic/bigcommandbutton.c b/qcsrc/menu/xonotic/bigcommandbutton.c deleted file mode 100644 index c96dd57a1..000000000 --- a/qcsrc/menu/xonotic/bigcommandbutton.c +++ /dev/null @@ -1,23 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticBigCommandButton) EXTENDS(XonoticCommandButton) - METHOD(XonoticBigCommandButton, configureXonoticBigCommandButton, void(entity, string, vector, string, float)) - ATTRIB(XonoticBigCommandButton, image, string, SKINGFX_BUTTON_BIG) - ATTRIB(XonoticBigCommandButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY) -ENDCLASS(XonoticBigCommandButton) -entity makeXonoticBigCommandButton(string theText, vector theColor, string theCommand, float closesMenu); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticBigCommandButton(string theText, vector theColor, string theCommand, float theFlags) -{ - entity me; - me = spawnXonoticBigCommandButton(); - me.configureXonoticBigCommandButton(me, theText, theColor, theCommand, theFlags); - return me; -} - -void XonoticBigCommandButton_configureXonoticBigCommandButton(entity me, string theText, vector theColor, string theCommand, float theFlags) -{ - me.configureXonoticCommandButton(me, theText, theColor, theCommand, theFlags); -} -#endif diff --git a/qcsrc/menu/xonotic/bigcommandbutton.qc b/qcsrc/menu/xonotic/bigcommandbutton.qc new file mode 100644 index 000000000..c96dd57a1 --- /dev/null +++ b/qcsrc/menu/xonotic/bigcommandbutton.qc @@ -0,0 +1,23 @@ +#ifdef INTERFACE +CLASS(XonoticBigCommandButton) EXTENDS(XonoticCommandButton) + METHOD(XonoticBigCommandButton, configureXonoticBigCommandButton, void(entity, string, vector, string, float)) + ATTRIB(XonoticBigCommandButton, image, string, SKINGFX_BUTTON_BIG) + ATTRIB(XonoticBigCommandButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY) +ENDCLASS(XonoticBigCommandButton) +entity makeXonoticBigCommandButton(string theText, vector theColor, string theCommand, float closesMenu); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticBigCommandButton(string theText, vector theColor, string theCommand, float theFlags) +{ + entity me; + me = spawnXonoticBigCommandButton(); + me.configureXonoticBigCommandButton(me, theText, theColor, theCommand, theFlags); + return me; +} + +void XonoticBigCommandButton_configureXonoticBigCommandButton(entity me, string theText, vector theColor, string theCommand, float theFlags) +{ + me.configureXonoticCommandButton(me, theText, theColor, theCommand, theFlags); +} +#endif diff --git a/qcsrc/menu/xonotic/button.c b/qcsrc/menu/xonotic/button.c deleted file mode 100644 index cbc7c47c4..000000000 --- a/qcsrc/menu/xonotic/button.c +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticButton) EXTENDS(Button) - METHOD(XonoticButton, configureXonoticButton, void(entity, string, vector)) - ATTRIB(XonoticButton, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticButton, image, string, SKINGFX_BUTTON) - ATTRIB(XonoticButton, grayImage, string, SKINGFX_BUTTON_GRAY) - ATTRIB(XonoticButton, color, vector, SKINCOLOR_BUTTON_N) - ATTRIB(XonoticButton, colorC, vector, SKINCOLOR_BUTTON_C) - ATTRIB(XonoticButton, colorF, vector, SKINCOLOR_BUTTON_F) - ATTRIB(XonoticButton, colorD, vector, SKINCOLOR_BUTTON_D) - ATTRIB(XonoticButton, alpha, float, SKINALPHA_TEXT) - ATTRIB(XonoticButton, disabledAlpha, float, SKINALPHA_DISABLED) - ATTRIB(XonoticButton, marginLeft, float, SKINMARGIN_BUTTON) // chars - ATTRIB(XonoticButton, marginRight, float, SKINMARGIN_BUTTON) // chars -ENDCLASS(XonoticButton) -entity makeXonoticButton(string theText, vector theColor); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticButton(string theText, vector theColor) -{ - entity me; - me = spawnXonoticButton(); - me.configureXonoticButton(me, theText, theColor); - return me; -} - -void XonoticButton_configureXonoticButton(entity me, string theText, vector theColor) -{ - if(theColor == '0 0 0') - { - me.configureButton(me, theText, me.fontSize, me.image); - } - else - { - me.configureButton(me, theText, me.fontSize, me.grayImage); - me.color = theColor; - me.colorC = theColor; - me.colorF = theColor; - } - me.tooltip = getZonedTooltipForIdentifier(strcat(currentDialog.classname, "/", me.text)); -} -#endif diff --git a/qcsrc/menu/xonotic/button.qc b/qcsrc/menu/xonotic/button.qc new file mode 100644 index 000000000..cbc7c47c4 --- /dev/null +++ b/qcsrc/menu/xonotic/button.qc @@ -0,0 +1,43 @@ +#ifdef INTERFACE +CLASS(XonoticButton) EXTENDS(Button) + METHOD(XonoticButton, configureXonoticButton, void(entity, string, vector)) + ATTRIB(XonoticButton, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticButton, image, string, SKINGFX_BUTTON) + ATTRIB(XonoticButton, grayImage, string, SKINGFX_BUTTON_GRAY) + ATTRIB(XonoticButton, color, vector, SKINCOLOR_BUTTON_N) + ATTRIB(XonoticButton, colorC, vector, SKINCOLOR_BUTTON_C) + ATTRIB(XonoticButton, colorF, vector, SKINCOLOR_BUTTON_F) + ATTRIB(XonoticButton, colorD, vector, SKINCOLOR_BUTTON_D) + ATTRIB(XonoticButton, alpha, float, SKINALPHA_TEXT) + ATTRIB(XonoticButton, disabledAlpha, float, SKINALPHA_DISABLED) + ATTRIB(XonoticButton, marginLeft, float, SKINMARGIN_BUTTON) // chars + ATTRIB(XonoticButton, marginRight, float, SKINMARGIN_BUTTON) // chars +ENDCLASS(XonoticButton) +entity makeXonoticButton(string theText, vector theColor); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticButton(string theText, vector theColor) +{ + entity me; + me = spawnXonoticButton(); + me.configureXonoticButton(me, theText, theColor); + return me; +} + +void XonoticButton_configureXonoticButton(entity me, string theText, vector theColor) +{ + if(theColor == '0 0 0') + { + me.configureButton(me, theText, me.fontSize, me.image); + } + else + { + me.configureButton(me, theText, me.fontSize, me.grayImage); + me.color = theColor; + me.colorC = theColor; + me.colorF = theColor; + } + me.tooltip = getZonedTooltipForIdentifier(strcat(currentDialog.classname, "/", me.text)); +} +#endif diff --git a/qcsrc/menu/xonotic/campaign.c b/qcsrc/menu/xonotic/campaign.c deleted file mode 100644 index 126b728c8..000000000 --- a/qcsrc/menu/xonotic/campaign.c +++ /dev/null @@ -1,314 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCampaignList) EXTENDS(XonoticListBox) - METHOD(XonoticCampaignList, configureXonoticCampaignList, void(entity)) - ATTRIB(XonoticCampaignList, rowsPerItem, float, 10) - METHOD(XonoticCampaignList, draw, void(entity)) - METHOD(XonoticCampaignList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticCampaignList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticCampaignList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticCampaignList, setSelected, void(entity, float)) - METHOD(XonoticCampaignList, keyDown, float(entity, float, float, float)) - METHOD(XonoticCampaignList, campaignGo, void(entity, float)) - METHOD(XonoticCampaignList, destroy, void(entity)) - - ATTRIB(XonoticCampaignList, campaignGlob, float, 0) - ATTRIB(XonoticCampaignList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticCampaignList, columnPreviewOrigin, float, 0) - ATTRIB(XonoticCampaignList, columnPreviewSize, float, 0) - ATTRIB(XonoticCampaignList, columnNameOrigin, float, 0) - ATTRIB(XonoticCampaignList, columnNameSize, float, 0) - ATTRIB(XonoticCampaignList, columnCheckMarkOrigin, float, 0) - ATTRIB(XonoticCampaignList, columnCheckMarkSize, float, 0) - ATTRIB(XonoticCampaignList, checkMarkOrigin, vector, '0 0 0') - ATTRIB(XonoticCampaignList, checkMarkSize, vector, '0 0 0') - ATTRIB(XonoticCampaignList, realUpperMargin1, float, 0) - ATTRIB(XonoticCampaignList, realUpperMargin2, float, 0) - - ATTRIB(XonoticCampaignList, origin, vector, '0 0 0') - ATTRIB(XonoticCampaignList, itemAbsSize, vector, '0 0 0') - ATTRIB(XonoticCampaignList, emptyLineHeight, float, 0.5) - - ATTRIB(XonoticCampaignList, campaignIndex, float, 0) - ATTRIB(XonoticCampaignList, cvarName, string, string_null) - METHOD(XonoticCampaignList, loadCvars, void(entity)) - METHOD(XonoticCampaignList, saveCvars, void(entity)) - - ATTRIB(XonoticCampaignList, buttonNext, entity, NULL) - ATTRIB(XonoticCampaignList, buttonPrev, entity, NULL) - ATTRIB(XonoticCampaignList, labelTitle, entity, NULL) -ENDCLASS(XonoticCampaignList) -entity makeXonoticCampaignList(); -void CampaignList_LoadMap(entity btn, entity me); -void MultiCampaign_Next(entity btn, entity me); -void MultiCampaign_Prev(entity btn, entity me); -#endif - -#ifdef IMPLEMENTATION -string campaign_longdesc_wrapped[CAMPAIGN_MAX_ENTRIES]; - -void rewrapCampaign(float w, float l0, float emptyheight, vector theFontSize) -{ - float i, j; - float n, l; - string r, s; - for(i = 0; i < campaign_entries; ++i) - { - l = l0; - if(campaign_longdesc_wrapped[i]) - strunzone(campaign_longdesc_wrapped[i]); - n = tokenizebyseparator(campaign_longdesc[i], "\n"); - r = ""; - for(j = 0; j < n; ++j) - { - s = argv(j); - if(s == "") - { - l -= emptyheight; - r = strcat(r, "\n"); - continue; - } - - getWrappedLine_remaining = s; - while(getWrappedLine_remaining) - { - s = getWrappedLine(w, theFontSize, draw_TextWidth_WithoutColors); - if(--l < 0) goto toolong; - r = strcat(r, s, "\n"); - } - } - goto nottoolong; -:toolong - while(substring(r, strlen(r) - 1, 1) == "\n") - r = substring(r, 0, strlen(r) - 1); - r = strcat(r, "...\n"); -:nottoolong - campaign_longdesc_wrapped[i] = strzone(substring(r, 0, strlen(r) - 1)); - } -} - -entity makeXonoticCampaignList() -{ - entity me; - me = spawnXonoticCampaignList(); - me.configureXonoticCampaignList(me); - return me; -} -void XonoticCampaignList_configureXonoticCampaignList(entity me) -{ - me.configureXonoticListBox(me); - me.campaignGlob = search_begin("maps/campaign*.txt", TRUE, TRUE); - me.loadCvars(me); - me.campaignGo(me, 0); // takes care of enabling/disabling buttons too -} - -void XonoticCampaignList_destroy(entity me) -{ - if(me.campaignGlob >= 0) - search_end(me.campaignGlob); -} - -void XonoticCampaignList_loadCvars(entity me) -{ - // read campaign cvars - if(campaign_name) - strunzone(campaign_name); - if(me.cvarName) - strunzone(me.cvarName); - campaign_name = strzone(cvar_string("g_campaign_name")); - me.cvarName = strzone(strcat("g_campaign", campaign_name, "_index")); - registercvar(me.cvarName, "", 0); // saved by server QC anyway - CampaignFile_Unload(); - CampaignFile_Load(0, CAMPAIGN_MAX_ENTRIES); - me.campaignIndex = bound(0, cvar(me.cvarName), campaign_entries); - cvar_set(me.cvarName, ftos(me.campaignIndex)); - if(me.columnNameSize) - rewrapCampaign(me.columnNameSize, me.rowsPerItem - 3, me.emptyLineHeight, me.realFontSize); - me.nItems = min(me.campaignIndex + 2, campaign_entries); - me.selectedItem = min(me.campaignIndex, me.nItems - 1); - me.scrollPos = me.nItems * me.itemHeight - 1; - if(me.labelTitle) - me.labelTitle.setText(me.labelTitle, campaign_title); -} - -void XonoticCampaignList_saveCvars(entity me) -{ - // write campaign cvars - // no reason to do this! - // cvar_set("g_campaign_name", campaign_name); - // cvar_set(me.cvarName, ftos(me.campaignIndex)); // NOTE: only server QC does that! -} - -void XonoticCampaignList_campaignGo(entity me, float step) -{ - float canNext, canPrev; - string s; - float i, j, n; - - canNext = canPrev = 0; - - if(me.campaignGlob >= 0) - { - n = search_getsize(me.campaignGlob); - if(n > 0) - { - j = -1; - s = strcat("maps/campaign", campaign_name, ".txt"); - for(i = 0; i < n; ++i) - { - if(search_getfilename(me.campaignGlob, i) == s) - j = i; - } - if(j < 0) - { - s = strcat("maps/campaign", cvar_defstring("g_campaign_name"), ".txt"); - for(i = 0; i < n; ++i) - { - if(search_getfilename(me.campaignGlob, i) == s) - j = i; - } - } - if(j < 0) - { - if(step >= 0) - j = 0; - else - j = n - 1; - } - else - j = mod(j + step, n); - s = search_getfilename(me.campaignGlob, j); - s = substring(s, 13, strlen(s) - 17); - cvar_set("g_campaign_name", s); - me.loadCvars(me); - canNext = (j != n - 1); - canPrev = (j != 0); - } - } - - if(me.buttonNext) - me.buttonNext.disabled = !canNext; - if(me.buttonPrev) - me.buttonPrev.disabled = !canPrev; -} - -void MultiCampaign_Next(entity btn, entity me) -{ - me.campaignGo(me, +1); -} -void MultiCampaign_Prev(entity btn, entity me) -{ - me.campaignGo(me, -1); -} - -void XonoticCampaignList_draw(entity me) -{ - if(cvar(me.cvarName) != me.campaignIndex || cvar_string("g_campaign_name") != campaign_name) - me.loadCvars(me); - SUPER(XonoticCampaignList).draw(me); -} - -void XonoticCampaignList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticCampaignList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin1 = 0.5 * me.realFontSize_y; - me.realUpperMargin2 = me.realUpperMargin1 + 2 * me.realFontSize_y; - - me.checkMarkSize = (eX * (me.itemAbsSize_y / me.itemAbsSize_x) + eY) * 0.5; - - me.columnPreviewOrigin = 0; - me.columnPreviewSize = me.itemAbsSize_y / me.itemAbsSize_x * 4 / 3; - me.columnCheckMarkSize = me.checkMarkSize_x; - me.columnNameSize = 1 - me.columnPreviewSize - me.columnCheckMarkSize - 4 * me.realFontSize_x; - me.columnNameOrigin = me.columnPreviewOrigin + me.columnPreviewSize + me.realFontSize_x; - me.columnCheckMarkOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x * 2; - - me.checkMarkOrigin = eY + eX * (me.columnCheckMarkOrigin + me.columnCheckMarkSize) - me.checkMarkSize; - - rewrapCampaign(me.columnNameSize, me.rowsPerItem - 3, me.emptyLineHeight, me.realFontSize); -} -void XonoticCampaignList_doubleClickListBoxItem(entity me, float i, vector where) -{ - CampaignList_LoadMap(me, me); -} -void XonoticCampaignList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s; - vector theColor; - float theAlpha; - float j, n; - vector o; - - if(i < me.campaignIndex) - { - theAlpha = SKINALPHA_CAMPAIGN_SELECTABLE; - theColor = SKINCOLOR_CAMPAIGN_SELECTABLE; - } - else if(i == me.campaignIndex) - { - theAlpha = SKINALPHA_CAMPAIGN_CURRENT; - theColor = SKINCOLOR_CAMPAIGN_CURRENT; - } - else - { - theAlpha = SKINALPHA_CAMPAIGN_FUTURE; - theColor = SKINCOLOR_CAMPAIGN_FUTURE; - } - - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - if(draw_PictureSize(strcat("/maps/", campaign_mapname[i])) == '0 0 0') - draw_Picture(me.columnPreviewOrigin * eX, "nopreview_map", me.columnPreviewSize * eX + eY, '1 1 1', theAlpha); - else - draw_Picture(me.columnPreviewOrigin * eX, strcat("/maps/", campaign_mapname[i]), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha); - - if(i < me.campaignIndex) - draw_Picture(me.checkMarkOrigin, "checkmark", me.checkMarkSize, '1 1 1', 1); - if(i <= me.campaignIndex) - s = campaign_shortdesc[i]; // fteqcc sucks - else - s = "???"; - s = draw_TextShortenToWidth(sprintf(_("Level %d: %s"), i+1, s), me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, theColor, theAlpha, 0); - - if(i <= me.campaignIndex) - { - s = campaign_longdesc_wrapped[i]; - n = tokenizebyseparator(s, "\n"); - o = me.realUpperMargin2 * eY + me.columnNameOrigin * eX; - for(j = 0; j < n; ++j) - if(argv(j) != "") - { - draw_Text(o, argv(j), me.realFontSize, theColor, theAlpha * SKINALPHA_CAMPAIGN_DESCRIPTION, 0); - o_y += me.realFontSize_y; - } - else - o_y += me.realFontSize_y * me.emptyLineHeight; - } -} -void CampaignList_LoadMap(entity btn, entity me) -{ - if(me.selectedItem >= me.nItems || me.selectedItem < 0) - return; - CampaignSetup(me.selectedItem); -} - -void XonoticCampaignList_setSelected(entity me, float i) -{ - // prevent too late items from being played - SUPER(XonoticCampaignList).setSelected(me, min(i, me.campaignIndex)); -} - -float XonoticCampaignList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(scan == K_ENTER || scan == K_SPACE || scan == K_KP_ENTER) - CampaignList_LoadMap(me, me); - else - return SUPER(XonoticCampaignList).keyDown(me, scan, ascii, shift); - return 1; -} -#endif diff --git a/qcsrc/menu/xonotic/campaign.qc b/qcsrc/menu/xonotic/campaign.qc new file mode 100644 index 000000000..126b728c8 --- /dev/null +++ b/qcsrc/menu/xonotic/campaign.qc @@ -0,0 +1,314 @@ +#ifdef INTERFACE +CLASS(XonoticCampaignList) EXTENDS(XonoticListBox) + METHOD(XonoticCampaignList, configureXonoticCampaignList, void(entity)) + ATTRIB(XonoticCampaignList, rowsPerItem, float, 10) + METHOD(XonoticCampaignList, draw, void(entity)) + METHOD(XonoticCampaignList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticCampaignList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticCampaignList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticCampaignList, setSelected, void(entity, float)) + METHOD(XonoticCampaignList, keyDown, float(entity, float, float, float)) + METHOD(XonoticCampaignList, campaignGo, void(entity, float)) + METHOD(XonoticCampaignList, destroy, void(entity)) + + ATTRIB(XonoticCampaignList, campaignGlob, float, 0) + ATTRIB(XonoticCampaignList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticCampaignList, columnPreviewOrigin, float, 0) + ATTRIB(XonoticCampaignList, columnPreviewSize, float, 0) + ATTRIB(XonoticCampaignList, columnNameOrigin, float, 0) + ATTRIB(XonoticCampaignList, columnNameSize, float, 0) + ATTRIB(XonoticCampaignList, columnCheckMarkOrigin, float, 0) + ATTRIB(XonoticCampaignList, columnCheckMarkSize, float, 0) + ATTRIB(XonoticCampaignList, checkMarkOrigin, vector, '0 0 0') + ATTRIB(XonoticCampaignList, checkMarkSize, vector, '0 0 0') + ATTRIB(XonoticCampaignList, realUpperMargin1, float, 0) + ATTRIB(XonoticCampaignList, realUpperMargin2, float, 0) + + ATTRIB(XonoticCampaignList, origin, vector, '0 0 0') + ATTRIB(XonoticCampaignList, itemAbsSize, vector, '0 0 0') + ATTRIB(XonoticCampaignList, emptyLineHeight, float, 0.5) + + ATTRIB(XonoticCampaignList, campaignIndex, float, 0) + ATTRIB(XonoticCampaignList, cvarName, string, string_null) + METHOD(XonoticCampaignList, loadCvars, void(entity)) + METHOD(XonoticCampaignList, saveCvars, void(entity)) + + ATTRIB(XonoticCampaignList, buttonNext, entity, NULL) + ATTRIB(XonoticCampaignList, buttonPrev, entity, NULL) + ATTRIB(XonoticCampaignList, labelTitle, entity, NULL) +ENDCLASS(XonoticCampaignList) +entity makeXonoticCampaignList(); +void CampaignList_LoadMap(entity btn, entity me); +void MultiCampaign_Next(entity btn, entity me); +void MultiCampaign_Prev(entity btn, entity me); +#endif + +#ifdef IMPLEMENTATION +string campaign_longdesc_wrapped[CAMPAIGN_MAX_ENTRIES]; + +void rewrapCampaign(float w, float l0, float emptyheight, vector theFontSize) +{ + float i, j; + float n, l; + string r, s; + for(i = 0; i < campaign_entries; ++i) + { + l = l0; + if(campaign_longdesc_wrapped[i]) + strunzone(campaign_longdesc_wrapped[i]); + n = tokenizebyseparator(campaign_longdesc[i], "\n"); + r = ""; + for(j = 0; j < n; ++j) + { + s = argv(j); + if(s == "") + { + l -= emptyheight; + r = strcat(r, "\n"); + continue; + } + + getWrappedLine_remaining = s; + while(getWrappedLine_remaining) + { + s = getWrappedLine(w, theFontSize, draw_TextWidth_WithoutColors); + if(--l < 0) goto toolong; + r = strcat(r, s, "\n"); + } + } + goto nottoolong; +:toolong + while(substring(r, strlen(r) - 1, 1) == "\n") + r = substring(r, 0, strlen(r) - 1); + r = strcat(r, "...\n"); +:nottoolong + campaign_longdesc_wrapped[i] = strzone(substring(r, 0, strlen(r) - 1)); + } +} + +entity makeXonoticCampaignList() +{ + entity me; + me = spawnXonoticCampaignList(); + me.configureXonoticCampaignList(me); + return me; +} +void XonoticCampaignList_configureXonoticCampaignList(entity me) +{ + me.configureXonoticListBox(me); + me.campaignGlob = search_begin("maps/campaign*.txt", TRUE, TRUE); + me.loadCvars(me); + me.campaignGo(me, 0); // takes care of enabling/disabling buttons too +} + +void XonoticCampaignList_destroy(entity me) +{ + if(me.campaignGlob >= 0) + search_end(me.campaignGlob); +} + +void XonoticCampaignList_loadCvars(entity me) +{ + // read campaign cvars + if(campaign_name) + strunzone(campaign_name); + if(me.cvarName) + strunzone(me.cvarName); + campaign_name = strzone(cvar_string("g_campaign_name")); + me.cvarName = strzone(strcat("g_campaign", campaign_name, "_index")); + registercvar(me.cvarName, "", 0); // saved by server QC anyway + CampaignFile_Unload(); + CampaignFile_Load(0, CAMPAIGN_MAX_ENTRIES); + me.campaignIndex = bound(0, cvar(me.cvarName), campaign_entries); + cvar_set(me.cvarName, ftos(me.campaignIndex)); + if(me.columnNameSize) + rewrapCampaign(me.columnNameSize, me.rowsPerItem - 3, me.emptyLineHeight, me.realFontSize); + me.nItems = min(me.campaignIndex + 2, campaign_entries); + me.selectedItem = min(me.campaignIndex, me.nItems - 1); + me.scrollPos = me.nItems * me.itemHeight - 1; + if(me.labelTitle) + me.labelTitle.setText(me.labelTitle, campaign_title); +} + +void XonoticCampaignList_saveCvars(entity me) +{ + // write campaign cvars + // no reason to do this! + // cvar_set("g_campaign_name", campaign_name); + // cvar_set(me.cvarName, ftos(me.campaignIndex)); // NOTE: only server QC does that! +} + +void XonoticCampaignList_campaignGo(entity me, float step) +{ + float canNext, canPrev; + string s; + float i, j, n; + + canNext = canPrev = 0; + + if(me.campaignGlob >= 0) + { + n = search_getsize(me.campaignGlob); + if(n > 0) + { + j = -1; + s = strcat("maps/campaign", campaign_name, ".txt"); + for(i = 0; i < n; ++i) + { + if(search_getfilename(me.campaignGlob, i) == s) + j = i; + } + if(j < 0) + { + s = strcat("maps/campaign", cvar_defstring("g_campaign_name"), ".txt"); + for(i = 0; i < n; ++i) + { + if(search_getfilename(me.campaignGlob, i) == s) + j = i; + } + } + if(j < 0) + { + if(step >= 0) + j = 0; + else + j = n - 1; + } + else + j = mod(j + step, n); + s = search_getfilename(me.campaignGlob, j); + s = substring(s, 13, strlen(s) - 17); + cvar_set("g_campaign_name", s); + me.loadCvars(me); + canNext = (j != n - 1); + canPrev = (j != 0); + } + } + + if(me.buttonNext) + me.buttonNext.disabled = !canNext; + if(me.buttonPrev) + me.buttonPrev.disabled = !canPrev; +} + +void MultiCampaign_Next(entity btn, entity me) +{ + me.campaignGo(me, +1); +} +void MultiCampaign_Prev(entity btn, entity me) +{ + me.campaignGo(me, -1); +} + +void XonoticCampaignList_draw(entity me) +{ + if(cvar(me.cvarName) != me.campaignIndex || cvar_string("g_campaign_name") != campaign_name) + me.loadCvars(me); + SUPER(XonoticCampaignList).draw(me); +} + +void XonoticCampaignList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticCampaignList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin1 = 0.5 * me.realFontSize_y; + me.realUpperMargin2 = me.realUpperMargin1 + 2 * me.realFontSize_y; + + me.checkMarkSize = (eX * (me.itemAbsSize_y / me.itemAbsSize_x) + eY) * 0.5; + + me.columnPreviewOrigin = 0; + me.columnPreviewSize = me.itemAbsSize_y / me.itemAbsSize_x * 4 / 3; + me.columnCheckMarkSize = me.checkMarkSize_x; + me.columnNameSize = 1 - me.columnPreviewSize - me.columnCheckMarkSize - 4 * me.realFontSize_x; + me.columnNameOrigin = me.columnPreviewOrigin + me.columnPreviewSize + me.realFontSize_x; + me.columnCheckMarkOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x * 2; + + me.checkMarkOrigin = eY + eX * (me.columnCheckMarkOrigin + me.columnCheckMarkSize) - me.checkMarkSize; + + rewrapCampaign(me.columnNameSize, me.rowsPerItem - 3, me.emptyLineHeight, me.realFontSize); +} +void XonoticCampaignList_doubleClickListBoxItem(entity me, float i, vector where) +{ + CampaignList_LoadMap(me, me); +} +void XonoticCampaignList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s; + vector theColor; + float theAlpha; + float j, n; + vector o; + + if(i < me.campaignIndex) + { + theAlpha = SKINALPHA_CAMPAIGN_SELECTABLE; + theColor = SKINCOLOR_CAMPAIGN_SELECTABLE; + } + else if(i == me.campaignIndex) + { + theAlpha = SKINALPHA_CAMPAIGN_CURRENT; + theColor = SKINCOLOR_CAMPAIGN_CURRENT; + } + else + { + theAlpha = SKINALPHA_CAMPAIGN_FUTURE; + theColor = SKINCOLOR_CAMPAIGN_FUTURE; + } + + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + if(draw_PictureSize(strcat("/maps/", campaign_mapname[i])) == '0 0 0') + draw_Picture(me.columnPreviewOrigin * eX, "nopreview_map", me.columnPreviewSize * eX + eY, '1 1 1', theAlpha); + else + draw_Picture(me.columnPreviewOrigin * eX, strcat("/maps/", campaign_mapname[i]), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha); + + if(i < me.campaignIndex) + draw_Picture(me.checkMarkOrigin, "checkmark", me.checkMarkSize, '1 1 1', 1); + if(i <= me.campaignIndex) + s = campaign_shortdesc[i]; // fteqcc sucks + else + s = "???"; + s = draw_TextShortenToWidth(sprintf(_("Level %d: %s"), i+1, s), me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, theColor, theAlpha, 0); + + if(i <= me.campaignIndex) + { + s = campaign_longdesc_wrapped[i]; + n = tokenizebyseparator(s, "\n"); + o = me.realUpperMargin2 * eY + me.columnNameOrigin * eX; + for(j = 0; j < n; ++j) + if(argv(j) != "") + { + draw_Text(o, argv(j), me.realFontSize, theColor, theAlpha * SKINALPHA_CAMPAIGN_DESCRIPTION, 0); + o_y += me.realFontSize_y; + } + else + o_y += me.realFontSize_y * me.emptyLineHeight; + } +} +void CampaignList_LoadMap(entity btn, entity me) +{ + if(me.selectedItem >= me.nItems || me.selectedItem < 0) + return; + CampaignSetup(me.selectedItem); +} + +void XonoticCampaignList_setSelected(entity me, float i) +{ + // prevent too late items from being played + SUPER(XonoticCampaignList).setSelected(me, min(i, me.campaignIndex)); +} + +float XonoticCampaignList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_SPACE || scan == K_KP_ENTER) + CampaignList_LoadMap(me, me); + else + return SUPER(XonoticCampaignList).keyDown(me, scan, ascii, shift); + return 1; +} +#endif diff --git a/qcsrc/menu/xonotic/charmap.c b/qcsrc/menu/xonotic/charmap.c deleted file mode 100644 index 5439c391d..000000000 --- a/qcsrc/menu/xonotic/charmap.c +++ /dev/null @@ -1,240 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCharmap) EXTENDS(Item) - METHOD(XonoticCharmap, configureXonoticCharmap, void(entity, entity)) - METHOD(XonoticCharmap, mousePress, float(entity, vector)) - METHOD(XonoticCharmap, mouseRelease, float(entity, vector)) - METHOD(XonoticCharmap, mouseMove, float(entity, vector)) - METHOD(XonoticCharmap, mouseDrag, float(entity, vector)) - METHOD(XonoticCharmap, keyDown, float(entity, float, float, float)) - METHOD(XonoticCharmap, focusLeave, void(entity)) - METHOD(XonoticCharmap, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticCharmap, draw, void(entity)) - ATTRIB(XonoticCharmap, focusable, float, 1) - - METHOD(XonoticCharmap, moveFocus, void(entity, vector, vector)) - METHOD(XonoticCharmap, enterChar, void(entity)) - ATTRIB(XonoticCharmap, inputBox, entity, NULL) - ATTRIB(XonoticCharmap, realFontSize, vector, '0 0 0') - ATTRIB(XonoticCharmap, realCellSize, vector, '0 0 0') - ATTRIB(XonoticCharmap, focusedCell, vector, '-1 -1 0') - ATTRIB(XonoticCharmap, previouslyFocusedCell, vector, '-1 -1 0') -ENDCLASS(XonoticCharmap) -entity makeXonoticCharmap(entity controlledInputBox); -#endif - -#ifdef IMPLEMENTATION - -const float CHARMAP_COLS = 14; -const float CHARMAP_ROWS = 10; - -string CHARMAP = - "★◆■▮▰▬◣◤◥◢◀▲▶▼" - "🌍🌎🌏🚀🌌👽🔫⌖❇❈←↑→↓" - "☠☣☢⚛⚡⚙🔥❌⚠⛔❰❱❲❳" - "😃😊😁😄😆😎😈😇😉😛😝😘❤ " - "😐😒😕😮😲😞😟😠😣😭😵😴 " - "\xEE\x83\xA1\xEE\x83\xA2\xEE\x83\xA3\xEE\x83\xA4\xEE\x83\xA5\xEE\x83\xA6\xEE\x83\xA7" - "\xEE\x83\xA8\xEE\x83\xA9\xEE\x83\xAA\xEE\x83\xAB\xEE\x83\xAC\xEE\x83\xAD\xEE\x83\xAE" - "\xEE\x83\xAF\xEE\x83\xB0\xEE\x83\xB1\xEE\x83\xB2\xEE\x83\xB3\xEE\x83\xB4\xEE\x83\xB5" - "\xEE\x83\xB6\xEE\x83\xB7\xEE\x83\xB8\xEE\x83\xB9\xEE\x83\xBA\xEE\x80\x90\xEE\x80\x91" - "\xEE\x82\xB0\xEE\x82\xB1\xEE\x82\xB2\xEE\x82\xB3\xEE\x82\xB4\xEE\x82\xB5\xEE\x82\xB6" - "\xEE\x82\xB7\xEE\x82\xB8\xEE\x82\xB9\xEE\x82\xA1\xEE\x82\xBF\xEE\x82\xA6\xEE\x82\xA5" - "\xEE\x83\x81\xEE\x83\x82\xEE\x83\x83\xEE\x83\x84\xEE\x83\x85\xEE\x83\x86\xEE\x83\x87" - "\xEE\x83\x88\xEE\x83\x89\xEE\x83\x8A\xEE\x83\x8B\xEE\x83\x8C\xEE\x83\x8D\xEE\x83\x8E" - "\xEE\x83\x8F\xEE\x83\x90\xEE\x83\x91\xEE\x83\x92\xEE\x83\x93\xEE\x83\x94\xEE\x83\x95" - "\xEE\x83\x96\xEE\x83\x97\xEE\x83\x98\xEE\x83\x99\xEE\x83\x9A\xEE\x81\x9B\xEE\x81\x9D"; - -string charmap_cellToChar(vector cell) -{ - string character = substring(CHARMAP, cell_y * CHARMAP_COLS + cell_x, 1); - - if (character != " ") - return character; - else - return ""; -} - -entity makeXonoticCharmap(entity controlledInputBox) -{ - entity me; - me = spawnXonoticCharmap(); - me.configureXonoticCharmap(me, controlledInputBox); - return me; -} - -void XonoticCharmap_configureXonoticCharmap(entity me, entity controlledInputBox) -{ - me.inputBox = controlledInputBox; - me.realCellSize = eX / CHARMAP_COLS + eY / CHARMAP_ROWS; -} - -void XonoticCharmap_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(XonoticCharmap).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - float maxFontWidth = SKINFONTSIZE_NORMAL / absSize_x; - float maxFontHeight = SKINFONTSIZE_NORMAL / absSize_y; - - if((me.realCellSize_x * absSize_x) > (me.realCellSize_y * absSize_y)) - { - me.realFontSize_x = me.realCellSize_y * absSize_y / absSize_x; - me.realFontSize_y = me.realCellSize_y; - } - else - { - me.realFontSize_x = me.realCellSize_x; - me.realFontSize_y = me.realCellSize_x * absSize_x / absSize_y; - } - - if(me.realFontSize_x > maxFontWidth || me.realFontSize_y > maxFontHeight) - me.realFontSize = eX * maxFontWidth + eY * maxFontHeight; -} - -float XonoticCharmap_mouseMove(entity me, vector coords) -{ - me.focusedCell_x = floor(coords_x * CHARMAP_COLS); - me.focusedCell_y = floor(coords_y * CHARMAP_ROWS); - - if(me.focusedCell_x < 0 || me.focusedCell_y < 0 || - me.focusedCell_x >= CHARMAP_COLS || me.focusedCell_y >= CHARMAP_ROWS) - { - me.focusedCell = '-1 -1 0'; - return 0; - } - - return 1; -} - -float XonoticCharmap_mouseDrag(entity me, vector coords) -{ - return me.mouseMove(me, coords); -} - -float XonoticCharmap_mousePress(entity me, vector coords) -{ - me.mouseMove(me, coords); - - if(me.focusedCell_x >= 0) - { - me.pressed = 1; - me.previouslyFocusedCell = me.focusedCell; - } - - return 1; -} - -float XonoticCharmap_mouseRelease(entity me, vector coords) -{ - if(!me.pressed) - return 0; - - me.mouseMove(me, coords); - - if(me.focusedCell == me.previouslyFocusedCell) - me.enterChar(me); - - me.pressed = 0; - return 1; -} - -float XonoticCharmap_keyDown(entity me, float key, float ascii, float shift) -{ - switch(key) - { - case K_LEFTARROW: - case K_KP_LEFTARROW: - me.moveFocus(me, me.focusedCell, '-1 0 0'); - return 1; - case K_RIGHTARROW: - case K_KP_RIGHTARROW: - me.moveFocus(me, me.focusedCell, '1 0 0'); - return 1; - case K_UPARROW: - case K_KP_UPARROW: - me.moveFocus(me, me.focusedCell, '0 -1 0'); - return 1; - case K_DOWNARROW: - case K_KP_DOWNARROW: - me.moveFocus(me, me.focusedCell, '0 1 0'); - return 1; - case K_HOME: - case K_KP_HOME: - me.focusedCell = '0 0 0'; - return 1; - case K_END: - case K_KP_END: - me.focusedCell_x = CHARMAP_COLS - 1; - me.focusedCell_y = CHARMAP_ROWS - 1; - return 1; - case K_ENTER: - case K_KP_ENTER: - case K_INS: - case K_KP_INS: - me.enterChar(me); - return 1; - default: - return me.inputBox.keyDown(me.inputBox, key, ascii, shift); - } -} - -void XonoticCharmap_moveFocus(entity me, vector initialCell, vector step) -{ - me.focusedCell_x = mod(me.focusedCell_x + step_x + CHARMAP_COLS, CHARMAP_COLS); - me.focusedCell_y = mod(me.focusedCell_y + step_y + CHARMAP_ROWS, CHARMAP_ROWS); - - if(me.focusedCell != initialCell) // Recursion break - if(charmap_cellToChar(me.focusedCell) == "") - me.moveFocus(me, initialCell, step); -} - -void XonoticCharmap_enterChar(entity me) -{ - string character = charmap_cellToChar(me.focusedCell); - if(character != "") - me.inputBox.enterText(me.inputBox, character); -} - -void XonoticCharmap_focusLeave(entity me) -{ - me.inputBox.saveCvars(me.inputBox); -} - -void XonoticCharmap_draw(entity me) -{ - string character; - vector cell, cellPos, charPos; - cell = '0 0 0'; - cellPos = '0 0 0'; - charPos = '0 0 0'; - - float CHAR_OFFSET_X = me.realCellSize_x / 2; - float CHAR_OFFSET_Y = (me.realCellSize_y - me.realFontSize_y) / 2; - - for(cell_y = 0; cell_y < CHARMAP_ROWS; ++cell_y) - { - charPos_y = cell_y / CHARMAP_ROWS + CHAR_OFFSET_Y; - for(cell_x = 0; cell_x < CHARMAP_COLS; ++cell_x) - { - character = charmap_cellToChar(cell); - - if(character == "") - continue; - - // Draw focused cell - if(cell == me.focusedCell && me.focused) - { - if(!me.pressed || me.focusedCell == me.previouslyFocusedCell) - { - cellPos_x = mod(me.focusedCell_x, CHARMAP_COLS) / CHARMAP_COLS; - cellPos_y = mod(me.focusedCell_y, CHARMAP_ROWS) / CHARMAP_ROWS; - draw_Fill(cellPos, me.realCellSize, SKINCOLOR_CHARMAP_FOCUS, SKINALPHA_CHARMAP_FOCUS); - } - } - - // Draw character - charPos_x = cell_x / CHARMAP_COLS + CHAR_OFFSET_X; - draw_CenterText(charPos, character, me.realFontSize, SKINCOLOR_CHARMAP_CHAR, SKINALPHA_CHARMAP_CHAR, 0); - } - } -} -#endif diff --git a/qcsrc/menu/xonotic/charmap.qc b/qcsrc/menu/xonotic/charmap.qc new file mode 100644 index 000000000..5439c391d --- /dev/null +++ b/qcsrc/menu/xonotic/charmap.qc @@ -0,0 +1,240 @@ +#ifdef INTERFACE +CLASS(XonoticCharmap) EXTENDS(Item) + METHOD(XonoticCharmap, configureXonoticCharmap, void(entity, entity)) + METHOD(XonoticCharmap, mousePress, float(entity, vector)) + METHOD(XonoticCharmap, mouseRelease, float(entity, vector)) + METHOD(XonoticCharmap, mouseMove, float(entity, vector)) + METHOD(XonoticCharmap, mouseDrag, float(entity, vector)) + METHOD(XonoticCharmap, keyDown, float(entity, float, float, float)) + METHOD(XonoticCharmap, focusLeave, void(entity)) + METHOD(XonoticCharmap, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticCharmap, draw, void(entity)) + ATTRIB(XonoticCharmap, focusable, float, 1) + + METHOD(XonoticCharmap, moveFocus, void(entity, vector, vector)) + METHOD(XonoticCharmap, enterChar, void(entity)) + ATTRIB(XonoticCharmap, inputBox, entity, NULL) + ATTRIB(XonoticCharmap, realFontSize, vector, '0 0 0') + ATTRIB(XonoticCharmap, realCellSize, vector, '0 0 0') + ATTRIB(XonoticCharmap, focusedCell, vector, '-1 -1 0') + ATTRIB(XonoticCharmap, previouslyFocusedCell, vector, '-1 -1 0') +ENDCLASS(XonoticCharmap) +entity makeXonoticCharmap(entity controlledInputBox); +#endif + +#ifdef IMPLEMENTATION + +const float CHARMAP_COLS = 14; +const float CHARMAP_ROWS = 10; + +string CHARMAP = + "★◆■▮▰▬◣◤◥◢◀▲▶▼" + "🌍🌎🌏🚀🌌👽🔫⌖❇❈←↑→↓" + "☠☣☢⚛⚡⚙🔥❌⚠⛔❰❱❲❳" + "😃😊😁😄😆😎😈😇😉😛😝😘❤ " + "😐😒😕😮😲😞😟😠😣😭😵😴 " + "\xEE\x83\xA1\xEE\x83\xA2\xEE\x83\xA3\xEE\x83\xA4\xEE\x83\xA5\xEE\x83\xA6\xEE\x83\xA7" + "\xEE\x83\xA8\xEE\x83\xA9\xEE\x83\xAA\xEE\x83\xAB\xEE\x83\xAC\xEE\x83\xAD\xEE\x83\xAE" + "\xEE\x83\xAF\xEE\x83\xB0\xEE\x83\xB1\xEE\x83\xB2\xEE\x83\xB3\xEE\x83\xB4\xEE\x83\xB5" + "\xEE\x83\xB6\xEE\x83\xB7\xEE\x83\xB8\xEE\x83\xB9\xEE\x83\xBA\xEE\x80\x90\xEE\x80\x91" + "\xEE\x82\xB0\xEE\x82\xB1\xEE\x82\xB2\xEE\x82\xB3\xEE\x82\xB4\xEE\x82\xB5\xEE\x82\xB6" + "\xEE\x82\xB7\xEE\x82\xB8\xEE\x82\xB9\xEE\x82\xA1\xEE\x82\xBF\xEE\x82\xA6\xEE\x82\xA5" + "\xEE\x83\x81\xEE\x83\x82\xEE\x83\x83\xEE\x83\x84\xEE\x83\x85\xEE\x83\x86\xEE\x83\x87" + "\xEE\x83\x88\xEE\x83\x89\xEE\x83\x8A\xEE\x83\x8B\xEE\x83\x8C\xEE\x83\x8D\xEE\x83\x8E" + "\xEE\x83\x8F\xEE\x83\x90\xEE\x83\x91\xEE\x83\x92\xEE\x83\x93\xEE\x83\x94\xEE\x83\x95" + "\xEE\x83\x96\xEE\x83\x97\xEE\x83\x98\xEE\x83\x99\xEE\x83\x9A\xEE\x81\x9B\xEE\x81\x9D"; + +string charmap_cellToChar(vector cell) +{ + string character = substring(CHARMAP, cell_y * CHARMAP_COLS + cell_x, 1); + + if (character != " ") + return character; + else + return ""; +} + +entity makeXonoticCharmap(entity controlledInputBox) +{ + entity me; + me = spawnXonoticCharmap(); + me.configureXonoticCharmap(me, controlledInputBox); + return me; +} + +void XonoticCharmap_configureXonoticCharmap(entity me, entity controlledInputBox) +{ + me.inputBox = controlledInputBox; + me.realCellSize = eX / CHARMAP_COLS + eY / CHARMAP_ROWS; +} + +void XonoticCharmap_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(XonoticCharmap).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + float maxFontWidth = SKINFONTSIZE_NORMAL / absSize_x; + float maxFontHeight = SKINFONTSIZE_NORMAL / absSize_y; + + if((me.realCellSize_x * absSize_x) > (me.realCellSize_y * absSize_y)) + { + me.realFontSize_x = me.realCellSize_y * absSize_y / absSize_x; + me.realFontSize_y = me.realCellSize_y; + } + else + { + me.realFontSize_x = me.realCellSize_x; + me.realFontSize_y = me.realCellSize_x * absSize_x / absSize_y; + } + + if(me.realFontSize_x > maxFontWidth || me.realFontSize_y > maxFontHeight) + me.realFontSize = eX * maxFontWidth + eY * maxFontHeight; +} + +float XonoticCharmap_mouseMove(entity me, vector coords) +{ + me.focusedCell_x = floor(coords_x * CHARMAP_COLS); + me.focusedCell_y = floor(coords_y * CHARMAP_ROWS); + + if(me.focusedCell_x < 0 || me.focusedCell_y < 0 || + me.focusedCell_x >= CHARMAP_COLS || me.focusedCell_y >= CHARMAP_ROWS) + { + me.focusedCell = '-1 -1 0'; + return 0; + } + + return 1; +} + +float XonoticCharmap_mouseDrag(entity me, vector coords) +{ + return me.mouseMove(me, coords); +} + +float XonoticCharmap_mousePress(entity me, vector coords) +{ + me.mouseMove(me, coords); + + if(me.focusedCell_x >= 0) + { + me.pressed = 1; + me.previouslyFocusedCell = me.focusedCell; + } + + return 1; +} + +float XonoticCharmap_mouseRelease(entity me, vector coords) +{ + if(!me.pressed) + return 0; + + me.mouseMove(me, coords); + + if(me.focusedCell == me.previouslyFocusedCell) + me.enterChar(me); + + me.pressed = 0; + return 1; +} + +float XonoticCharmap_keyDown(entity me, float key, float ascii, float shift) +{ + switch(key) + { + case K_LEFTARROW: + case K_KP_LEFTARROW: + me.moveFocus(me, me.focusedCell, '-1 0 0'); + return 1; + case K_RIGHTARROW: + case K_KP_RIGHTARROW: + me.moveFocus(me, me.focusedCell, '1 0 0'); + return 1; + case K_UPARROW: + case K_KP_UPARROW: + me.moveFocus(me, me.focusedCell, '0 -1 0'); + return 1; + case K_DOWNARROW: + case K_KP_DOWNARROW: + me.moveFocus(me, me.focusedCell, '0 1 0'); + return 1; + case K_HOME: + case K_KP_HOME: + me.focusedCell = '0 0 0'; + return 1; + case K_END: + case K_KP_END: + me.focusedCell_x = CHARMAP_COLS - 1; + me.focusedCell_y = CHARMAP_ROWS - 1; + return 1; + case K_ENTER: + case K_KP_ENTER: + case K_INS: + case K_KP_INS: + me.enterChar(me); + return 1; + default: + return me.inputBox.keyDown(me.inputBox, key, ascii, shift); + } +} + +void XonoticCharmap_moveFocus(entity me, vector initialCell, vector step) +{ + me.focusedCell_x = mod(me.focusedCell_x + step_x + CHARMAP_COLS, CHARMAP_COLS); + me.focusedCell_y = mod(me.focusedCell_y + step_y + CHARMAP_ROWS, CHARMAP_ROWS); + + if(me.focusedCell != initialCell) // Recursion break + if(charmap_cellToChar(me.focusedCell) == "") + me.moveFocus(me, initialCell, step); +} + +void XonoticCharmap_enterChar(entity me) +{ + string character = charmap_cellToChar(me.focusedCell); + if(character != "") + me.inputBox.enterText(me.inputBox, character); +} + +void XonoticCharmap_focusLeave(entity me) +{ + me.inputBox.saveCvars(me.inputBox); +} + +void XonoticCharmap_draw(entity me) +{ + string character; + vector cell, cellPos, charPos; + cell = '0 0 0'; + cellPos = '0 0 0'; + charPos = '0 0 0'; + + float CHAR_OFFSET_X = me.realCellSize_x / 2; + float CHAR_OFFSET_Y = (me.realCellSize_y - me.realFontSize_y) / 2; + + for(cell_y = 0; cell_y < CHARMAP_ROWS; ++cell_y) + { + charPos_y = cell_y / CHARMAP_ROWS + CHAR_OFFSET_Y; + for(cell_x = 0; cell_x < CHARMAP_COLS; ++cell_x) + { + character = charmap_cellToChar(cell); + + if(character == "") + continue; + + // Draw focused cell + if(cell == me.focusedCell && me.focused) + { + if(!me.pressed || me.focusedCell == me.previouslyFocusedCell) + { + cellPos_x = mod(me.focusedCell_x, CHARMAP_COLS) / CHARMAP_COLS; + cellPos_y = mod(me.focusedCell_y, CHARMAP_ROWS) / CHARMAP_ROWS; + draw_Fill(cellPos, me.realCellSize, SKINCOLOR_CHARMAP_FOCUS, SKINALPHA_CHARMAP_FOCUS); + } + } + + // Draw character + charPos_x = cell_x / CHARMAP_COLS + CHAR_OFFSET_X; + draw_CenterText(charPos, character, me.realFontSize, SKINCOLOR_CHARMAP_CHAR, SKINALPHA_CHARMAP_CHAR, 0); + } + } +} +#endif diff --git a/qcsrc/menu/xonotic/checkbox.c b/qcsrc/menu/xonotic/checkbox.c deleted file mode 100644 index 631a430dc..000000000 --- a/qcsrc/menu/xonotic/checkbox.c +++ /dev/null @@ -1,104 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCheckBox) EXTENDS(CheckBox) - METHOD(XonoticCheckBox, configureXonoticCheckBox, void(entity, float, float, string, string)) - METHOD(XonoticCheckBox, setChecked, void(entity, float)) - ATTRIB(XonoticCheckBox, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticCheckBox, image, string, SKINGFX_CHECKBOX) - ATTRIB(XonoticCheckBox, yesValue, float, 1) - ATTRIB(XonoticCheckBox, noValue, float, 0) - - ATTRIB(XonoticCheckBox, color, vector, SKINCOLOR_CHECKBOX_N) - ATTRIB(XonoticCheckBox, colorC, vector, SKINCOLOR_CHECKBOX_C) - ATTRIB(XonoticCheckBox, colorF, vector, SKINCOLOR_CHECKBOX_F) - ATTRIB(XonoticCheckBox, colorD, vector, SKINCOLOR_CHECKBOX_D) - - ATTRIB(XonoticCheckBox, cvarName, string, string_null) - METHOD(XonoticCheckBox, loadCvars, void(entity)) - METHOD(XonoticCheckBox, saveCvars, void(entity)) - ATTRIB(XonoticCheckBox, sendCvars, float, 0) - - ATTRIB(XonoticCheckBox, alpha, float, SKINALPHA_TEXT) - ATTRIB(XonoticCheckBox, disabledAlpha, float, SKINALPHA_DISABLED) -ENDCLASS(XonoticCheckBox) -entity makeXonoticCheckBox(float, string, string); -entity makeXonoticCheckBoxEx(float, float, string, string); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticCheckBox(float isInverted, string theCvar, string theText) -{ - float y, n; - if(isInverted > 1) - { - n = isInverted - 1; - y = -n; - } - else if(isInverted < -1) - { - n = isInverted + 1; - y = -n; - } - else if(isInverted == 1) - { - n = 1; - y = 0; - } - else - { - n = 0; - y = 1; - } - return makeXonoticCheckBoxEx(y, n, theCvar, theText); -} -entity makeXonoticCheckBoxEx(float theYesValue, float theNoValue, string theCvar, string theText) -{ - entity me; - me = spawnXonoticCheckBox(); - me.configureXonoticCheckBox(me, theYesValue, theNoValue, theCvar, theText); - return me; -} -void XonoticCheckBox_configureXonoticCheckBox(entity me, float theYesValue, float theNoValue, string theCvar, string theText) -{ - me.yesValue = theYesValue; - me.noValue = theNoValue; - me.checked = 0; - if(theCvar) - { - me.cvarName = theCvar; - me.tooltip = getZonedTooltipForIdentifier(theCvar); - me.loadCvars(me); - } - me.configureCheckBox(me, theText, me.fontSize, me.image); -} -void XonoticCheckBox_setChecked(entity me, float val) -{ - if(val != me.checked) - { - me.checked = val; - me.saveCvars(me); - } -} -void XonoticCheckBox_loadCvars(entity me) -{ - float m, d; - - if (!me.cvarName) - return; - - m = (me.yesValue + me.noValue) * 0.5; - d = (cvar(me.cvarName) - m) / (me.yesValue - m); - me.checked = (d > 0); -} -void XonoticCheckBox_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - if(me.checked) - cvar_set(me.cvarName, ftos(me.yesValue)); - else - cvar_set(me.cvarName, ftos(me.noValue)); - - CheckSendCvars(me, me.cvarName); -} -#endif diff --git a/qcsrc/menu/xonotic/checkbox.qc b/qcsrc/menu/xonotic/checkbox.qc new file mode 100644 index 000000000..631a430dc --- /dev/null +++ b/qcsrc/menu/xonotic/checkbox.qc @@ -0,0 +1,104 @@ +#ifdef INTERFACE +CLASS(XonoticCheckBox) EXTENDS(CheckBox) + METHOD(XonoticCheckBox, configureXonoticCheckBox, void(entity, float, float, string, string)) + METHOD(XonoticCheckBox, setChecked, void(entity, float)) + ATTRIB(XonoticCheckBox, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticCheckBox, image, string, SKINGFX_CHECKBOX) + ATTRIB(XonoticCheckBox, yesValue, float, 1) + ATTRIB(XonoticCheckBox, noValue, float, 0) + + ATTRIB(XonoticCheckBox, color, vector, SKINCOLOR_CHECKBOX_N) + ATTRIB(XonoticCheckBox, colorC, vector, SKINCOLOR_CHECKBOX_C) + ATTRIB(XonoticCheckBox, colorF, vector, SKINCOLOR_CHECKBOX_F) + ATTRIB(XonoticCheckBox, colorD, vector, SKINCOLOR_CHECKBOX_D) + + ATTRIB(XonoticCheckBox, cvarName, string, string_null) + METHOD(XonoticCheckBox, loadCvars, void(entity)) + METHOD(XonoticCheckBox, saveCvars, void(entity)) + ATTRIB(XonoticCheckBox, sendCvars, float, 0) + + ATTRIB(XonoticCheckBox, alpha, float, SKINALPHA_TEXT) + ATTRIB(XonoticCheckBox, disabledAlpha, float, SKINALPHA_DISABLED) +ENDCLASS(XonoticCheckBox) +entity makeXonoticCheckBox(float, string, string); +entity makeXonoticCheckBoxEx(float, float, string, string); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticCheckBox(float isInverted, string theCvar, string theText) +{ + float y, n; + if(isInverted > 1) + { + n = isInverted - 1; + y = -n; + } + else if(isInverted < -1) + { + n = isInverted + 1; + y = -n; + } + else if(isInverted == 1) + { + n = 1; + y = 0; + } + else + { + n = 0; + y = 1; + } + return makeXonoticCheckBoxEx(y, n, theCvar, theText); +} +entity makeXonoticCheckBoxEx(float theYesValue, float theNoValue, string theCvar, string theText) +{ + entity me; + me = spawnXonoticCheckBox(); + me.configureXonoticCheckBox(me, theYesValue, theNoValue, theCvar, theText); + return me; +} +void XonoticCheckBox_configureXonoticCheckBox(entity me, float theYesValue, float theNoValue, string theCvar, string theText) +{ + me.yesValue = theYesValue; + me.noValue = theNoValue; + me.checked = 0; + if(theCvar) + { + me.cvarName = theCvar; + me.tooltip = getZonedTooltipForIdentifier(theCvar); + me.loadCvars(me); + } + me.configureCheckBox(me, theText, me.fontSize, me.image); +} +void XonoticCheckBox_setChecked(entity me, float val) +{ + if(val != me.checked) + { + me.checked = val; + me.saveCvars(me); + } +} +void XonoticCheckBox_loadCvars(entity me) +{ + float m, d; + + if (!me.cvarName) + return; + + m = (me.yesValue + me.noValue) * 0.5; + d = (cvar(me.cvarName) - m) / (me.yesValue - m); + me.checked = (d > 0); +} +void XonoticCheckBox_saveCvars(entity me) +{ + if (!me.cvarName) + return; + + if(me.checked) + cvar_set(me.cvarName, ftos(me.yesValue)); + else + cvar_set(me.cvarName, ftos(me.noValue)); + + CheckSendCvars(me, me.cvarName); +} +#endif diff --git a/qcsrc/menu/xonotic/checkbox_slider_invalid.c b/qcsrc/menu/xonotic/checkbox_slider_invalid.c deleted file mode 100644 index e3043184a..000000000 --- a/qcsrc/menu/xonotic/checkbox_slider_invalid.c +++ /dev/null @@ -1,65 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticSliderCheckBox) EXTENDS(CheckBox) - METHOD(XonoticSliderCheckBox, configureXonoticSliderCheckBox, void(entity, float, float, entity, string)) - METHOD(XonoticSliderCheckBox, setChecked, void(entity, float)) - METHOD(XonoticSliderCheckBox, draw, void(entity)) - ATTRIB(XonoticSliderCheckBox, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticSliderCheckBox, image, string, SKINGFX_CHECKBOX) - - ATTRIB(XonoticSliderCheckBox, color, vector, SKINCOLOR_CHECKBOX_N) - ATTRIB(XonoticSliderCheckBox, colorC, vector, SKINCOLOR_CHECKBOX_C) - ATTRIB(XonoticSliderCheckBox, colorF, vector, SKINCOLOR_CHECKBOX_F) - ATTRIB(XonoticSliderCheckBox, colorD, vector, SKINCOLOR_CHECKBOX_D) - - ATTRIB(XonoticSliderCheckBox, alpha, float, SKINALPHA_TEXT) - ATTRIB(XonoticSliderCheckBox, disabledAlpha, float, SKINALPHA_DISABLED) - - ATTRIB(XonoticSliderCheckBox, controlledSlider, entity, NULL) - ATTRIB(XonoticSliderCheckBox, offValue, float, -1) - ATTRIB(XonoticSliderCheckBox, inverted, float, 0) - ATTRIB(XonoticSliderCheckBox, savedValue, float, -1) -ENDCLASS(XonoticSliderCheckBox) -entity makeXonoticSliderCheckBox(float, float, entity, string); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticSliderCheckBox(float theOffValue, float isInverted, entity theControlledSlider, string theText) -{ - entity me; - me = spawnXonoticSliderCheckBox(); - me.configureXonoticSliderCheckBox(me, theOffValue, isInverted, theControlledSlider, theText); - return me; -} -void XonoticSliderCheckBox_configureXonoticSliderCheckBox(entity me, float theOffValue, float isInverted, entity theControlledSlider, string theText) -{ - me.offValue = theOffValue; - me.inverted = isInverted; - me.checked = (theControlledSlider.value == theOffValue); - if(theControlledSlider.value == median(theControlledSlider.valueMin, theControlledSlider.value, theControlledSlider.valueMax)) - me.savedValue = theControlledSlider.value; - else - me.savedValue = theControlledSlider.valueMin; - me.controlledSlider = theControlledSlider; - me.configureCheckBox(me, theText, me.fontSize, me.image); - me.tooltip = theControlledSlider.tooltip; - me.cvarName = theControlledSlider.cvarName; // in case we want to display the cvar in the tooltip -} -void XonoticSliderCheckBox_draw(entity me) -{ - me.checked = ((me.controlledSlider.value == me.offValue) != me.inverted); - if(me.controlledSlider.value == median(me.controlledSlider.valueMin, me.controlledSlider.value, me.controlledSlider.valueMax)) - me.savedValue = me.controlledSlider.value; - SUPER(XonoticSliderCheckBox).draw(me); -} -void XonoticSliderCheckBox_setChecked(entity me, float val) -{ - if(me.checked == val) - return; - me.checked = val; - if(val == me.inverted) - me.controlledSlider.setValue(me.controlledSlider, median(me.controlledSlider.valueMin, me.savedValue, me.controlledSlider.valueMax)); - else - me.controlledSlider.setValue(me.controlledSlider, me.offValue); -} - -#endif diff --git a/qcsrc/menu/xonotic/checkbox_slider_invalid.qc b/qcsrc/menu/xonotic/checkbox_slider_invalid.qc new file mode 100644 index 000000000..e3043184a --- /dev/null +++ b/qcsrc/menu/xonotic/checkbox_slider_invalid.qc @@ -0,0 +1,65 @@ +#ifdef INTERFACE +CLASS(XonoticSliderCheckBox) EXTENDS(CheckBox) + METHOD(XonoticSliderCheckBox, configureXonoticSliderCheckBox, void(entity, float, float, entity, string)) + METHOD(XonoticSliderCheckBox, setChecked, void(entity, float)) + METHOD(XonoticSliderCheckBox, draw, void(entity)) + ATTRIB(XonoticSliderCheckBox, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticSliderCheckBox, image, string, SKINGFX_CHECKBOX) + + ATTRIB(XonoticSliderCheckBox, color, vector, SKINCOLOR_CHECKBOX_N) + ATTRIB(XonoticSliderCheckBox, colorC, vector, SKINCOLOR_CHECKBOX_C) + ATTRIB(XonoticSliderCheckBox, colorF, vector, SKINCOLOR_CHECKBOX_F) + ATTRIB(XonoticSliderCheckBox, colorD, vector, SKINCOLOR_CHECKBOX_D) + + ATTRIB(XonoticSliderCheckBox, alpha, float, SKINALPHA_TEXT) + ATTRIB(XonoticSliderCheckBox, disabledAlpha, float, SKINALPHA_DISABLED) + + ATTRIB(XonoticSliderCheckBox, controlledSlider, entity, NULL) + ATTRIB(XonoticSliderCheckBox, offValue, float, -1) + ATTRIB(XonoticSliderCheckBox, inverted, float, 0) + ATTRIB(XonoticSliderCheckBox, savedValue, float, -1) +ENDCLASS(XonoticSliderCheckBox) +entity makeXonoticSliderCheckBox(float, float, entity, string); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticSliderCheckBox(float theOffValue, float isInverted, entity theControlledSlider, string theText) +{ + entity me; + me = spawnXonoticSliderCheckBox(); + me.configureXonoticSliderCheckBox(me, theOffValue, isInverted, theControlledSlider, theText); + return me; +} +void XonoticSliderCheckBox_configureXonoticSliderCheckBox(entity me, float theOffValue, float isInverted, entity theControlledSlider, string theText) +{ + me.offValue = theOffValue; + me.inverted = isInverted; + me.checked = (theControlledSlider.value == theOffValue); + if(theControlledSlider.value == median(theControlledSlider.valueMin, theControlledSlider.value, theControlledSlider.valueMax)) + me.savedValue = theControlledSlider.value; + else + me.savedValue = theControlledSlider.valueMin; + me.controlledSlider = theControlledSlider; + me.configureCheckBox(me, theText, me.fontSize, me.image); + me.tooltip = theControlledSlider.tooltip; + me.cvarName = theControlledSlider.cvarName; // in case we want to display the cvar in the tooltip +} +void XonoticSliderCheckBox_draw(entity me) +{ + me.checked = ((me.controlledSlider.value == me.offValue) != me.inverted); + if(me.controlledSlider.value == median(me.controlledSlider.valueMin, me.controlledSlider.value, me.controlledSlider.valueMax)) + me.savedValue = me.controlledSlider.value; + SUPER(XonoticSliderCheckBox).draw(me); +} +void XonoticSliderCheckBox_setChecked(entity me, float val) +{ + if(me.checked == val) + return; + me.checked = val; + if(val == me.inverted) + me.controlledSlider.setValue(me.controlledSlider, median(me.controlledSlider.valueMin, me.savedValue, me.controlledSlider.valueMax)); + else + me.controlledSlider.setValue(me.controlledSlider, me.offValue); +} + +#endif diff --git a/qcsrc/menu/xonotic/checkbox_string.c b/qcsrc/menu/xonotic/checkbox_string.c deleted file mode 100644 index aeda757f0..000000000 --- a/qcsrc/menu/xonotic/checkbox_string.c +++ /dev/null @@ -1,72 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCheckBoxString) EXTENDS(CheckBox) - METHOD(XonoticCheckBoxString, configureXonoticCheckBoxString, void(entity, string, string, string, string)) - METHOD(XonoticCheckBoxString, setChecked, void(entity, float)) - ATTRIB(XonoticCheckBoxString, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticCheckBoxString, image, string, SKINGFX_CHECKBOX) - ATTRIB(XonoticCheckBoxString, yesString, string, string_null) - ATTRIB(XonoticCheckBoxString, noString, string, string_null) - - ATTRIB(XonoticCheckBoxString, color, vector, SKINCOLOR_CHECKBOX_N) - ATTRIB(XonoticCheckBoxString, colorC, vector, SKINCOLOR_CHECKBOX_C) - ATTRIB(XonoticCheckBoxString, colorF, vector, SKINCOLOR_CHECKBOX_F) - ATTRIB(XonoticCheckBoxString, colorD, vector, SKINCOLOR_CHECKBOX_D) - - ATTRIB(XonoticCheckBoxString, cvarName, string, string_null) - METHOD(XonoticCheckBoxString, loadCvars, void(entity)) - METHOD(XonoticCheckBoxString, saveCvars, void(entity)) - ATTRIB(XonoticCheckBoxString, sendCvars, float, 0) - - ATTRIB(XonoticCheckBoxString, alpha, float, SKINALPHA_TEXT) - ATTRIB(XonoticCheckBoxString, disabledAlpha, float, SKINALPHA_DISABLED) -ENDCLASS(XonoticCheckBoxString) -entity makeXonoticCheckBoxString(string, string, string, string); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticCheckBoxString(string theYesValue, string theNoValue, string theCvar, string theText) -{ - entity me; - me = spawnXonoticCheckBoxString(); - me.configureXonoticCheckBoxString(me, theYesValue, theNoValue, theCvar, theText); - return me; -} -void XonoticCheckBoxString_configureXonoticCheckBoxString(entity me, string theYesValue, string theNoValue, string theCvar, string theText) -{ - me.yesString = theYesValue; - me.noString = theNoValue; - me.checked = 0; - if(theCvar) - { - me.cvarName = theCvar; - me.tooltip = getZonedTooltipForIdentifier(theCvar); - me.loadCvars(me); - } - me.configureCheckBox(me, theText, me.fontSize, me.image); -} -void XonoticCheckBoxString_setChecked(entity me, float foo) -{ - me.checked = !me.checked; - me.saveCvars(me); -} -void XonoticCheckBoxString_loadCvars(entity me) -{ - if (!me.cvarName) - return; - - if(cvar_string(me.cvarName) == me.yesString) - me.checked = 1; -} -void XonoticCheckBoxString_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - if(me.checked) - cvar_set(me.cvarName, me.yesString); - else - cvar_set(me.cvarName, me.noString); - - CheckSendCvars(me, me.cvarName); -} -#endif diff --git a/qcsrc/menu/xonotic/checkbox_string.qc b/qcsrc/menu/xonotic/checkbox_string.qc new file mode 100644 index 000000000..aeda757f0 --- /dev/null +++ b/qcsrc/menu/xonotic/checkbox_string.qc @@ -0,0 +1,72 @@ +#ifdef INTERFACE +CLASS(XonoticCheckBoxString) EXTENDS(CheckBox) + METHOD(XonoticCheckBoxString, configureXonoticCheckBoxString, void(entity, string, string, string, string)) + METHOD(XonoticCheckBoxString, setChecked, void(entity, float)) + ATTRIB(XonoticCheckBoxString, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticCheckBoxString, image, string, SKINGFX_CHECKBOX) + ATTRIB(XonoticCheckBoxString, yesString, string, string_null) + ATTRIB(XonoticCheckBoxString, noString, string, string_null) + + ATTRIB(XonoticCheckBoxString, color, vector, SKINCOLOR_CHECKBOX_N) + ATTRIB(XonoticCheckBoxString, colorC, vector, SKINCOLOR_CHECKBOX_C) + ATTRIB(XonoticCheckBoxString, colorF, vector, SKINCOLOR_CHECKBOX_F) + ATTRIB(XonoticCheckBoxString, colorD, vector, SKINCOLOR_CHECKBOX_D) + + ATTRIB(XonoticCheckBoxString, cvarName, string, string_null) + METHOD(XonoticCheckBoxString, loadCvars, void(entity)) + METHOD(XonoticCheckBoxString, saveCvars, void(entity)) + ATTRIB(XonoticCheckBoxString, sendCvars, float, 0) + + ATTRIB(XonoticCheckBoxString, alpha, float, SKINALPHA_TEXT) + ATTRIB(XonoticCheckBoxString, disabledAlpha, float, SKINALPHA_DISABLED) +ENDCLASS(XonoticCheckBoxString) +entity makeXonoticCheckBoxString(string, string, string, string); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticCheckBoxString(string theYesValue, string theNoValue, string theCvar, string theText) +{ + entity me; + me = spawnXonoticCheckBoxString(); + me.configureXonoticCheckBoxString(me, theYesValue, theNoValue, theCvar, theText); + return me; +} +void XonoticCheckBoxString_configureXonoticCheckBoxString(entity me, string theYesValue, string theNoValue, string theCvar, string theText) +{ + me.yesString = theYesValue; + me.noString = theNoValue; + me.checked = 0; + if(theCvar) + { + me.cvarName = theCvar; + me.tooltip = getZonedTooltipForIdentifier(theCvar); + me.loadCvars(me); + } + me.configureCheckBox(me, theText, me.fontSize, me.image); +} +void XonoticCheckBoxString_setChecked(entity me, float foo) +{ + me.checked = !me.checked; + me.saveCvars(me); +} +void XonoticCheckBoxString_loadCvars(entity me) +{ + if (!me.cvarName) + return; + + if(cvar_string(me.cvarName) == me.yesString) + me.checked = 1; +} +void XonoticCheckBoxString_saveCvars(entity me) +{ + if (!me.cvarName) + return; + + if(me.checked) + cvar_set(me.cvarName, me.yesString); + else + cvar_set(me.cvarName, me.noString); + + CheckSendCvars(me, me.cvarName); +} +#endif diff --git a/qcsrc/menu/xonotic/colorbutton.c b/qcsrc/menu/xonotic/colorbutton.c deleted file mode 100644 index bcbdfee8d..000000000 --- a/qcsrc/menu/xonotic/colorbutton.c +++ /dev/null @@ -1,100 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticColorButton) EXTENDS(RadioButton) - METHOD(XonoticColorButton, configureXonoticColorButton, void(entity, float, float, float)) - METHOD(XonoticColorButton, setChecked, void(entity, float)) - METHOD(XonoticColorButton, draw, void(entity)) - ATTRIB(XonoticColorButton, fontSize, float, 0) - ATTRIB(XonoticColorButton, image, string, SKINGFX_COLORBUTTON) - - ATTRIB(XonoticColorButton, useDownAsChecked, float, 1) - - ATTRIB(XonoticColorButton, cvarPart, float, 0) - ATTRIB(XonoticColorButton, cvarName, string, string_null) - ATTRIB(XonoticColorButton, cvarValueFloat, float, 0) - METHOD(XonoticColorButton, loadCvars, void(entity)) - METHOD(XonoticColorButton, saveCvars, void(entity)) -ENDCLASS(XonoticColorButton) -entity makeXonoticColorButton(float, float, float); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticColorButton(float theGroup, float theColor, float theValue) -{ - entity me; - me = spawnXonoticColorButton(); - me.configureXonoticColorButton(me, theGroup, theColor, theValue); - return me; -} -void XonoticColorButton_configureXonoticColorButton(entity me, float theGroup, float theColor, float theValue) -{ - switch(theValue) - { - // rearrange 1..14 for rainbow order - case 1: theValue = 10; break; - case 2: theValue = 4; break; - case 3: theValue = 1; break; - case 4: theValue = 14; break; - case 5: theValue = 12; break; - case 6: theValue = 7; break; - case 7: theValue = 3; break; - case 8: theValue = 2; break; - case 9: theValue = 6; break; - case 10: theValue = 5; break; - case 11: theValue = 13; break; - case 12: theValue = 11; break; - case 13: theValue = 8; break; - case 14: theValue = 9; break; - default: - // no change - break; - } - me.cvarName = "_cl_color"; - me.cvarValueFloat = theValue; - me.cvarPart = theColor; - me.loadCvars(me); - me.configureRadioButton(me, string_null, me.fontSize, me.image, theGroup, 0); -} -void XonoticColorButton_setChecked(entity me, float val) -{ - if(val != me.checked) - { - me.checked = val; - me.saveCvars(me); - } -} -void XonoticColorButton_loadCvars(entity me) -{ - if (!me.cvarName) - return; - - if(cvar_string(me.cvarName) == cvar_defstring(me.cvarName)) - cvar_set(me.cvarName, ftos(16 * floor(random() * 15) + floor(random() * 15))); - - if(me.cvarPart == 1) - me.checked = (cvar(me.cvarName) & 240) == me.cvarValueFloat * 16; - else - me.checked = (cvar(me.cvarName) & 15) == me.cvarValueFloat; -} -void XonoticColorButton_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - if(me.checked) - { - if(me.cvarPart == 1) - cvar_set(me.cvarName, ftos((cvar(me.cvarName) & 15) + me.cvarValueFloat * 16)); - else - cvar_set(me.cvarName, ftos((cvar(me.cvarName) & 240) + me.cvarValueFloat)); - } - // TODO on an apply button, read _cl_color and execute the color command for it -} -void XonoticColorButton_draw(entity me) -{ - me.color = colormapPaletteColor(me.cvarValueFloat, me.cvarPart); - me.colorC = me.color; - me.colorF = me.color; - me.colorD = me.color; - SUPER(XonoticColorButton).draw(me); -} -#endif diff --git a/qcsrc/menu/xonotic/colorbutton.qc b/qcsrc/menu/xonotic/colorbutton.qc new file mode 100644 index 000000000..bcbdfee8d --- /dev/null +++ b/qcsrc/menu/xonotic/colorbutton.qc @@ -0,0 +1,100 @@ +#ifdef INTERFACE +CLASS(XonoticColorButton) EXTENDS(RadioButton) + METHOD(XonoticColorButton, configureXonoticColorButton, void(entity, float, float, float)) + METHOD(XonoticColorButton, setChecked, void(entity, float)) + METHOD(XonoticColorButton, draw, void(entity)) + ATTRIB(XonoticColorButton, fontSize, float, 0) + ATTRIB(XonoticColorButton, image, string, SKINGFX_COLORBUTTON) + + ATTRIB(XonoticColorButton, useDownAsChecked, float, 1) + + ATTRIB(XonoticColorButton, cvarPart, float, 0) + ATTRIB(XonoticColorButton, cvarName, string, string_null) + ATTRIB(XonoticColorButton, cvarValueFloat, float, 0) + METHOD(XonoticColorButton, loadCvars, void(entity)) + METHOD(XonoticColorButton, saveCvars, void(entity)) +ENDCLASS(XonoticColorButton) +entity makeXonoticColorButton(float, float, float); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticColorButton(float theGroup, float theColor, float theValue) +{ + entity me; + me = spawnXonoticColorButton(); + me.configureXonoticColorButton(me, theGroup, theColor, theValue); + return me; +} +void XonoticColorButton_configureXonoticColorButton(entity me, float theGroup, float theColor, float theValue) +{ + switch(theValue) + { + // rearrange 1..14 for rainbow order + case 1: theValue = 10; break; + case 2: theValue = 4; break; + case 3: theValue = 1; break; + case 4: theValue = 14; break; + case 5: theValue = 12; break; + case 6: theValue = 7; break; + case 7: theValue = 3; break; + case 8: theValue = 2; break; + case 9: theValue = 6; break; + case 10: theValue = 5; break; + case 11: theValue = 13; break; + case 12: theValue = 11; break; + case 13: theValue = 8; break; + case 14: theValue = 9; break; + default: + // no change + break; + } + me.cvarName = "_cl_color"; + me.cvarValueFloat = theValue; + me.cvarPart = theColor; + me.loadCvars(me); + me.configureRadioButton(me, string_null, me.fontSize, me.image, theGroup, 0); +} +void XonoticColorButton_setChecked(entity me, float val) +{ + if(val != me.checked) + { + me.checked = val; + me.saveCvars(me); + } +} +void XonoticColorButton_loadCvars(entity me) +{ + if (!me.cvarName) + return; + + if(cvar_string(me.cvarName) == cvar_defstring(me.cvarName)) + cvar_set(me.cvarName, ftos(16 * floor(random() * 15) + floor(random() * 15))); + + if(me.cvarPart == 1) + me.checked = (cvar(me.cvarName) & 240) == me.cvarValueFloat * 16; + else + me.checked = (cvar(me.cvarName) & 15) == me.cvarValueFloat; +} +void XonoticColorButton_saveCvars(entity me) +{ + if (!me.cvarName) + return; + + if(me.checked) + { + if(me.cvarPart == 1) + cvar_set(me.cvarName, ftos((cvar(me.cvarName) & 15) + me.cvarValueFloat * 16)); + else + cvar_set(me.cvarName, ftos((cvar(me.cvarName) & 240) + me.cvarValueFloat)); + } + // TODO on an apply button, read _cl_color and execute the color command for it +} +void XonoticColorButton_draw(entity me) +{ + me.color = colormapPaletteColor(me.cvarValueFloat, me.cvarPart); + me.colorC = me.color; + me.colorF = me.color; + me.colorD = me.color; + SUPER(XonoticColorButton).draw(me); +} +#endif diff --git a/qcsrc/menu/xonotic/colorpicker.c b/qcsrc/menu/xonotic/colorpicker.c deleted file mode 100644 index e0727373c..000000000 --- a/qcsrc/menu/xonotic/colorpicker.c +++ /dev/null @@ -1,174 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticColorpicker) EXTENDS(Image) - METHOD(XonoticColorpicker, configureXonoticColorpicker, void(entity, entity)) - METHOD(XonoticColorpicker, mousePress, float(entity, vector)) - METHOD(XonoticColorpicker, mouseRelease, float(entity, vector)) - METHOD(XonoticColorpicker, mouseDrag, float(entity, vector)) - ATTRIB(XonoticColorpicker, controlledTextbox, entity, NULL) - ATTRIB(XonoticColorpicker, image, string, SKINGFX_COLORPICKER) - ATTRIB(XonoticColorpicker, imagemargin, vector, SKINMARGIN_COLORPICKER) - ATTRIB(XonoticColorpicker, focusable, float, 1) - METHOD(XonoticColorpicker, focusLeave, void(entity)) - METHOD(XonoticColorpicker, keyDown, float(entity, float, float, float)) - METHOD(XonoticColorpicker, draw, void(entity)) -ENDCLASS(XonoticColorpicker) -entity makeXonoticColorpicker(entity theTextbox); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticColorpicker(entity theTextbox) -{ - entity me; - me = spawnXonoticColorpicker(); - me.configureXonoticColorpicker(me, theTextbox); - return me; -} - -void XonoticColorpicker_configureXonoticColorpicker(entity me, entity theTextbox) -{ - me.controlledTextbox = theTextbox; - me.configureImage(me, me.image); -} - -float XonoticColorpicker_mousePress(entity me, vector coords) -{ - me.mouseDrag(me, coords); - return 1; -} - -// must match hslimage.c -vector hslimage_color(vector v, vector margin) -{ - v_x = (v_x - margin_x) / (1 - 2 * margin_x); - v_y = (v_y - margin_y) / (1 - 2 * margin_y); - if(v_x < 0) v_x = 0; - if(v_y < 0) v_y = 0; - if(v_x > 1) v_x = 1; - if(v_y > 1) v_y = 1; - if(v_y > 0.875) // grey bar - return hsl_to_rgb(eZ * v_x); - else - return hsl_to_rgb(v_x * 6 * eX + eY + v_y / 0.875 * eZ); -} - -vector color_hslimage(vector v, vector margin) -{ - vector pos = '0 0 0'; - v = rgb_to_hsl(v); - if (v_y) - { - pos_x = v_x / 6; - pos_y = v_z * 0.875; - } - else // grey scale - { - pos_x = v_z; - pos_y = 0.875 + 0.07; - } - pos_x = margin_x + pos_x * (1 - 2 * margin_x); - pos_y = margin_y + pos_y * (1 - 2 * margin_y); - return pos; -} - -float XonoticColorpicker_mouseDrag(entity me, vector coords) -{ - float i, carets; - for(;;) - { - i = me.controlledTextbox.cursorPos; - if(i >= 2) - { - if(substring(me.controlledTextbox.text, i-2, 1) == "^") - { - carets = 1; - while (i - 2 - carets >= 0 && substring(me.controlledTextbox.text, i - 2 - carets, 1) == "^") - ++carets; - if (carets & 1) - if(strstrofs("0123456789", substring(me.controlledTextbox.text, i-1, 1), 0) >= 0) - { - me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); - me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); - continue; - } - } - } - - if(i >= 5) - { - if(substring(me.controlledTextbox.text, i-5, 2) == "^x") - { - carets = 1; - while (i - 5 - carets >= 0 && substring(me.controlledTextbox.text, i - 5 - carets, 1) == "^") - ++carets; - if (carets & 1) - if(strstrofs("0123456789abcdefABCDEF", substring(me.controlledTextbox.text, i-3, 1), 0) >= 0) - if(strstrofs("0123456789abcdefABCDEF", substring(me.controlledTextbox.text, i-2, 1), 0) >= 0) - if(strstrofs("0123456789abcdefABCDEF", substring(me.controlledTextbox.text, i-1, 1), 0) >= 0) - { - me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); - me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); - me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); - me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); - me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); - continue; - } - } - } - break; - } - - if(substring(me.controlledTextbox.text, i-1, 1) == "^") - { - carets = 1; - while (i - 1 - carets >= 0 && substring(me.controlledTextbox.text, i - 1 - carets, 1) == "^") - ++carets; - if (carets & 1) - me.controlledTextbox.enterText(me.controlledTextbox, "^"); // escape previous caret - } - - vector margin; - margin = me.imagemargin; - if(coords_x >= margin_x) - if(coords_y >= margin_y) - if(coords_x <= 1 - margin_x) - if(coords_y <= 1 - margin_y) - me.controlledTextbox.enterText(me.controlledTextbox, rgb_to_hexcolor(hslimage_color(coords, margin))); - - return 1; -} - -float XonoticColorpicker_mouseRelease(entity me, vector coords) -{ - me.mouseDrag(me, coords); - return 1; -} - -void XonoticColorpicker_focusLeave(entity me) -{ - me.controlledTextbox.saveCvars(me.controlledTextbox); -} -float XonoticColorpicker_keyDown(entity me, float key, float ascii, float shift) -{ - return me.controlledTextbox.keyDown(me.controlledTextbox, key, ascii, shift); -} -void XonoticColorpicker_draw(entity me) -{ - SUPER(XonoticColorpicker).draw(me); - - float B, C, aC; - C = cvar("r_textcontrast"); - B = cvar("r_textbrightness"); - - // for this to work, C/(1-B) must be in 0..1 - // B must be < 1 - // C must be < 1-B - - B = bound(0, B, 1); - C = bound(0, C, 1-B); - - aC = 1 - C / (1 - B); - - draw_Picture(me.imgOrigin, strcat(me.src, "_m"), me.imgSize, '0 0 0', aC); - draw_Picture(me.imgOrigin, strcat(me.src, "_m"), me.imgSize, me.color, B); -} -#endif diff --git a/qcsrc/menu/xonotic/colorpicker.qc b/qcsrc/menu/xonotic/colorpicker.qc new file mode 100644 index 000000000..e0727373c --- /dev/null +++ b/qcsrc/menu/xonotic/colorpicker.qc @@ -0,0 +1,174 @@ +#ifdef INTERFACE +CLASS(XonoticColorpicker) EXTENDS(Image) + METHOD(XonoticColorpicker, configureXonoticColorpicker, void(entity, entity)) + METHOD(XonoticColorpicker, mousePress, float(entity, vector)) + METHOD(XonoticColorpicker, mouseRelease, float(entity, vector)) + METHOD(XonoticColorpicker, mouseDrag, float(entity, vector)) + ATTRIB(XonoticColorpicker, controlledTextbox, entity, NULL) + ATTRIB(XonoticColorpicker, image, string, SKINGFX_COLORPICKER) + ATTRIB(XonoticColorpicker, imagemargin, vector, SKINMARGIN_COLORPICKER) + ATTRIB(XonoticColorpicker, focusable, float, 1) + METHOD(XonoticColorpicker, focusLeave, void(entity)) + METHOD(XonoticColorpicker, keyDown, float(entity, float, float, float)) + METHOD(XonoticColorpicker, draw, void(entity)) +ENDCLASS(XonoticColorpicker) +entity makeXonoticColorpicker(entity theTextbox); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticColorpicker(entity theTextbox) +{ + entity me; + me = spawnXonoticColorpicker(); + me.configureXonoticColorpicker(me, theTextbox); + return me; +} + +void XonoticColorpicker_configureXonoticColorpicker(entity me, entity theTextbox) +{ + me.controlledTextbox = theTextbox; + me.configureImage(me, me.image); +} + +float XonoticColorpicker_mousePress(entity me, vector coords) +{ + me.mouseDrag(me, coords); + return 1; +} + +// must match hslimage.c +vector hslimage_color(vector v, vector margin) +{ + v_x = (v_x - margin_x) / (1 - 2 * margin_x); + v_y = (v_y - margin_y) / (1 - 2 * margin_y); + if(v_x < 0) v_x = 0; + if(v_y < 0) v_y = 0; + if(v_x > 1) v_x = 1; + if(v_y > 1) v_y = 1; + if(v_y > 0.875) // grey bar + return hsl_to_rgb(eZ * v_x); + else + return hsl_to_rgb(v_x * 6 * eX + eY + v_y / 0.875 * eZ); +} + +vector color_hslimage(vector v, vector margin) +{ + vector pos = '0 0 0'; + v = rgb_to_hsl(v); + if (v_y) + { + pos_x = v_x / 6; + pos_y = v_z * 0.875; + } + else // grey scale + { + pos_x = v_z; + pos_y = 0.875 + 0.07; + } + pos_x = margin_x + pos_x * (1 - 2 * margin_x); + pos_y = margin_y + pos_y * (1 - 2 * margin_y); + return pos; +} + +float XonoticColorpicker_mouseDrag(entity me, vector coords) +{ + float i, carets; + for(;;) + { + i = me.controlledTextbox.cursorPos; + if(i >= 2) + { + if(substring(me.controlledTextbox.text, i-2, 1) == "^") + { + carets = 1; + while (i - 2 - carets >= 0 && substring(me.controlledTextbox.text, i - 2 - carets, 1) == "^") + ++carets; + if (carets & 1) + if(strstrofs("0123456789", substring(me.controlledTextbox.text, i-1, 1), 0) >= 0) + { + me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); + me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); + continue; + } + } + } + + if(i >= 5) + { + if(substring(me.controlledTextbox.text, i-5, 2) == "^x") + { + carets = 1; + while (i - 5 - carets >= 0 && substring(me.controlledTextbox.text, i - 5 - carets, 1) == "^") + ++carets; + if (carets & 1) + if(strstrofs("0123456789abcdefABCDEF", substring(me.controlledTextbox.text, i-3, 1), 0) >= 0) + if(strstrofs("0123456789abcdefABCDEF", substring(me.controlledTextbox.text, i-2, 1), 0) >= 0) + if(strstrofs("0123456789abcdefABCDEF", substring(me.controlledTextbox.text, i-1, 1), 0) >= 0) + { + me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); + me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); + me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); + me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); + me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0); + continue; + } + } + } + break; + } + + if(substring(me.controlledTextbox.text, i-1, 1) == "^") + { + carets = 1; + while (i - 1 - carets >= 0 && substring(me.controlledTextbox.text, i - 1 - carets, 1) == "^") + ++carets; + if (carets & 1) + me.controlledTextbox.enterText(me.controlledTextbox, "^"); // escape previous caret + } + + vector margin; + margin = me.imagemargin; + if(coords_x >= margin_x) + if(coords_y >= margin_y) + if(coords_x <= 1 - margin_x) + if(coords_y <= 1 - margin_y) + me.controlledTextbox.enterText(me.controlledTextbox, rgb_to_hexcolor(hslimage_color(coords, margin))); + + return 1; +} + +float XonoticColorpicker_mouseRelease(entity me, vector coords) +{ + me.mouseDrag(me, coords); + return 1; +} + +void XonoticColorpicker_focusLeave(entity me) +{ + me.controlledTextbox.saveCvars(me.controlledTextbox); +} +float XonoticColorpicker_keyDown(entity me, float key, float ascii, float shift) +{ + return me.controlledTextbox.keyDown(me.controlledTextbox, key, ascii, shift); +} +void XonoticColorpicker_draw(entity me) +{ + SUPER(XonoticColorpicker).draw(me); + + float B, C, aC; + C = cvar("r_textcontrast"); + B = cvar("r_textbrightness"); + + // for this to work, C/(1-B) must be in 0..1 + // B must be < 1 + // C must be < 1-B + + B = bound(0, B, 1); + C = bound(0, C, 1-B); + + aC = 1 - C / (1 - B); + + draw_Picture(me.imgOrigin, strcat(me.src, "_m"), me.imgSize, '0 0 0', aC); + draw_Picture(me.imgOrigin, strcat(me.src, "_m"), me.imgSize, me.color, B); +} +#endif diff --git a/qcsrc/menu/xonotic/colorpicker_string.c b/qcsrc/menu/xonotic/colorpicker_string.c deleted file mode 100644 index 5d53135e9..000000000 --- a/qcsrc/menu/xonotic/colorpicker_string.c +++ /dev/null @@ -1,122 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticColorpickerString) EXTENDS(Image) - METHOD(XonoticColorpickerString, configureXonoticColorpickerString, void(entity, string, string)) - METHOD(XonoticColorpickerString, mousePress, float(entity, vector)) - METHOD(XonoticColorpickerString, mouseRelease, float(entity, vector)) - METHOD(XonoticColorpickerString, mouseDrag, float(entity, vector)) - ATTRIB(XonoticColorpickerString, cvarName, string, string_null) - METHOD(XonoticColorPickerString, loadCvars, void(entity)) - METHOD(XonoticColorPickerString, saveCvars, void(entity)) - ATTRIB(XonoticColorpickerString, prevcoords, vector, '0 0 0') - ATTRIB(XonoticColorpickerString, image, string, SKINGFX_COLORPICKER) - ATTRIB(XonoticColorpickerString, imagemargin, vector, SKINMARGIN_COLORPICKER) - ATTRIB(XonoticColorpickerString, focusable, float, 1) - METHOD(XonoticColorpickerString, draw, void(entity)) - ATTRIB(XonoticColorpickerString, disabledAlpha, float, 0.3) -ENDCLASS(XonoticColorpickerString) -entity makeXonoticColorpickerString(string theCvar, string theDefaultCvar); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticColorpickerString(string theCvar, string theDefaultCvar) -{ - entity me; - me = spawnXonoticColorpickerString(); - me.configureXonoticColorpickerString(me, theCvar, theDefaultCvar); - return me; -} - -void XonoticColorpickerString_configureXonoticColorpickerString(entity me, string theCvar, string theDefaultCvar) -{ - me.cvarName = theCvar; - me.configureImage(me, me.image); - if(theCvar) - { - me.cvarName = theCvar; - me.tooltip = getZonedTooltipForIdentifier(theCvar); - me.loadCvars(me); - } -} - -void XonoticColorPickerString_loadCvars(entity me) -{ - if (!me.cvarName) - return; - - if(substring(me.cvarName, -1, 1) == "_") - { - me.prevcoords = color_hslimage( - eX * cvar(strcat(me.cvarName, "red")) + - eY * cvar(strcat(me.cvarName, "green")) + - eZ * cvar(strcat(me.cvarName, "blue")), - me.imagemargin); - } - else - me.prevcoords = color_hslimage(stov(cvar_string(me.cvarName)), me.imagemargin); -} - -void XonoticColorPickerString_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - if(substring(me.cvarName, -1, 1) == "_") - { - vector v = hslimage_color(me.prevcoords, me.imagemargin); - cvar_set(strcat(me.cvarName, "red"), ftos(v_x)); - cvar_set(strcat(me.cvarName, "green"), ftos(v_y)); - cvar_set(strcat(me.cvarName, "blue"), ftos(v_z)); - } - else - cvar_set(me.cvarName, sprintf("%v", hslimage_color(me.prevcoords, me.imagemargin))); -} - -float XonoticColorpickerString_mousePress(entity me, vector coords) -{ - me.mouseDrag(me, coords); - return 1; -} - -float XonoticColorpickerString_mouseDrag(entity me, vector coords) -{ - if(me.disabled) - return 0; - vector margin; - margin = me.imagemargin; - if(coords_x >= margin_x) - if(coords_y >= margin_y) - if(coords_x <= 1 - margin_x) - if(coords_y <= 1 - margin_y) - { - me.prevcoords = coords; - me.saveCvars(me); - } - - return 1; -} - -float XonoticColorpickerString_mouseRelease(entity me, vector coords) -{ - me.mouseDrag(me, coords); - return 1; -} - -void XonoticColorpickerString_draw(entity me) -{ - float save; - save = draw_alpha; - if(me.disabled) - draw_alpha *= me.disabledAlpha; - - SUPER(XonoticColorpickerString).draw(me); - - vector sz; - sz = draw_PictureSize(strcat(me.src, "_selected")); - sz = globalToBoxSize(sz, draw_scale); - - if(!me.disabled) - draw_Picture(me.imgOrigin + me.prevcoords - 0.5 * sz, strcat(me.src, "_selected"), sz, '1 1 1', 1); - - draw_alpha = save; -} -#endif diff --git a/qcsrc/menu/xonotic/colorpicker_string.qc b/qcsrc/menu/xonotic/colorpicker_string.qc new file mode 100644 index 000000000..5d53135e9 --- /dev/null +++ b/qcsrc/menu/xonotic/colorpicker_string.qc @@ -0,0 +1,122 @@ +#ifdef INTERFACE +CLASS(XonoticColorpickerString) EXTENDS(Image) + METHOD(XonoticColorpickerString, configureXonoticColorpickerString, void(entity, string, string)) + METHOD(XonoticColorpickerString, mousePress, float(entity, vector)) + METHOD(XonoticColorpickerString, mouseRelease, float(entity, vector)) + METHOD(XonoticColorpickerString, mouseDrag, float(entity, vector)) + ATTRIB(XonoticColorpickerString, cvarName, string, string_null) + METHOD(XonoticColorPickerString, loadCvars, void(entity)) + METHOD(XonoticColorPickerString, saveCvars, void(entity)) + ATTRIB(XonoticColorpickerString, prevcoords, vector, '0 0 0') + ATTRIB(XonoticColorpickerString, image, string, SKINGFX_COLORPICKER) + ATTRIB(XonoticColorpickerString, imagemargin, vector, SKINMARGIN_COLORPICKER) + ATTRIB(XonoticColorpickerString, focusable, float, 1) + METHOD(XonoticColorpickerString, draw, void(entity)) + ATTRIB(XonoticColorpickerString, disabledAlpha, float, 0.3) +ENDCLASS(XonoticColorpickerString) +entity makeXonoticColorpickerString(string theCvar, string theDefaultCvar); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticColorpickerString(string theCvar, string theDefaultCvar) +{ + entity me; + me = spawnXonoticColorpickerString(); + me.configureXonoticColorpickerString(me, theCvar, theDefaultCvar); + return me; +} + +void XonoticColorpickerString_configureXonoticColorpickerString(entity me, string theCvar, string theDefaultCvar) +{ + me.cvarName = theCvar; + me.configureImage(me, me.image); + if(theCvar) + { + me.cvarName = theCvar; + me.tooltip = getZonedTooltipForIdentifier(theCvar); + me.loadCvars(me); + } +} + +void XonoticColorPickerString_loadCvars(entity me) +{ + if (!me.cvarName) + return; + + if(substring(me.cvarName, -1, 1) == "_") + { + me.prevcoords = color_hslimage( + eX * cvar(strcat(me.cvarName, "red")) + + eY * cvar(strcat(me.cvarName, "green")) + + eZ * cvar(strcat(me.cvarName, "blue")), + me.imagemargin); + } + else + me.prevcoords = color_hslimage(stov(cvar_string(me.cvarName)), me.imagemargin); +} + +void XonoticColorPickerString_saveCvars(entity me) +{ + if (!me.cvarName) + return; + + if(substring(me.cvarName, -1, 1) == "_") + { + vector v = hslimage_color(me.prevcoords, me.imagemargin); + cvar_set(strcat(me.cvarName, "red"), ftos(v_x)); + cvar_set(strcat(me.cvarName, "green"), ftos(v_y)); + cvar_set(strcat(me.cvarName, "blue"), ftos(v_z)); + } + else + cvar_set(me.cvarName, sprintf("%v", hslimage_color(me.prevcoords, me.imagemargin))); +} + +float XonoticColorpickerString_mousePress(entity me, vector coords) +{ + me.mouseDrag(me, coords); + return 1; +} + +float XonoticColorpickerString_mouseDrag(entity me, vector coords) +{ + if(me.disabled) + return 0; + vector margin; + margin = me.imagemargin; + if(coords_x >= margin_x) + if(coords_y >= margin_y) + if(coords_x <= 1 - margin_x) + if(coords_y <= 1 - margin_y) + { + me.prevcoords = coords; + me.saveCvars(me); + } + + return 1; +} + +float XonoticColorpickerString_mouseRelease(entity me, vector coords) +{ + me.mouseDrag(me, coords); + return 1; +} + +void XonoticColorpickerString_draw(entity me) +{ + float save; + save = draw_alpha; + if(me.disabled) + draw_alpha *= me.disabledAlpha; + + SUPER(XonoticColorpickerString).draw(me); + + vector sz; + sz = draw_PictureSize(strcat(me.src, "_selected")); + sz = globalToBoxSize(sz, draw_scale); + + if(!me.disabled) + draw_Picture(me.imgOrigin + me.prevcoords - 0.5 * sz, strcat(me.src, "_selected"), sz, '1 1 1', 1); + + draw_alpha = save; +} +#endif diff --git a/qcsrc/menu/xonotic/commandbutton.c b/qcsrc/menu/xonotic/commandbutton.c deleted file mode 100644 index 8ee4e7de3..000000000 --- a/qcsrc/menu/xonotic/commandbutton.c +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef COMMANDBUTTON_CLOSE -# define COMMANDBUTTON_CLOSE 1 -# define COMMANDBUTTON_APPLY 2 -//# define COMMANDBUTTON_REVERT 4 -#endif - -#ifdef INTERFACE -CLASS(XonoticCommandButton) EXTENDS(XonoticButton) - METHOD(XonoticCommandButton, configureXonoticCommandButton, void(entity, string, vector, string, float)) - ATTRIB(XonoticCommandButton, onClickCommand, string, string_null) - ATTRIB(XonoticCommandButton, flags, float, 0) -ENDCLASS(XonoticCommandButton) -entity makeXonoticCommandButton(string theText, vector theColor, string theCommand, float closesMenu); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticCommandButton(string theText, vector theColor, string theCommand, float theFlags) -{ - entity me; - me = spawnXonoticCommandButton(); - me.configureXonoticCommandButton(me, theText, theColor, theCommand, theFlags); - return me; -} - -void XonoticCommandButton_Click(entity me, entity other) -{ - //if(me.flags & COMMANDBUTTON_APPLY) - // saveAllCvars(me.parent); - cmd("\n", me.onClickCommand, "\n"); - //if(me.flags & COMMANDBUTTON_REVERT) - // loadAllCvars(me.parent); - if(me.flags & COMMANDBUTTON_CLOSE) - m_goto(string_null); -} - -void XonoticCommandButton_configureXonoticCommandButton(entity me, string theText, vector theColor, string theCommand, float theFlags) -{ - me.configureXonoticButton(me, theText, theColor); - me.onClickCommand = theCommand; - me.flags = theFlags; - me.onClick = XonoticCommandButton_Click; - me.onClickEntity = me; -} -#endif diff --git a/qcsrc/menu/xonotic/commandbutton.qc b/qcsrc/menu/xonotic/commandbutton.qc new file mode 100644 index 000000000..8ee4e7de3 --- /dev/null +++ b/qcsrc/menu/xonotic/commandbutton.qc @@ -0,0 +1,44 @@ +#ifndef COMMANDBUTTON_CLOSE +# define COMMANDBUTTON_CLOSE 1 +# define COMMANDBUTTON_APPLY 2 +//# define COMMANDBUTTON_REVERT 4 +#endif + +#ifdef INTERFACE +CLASS(XonoticCommandButton) EXTENDS(XonoticButton) + METHOD(XonoticCommandButton, configureXonoticCommandButton, void(entity, string, vector, string, float)) + ATTRIB(XonoticCommandButton, onClickCommand, string, string_null) + ATTRIB(XonoticCommandButton, flags, float, 0) +ENDCLASS(XonoticCommandButton) +entity makeXonoticCommandButton(string theText, vector theColor, string theCommand, float closesMenu); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticCommandButton(string theText, vector theColor, string theCommand, float theFlags) +{ + entity me; + me = spawnXonoticCommandButton(); + me.configureXonoticCommandButton(me, theText, theColor, theCommand, theFlags); + return me; +} + +void XonoticCommandButton_Click(entity me, entity other) +{ + //if(me.flags & COMMANDBUTTON_APPLY) + // saveAllCvars(me.parent); + cmd("\n", me.onClickCommand, "\n"); + //if(me.flags & COMMANDBUTTON_REVERT) + // loadAllCvars(me.parent); + if(me.flags & COMMANDBUTTON_CLOSE) + m_goto(string_null); +} + +void XonoticCommandButton_configureXonoticCommandButton(entity me, string theText, vector theColor, string theCommand, float theFlags) +{ + me.configureXonoticButton(me, theText, theColor); + me.onClickCommand = theCommand; + me.flags = theFlags; + me.onClick = XonoticCommandButton_Click; + me.onClickEntity = me; +} +#endif diff --git a/qcsrc/menu/xonotic/credits.c b/qcsrc/menu/xonotic/credits.c deleted file mode 100644 index 0d998d7de..000000000 --- a/qcsrc/menu/xonotic/credits.c +++ /dev/null @@ -1,112 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCreditsList) EXTENDS(XonoticListBox) - METHOD(XonoticCreditsList, configureXonoticCreditsList, void(entity)) - ATTRIB(XonoticCreditsList, rowsPerItem, float, 1) - METHOD(XonoticCreditsList, draw, void(entity)) - METHOD(XonoticCreditsList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticCreditsList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticCreditsList, keyDown, float(entity, float, float, float)) - METHOD(XonoticCreditsList, destroy, void(entity)) - - ATTRIB(XonoticCreditsList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticCreditsList, realUpperMargin, float, 0) - ATTRIB(XonoticCreditsList, bufferIndex, float, 0) - ATTRIB(XonoticCreditsList, scrolling, float, 0) - - ATTRIB(XonoticListBox, alphaBG, float, 0) -ENDCLASS(XonoticCreditsList) -entity makeXonoticCreditsList(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticCreditsList() -{ - entity me; - me = spawnXonoticCreditsList(); - me.configureXonoticCreditsList(me); - return me; -} -void XonoticCreditsList_configureXonoticCreditsList(entity me) -{ - me.configureXonoticListBox(me); - // load the file - me.bufferIndex = buf_load(language_filename("xonotic-credits.txt")); - me.nItems = buf_getsize(me.bufferIndex); -} -void XonoticCreditsList_destroy(entity me) -{ - buf_del(me.bufferIndex); -} -void XonoticCreditsList_draw(entity me) -{ - float i; - if(me.scrolling) - { - me.scrollPos = bound(0, (time - me.scrolling) * me.itemHeight, me.nItems * me.itemHeight - 1); - i = min(me.selectedItem, floor((me.scrollPos + 1) / me.itemHeight - 1)); - i = max(i, ceil(me.scrollPos / me.itemHeight)); - me.setSelected(me, i); - } - SUPER(XonoticCreditsList).draw(me); -} -void XonoticCreditsList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(XonoticCreditsList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); - me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); -} -void XonoticCreditsList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - // layout: Ping, Credits name, Map name, NP, TP, MP - string s; - float theAlpha; - vector theColor; - - s = bufstr_get(me.bufferIndex, i); - - if(substring(s, 0, 2) == "**") - { - s = substring(s, 2, strlen(s) - 2); - theColor = SKINCOLOR_CREDITS_TITLE; - theAlpha = SKINALPHA_CREDITS_TITLE; - } - else if(substring(s, 0, 1) == "*") - { - s = substring(s, 1, strlen(s) - 1); - theColor = SKINCOLOR_CREDITS_FUNCTION; - theAlpha = SKINALPHA_CREDITS_FUNCTION; - } - else - { - theColor = SKINCOLOR_CREDITS_PERSON; - theAlpha = SKINALPHA_CREDITS_PERSON; - } - - draw_CenterText(me.realUpperMargin * eY + 0.5 * eX, s, me.realFontSize, theColor, theAlpha, 0); -} - -float XonoticCreditsList_keyDown(entity me, float key, float ascii, float shift) -{ - float i; - me.dragScrollTimer = time; - me.scrolling = 0; - if(key == K_PGUP || key == K_KP_PGUP) - me.scrollPos = max(me.scrollPos - 0.5, 0); - else if(key == K_PGDN || key == K_KP_PGDN) - me.scrollPos = min(me.scrollPos + 0.5, me.nItems * me.itemHeight - 1); - else if(key == K_UPARROW || key == K_KP_UPARROW) - me.scrollPos = max(me.scrollPos - me.itemHeight, 0); - else if(key == K_DOWNARROW || key == K_KP_DOWNARROW) - me.scrollPos = min(me.scrollPos + me.itemHeight, me.nItems * me.itemHeight - 1); - else - return SUPER(XonoticCreditsList).keyDown(me, key, ascii, shift); - - i = min(me.selectedItem, floor((me.scrollPos + 1) / me.itemHeight - 1)); - i = max(i, ceil(me.scrollPos / me.itemHeight)); - me.setSelected(me, i); - - return 1; -} -#endif diff --git a/qcsrc/menu/xonotic/credits.qc b/qcsrc/menu/xonotic/credits.qc new file mode 100644 index 000000000..0d998d7de --- /dev/null +++ b/qcsrc/menu/xonotic/credits.qc @@ -0,0 +1,112 @@ +#ifdef INTERFACE +CLASS(XonoticCreditsList) EXTENDS(XonoticListBox) + METHOD(XonoticCreditsList, configureXonoticCreditsList, void(entity)) + ATTRIB(XonoticCreditsList, rowsPerItem, float, 1) + METHOD(XonoticCreditsList, draw, void(entity)) + METHOD(XonoticCreditsList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticCreditsList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticCreditsList, keyDown, float(entity, float, float, float)) + METHOD(XonoticCreditsList, destroy, void(entity)) + + ATTRIB(XonoticCreditsList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticCreditsList, realUpperMargin, float, 0) + ATTRIB(XonoticCreditsList, bufferIndex, float, 0) + ATTRIB(XonoticCreditsList, scrolling, float, 0) + + ATTRIB(XonoticListBox, alphaBG, float, 0) +ENDCLASS(XonoticCreditsList) +entity makeXonoticCreditsList(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticCreditsList() +{ + entity me; + me = spawnXonoticCreditsList(); + me.configureXonoticCreditsList(me); + return me; +} +void XonoticCreditsList_configureXonoticCreditsList(entity me) +{ + me.configureXonoticListBox(me); + // load the file + me.bufferIndex = buf_load(language_filename("xonotic-credits.txt")); + me.nItems = buf_getsize(me.bufferIndex); +} +void XonoticCreditsList_destroy(entity me) +{ + buf_del(me.bufferIndex); +} +void XonoticCreditsList_draw(entity me) +{ + float i; + if(me.scrolling) + { + me.scrollPos = bound(0, (time - me.scrolling) * me.itemHeight, me.nItems * me.itemHeight - 1); + i = min(me.selectedItem, floor((me.scrollPos + 1) / me.itemHeight - 1)); + i = max(i, ceil(me.scrollPos / me.itemHeight)); + me.setSelected(me, i); + } + SUPER(XonoticCreditsList).draw(me); +} +void XonoticCreditsList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(XonoticCreditsList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); + me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); +} +void XonoticCreditsList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + // layout: Ping, Credits name, Map name, NP, TP, MP + string s; + float theAlpha; + vector theColor; + + s = bufstr_get(me.bufferIndex, i); + + if(substring(s, 0, 2) == "**") + { + s = substring(s, 2, strlen(s) - 2); + theColor = SKINCOLOR_CREDITS_TITLE; + theAlpha = SKINALPHA_CREDITS_TITLE; + } + else if(substring(s, 0, 1) == "*") + { + s = substring(s, 1, strlen(s) - 1); + theColor = SKINCOLOR_CREDITS_FUNCTION; + theAlpha = SKINALPHA_CREDITS_FUNCTION; + } + else + { + theColor = SKINCOLOR_CREDITS_PERSON; + theAlpha = SKINALPHA_CREDITS_PERSON; + } + + draw_CenterText(me.realUpperMargin * eY + 0.5 * eX, s, me.realFontSize, theColor, theAlpha, 0); +} + +float XonoticCreditsList_keyDown(entity me, float key, float ascii, float shift) +{ + float i; + me.dragScrollTimer = time; + me.scrolling = 0; + if(key == K_PGUP || key == K_KP_PGUP) + me.scrollPos = max(me.scrollPos - 0.5, 0); + else if(key == K_PGDN || key == K_KP_PGDN) + me.scrollPos = min(me.scrollPos + 0.5, me.nItems * me.itemHeight - 1); + else if(key == K_UPARROW || key == K_KP_UPARROW) + me.scrollPos = max(me.scrollPos - me.itemHeight, 0); + else if(key == K_DOWNARROW || key == K_KP_DOWNARROW) + me.scrollPos = min(me.scrollPos + me.itemHeight, me.nItems * me.itemHeight - 1); + else + return SUPER(XonoticCreditsList).keyDown(me, key, ascii, shift); + + i = min(me.selectedItem, floor((me.scrollPos + 1) / me.itemHeight - 1)); + i = max(i, ceil(me.scrollPos / me.itemHeight)); + me.setSelected(me, i); + + return 1; +} +#endif diff --git a/qcsrc/menu/xonotic/crosshairbutton.c b/qcsrc/menu/xonotic/crosshairbutton.c deleted file mode 100644 index 7fe3a600f..000000000 --- a/qcsrc/menu/xonotic/crosshairbutton.c +++ /dev/null @@ -1,128 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCrosshairButton) EXTENDS(RadioButton) - METHOD(XonoticCrosshairButton, configureXonoticCrosshairButton, void(entity, float, float)) - METHOD(XonoticCrosshairButton, setChecked, void(entity, float)) - METHOD(XonoticCrosshairButton, draw, void(entity)) - ATTRIB(XonoticCrosshairButton, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticCrosshairButton, image, string, SKINGFX_CROSSHAIRBUTTON) - - ATTRIB(XonoticCrosshairButton, useDownAsChecked, float, 1) - ATTRIB(XonoticCrosshairButton, src3, string, string_null) - ATTRIB(XonoticCrosshairButton, src4, string, string_null) - - ATTRIB(XonoticCrosshairButton, cvarName, string, string_null) - ATTRIB(XonoticCrosshairButton, cvarValueFloat, float, 0) - METHOD(XonoticCrosshairButton, loadCvars, void(entity)) - METHOD(XonoticCrosshairButton, saveCvars, void(entity)) -ENDCLASS(XonoticCrosshairButton) -entity makeXonoticCrosshairButton(float, float); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticCrosshairButton(float theGroup, float theCrosshair) -{ - entity me; - me = spawnXonoticCrosshairButton(); - me.configureXonoticCrosshairButton(me, theGroup, theCrosshair); - return me; -} -void XonoticCrosshairButton_configureXonoticCrosshairButton(entity me, float theGroup, float theCrosshair) -{ - me.cvarName = "crosshair"; - me.cvarValueFloat = theCrosshair; - me.loadCvars(me); - me.configureRadioButton(me, string_null, me.fontSize, me.image, theGroup, 0); - me.srcMulti = 1; - if(me.cvarValueFloat == -1) - me.src3 = strzone(strcat("/gfx/crosshair", cvar_string("crosshair"))); - else - me.src3 = strzone(strcat("/gfx/crosshair", ftos(me.cvarValueFloat))); - me.src4 = "/gfx/crosshairdot"; -} -void XonoticCrosshairButton_setChecked(entity me, float val) -{ - if(me.cvarValueFloat != -1) // preview shouldn't work as a button - if(val != me.checked) - { - me.checked = val; - me.saveCvars(me); - } -} -void XonoticCrosshairButton_loadCvars(entity me) -{ - if (!me.cvarName) - return; - - me.checked = (cvar(me.cvarName) == me.cvarValueFloat); -} -void XonoticCrosshairButton_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - if(me.checked) - cvar_set(me.cvarName, ftos(me.cvarValueFloat)); - // TODO on an apply button, read _cl_color and execute the color command for it -} -void XonoticCrosshairButton_draw(entity me) -{ - vector sz, rgb; - float a; - - - if(me.cvarValueFloat == -1) - { - rgb = stov(cvar_string("crosshair_color")); - a = cvar("crosshair_alpha"); - } - else if(me.checked || me.focused) - { - a = 1; - rgb = '1 1 1'; - } - else - { - a = me.disabledAlpha; - rgb = '1 1 1'; - } - - if(me.cvarValueFloat == -1) // update the preview if this is the preview button - { - if(me.src3) - strunzone(me.src3); - me.src3 = strzone(strcat("/gfx/crosshair", cvar_string("crosshair"))); - me.focused = 1; - me.checked = 0; - } - - SUPER(XonoticCrosshairButton).draw(me); - - sz = draw_PictureSize(me.src3); - sz = globalToBoxSize(sz, me.size); - if(me.cvarValueFloat == -1) - { - sz = sz * cvar("crosshair_size"); // (6 * '1 1 0' + ...) * 0.08 here to make visible size changes happen also at bigger sizes - /* - if(sz_x > 0.95) - sz = sz * (0.95 / sz_x); - if(sz_y > 0.95) - sz = sz * (0.95 / sz_y); - */ - } - else // show the crosshair picker at full size - { - sz = sz * (0.95 / sz_x); - if(sz_y > 0.95) - sz = sz * (0.95 / sz_y); - } - - draw_Picture('0.5 0.5 0' - 0.5 * sz, me.src3, sz, rgb, a); - if(cvar("crosshair_dot")) - { - if(cvar("crosshair_dot_color_custom") && (cvar_string("crosshair_dot_color") != "0")) - rgb = stov(cvar_string("crosshair_dot_color")); - - draw_Picture('0.5 0.5 0' - 0.5 * sz * cvar("crosshair_dot_size"), me.src4, sz * cvar("crosshair_dot_size"), rgb, a * cvar("crosshair_dot_alpha")); - } -} -#endif diff --git a/qcsrc/menu/xonotic/crosshairbutton.qc b/qcsrc/menu/xonotic/crosshairbutton.qc new file mode 100644 index 000000000..7fe3a600f --- /dev/null +++ b/qcsrc/menu/xonotic/crosshairbutton.qc @@ -0,0 +1,128 @@ +#ifdef INTERFACE +CLASS(XonoticCrosshairButton) EXTENDS(RadioButton) + METHOD(XonoticCrosshairButton, configureXonoticCrosshairButton, void(entity, float, float)) + METHOD(XonoticCrosshairButton, setChecked, void(entity, float)) + METHOD(XonoticCrosshairButton, draw, void(entity)) + ATTRIB(XonoticCrosshairButton, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticCrosshairButton, image, string, SKINGFX_CROSSHAIRBUTTON) + + ATTRIB(XonoticCrosshairButton, useDownAsChecked, float, 1) + ATTRIB(XonoticCrosshairButton, src3, string, string_null) + ATTRIB(XonoticCrosshairButton, src4, string, string_null) + + ATTRIB(XonoticCrosshairButton, cvarName, string, string_null) + ATTRIB(XonoticCrosshairButton, cvarValueFloat, float, 0) + METHOD(XonoticCrosshairButton, loadCvars, void(entity)) + METHOD(XonoticCrosshairButton, saveCvars, void(entity)) +ENDCLASS(XonoticCrosshairButton) +entity makeXonoticCrosshairButton(float, float); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticCrosshairButton(float theGroup, float theCrosshair) +{ + entity me; + me = spawnXonoticCrosshairButton(); + me.configureXonoticCrosshairButton(me, theGroup, theCrosshair); + return me; +} +void XonoticCrosshairButton_configureXonoticCrosshairButton(entity me, float theGroup, float theCrosshair) +{ + me.cvarName = "crosshair"; + me.cvarValueFloat = theCrosshair; + me.loadCvars(me); + me.configureRadioButton(me, string_null, me.fontSize, me.image, theGroup, 0); + me.srcMulti = 1; + if(me.cvarValueFloat == -1) + me.src3 = strzone(strcat("/gfx/crosshair", cvar_string("crosshair"))); + else + me.src3 = strzone(strcat("/gfx/crosshair", ftos(me.cvarValueFloat))); + me.src4 = "/gfx/crosshairdot"; +} +void XonoticCrosshairButton_setChecked(entity me, float val) +{ + if(me.cvarValueFloat != -1) // preview shouldn't work as a button + if(val != me.checked) + { + me.checked = val; + me.saveCvars(me); + } +} +void XonoticCrosshairButton_loadCvars(entity me) +{ + if (!me.cvarName) + return; + + me.checked = (cvar(me.cvarName) == me.cvarValueFloat); +} +void XonoticCrosshairButton_saveCvars(entity me) +{ + if (!me.cvarName) + return; + + if(me.checked) + cvar_set(me.cvarName, ftos(me.cvarValueFloat)); + // TODO on an apply button, read _cl_color and execute the color command for it +} +void XonoticCrosshairButton_draw(entity me) +{ + vector sz, rgb; + float a; + + + if(me.cvarValueFloat == -1) + { + rgb = stov(cvar_string("crosshair_color")); + a = cvar("crosshair_alpha"); + } + else if(me.checked || me.focused) + { + a = 1; + rgb = '1 1 1'; + } + else + { + a = me.disabledAlpha; + rgb = '1 1 1'; + } + + if(me.cvarValueFloat == -1) // update the preview if this is the preview button + { + if(me.src3) + strunzone(me.src3); + me.src3 = strzone(strcat("/gfx/crosshair", cvar_string("crosshair"))); + me.focused = 1; + me.checked = 0; + } + + SUPER(XonoticCrosshairButton).draw(me); + + sz = draw_PictureSize(me.src3); + sz = globalToBoxSize(sz, me.size); + if(me.cvarValueFloat == -1) + { + sz = sz * cvar("crosshair_size"); // (6 * '1 1 0' + ...) * 0.08 here to make visible size changes happen also at bigger sizes + /* + if(sz_x > 0.95) + sz = sz * (0.95 / sz_x); + if(sz_y > 0.95) + sz = sz * (0.95 / sz_y); + */ + } + else // show the crosshair picker at full size + { + sz = sz * (0.95 / sz_x); + if(sz_y > 0.95) + sz = sz * (0.95 / sz_y); + } + + draw_Picture('0.5 0.5 0' - 0.5 * sz, me.src3, sz, rgb, a); + if(cvar("crosshair_dot")) + { + if(cvar("crosshair_dot_color_custom") && (cvar_string("crosshair_dot_color") != "0")) + rgb = stov(cvar_string("crosshair_dot_color")); + + draw_Picture('0.5 0.5 0' - 0.5 * sz * cvar("crosshair_dot_size"), me.src4, sz * cvar("crosshair_dot_size"), rgb, a * cvar("crosshair_dot_alpha")); + } +} +#endif diff --git a/qcsrc/menu/xonotic/cvarlist.c b/qcsrc/menu/xonotic/cvarlist.c deleted file mode 100644 index 913a03eaf..000000000 --- a/qcsrc/menu/xonotic/cvarlist.c +++ /dev/null @@ -1,255 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCvarList) EXTENDS(XonoticListBox) - METHOD(XonoticCvarList, configureXonoticCvarList, void(entity)) - ATTRIB(XonoticCvarList, rowsPerItem, float, 1) - METHOD(XonoticCvarList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticCvarList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticCvarList, keyDown, float(entity, float, float, float)) - - METHOD(XonoticCvarList, destroy, void(entity)) - - ATTRIB(XonoticCvarList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticCvarList, realUpperMargin, float, 0) - ATTRIB(XonoticCvarList, columnNameOrigin, float, 0) - ATTRIB(XonoticCvarList, columnNameSize, float, 0) - ATTRIB(XonoticCvarList, columnValueOrigin, float, 0) - ATTRIB(XonoticCvarList, columnValueSize, float, 0) - - METHOD(XonoticCvarList, mouseRelease, float(entity, vector)) - METHOD(XonoticCvarList, setSelected, void(entity, float)) - METHOD(XonoticCvarList, updateCvarType, float(entity)) - - ATTRIB(XonoticCvarList, controlledTextbox, entity, NULL) - ATTRIB(XonoticCvarList, cvarNameBox, entity, NULL) - ATTRIB(XonoticCvarList, cvarDescriptionBox, entity, NULL) - ATTRIB(XonoticCvarList, cvarTypeBox, entity, NULL) - ATTRIB(XonoticCvarList, cvarValueBox, entity, NULL) - ATTRIB(XonoticCvarList, cvarDefaultBox, entity, NULL) - ATTRIB(XonoticCvarList, cvarNeedsForcing, float, 0) - - ATTRIB(XonoticCvarList, handle, float, -1) - ATTRIB(XonoticCvarList, cvarName, string, string_null) - ATTRIB(XonoticCvarList, cvarDescription, string, string_null) - ATTRIB(XonoticCvarList, cvarType, string, string_null) - ATTRIB(XonoticCvarList, cvarDefault, string, string_null) -ENDCLASS(XonoticCvarList) -entity makeXonoticCvarList(); -void CvarList_Filter_Change(entity box, entity me); -void CvarList_Value_Change(entity box, entity me); -void CvarList_Revert_Click(entity btn, entity me); -void CvarList_End_Editing(entity box, entity me); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticCvarList() -{ - entity me; - me = spawnXonoticCvarList(); - me.configureXonoticCvarList(me); - return me; -} -void XonoticCvarList_configureXonoticCvarList(entity me) -{ - me.configureXonoticListBox(me); - - me.handle = buf_create(); - buf_cvarlist(me.handle, "", "_"); - me.nItems = buf_getsize(me.handle); -} -void XonoticCvarList_destroy(entity me) -{ - buf_del(me.handle); -} -string autocvar_menu_forced_saved_cvars; -string autocvar_menu_reverted_nonsaved_cvars; -float XonoticCvarList_updateCvarType(entity me) -{ - float t; - t = cvar_type(me.cvarName); - me.cvarType = ""; - float needsForcing; - if(strstrofs(strcat(" ", autocvar_menu_forced_saved_cvars, " "), strcat(" ", me.cvarName, " "), 0) >= 0) - { - me.cvarType = strcat(me.cvarType, ", ", _("forced to be saved to config.cfg")); - needsForcing = 0; - } - else if(strstrofs(strcat(" ", autocvar_menu_reverted_nonsaved_cvars, " "), strcat(" ", me.cvarName, " "), 0) >= 0) - { - // Currently claims to be saved, but won't be on next startup. - me.cvarType = strcat(me.cvarType, ", ", _("will not be saved")); - needsForcing = 1; - } - else if(t & CVAR_TYPEFLAG_SAVED) - { - me.cvarType = strcat(me.cvarType, ", ", _("will be saved to config.cfg")); - needsForcing = 0; - } - else - { - me.cvarType = strcat(me.cvarType, ", ", _("will not be saved")); - needsForcing = 1; - } - if(t & CVAR_TYPEFLAG_PRIVATE) - me.cvarType = strcat(me.cvarType, ", ", _("private")); - if(t & CVAR_TYPEFLAG_ENGINE) - me.cvarType = strcat(me.cvarType, ", ", _("engine setting")); - if(t & CVAR_TYPEFLAG_READONLY) - me.cvarType = strcat(me.cvarType, ", ", _("read only")); - me.cvarType = strzone(substring(me.cvarType, 2, strlen(me.cvarType) - 2)); - me.cvarTypeBox.setText(me.cvarTypeBox, me.cvarType); - return needsForcing; -} -void XonoticCvarList_setSelected(entity me, float i) -{ - string s; - - SUPER(XonoticCvarList).setSelected(me, i); - if(me.nItems == 0) - return; - - if(me.cvarName) - strunzone(me.cvarName); - if(me.cvarDescription) - strunzone(me.cvarDescription); - if(me.cvarType) - strunzone(me.cvarType); - if(me.cvarDefault) - strunzone(me.cvarDefault); - me.cvarName = strzone(bufstr_get(me.handle, me.selectedItem)); - me.cvarDescription = strzone(cvar_description(me.cvarName)); - me.cvarDefault = strzone(cvar_defstring(me.cvarName)); - me.cvarNameBox.setText(me.cvarNameBox, me.cvarName); - me.cvarDescriptionBox.setText(me.cvarDescriptionBox, me.cvarDescription); - float needsForcing = me.updateCvarType(me); - me.cvarDefaultBox.setText(me.cvarDefaultBox, me.cvarDefault); - - // this one can handle tempstrings - s = cvar_string(me.cvarName); - me.cvarNeedsForcing = 0; - me.cvarValueBox.setText(me.cvarValueBox, s); - me.cvarNeedsForcing = needsForcing; - me.cvarValueBox.cursorPos = strlen(s); -} -void CvarList_Filter_Change(entity box, entity me) -{ - buf_cvarlist(me.handle, box.text, "_"); - me.nItems = buf_getsize(me.handle); - - me.setSelected(me, 0); -} -void XonoticCvarList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(XonoticCvarList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); - me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - - me.columnNameOrigin = 0; - me.columnValueSize = me.realFontSize_x * 20; - me.columnNameSize = 1 - me.columnValueSize - me.realFontSize_x; - me.columnValueOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x; - - me.setSelected(me, me.selectedItem); -} -void XonoticCvarList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string k, v, d; - float t; - - vector theColor; - float theAlpha; - - string s; - - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - k = bufstr_get(me.handle, i); - - v = cvar_string(k); - d = cvar_defstring(k); - t = cvar_type(k); - if(strstrofs(strcat(" ", autocvar_menu_forced_saved_cvars, " "), strcat(" ", k, " "), 0) >= 0) - theAlpha = SKINALPHA_CVARLIST_SAVED; - else if(strstrofs(strcat(" ", autocvar_menu_reverted_nonsaved_cvars, " "), strcat(" ", k, " "), 0) >= 0) - theAlpha = SKINALPHA_CVARLIST_TEMPORARY; - else if(t & CVAR_TYPEFLAG_SAVED) - theAlpha = SKINALPHA_CVARLIST_SAVED; - else - theAlpha = SKINALPHA_CVARLIST_TEMPORARY; - if(v == d) - theColor = SKINCOLOR_CVARLIST_UNCHANGED; - else - theColor = SKINCOLOR_CVARLIST_CHANGED; - - s = draw_TextShortenToWidth(k, me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0); - s = draw_TextShortenToWidth(v, me.columnValueSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + me.columnValueOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0); -} - -float XonoticCvarList_keyDown(entity me, float scan, float ascii, float shift) -{ - if (scan == K_MOUSE3 || ((shift & S_CTRL) && scan == K_SPACE)) - { - CvarList_Revert_Click(world, me); - return 1; - } - else if(scan == K_ENTER) - { - me.cvarValueBox.parent.setFocus(me.cvarValueBox.parent, me.cvarValueBox); - return 1; - } - else if(SUPER(XonoticCvarList).keyDown(me, scan, ascii, shift)) - return 1; - else if(!me.controlledTextbox) - return 0; - else - return me.controlledTextbox.keyDown(me.controlledTextbox, scan, ascii, shift); -} - -float XonoticCvarList_mouseRelease(entity me, vector pos) -{ - if(me.pressed == 2) - me.cvarValueBox.parent.setFocus(me.cvarValueBox.parent, me.cvarValueBox); - return SUPER(XonoticCvarList).mouseRelease(me, pos); -} - -void CvarList_Value_Change(entity box, entity me) -{ - cvar_set(me.cvarNameBox.text, box.text); - if(me.cvarNeedsForcing) - { - localcmd(sprintf("\nseta %1$s \"$%1$s\"\n", me.cvarName)); - cvar_set("menu_reverted_nonsaved_cvars", substring(strreplace(strcat(" ", me.cvarName, " "), " ", strcat(" ", autocvar_menu_reverted_nonsaved_cvars, " ")), 1, -2)); - if (autocvar_menu_forced_saved_cvars == "") - cvar_set("menu_forced_saved_cvars", me.cvarName); - else - cvar_set("menu_forced_saved_cvars", strcat(autocvar_menu_forced_saved_cvars, " ", me.cvarName)); - me.cvarNeedsForcing = 0; - me.updateCvarType(me); - } -} - -void CvarList_Revert_Click(entity btn, entity me) -{ - me.cvarValueBox.setText(me.cvarValueBox, me.cvarDefault); - me.cvarValueBox.cursorPos = strlen(me.cvarDefault); - if(strstrofs(strcat(" ", autocvar_menu_forced_saved_cvars, " "), strcat(" ", me.cvarName, " "), 0) >= 0) - { - cvar_set("menu_forced_saved_cvars", substring(strreplace(strcat(" ", me.cvarName, " "), " ", strcat(" ", autocvar_menu_forced_saved_cvars, " ")), 1, -2)); - if (autocvar_menu_reverted_nonsaved_cvars == "") - cvar_set("menu_reverted_nonsaved_cvars", me.cvarName); - else - cvar_set("menu_reverted_nonsaved_cvars", strcat(autocvar_menu_reverted_nonsaved_cvars, " ", me.cvarName)); - } - me.cvarNeedsForcing = me.updateCvarType(me); -} - -void CvarList_End_Editing(entity box, entity me) -{ - box.parent.setFocus(box.parent, me); -} - -#endif diff --git a/qcsrc/menu/xonotic/cvarlist.qc b/qcsrc/menu/xonotic/cvarlist.qc new file mode 100644 index 000000000..913a03eaf --- /dev/null +++ b/qcsrc/menu/xonotic/cvarlist.qc @@ -0,0 +1,255 @@ +#ifdef INTERFACE +CLASS(XonoticCvarList) EXTENDS(XonoticListBox) + METHOD(XonoticCvarList, configureXonoticCvarList, void(entity)) + ATTRIB(XonoticCvarList, rowsPerItem, float, 1) + METHOD(XonoticCvarList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticCvarList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticCvarList, keyDown, float(entity, float, float, float)) + + METHOD(XonoticCvarList, destroy, void(entity)) + + ATTRIB(XonoticCvarList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticCvarList, realUpperMargin, float, 0) + ATTRIB(XonoticCvarList, columnNameOrigin, float, 0) + ATTRIB(XonoticCvarList, columnNameSize, float, 0) + ATTRIB(XonoticCvarList, columnValueOrigin, float, 0) + ATTRIB(XonoticCvarList, columnValueSize, float, 0) + + METHOD(XonoticCvarList, mouseRelease, float(entity, vector)) + METHOD(XonoticCvarList, setSelected, void(entity, float)) + METHOD(XonoticCvarList, updateCvarType, float(entity)) + + ATTRIB(XonoticCvarList, controlledTextbox, entity, NULL) + ATTRIB(XonoticCvarList, cvarNameBox, entity, NULL) + ATTRIB(XonoticCvarList, cvarDescriptionBox, entity, NULL) + ATTRIB(XonoticCvarList, cvarTypeBox, entity, NULL) + ATTRIB(XonoticCvarList, cvarValueBox, entity, NULL) + ATTRIB(XonoticCvarList, cvarDefaultBox, entity, NULL) + ATTRIB(XonoticCvarList, cvarNeedsForcing, float, 0) + + ATTRIB(XonoticCvarList, handle, float, -1) + ATTRIB(XonoticCvarList, cvarName, string, string_null) + ATTRIB(XonoticCvarList, cvarDescription, string, string_null) + ATTRIB(XonoticCvarList, cvarType, string, string_null) + ATTRIB(XonoticCvarList, cvarDefault, string, string_null) +ENDCLASS(XonoticCvarList) +entity makeXonoticCvarList(); +void CvarList_Filter_Change(entity box, entity me); +void CvarList_Value_Change(entity box, entity me); +void CvarList_Revert_Click(entity btn, entity me); +void CvarList_End_Editing(entity box, entity me); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticCvarList() +{ + entity me; + me = spawnXonoticCvarList(); + me.configureXonoticCvarList(me); + return me; +} +void XonoticCvarList_configureXonoticCvarList(entity me) +{ + me.configureXonoticListBox(me); + + me.handle = buf_create(); + buf_cvarlist(me.handle, "", "_"); + me.nItems = buf_getsize(me.handle); +} +void XonoticCvarList_destroy(entity me) +{ + buf_del(me.handle); +} +string autocvar_menu_forced_saved_cvars; +string autocvar_menu_reverted_nonsaved_cvars; +float XonoticCvarList_updateCvarType(entity me) +{ + float t; + t = cvar_type(me.cvarName); + me.cvarType = ""; + float needsForcing; + if(strstrofs(strcat(" ", autocvar_menu_forced_saved_cvars, " "), strcat(" ", me.cvarName, " "), 0) >= 0) + { + me.cvarType = strcat(me.cvarType, ", ", _("forced to be saved to config.cfg")); + needsForcing = 0; + } + else if(strstrofs(strcat(" ", autocvar_menu_reverted_nonsaved_cvars, " "), strcat(" ", me.cvarName, " "), 0) >= 0) + { + // Currently claims to be saved, but won't be on next startup. + me.cvarType = strcat(me.cvarType, ", ", _("will not be saved")); + needsForcing = 1; + } + else if(t & CVAR_TYPEFLAG_SAVED) + { + me.cvarType = strcat(me.cvarType, ", ", _("will be saved to config.cfg")); + needsForcing = 0; + } + else + { + me.cvarType = strcat(me.cvarType, ", ", _("will not be saved")); + needsForcing = 1; + } + if(t & CVAR_TYPEFLAG_PRIVATE) + me.cvarType = strcat(me.cvarType, ", ", _("private")); + if(t & CVAR_TYPEFLAG_ENGINE) + me.cvarType = strcat(me.cvarType, ", ", _("engine setting")); + if(t & CVAR_TYPEFLAG_READONLY) + me.cvarType = strcat(me.cvarType, ", ", _("read only")); + me.cvarType = strzone(substring(me.cvarType, 2, strlen(me.cvarType) - 2)); + me.cvarTypeBox.setText(me.cvarTypeBox, me.cvarType); + return needsForcing; +} +void XonoticCvarList_setSelected(entity me, float i) +{ + string s; + + SUPER(XonoticCvarList).setSelected(me, i); + if(me.nItems == 0) + return; + + if(me.cvarName) + strunzone(me.cvarName); + if(me.cvarDescription) + strunzone(me.cvarDescription); + if(me.cvarType) + strunzone(me.cvarType); + if(me.cvarDefault) + strunzone(me.cvarDefault); + me.cvarName = strzone(bufstr_get(me.handle, me.selectedItem)); + me.cvarDescription = strzone(cvar_description(me.cvarName)); + me.cvarDefault = strzone(cvar_defstring(me.cvarName)); + me.cvarNameBox.setText(me.cvarNameBox, me.cvarName); + me.cvarDescriptionBox.setText(me.cvarDescriptionBox, me.cvarDescription); + float needsForcing = me.updateCvarType(me); + me.cvarDefaultBox.setText(me.cvarDefaultBox, me.cvarDefault); + + // this one can handle tempstrings + s = cvar_string(me.cvarName); + me.cvarNeedsForcing = 0; + me.cvarValueBox.setText(me.cvarValueBox, s); + me.cvarNeedsForcing = needsForcing; + me.cvarValueBox.cursorPos = strlen(s); +} +void CvarList_Filter_Change(entity box, entity me) +{ + buf_cvarlist(me.handle, box.text, "_"); + me.nItems = buf_getsize(me.handle); + + me.setSelected(me, 0); +} +void XonoticCvarList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(XonoticCvarList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); + me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + + me.columnNameOrigin = 0; + me.columnValueSize = me.realFontSize_x * 20; + me.columnNameSize = 1 - me.columnValueSize - me.realFontSize_x; + me.columnValueOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x; + + me.setSelected(me, me.selectedItem); +} +void XonoticCvarList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string k, v, d; + float t; + + vector theColor; + float theAlpha; + + string s; + + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + k = bufstr_get(me.handle, i); + + v = cvar_string(k); + d = cvar_defstring(k); + t = cvar_type(k); + if(strstrofs(strcat(" ", autocvar_menu_forced_saved_cvars, " "), strcat(" ", k, " "), 0) >= 0) + theAlpha = SKINALPHA_CVARLIST_SAVED; + else if(strstrofs(strcat(" ", autocvar_menu_reverted_nonsaved_cvars, " "), strcat(" ", k, " "), 0) >= 0) + theAlpha = SKINALPHA_CVARLIST_TEMPORARY; + else if(t & CVAR_TYPEFLAG_SAVED) + theAlpha = SKINALPHA_CVARLIST_SAVED; + else + theAlpha = SKINALPHA_CVARLIST_TEMPORARY; + if(v == d) + theColor = SKINCOLOR_CVARLIST_UNCHANGED; + else + theColor = SKINCOLOR_CVARLIST_CHANGED; + + s = draw_TextShortenToWidth(k, me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0); + s = draw_TextShortenToWidth(v, me.columnValueSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + me.columnValueOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0); +} + +float XonoticCvarList_keyDown(entity me, float scan, float ascii, float shift) +{ + if (scan == K_MOUSE3 || ((shift & S_CTRL) && scan == K_SPACE)) + { + CvarList_Revert_Click(world, me); + return 1; + } + else if(scan == K_ENTER) + { + me.cvarValueBox.parent.setFocus(me.cvarValueBox.parent, me.cvarValueBox); + return 1; + } + else if(SUPER(XonoticCvarList).keyDown(me, scan, ascii, shift)) + return 1; + else if(!me.controlledTextbox) + return 0; + else + return me.controlledTextbox.keyDown(me.controlledTextbox, scan, ascii, shift); +} + +float XonoticCvarList_mouseRelease(entity me, vector pos) +{ + if(me.pressed == 2) + me.cvarValueBox.parent.setFocus(me.cvarValueBox.parent, me.cvarValueBox); + return SUPER(XonoticCvarList).mouseRelease(me, pos); +} + +void CvarList_Value_Change(entity box, entity me) +{ + cvar_set(me.cvarNameBox.text, box.text); + if(me.cvarNeedsForcing) + { + localcmd(sprintf("\nseta %1$s \"$%1$s\"\n", me.cvarName)); + cvar_set("menu_reverted_nonsaved_cvars", substring(strreplace(strcat(" ", me.cvarName, " "), " ", strcat(" ", autocvar_menu_reverted_nonsaved_cvars, " ")), 1, -2)); + if (autocvar_menu_forced_saved_cvars == "") + cvar_set("menu_forced_saved_cvars", me.cvarName); + else + cvar_set("menu_forced_saved_cvars", strcat(autocvar_menu_forced_saved_cvars, " ", me.cvarName)); + me.cvarNeedsForcing = 0; + me.updateCvarType(me); + } +} + +void CvarList_Revert_Click(entity btn, entity me) +{ + me.cvarValueBox.setText(me.cvarValueBox, me.cvarDefault); + me.cvarValueBox.cursorPos = strlen(me.cvarDefault); + if(strstrofs(strcat(" ", autocvar_menu_forced_saved_cvars, " "), strcat(" ", me.cvarName, " "), 0) >= 0) + { + cvar_set("menu_forced_saved_cvars", substring(strreplace(strcat(" ", me.cvarName, " "), " ", strcat(" ", autocvar_menu_forced_saved_cvars, " ")), 1, -2)); + if (autocvar_menu_reverted_nonsaved_cvars == "") + cvar_set("menu_reverted_nonsaved_cvars", me.cvarName); + else + cvar_set("menu_reverted_nonsaved_cvars", strcat(autocvar_menu_reverted_nonsaved_cvars, " ", me.cvarName)); + } + me.cvarNeedsForcing = me.updateCvarType(me); +} + +void CvarList_End_Editing(entity box, entity me) +{ + box.parent.setFocus(box.parent, me); +} + +#endif diff --git a/qcsrc/menu/xonotic/demolist.c b/qcsrc/menu/xonotic/demolist.c deleted file mode 100644 index 9f5909676..000000000 --- a/qcsrc/menu/xonotic/demolist.c +++ /dev/null @@ -1,226 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticDemoList) EXTENDS(XonoticListBox) - METHOD(XonoticDemoList, configureXonoticDemoList, void(entity)) - ATTRIB(XonoticDemoList, rowsPerItem, float, 1) - METHOD(XonoticDemoList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticDemoList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticDemoList, getDemos, void(entity)) - METHOD(XonoticDemoList, startDemo, void(entity)) - METHOD(XonoticDemoList, timeDemo, void(entity)) - METHOD(XonoticDemoList, demoName, string(entity, float)) - METHOD(XonoticDemoList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticDemoList, keyDown, float(entity, float, float, float)) - METHOD(XonoticDemoList, destroy, void(entity)) - METHOD(XonoticDemoList, showNotify, void(entity)) - - ATTRIB(XonoticDemoList, listDemo, float, -1) - ATTRIB(XonoticDemoList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticDemoList, columnNameOrigin, float, 0) - ATTRIB(XonoticDemoList, columnNameSize, float, 0) - ATTRIB(XonoticDemoList, realUpperMargin, float, 0) - ATTRIB(XonoticDemoList, origin, vector, '0 0 0') - ATTRIB(XonoticDemoList, itemAbsSize, vector, '0 0 0') - - ATTRIB(XonoticDemoList, filterString, string, string_null) -ENDCLASS(XonoticDemoList) - -entity demolist; // for reference elsewhere -entity makeXonoticDemoList(); -void DemoList_Refresh_Click(entity btn, entity me); -void DemoList_Filter_Change(entity box, entity me); -#endif - -#ifdef IMPLEMENTATION - -entity makeXonoticDemoList() -{ - entity me; - me = spawnXonoticDemoList(); - me.configureXonoticDemoList(me); - return me; -} - -void XonoticDemoList_configureXonoticDemoList(entity me) -{ - me.configureXonoticListBox(me); - me.getDemos(me); -} - -string XonoticDemoList_demoName(entity me, float i) -{ - string s; - s = bufstr_get(me.listDemo, i); - - if(substring(s, 0, 1) == "/") - s = substring(s, 1, strlen(s) - 1); // remove the first forward slash - - return s; -} - -// if subdir is TRUE look in subdirectories too (1 level) -void getDemos_for_ext(entity me, string ext, float subdir) -{ - string s; - if (subdir) - s="demos/*/"; - else - s="demos/"; - if(me.filterString) - s=strcat(s, me.filterString, ext); - else - s=strcat(s, "*", ext); - - float list, i, n; - list = search_begin(s, FALSE, TRUE); - if(list >= 0) - { - n = search_getsize(list); - for(i = 0; i < n; ++i) - { - s = search_getfilename(list, i); // get initial full file name - s = substring(s, 6, (strlen(s) - 6 - 4)); // remove "demos/" prefix and ".dem" suffix - s = strdecolorize(s); // remove any pre-existing colors - if(subdir) - { - s = strreplace("/", "^7/", s); // clear colors at the forward slash - s = strcat("/", rgb_to_hexcolor(SKINCOLOR_DEMOLIST_SUBDIR), s); // add a forward slash for sorting, then color - bufstr_add(me.listDemo, s, TRUE); - } - else { bufstr_add(me.listDemo, s, TRUE); } - } - search_end(list); - } - - if (subdir) - getDemos_for_ext(me, ext, FALSE); -} - -void XonoticDemoList_getDemos(entity me) -{ - if (me.listDemo >= 0) - buf_del(me.listDemo); - me.listDemo = buf_create(); - if (me.listDemo < 0) - { - me.nItems = 0; - return; - } - getDemos_for_ext(me, ".dem", TRUE); - me.nItems = buf_getsize(me.listDemo); - if(me.nItems > 0) - buf_sort(me.listDemo, 128, FALSE); -} - -void XonoticDemoList_destroy(entity me) -{ - if(me.nItems > 0) - buf_del(me.listDemo); -} - -void XonoticDemoList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticDemoList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - - me.columnNameOrigin = me.realFontSize_x; - me.columnNameSize = 1 - 2 * me.realFontSize_x; -} - -void XonoticDemoList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s; - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - s = me.demoName(me,i); - s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 1); -} - -void XonoticDemoList_showNotify(entity me) -{ - me.getDemos(me); -} - -void DemoList_Refresh_Click(entity btn, entity me) -{ - me.getDemos(me); - me.setSelected(me, 0); //always select the first element after a list update -} - -void DemoList_Filter_Change(entity box, entity me) -{ - if(me.filterString) - strunzone(me.filterString); - - if(box.text != "") - { - if (strstrofs(box.text, "*", 0) >= 0 || strstrofs(box.text, "?", 0) >= 0) - me.filterString = strzone(box.text); - else - me.filterString = strzone(strcat("*", box.text, "*")); - } - else - me.filterString = string_null; - - me.getDemos(me); -} - -void XonoticDemoList_startDemo(entity me) -{ - string s; - s = me.demoName(me, me.selectedItem); - s = strdecolorize(s); - - localcmd("playdemo \"demos/", s, ".dem\" \nwait \ntogglemenu\n"); -} - -void XonoticDemoList_timeDemo(entity me) -{ - string s; - s = me.demoName(me, me.selectedItem); - s = strdecolorize(s); - - localcmd("timedemo \"demos/", s, ".dem\" \nwait \ntogglemenu\n"); -} - -void DemoConfirm_ListClick_Check_Gamestatus(entity me) -{ - if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) // we're not in a match, lets watch the demo - { - me.startDemo(me); - } - else // already in a match, player has to confirm - { - DialogOpenButton_Click_withCoords( - me, - main.demostartconfirmDialog, - boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size), - boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size) - ); - } -} - -void XonoticDemoList_doubleClickListBoxItem(entity me, float i, vector where) -{ - DemoConfirm_ListClick_Check_Gamestatus(me); -} - -float XonoticDemoList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(scan == K_ENTER || scan == K_KP_ENTER) - { - DemoConfirm_ListClick_Check_Gamestatus(me); - return 1; - } - else - { - return SUPER(XonoticDemoList).keyDown(me, scan, ascii, shift); - } -} -#endif - diff --git a/qcsrc/menu/xonotic/demolist.qc b/qcsrc/menu/xonotic/demolist.qc new file mode 100644 index 000000000..9f5909676 --- /dev/null +++ b/qcsrc/menu/xonotic/demolist.qc @@ -0,0 +1,226 @@ +#ifdef INTERFACE +CLASS(XonoticDemoList) EXTENDS(XonoticListBox) + METHOD(XonoticDemoList, configureXonoticDemoList, void(entity)) + ATTRIB(XonoticDemoList, rowsPerItem, float, 1) + METHOD(XonoticDemoList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticDemoList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticDemoList, getDemos, void(entity)) + METHOD(XonoticDemoList, startDemo, void(entity)) + METHOD(XonoticDemoList, timeDemo, void(entity)) + METHOD(XonoticDemoList, demoName, string(entity, float)) + METHOD(XonoticDemoList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticDemoList, keyDown, float(entity, float, float, float)) + METHOD(XonoticDemoList, destroy, void(entity)) + METHOD(XonoticDemoList, showNotify, void(entity)) + + ATTRIB(XonoticDemoList, listDemo, float, -1) + ATTRIB(XonoticDemoList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticDemoList, columnNameOrigin, float, 0) + ATTRIB(XonoticDemoList, columnNameSize, float, 0) + ATTRIB(XonoticDemoList, realUpperMargin, float, 0) + ATTRIB(XonoticDemoList, origin, vector, '0 0 0') + ATTRIB(XonoticDemoList, itemAbsSize, vector, '0 0 0') + + ATTRIB(XonoticDemoList, filterString, string, string_null) +ENDCLASS(XonoticDemoList) + +entity demolist; // for reference elsewhere +entity makeXonoticDemoList(); +void DemoList_Refresh_Click(entity btn, entity me); +void DemoList_Filter_Change(entity box, entity me); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticDemoList() +{ + entity me; + me = spawnXonoticDemoList(); + me.configureXonoticDemoList(me); + return me; +} + +void XonoticDemoList_configureXonoticDemoList(entity me) +{ + me.configureXonoticListBox(me); + me.getDemos(me); +} + +string XonoticDemoList_demoName(entity me, float i) +{ + string s; + s = bufstr_get(me.listDemo, i); + + if(substring(s, 0, 1) == "/") + s = substring(s, 1, strlen(s) - 1); // remove the first forward slash + + return s; +} + +// if subdir is TRUE look in subdirectories too (1 level) +void getDemos_for_ext(entity me, string ext, float subdir) +{ + string s; + if (subdir) + s="demos/*/"; + else + s="demos/"; + if(me.filterString) + s=strcat(s, me.filterString, ext); + else + s=strcat(s, "*", ext); + + float list, i, n; + list = search_begin(s, FALSE, TRUE); + if(list >= 0) + { + n = search_getsize(list); + for(i = 0; i < n; ++i) + { + s = search_getfilename(list, i); // get initial full file name + s = substring(s, 6, (strlen(s) - 6 - 4)); // remove "demos/" prefix and ".dem" suffix + s = strdecolorize(s); // remove any pre-existing colors + if(subdir) + { + s = strreplace("/", "^7/", s); // clear colors at the forward slash + s = strcat("/", rgb_to_hexcolor(SKINCOLOR_DEMOLIST_SUBDIR), s); // add a forward slash for sorting, then color + bufstr_add(me.listDemo, s, TRUE); + } + else { bufstr_add(me.listDemo, s, TRUE); } + } + search_end(list); + } + + if (subdir) + getDemos_for_ext(me, ext, FALSE); +} + +void XonoticDemoList_getDemos(entity me) +{ + if (me.listDemo >= 0) + buf_del(me.listDemo); + me.listDemo = buf_create(); + if (me.listDemo < 0) + { + me.nItems = 0; + return; + } + getDemos_for_ext(me, ".dem", TRUE); + me.nItems = buf_getsize(me.listDemo); + if(me.nItems > 0) + buf_sort(me.listDemo, 128, FALSE); +} + +void XonoticDemoList_destroy(entity me) +{ + if(me.nItems > 0) + buf_del(me.listDemo); +} + +void XonoticDemoList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticDemoList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + + me.columnNameOrigin = me.realFontSize_x; + me.columnNameSize = 1 - 2 * me.realFontSize_x; +} + +void XonoticDemoList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s; + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + s = me.demoName(me,i); + s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 1); +} + +void XonoticDemoList_showNotify(entity me) +{ + me.getDemos(me); +} + +void DemoList_Refresh_Click(entity btn, entity me) +{ + me.getDemos(me); + me.setSelected(me, 0); //always select the first element after a list update +} + +void DemoList_Filter_Change(entity box, entity me) +{ + if(me.filterString) + strunzone(me.filterString); + + if(box.text != "") + { + if (strstrofs(box.text, "*", 0) >= 0 || strstrofs(box.text, "?", 0) >= 0) + me.filterString = strzone(box.text); + else + me.filterString = strzone(strcat("*", box.text, "*")); + } + else + me.filterString = string_null; + + me.getDemos(me); +} + +void XonoticDemoList_startDemo(entity me) +{ + string s; + s = me.demoName(me, me.selectedItem); + s = strdecolorize(s); + + localcmd("playdemo \"demos/", s, ".dem\" \nwait \ntogglemenu\n"); +} + +void XonoticDemoList_timeDemo(entity me) +{ + string s; + s = me.demoName(me, me.selectedItem); + s = strdecolorize(s); + + localcmd("timedemo \"demos/", s, ".dem\" \nwait \ntogglemenu\n"); +} + +void DemoConfirm_ListClick_Check_Gamestatus(entity me) +{ + if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) // we're not in a match, lets watch the demo + { + me.startDemo(me); + } + else // already in a match, player has to confirm + { + DialogOpenButton_Click_withCoords( + me, + main.demostartconfirmDialog, + boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size), + boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size) + ); + } +} + +void XonoticDemoList_doubleClickListBoxItem(entity me, float i, vector where) +{ + DemoConfirm_ListClick_Check_Gamestatus(me); +} + +float XonoticDemoList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_KP_ENTER) + { + DemoConfirm_ListClick_Check_Gamestatus(me); + return 1; + } + else + { + return SUPER(XonoticDemoList).keyDown(me, scan, ascii, shift); + } +} +#endif + diff --git a/qcsrc/menu/xonotic/dialog.c b/qcsrc/menu/xonotic/dialog.c deleted file mode 100644 index 6ca90254a..000000000 --- a/qcsrc/menu/xonotic/dialog.c +++ /dev/null @@ -1,44 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticDialog) EXTENDS(Dialog) - // still to be customized by user - /* - ATTRIB(XonoticDialog, closable, float, 1) - ATTRIB(XonoticDialog, title, string, _("Form1")) // ;) - ATTRIB(XonoticDialog, color, vector, '1 0.5 1') - ATTRIB(XonoticDialog, intendedWidth, float, 0) - ATTRIB(XonoticDialog, rows, float, 3) - ATTRIB(XonoticDialog, columns, float, 2) - */ - ATTRIB(XonoticDialog, marginTop, float, SKINMARGIN_TOP) // pixels - ATTRIB(XonoticDialog, marginBottom, float, SKINMARGIN_BOTTOM) // pixels - ATTRIB(XonoticDialog, marginLeft, float, SKINMARGIN_LEFT) // pixels - ATTRIB(XonoticDialog, marginRight, float, SKINMARGIN_RIGHT) // pixels - ATTRIB(XonoticDialog, columnSpacing, float, SKINMARGIN_COLUMNS) // pixels - ATTRIB(XonoticDialog, rowSpacing, float, SKINMARGIN_ROWS) // pixels - ATTRIB(XonoticDialog, rowHeight, float, SKINFONTSIZE_NORMAL * SKINHEIGHT_NORMAL) // pixels - ATTRIB(XonoticDialog, titleHeight, float, SKINFONTSIZE_TITLE * SKINHEIGHT_TITLE) // pixels - ATTRIB(XonoticDialog, titleFontSize, float, SKINFONTSIZE_TITLE) // pixels - - ATTRIB(XonoticDialog, backgroundImage, string, SKINGFX_DIALOGBORDER) - ATTRIB(XonoticDialog, borderLines, float, SKINHEIGHT_DIALOGBORDER) - ATTRIB(XonoticDialog, closeButtonImage, string, SKINGFX_CLOSEBUTTON) - ATTRIB(XonoticDialog, zoomedOutTitleBarPosition, float, SKINHEIGHT_ZOOMEDTITLE * 0.5 - 0.5) - ATTRIB(XonoticDialog, zoomedOutTitleBar, float, SKINHEIGHT_ZOOMEDTITLE != 0) - - ATTRIB(XonoticDialog, alpha, float, SKINALPHA_TEXT) - - METHOD(XonoticDialog, configureDialog, void(entity)) -ENDCLASS(XonoticDialog) -#ifndef IMPLEMENTATION -entity currentDialog; -#endif -#endif - -#ifdef IMPLEMENTATION -void XonoticDialog_configureDialog(entity me) -{ - currentDialog = me; - SUPER(XonoticDialog).configureDialog(me); - me.tooltip = getZonedTooltipForIdentifier(me.classname); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog.qc b/qcsrc/menu/xonotic/dialog.qc new file mode 100644 index 000000000..6ca90254a --- /dev/null +++ b/qcsrc/menu/xonotic/dialog.qc @@ -0,0 +1,44 @@ +#ifdef INTERFACE +CLASS(XonoticDialog) EXTENDS(Dialog) + // still to be customized by user + /* + ATTRIB(XonoticDialog, closable, float, 1) + ATTRIB(XonoticDialog, title, string, _("Form1")) // ;) + ATTRIB(XonoticDialog, color, vector, '1 0.5 1') + ATTRIB(XonoticDialog, intendedWidth, float, 0) + ATTRIB(XonoticDialog, rows, float, 3) + ATTRIB(XonoticDialog, columns, float, 2) + */ + ATTRIB(XonoticDialog, marginTop, float, SKINMARGIN_TOP) // pixels + ATTRIB(XonoticDialog, marginBottom, float, SKINMARGIN_BOTTOM) // pixels + ATTRIB(XonoticDialog, marginLeft, float, SKINMARGIN_LEFT) // pixels + ATTRIB(XonoticDialog, marginRight, float, SKINMARGIN_RIGHT) // pixels + ATTRIB(XonoticDialog, columnSpacing, float, SKINMARGIN_COLUMNS) // pixels + ATTRIB(XonoticDialog, rowSpacing, float, SKINMARGIN_ROWS) // pixels + ATTRIB(XonoticDialog, rowHeight, float, SKINFONTSIZE_NORMAL * SKINHEIGHT_NORMAL) // pixels + ATTRIB(XonoticDialog, titleHeight, float, SKINFONTSIZE_TITLE * SKINHEIGHT_TITLE) // pixels + ATTRIB(XonoticDialog, titleFontSize, float, SKINFONTSIZE_TITLE) // pixels + + ATTRIB(XonoticDialog, backgroundImage, string, SKINGFX_DIALOGBORDER) + ATTRIB(XonoticDialog, borderLines, float, SKINHEIGHT_DIALOGBORDER) + ATTRIB(XonoticDialog, closeButtonImage, string, SKINGFX_CLOSEBUTTON) + ATTRIB(XonoticDialog, zoomedOutTitleBarPosition, float, SKINHEIGHT_ZOOMEDTITLE * 0.5 - 0.5) + ATTRIB(XonoticDialog, zoomedOutTitleBar, float, SKINHEIGHT_ZOOMEDTITLE != 0) + + ATTRIB(XonoticDialog, alpha, float, SKINALPHA_TEXT) + + METHOD(XonoticDialog, configureDialog, void(entity)) +ENDCLASS(XonoticDialog) +#ifndef IMPLEMENTATION +entity currentDialog; +#endif +#endif + +#ifdef IMPLEMENTATION +void XonoticDialog_configureDialog(entity me) +{ + currentDialog = me; + SUPER(XonoticDialog).configureDialog(me); + me.tooltip = getZonedTooltipForIdentifier(me.classname); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_credits.c b/qcsrc/menu/xonotic/dialog_credits.c deleted file mode 100644 index e90ae4b42..000000000 --- a/qcsrc/menu/xonotic/dialog_credits.c +++ /dev/null @@ -1,29 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCreditsDialog) EXTENDS(XonoticDialog) - METHOD(XonoticCreditsDialog, fill, void(entity)) - METHOD(XonoticCreditsDialog, focusEnter, void(entity)) - ATTRIB(XonoticCreditsDialog, title, string, _("Credits")) - ATTRIB(XonoticCreditsDialog, color, vector, SKINCOLOR_DIALOG_CREDITS) - ATTRIB(XonoticCreditsDialog, intendedWidth, float, SKINWIDTH_CREDITS) - ATTRIB(XonoticCreditsDialog, rows, float, SKINROWS_CREDITS) - ATTRIB(XonoticCreditsDialog, columns, float, 2) - ATTRIB(XonoticCreditsDialog, creditsList, entity, NULL) -ENDCLASS(XonoticCreditsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticCreditsDialog_fill(entity me) -{ - entity e; - me.TR(me); - me.TD(me, me.rows - 1, me.columns, me.creditsList = makeXonoticCreditsList()); - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -void XonoticCreditsDialog_focusEnter(entity me) -{ - me.creditsList.scrolling = time + 1; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_credits.qc b/qcsrc/menu/xonotic/dialog_credits.qc new file mode 100644 index 000000000..e90ae4b42 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_credits.qc @@ -0,0 +1,29 @@ +#ifdef INTERFACE +CLASS(XonoticCreditsDialog) EXTENDS(XonoticDialog) + METHOD(XonoticCreditsDialog, fill, void(entity)) + METHOD(XonoticCreditsDialog, focusEnter, void(entity)) + ATTRIB(XonoticCreditsDialog, title, string, _("Credits")) + ATTRIB(XonoticCreditsDialog, color, vector, SKINCOLOR_DIALOG_CREDITS) + ATTRIB(XonoticCreditsDialog, intendedWidth, float, SKINWIDTH_CREDITS) + ATTRIB(XonoticCreditsDialog, rows, float, SKINROWS_CREDITS) + ATTRIB(XonoticCreditsDialog, columns, float, 2) + ATTRIB(XonoticCreditsDialog, creditsList, entity, NULL) +ENDCLASS(XonoticCreditsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticCreditsDialog_fill(entity me) +{ + entity e; + me.TR(me); + me.TD(me, me.rows - 1, me.columns, me.creditsList = makeXonoticCreditsList()); + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +void XonoticCreditsDialog_focusEnter(entity me) +{ + me.creditsList.scrolling = time + 1; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_firstrun.c b/qcsrc/menu/xonotic/dialog_firstrun.c deleted file mode 100644 index 90988703e..000000000 --- a/qcsrc/menu/xonotic/dialog_firstrun.c +++ /dev/null @@ -1,96 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticFirstRunDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticFirstRunDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls - ATTRIB(XonoticFirstRunDialog, title, string, _("Welcome")) - ATTRIB(XonoticFirstRunDialog, color, vector, SKINCOLOR_DIALOG_FIRSTRUN) - ATTRIB(XonoticFirstRunDialog, intendedWidth, float, 0.7) - ATTRIB(XonoticFirstRunDialog, rows, float, 16) - ATTRIB(XonoticFirstRunDialog, columns, float, 6) - ATTRIB(XonoticFirstRunDialog, name, string, "FirstRun") - ATTRIB(XonoticFirstRunDialog, playerNameLabel, entity, NULL) - ATTRIB(XonoticFirstRunDialog, playerNameLabelAlpha, float, 0) - - ATTRIB(XonoticFirstRunDialog, closable, float, 0) -ENDCLASS(XonoticFirstRunDialog) -#endif - -#ifdef IMPLEMENTATION -float CheckFirstRunButton(entity me) -{ - if(cvar_string("_cl_name") != cvar_defstring("_cl_name")) - return 1; - - if(cvar_string("_menu_prvm_language") != prvm_language) - return 1; // OK will then reopen the dialog in another language - - if(cvar_string("cl_allow_uid2name") != "-1") - return 1; - - return 0; -} - -void firstRun_setLanguage(entity me) -{ - if(prvm_language != cvar_string("_menu_prvm_language")) - localcmd("\nprvm_language \"$_menu_prvm_language\"; saveconfig; menu_restart\n"); -} - -void XonoticFirstRunDialog_fill(entity me) -{ - entity e; - entity label, box; - - me.TR(me); - me.TR(me); - me.TDempty(me, 1); - me.TD(me, 2, 4, e = makeXonoticTextLabel(0, _("Welcome to Xonotic, please select your language preference and enter your player name to get started. You can change these options later through the menu system."))); - e.allowWrap = 1; - me.TR(me); - - me.TR(me); - me.TR(me); - me.TD(me, 1, 0.5, me.playerNameLabel = makeXonoticTextLabel(0, _("Name:"))); - me.playerNameLabelAlpha = me.playerNameLabel.alpha; - me.TD(me, 1, 3.25, label = makeXonoticTextLabel(0, string_null)); - label.allowCut = 1; - label.allowColors = 1; - label.alpha = 1; - me.TR(me); - me.TD(me, 1, 3.75, box = makeXonoticInputBox(1, "_cl_name")); - box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved - box.maxLength = -127; // negative means encoded length in bytes - box.saveImmediately = 1; - label.textEntity = box; - me.TR(me); - me.TD(me, 5, 1.25, e = makeXonoticColorpicker(box)); - me.TD(me, 5, 2.5, e = makeXonoticCharmap(box)); - me.TR(me); - me.TR(me); - me.TR(me); - me.TR(me); - - me.gotoRC(me, 3, 4); me.setFirstColumn(me, me.currentColumn); - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticTextLabel(0, _("Text language:"))); - me.TR(me); - me.TD(me, 6, 2, e = makeXonoticLanguageList()); - e.name = "languageselector_firstrun"; - e.setLanguage = firstRun_setLanguage; - me.TR(me); - me.TR(me); - - me.gotoRC(me, me.rows - 4, 0); - me.TD(me, 1, me.columns, e = makeXonoticTextLabel(0.5, _("Allow player statistics to use your nickname at stats.xonotic.org?"))); - - me.gotoRC(me, me.rows - 3, 0); - me.TDempty(me, 1.5); - me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "cl_allow_uid2name", "1", ZCTX(_("ALWU2N^Yes")))); - me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "cl_allow_uid2name", "0", ZCTX(_("ALWU2N^No")))); - me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "cl_allow_uid2name", "-1", ZCTX(_("ALWU2N^Undecided")))); - - // because of the language selector, this is a menu_restart! - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticCommandButton(_("Save settings"), '0 0 0', "prvm_language \"$_menu_prvm_language\"; saveconfig; menu_restart", COMMANDBUTTON_APPLY)); - setDependentWeird(e, CheckFirstRunButton); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_firstrun.qc b/qcsrc/menu/xonotic/dialog_firstrun.qc new file mode 100644 index 000000000..90988703e --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_firstrun.qc @@ -0,0 +1,96 @@ +#ifdef INTERFACE +CLASS(XonoticFirstRunDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticFirstRunDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls + ATTRIB(XonoticFirstRunDialog, title, string, _("Welcome")) + ATTRIB(XonoticFirstRunDialog, color, vector, SKINCOLOR_DIALOG_FIRSTRUN) + ATTRIB(XonoticFirstRunDialog, intendedWidth, float, 0.7) + ATTRIB(XonoticFirstRunDialog, rows, float, 16) + ATTRIB(XonoticFirstRunDialog, columns, float, 6) + ATTRIB(XonoticFirstRunDialog, name, string, "FirstRun") + ATTRIB(XonoticFirstRunDialog, playerNameLabel, entity, NULL) + ATTRIB(XonoticFirstRunDialog, playerNameLabelAlpha, float, 0) + + ATTRIB(XonoticFirstRunDialog, closable, float, 0) +ENDCLASS(XonoticFirstRunDialog) +#endif + +#ifdef IMPLEMENTATION +float CheckFirstRunButton(entity me) +{ + if(cvar_string("_cl_name") != cvar_defstring("_cl_name")) + return 1; + + if(cvar_string("_menu_prvm_language") != prvm_language) + return 1; // OK will then reopen the dialog in another language + + if(cvar_string("cl_allow_uid2name") != "-1") + return 1; + + return 0; +} + +void firstRun_setLanguage(entity me) +{ + if(prvm_language != cvar_string("_menu_prvm_language")) + localcmd("\nprvm_language \"$_menu_prvm_language\"; saveconfig; menu_restart\n"); +} + +void XonoticFirstRunDialog_fill(entity me) +{ + entity e; + entity label, box; + + me.TR(me); + me.TR(me); + me.TDempty(me, 1); + me.TD(me, 2, 4, e = makeXonoticTextLabel(0, _("Welcome to Xonotic, please select your language preference and enter your player name to get started. You can change these options later through the menu system."))); + e.allowWrap = 1; + me.TR(me); + + me.TR(me); + me.TR(me); + me.TD(me, 1, 0.5, me.playerNameLabel = makeXonoticTextLabel(0, _("Name:"))); + me.playerNameLabelAlpha = me.playerNameLabel.alpha; + me.TD(me, 1, 3.25, label = makeXonoticTextLabel(0, string_null)); + label.allowCut = 1; + label.allowColors = 1; + label.alpha = 1; + me.TR(me); + me.TD(me, 1, 3.75, box = makeXonoticInputBox(1, "_cl_name")); + box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved + box.maxLength = -127; // negative means encoded length in bytes + box.saveImmediately = 1; + label.textEntity = box; + me.TR(me); + me.TD(me, 5, 1.25, e = makeXonoticColorpicker(box)); + me.TD(me, 5, 2.5, e = makeXonoticCharmap(box)); + me.TR(me); + me.TR(me); + me.TR(me); + me.TR(me); + + me.gotoRC(me, 3, 4); me.setFirstColumn(me, me.currentColumn); + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticTextLabel(0, _("Text language:"))); + me.TR(me); + me.TD(me, 6, 2, e = makeXonoticLanguageList()); + e.name = "languageselector_firstrun"; + e.setLanguage = firstRun_setLanguage; + me.TR(me); + me.TR(me); + + me.gotoRC(me, me.rows - 4, 0); + me.TD(me, 1, me.columns, e = makeXonoticTextLabel(0.5, _("Allow player statistics to use your nickname at stats.xonotic.org?"))); + + me.gotoRC(me, me.rows - 3, 0); + me.TDempty(me, 1.5); + me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "cl_allow_uid2name", "1", ZCTX(_("ALWU2N^Yes")))); + me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "cl_allow_uid2name", "0", ZCTX(_("ALWU2N^No")))); + me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "cl_allow_uid2name", "-1", ZCTX(_("ALWU2N^Undecided")))); + + // because of the language selector, this is a menu_restart! + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticCommandButton(_("Save settings"), '0 0 0', "prvm_language \"$_menu_prvm_language\"; saveconfig; menu_restart", COMMANDBUTTON_APPLY)); + setDependentWeird(e, CheckFirstRunButton); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_ammo.c b/qcsrc/menu/xonotic/dialog_hudpanel_ammo.c deleted file mode 100644 index 15095b2ba..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_ammo.c +++ /dev/null @@ -1,41 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDAmmoDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDAmmoDialog, fill, void(entity)) - ATTRIB(XonoticHUDAmmoDialog, title, string, _("Ammo Panel")) - ATTRIB(XonoticHUDAmmoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDAmmoDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDAmmoDialog, rows, float, 15) - ATTRIB(XonoticHUDAmmoDialog, columns, float, 4) - ATTRIB(XonoticHUDAmmoDialog, name, string, "HUDammo") - ATTRIB(XonoticHUDAmmoDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDAmmoDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDAmmoDialog_fill(entity me) -{ - entity e; - string panelname = "ammo"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Ammunition display:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_ammo_onlycurrent", _("Show only current ammo type"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Noncurrent alpha:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(0, 1, 0.1, "hud_panel_ammo_noncurrent_alpha")); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Noncurrent scale:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(0, 1, 0.1, "hud_panel_ammo_noncurrent_scale")); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Align icon:"))); - me.TD(me, 1, 2.6/2, e = makeXonoticRadioButton(2, "hud_panel_ammo_iconalign", "0", _("Left"))); - me.TD(me, 1, 2.6/2, e = makeXonoticRadioButton(2, "hud_panel_ammo_iconalign", "1", _("Right"))); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc b/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc new file mode 100644 index 000000000..15095b2ba --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc @@ -0,0 +1,41 @@ +#ifdef INTERFACE +CLASS(XonoticHUDAmmoDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDAmmoDialog, fill, void(entity)) + ATTRIB(XonoticHUDAmmoDialog, title, string, _("Ammo Panel")) + ATTRIB(XonoticHUDAmmoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDAmmoDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDAmmoDialog, rows, float, 15) + ATTRIB(XonoticHUDAmmoDialog, columns, float, 4) + ATTRIB(XonoticHUDAmmoDialog, name, string, "HUDammo") + ATTRIB(XonoticHUDAmmoDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDAmmoDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDAmmoDialog_fill(entity me) +{ + entity e; + string panelname = "ammo"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Ammunition display:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_ammo_onlycurrent", _("Show only current ammo type"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Noncurrent alpha:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(0, 1, 0.1, "hud_panel_ammo_noncurrent_alpha")); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Noncurrent scale:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(0, 1, 0.1, "hud_panel_ammo_noncurrent_scale")); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Align icon:"))); + me.TD(me, 1, 2.6/2, e = makeXonoticRadioButton(2, "hud_panel_ammo_iconalign", "0", _("Left"))); + me.TD(me, 1, 2.6/2, e = makeXonoticRadioButton(2, "hud_panel_ammo_iconalign", "1", _("Right"))); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_buffs.c b/qcsrc/menu/xonotic/dialog_hudpanel_buffs.c deleted file mode 100644 index ac1033cd5..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_buffs.c +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDBuffsDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDBuffsDialog, fill, void(entity)) - ATTRIB(XonoticHUDBuffsDialog, title, string, _("Buffs Panel")) - ATTRIB(XonoticHUDBuffsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDBuffsDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDBuffsDialog, rows, float, 15) - ATTRIB(XonoticHUDBuffsDialog, columns, float, 4) - ATTRIB(XonoticHUDBuffsDialog, name, string, "HUDbuffs") - ATTRIB(XonoticHUDBuffsDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDBuffsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDBuffsDialog_fill(entity me) -{ - entity e; - string panelname = "buffs"; - - DIALOG_HUDPANEL_COMMON(); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_buffs.qc b/qcsrc/menu/xonotic/dialog_hudpanel_buffs.qc new file mode 100644 index 000000000..ac1033cd5 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_buffs.qc @@ -0,0 +1,22 @@ +#ifdef INTERFACE +CLASS(XonoticHUDBuffsDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDBuffsDialog, fill, void(entity)) + ATTRIB(XonoticHUDBuffsDialog, title, string, _("Buffs Panel")) + ATTRIB(XonoticHUDBuffsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDBuffsDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDBuffsDialog, rows, float, 15) + ATTRIB(XonoticHUDBuffsDialog, columns, float, 4) + ATTRIB(XonoticHUDBuffsDialog, name, string, "HUDbuffs") + ATTRIB(XonoticHUDBuffsDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDBuffsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDBuffsDialog_fill(entity me) +{ + entity e; + string panelname = "buffs"; + + DIALOG_HUDPANEL_COMMON(); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.c b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.c deleted file mode 100644 index dce687a0d..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.c +++ /dev/null @@ -1,45 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDCenterprintDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDCenterprintDialog, fill, void(entity)) - ATTRIB(XonoticHUDCenterprintDialog, title, string, _("Centerprint Panel")) - ATTRIB(XonoticHUDCenterprintDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDCenterprintDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDCenterprintDialog, rows, float, 15) - ATTRIB(XonoticHUDCenterprintDialog, columns, float, 4) - ATTRIB(XonoticHUDCenterprintDialog, name, string, "HUDcenterprint") - ATTRIB(XonoticHUDCenterprintDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDCenterprintDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDCenterprintDialog_fill(entity me) -{ - entity e; - string panelname = "centerprint"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Message duration:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(1, 10, 1, "hud_panel_centerprint_time")); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Fade time:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(0, 1, 0.05, "hud_panel_centerprint_fade_out")); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_centerprint_flip", _("Flip messages order"))); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Text alignment:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_centerprint_align", "0", _("Left"))); - me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_centerprint_align", "0.5", _("Center"))); - me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_centerprint_align", "1", _("Right"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Font scale:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(0.5, 2, 0.1, "hud_panel_centerprint_fontscale")); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc new file mode 100644 index 000000000..dce687a0d --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc @@ -0,0 +1,45 @@ +#ifdef INTERFACE +CLASS(XonoticHUDCenterprintDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDCenterprintDialog, fill, void(entity)) + ATTRIB(XonoticHUDCenterprintDialog, title, string, _("Centerprint Panel")) + ATTRIB(XonoticHUDCenterprintDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDCenterprintDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDCenterprintDialog, rows, float, 15) + ATTRIB(XonoticHUDCenterprintDialog, columns, float, 4) + ATTRIB(XonoticHUDCenterprintDialog, name, string, "HUDcenterprint") + ATTRIB(XonoticHUDCenterprintDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDCenterprintDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDCenterprintDialog_fill(entity me) +{ + entity e; + string panelname = "centerprint"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Message duration:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(1, 10, 1, "hud_panel_centerprint_time")); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Fade time:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(0, 1, 0.05, "hud_panel_centerprint_fade_out")); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_centerprint_flip", _("Flip messages order"))); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Text alignment:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_centerprint_align", "0", _("Left"))); + me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_centerprint_align", "0.5", _("Center"))); + me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_centerprint_align", "1", _("Right"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Font scale:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(0.5, 2, 0.1, "hud_panel_centerprint_fontscale")); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_chat.c b/qcsrc/menu/xonotic/dialog_hudpanel_chat.c deleted file mode 100644 index eb6ced2c4..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_chat.c +++ /dev/null @@ -1,36 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDChatDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDChatDialog, fill, void(entity)) - ATTRIB(XonoticHUDChatDialog, title, string, _("Chat Panel")) - ATTRIB(XonoticHUDChatDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDChatDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDChatDialog, rows, float, 15) - ATTRIB(XonoticHUDChatDialog, columns, float, 4) - ATTRIB(XonoticHUDChatDialog, name, string, "HUDchat") - ATTRIB(XonoticHUDChatDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDChatDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDChatDialog_fill(entity me) -{ - entity e; - string panelname = "chat"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticTextLabel(0, _("Chat entries:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Chat size:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(6, 20, 1, "con_chatsize")); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Chat lifetime:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(5, 60, 5, "con_chattime")); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "con_chatsound", _("Chat beep sound"))); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc b/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc new file mode 100644 index 000000000..eb6ced2c4 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc @@ -0,0 +1,36 @@ +#ifdef INTERFACE +CLASS(XonoticHUDChatDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDChatDialog, fill, void(entity)) + ATTRIB(XonoticHUDChatDialog, title, string, _("Chat Panel")) + ATTRIB(XonoticHUDChatDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDChatDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDChatDialog, rows, float, 15) + ATTRIB(XonoticHUDChatDialog, columns, float, 4) + ATTRIB(XonoticHUDChatDialog, name, string, "HUDchat") + ATTRIB(XonoticHUDChatDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDChatDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDChatDialog_fill(entity me) +{ + entity e; + string panelname = "chat"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticTextLabel(0, _("Chat entries:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Chat size:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(6, 20, 1, "con_chatsize")); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Chat lifetime:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(5, 60, 5, "con_chattime")); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "con_chatsound", _("Chat beep sound"))); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.c b/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.c deleted file mode 100644 index bbc3f8cf3..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.c +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDEngineInfoDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDEngineInfoDialog, fill, void(entity)) - ATTRIB(XonoticHUDEngineInfoDialog, title, string, _("Engine Info Panel")) - ATTRIB(XonoticHUDEngineInfoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDEngineInfoDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDEngineInfoDialog, rows, float, 15) - ATTRIB(XonoticHUDEngineInfoDialog, columns, float, 4) - ATTRIB(XonoticHUDEngineInfoDialog, name, string, "HUDengineinfo") - ATTRIB(XonoticHUDEngineInfoDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDEngineInfoDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDEngineInfoDialog_fill(entity me) -{ - entity e; - string panelname = "engineinfo"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Engine info:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_engineinfo_framecounter_exponentialmovingaverage", _("Use an averaging algorithm for fps"))); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc b/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc new file mode 100644 index 000000000..bbc3f8cf3 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc @@ -0,0 +1,28 @@ +#ifdef INTERFACE +CLASS(XonoticHUDEngineInfoDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDEngineInfoDialog, fill, void(entity)) + ATTRIB(XonoticHUDEngineInfoDialog, title, string, _("Engine Info Panel")) + ATTRIB(XonoticHUDEngineInfoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDEngineInfoDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDEngineInfoDialog, rows, float, 15) + ATTRIB(XonoticHUDEngineInfoDialog, columns, float, 4) + ATTRIB(XonoticHUDEngineInfoDialog, name, string, "HUDengineinfo") + ATTRIB(XonoticHUDEngineInfoDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDEngineInfoDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDEngineInfoDialog_fill(entity me) +{ + entity e; + string panelname = "engineinfo"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Engine info:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_engineinfo_framecounter_exponentialmovingaverage", _("Use an averaging algorithm for fps"))); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.c b/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.c deleted file mode 100644 index 976139c8e..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.c +++ /dev/null @@ -1,48 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDHealthArmorDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDHealthArmorDialog, fill, void(entity)) - ATTRIB(XonoticHUDHealthArmorDialog, title, string, _("Health/Armor Panel")) - ATTRIB(XonoticHUDHealthArmorDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDHealthArmorDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDHealthArmorDialog, rows, float, 15) - ATTRIB(XonoticHUDHealthArmorDialog, columns, float, 4) - ATTRIB(XonoticHUDHealthArmorDialog, name, string, "HUDhealtharmor") - ATTRIB(XonoticHUDHealthArmorDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDHealthArmorDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDHealthArmorDialog_fill(entity me) -{ - entity e; - string panelname = "healtharmor"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_healtharmor_progressbar", _("Enable status bar"))); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Status bar alignment:"))); - setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_healtharmor_baralign", "0", _("Left"))); - setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_healtharmor_baralign", "1", _("Right"))); - setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_healtharmor_baralign", "2", _("Inward"))); - setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_healtharmor_baralign", "3", _("Outward"))); - setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Icon alignment:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_healtharmor_iconalign", "0", _("Left"))); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_healtharmor_iconalign", "1", _("Right"))); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_healtharmor_iconalign", "2", _("Inward"))); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_healtharmor_iconalign", "3", _("Outward"))); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_healtharmor_flip", _("Flip health and armor positions"))); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc b/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc new file mode 100644 index 000000000..976139c8e --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc @@ -0,0 +1,48 @@ +#ifdef INTERFACE +CLASS(XonoticHUDHealthArmorDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDHealthArmorDialog, fill, void(entity)) + ATTRIB(XonoticHUDHealthArmorDialog, title, string, _("Health/Armor Panel")) + ATTRIB(XonoticHUDHealthArmorDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDHealthArmorDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDHealthArmorDialog, rows, float, 15) + ATTRIB(XonoticHUDHealthArmorDialog, columns, float, 4) + ATTRIB(XonoticHUDHealthArmorDialog, name, string, "HUDhealtharmor") + ATTRIB(XonoticHUDHealthArmorDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDHealthArmorDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDHealthArmorDialog_fill(entity me) +{ + entity e; + string panelname = "healtharmor"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_healtharmor_progressbar", _("Enable status bar"))); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Status bar alignment:"))); + setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_healtharmor_baralign", "0", _("Left"))); + setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_healtharmor_baralign", "1", _("Right"))); + setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_healtharmor_baralign", "2", _("Inward"))); + setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_healtharmor_baralign", "3", _("Outward"))); + setDependent(e, "hud_panel_healtharmor_progressbar", 1, 1); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Icon alignment:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_healtharmor_iconalign", "0", _("Left"))); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_healtharmor_iconalign", "1", _("Right"))); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_healtharmor_iconalign", "2", _("Inward"))); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_healtharmor_iconalign", "3", _("Outward"))); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_healtharmor_flip", _("Flip health and armor positions"))); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.c b/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.c deleted file mode 100644 index 5bd8846c5..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.c +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDInfoMessagesDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDInfoMessagesDialog, fill, void(entity)) - ATTRIB(XonoticHUDInfoMessagesDialog, title, string, _("Info Messages Panel")) - ATTRIB(XonoticHUDInfoMessagesDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDInfoMessagesDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDInfoMessagesDialog, rows, float, 15) - ATTRIB(XonoticHUDInfoMessagesDialog, columns, float, 4) - ATTRIB(XonoticHUDInfoMessagesDialog, name, string, "HUDinfomessages") - ATTRIB(XonoticHUDInfoMessagesDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDInfoMessagesDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDInfoMessagesDialog_fill(entity me) -{ - entity e; - string panelname = "infomessages"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Info messages:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_infomessages_flip", _("Flip align"))); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc b/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc new file mode 100644 index 000000000..5bd8846c5 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc @@ -0,0 +1,28 @@ +#ifdef INTERFACE +CLASS(XonoticHUDInfoMessagesDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDInfoMessagesDialog, fill, void(entity)) + ATTRIB(XonoticHUDInfoMessagesDialog, title, string, _("Info Messages Panel")) + ATTRIB(XonoticHUDInfoMessagesDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDInfoMessagesDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDInfoMessagesDialog, rows, float, 15) + ATTRIB(XonoticHUDInfoMessagesDialog, columns, float, 4) + ATTRIB(XonoticHUDInfoMessagesDialog, name, string, "HUDinfomessages") + ATTRIB(XonoticHUDInfoMessagesDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDInfoMessagesDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDInfoMessagesDialog_fill(entity me) +{ + entity e; + string panelname = "infomessages"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Info messages:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_infomessages_flip", _("Flip align"))); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_modicons.c b/qcsrc/menu/xonotic/dialog_hudpanel_modicons.c deleted file mode 100644 index 4c9e64c2a..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_modicons.c +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDModIconsDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDModIconsDialog, fill, void(entity)) - ATTRIB(XonoticHUDModIconsDialog, title, string, _("Mod Icons Panel")) - ATTRIB(XonoticHUDModIconsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDModIconsDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDModIconsDialog, rows, float, 15) - ATTRIB(XonoticHUDModIconsDialog, columns, float, 4) - ATTRIB(XonoticHUDModIconsDialog, name, string, "HUDmodicons") - ATTRIB(XonoticHUDModIconsDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDModIconsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDModIconsDialog_fill(entity me) -{ - entity e; - string panelname = "modicons"; - - DIALOG_HUDPANEL_COMMON(); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc b/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc new file mode 100644 index 000000000..4c9e64c2a --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc @@ -0,0 +1,22 @@ +#ifdef INTERFACE +CLASS(XonoticHUDModIconsDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDModIconsDialog, fill, void(entity)) + ATTRIB(XonoticHUDModIconsDialog, title, string, _("Mod Icons Panel")) + ATTRIB(XonoticHUDModIconsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDModIconsDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDModIconsDialog, rows, float, 15) + ATTRIB(XonoticHUDModIconsDialog, columns, float, 4) + ATTRIB(XonoticHUDModIconsDialog, name, string, "HUDmodicons") + ATTRIB(XonoticHUDModIconsDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDModIconsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDModIconsDialog_fill(entity me) +{ + entity e; + string panelname = "modicons"; + + DIALOG_HUDPANEL_COMMON(); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_notification.c b/qcsrc/menu/xonotic/dialog_hudpanel_notification.c deleted file mode 100644 index 1239bd316..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_notification.c +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDNotificationDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDNotificationDialog, fill, void(entity)) - ATTRIB(XonoticHUDNotificationDialog, title, string, _("Notification Panel")) - ATTRIB(XonoticHUDNotificationDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDNotificationDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDNotificationDialog, rows, float, 15) - ATTRIB(XonoticHUDNotificationDialog, columns, float, 4) - ATTRIB(XonoticHUDNotificationDialog, name, string, "HUDnotify") - ATTRIB(XonoticHUDNotificationDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDNotificationDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDNotificationDialog_fill(entity me) -{ - entity e; - string panelname = "notify"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Notifications:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_notify_print", _("Also print notifications to the console"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_notify_flip", _("Flip notify order"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Entry lifetime:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(3, 15, 1, "hud_panel_notify_time")); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Entry fadetime:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(0.5, 5, 0.5, "hud_panel_notify_fadetime")); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc b/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc new file mode 100644 index 000000000..1239bd316 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc @@ -0,0 +1,39 @@ +#ifdef INTERFACE +CLASS(XonoticHUDNotificationDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDNotificationDialog, fill, void(entity)) + ATTRIB(XonoticHUDNotificationDialog, title, string, _("Notification Panel")) + ATTRIB(XonoticHUDNotificationDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDNotificationDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDNotificationDialog, rows, float, 15) + ATTRIB(XonoticHUDNotificationDialog, columns, float, 4) + ATTRIB(XonoticHUDNotificationDialog, name, string, "HUDnotify") + ATTRIB(XonoticHUDNotificationDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDNotificationDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDNotificationDialog_fill(entity me) +{ + entity e; + string panelname = "notify"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Notifications:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_notify_print", _("Also print notifications to the console"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_notify_flip", _("Flip notify order"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Entry lifetime:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(3, 15, 1, "hud_panel_notify_time")); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Entry fadetime:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(0.5, 5, 0.5, "hud_panel_notify_fadetime")); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_physics.c b/qcsrc/menu/xonotic/dialog_hudpanel_physics.c deleted file mode 100644 index 0144d6649..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_physics.c +++ /dev/null @@ -1,83 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDPhysicsDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDPhysicsDialog, fill, void(entity)) - ATTRIB(XonoticHUDPhysicsDialog, title, string, _("Physics Panel")) - ATTRIB(XonoticHUDPhysicsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDPhysicsDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDPhysicsDialog, rows, float, 15) - ATTRIB(XonoticHUDPhysicsDialog, columns, float, 4) - ATTRIB(XonoticHUDPhysicsDialog, name, string, "HUDphysics") - ATTRIB(XonoticHUDPhysicsDialog, sliderTopspeedTime, entity, NULL) - ATTRIB(XonoticHUDPhysicsDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDPhysicsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDPhysicsDialog_fill(entity me) -{ - entity e; - string panelname = "physics"; - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextSlider("hud_panel_physics")); - e.addValue(e, _("Panel disabled"), "0"); - e.addValue(e, _("Panel enabled"), "1"); - e.addValue(e, _("Panel enabled even observing"), "2"); - e.addValue(e, _("Panel enabled only in Race/CTS"), "3"); - e.configureXonoticTextSliderValues(e); - - DIALOG_HUDPANEL_COMMON_NOTOGGLE(); - - me.TR(me); - me.TD(me, 1, 1.4, e = makeXonoticCheckBox(0, "hud_panel_physics_progressbar", _("Status bar"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_physics_baralign")); - e.addValue(e, _("Left align") , "0"); - e.addValue(e, _("Right align") , "1"); - e.addValue(e, _("Inward align") , "2"); - e.addValue(e, _("Outward align"), "3"); - e.configureXonoticTextSliderValues(e); - setDependent(e, "hud_panel_physics_progressbar", 1, 3); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_physics_flip", _("Flip speed/acceleration positions"))); - -//speed - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Speed:"))); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "hud_panel_physics_speed_vertical", _("Include vertical speed"))); - // me.TR(me); - // me.TDempty(me, 0.2); - // me.TD(me, 1, 1.8, e = makeXonoticTextLabel(0, _("Full status bar at:"))); - // setDependent(e, "hud_panel_physics_progressbar", 1, 1); - // me.TD(me, 1, 1, e = makeXonoticInputBox(1, "hud_panel_physics_speed_max")); - // setDependent(e, "hud_panel_physics_progressbar", 1, 1); - // me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("qu/s"))); - // setDependent(e, "hud_panel_physics_progressbar", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Speed unit:"))); - me.TD(me, 1, 2.6/3*2, e = makeXonoticTextSlider("hud_panel_physics_speed_unit")); - e.addValue(e, _("qu/s") , "1"); - e.addValue(e, _("m/s") , "2"); - e.addValue(e, _("km/h") , "3"); - e.addValue(e, _("mph") , "4"); - e.addValue(e, _("knots"), "5"); - e.configureXonoticTextSliderValues(e); - me.TD(me, 1, 2.6/3, e = makeXonoticCheckBox(0, "hud_panel_physics_speed_unit_show", _("Show"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8/2, e = makeXonoticCheckBox(0, "hud_panel_physics_topspeed", _("Top speed"))); - me.TD(me, 1, 3.8/2, e = makeXonoticSlider(1, 10, 1, "hud_panel_physics_topspeed_time")); - setDependent(e, "hud_panel_physics_topspeed", 1, 1); - -//acceleration - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Acceleration:"))); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "hud_panel_physics_acceleration_vertical", _("Include vertical acceleration"))); - // me.TR(me); - // me.TDempty(me, 0.2); - // me.TD(me, 1, 1.8, e = makeXonoticTextLabel(0, _("Full status bar at:"))); - // setDependent(e, "hud_panel_physics_progressbar", 1, 1); - // me.TD(me, 1, 0.6, e = makeXonoticInputBox(1, "hud_panel_physics_acceleration_max")); - // setDependent(e, "hud_panel_physics_progressbar", 1, 1); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc new file mode 100644 index 000000000..0144d6649 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc @@ -0,0 +1,83 @@ +#ifdef INTERFACE +CLASS(XonoticHUDPhysicsDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDPhysicsDialog, fill, void(entity)) + ATTRIB(XonoticHUDPhysicsDialog, title, string, _("Physics Panel")) + ATTRIB(XonoticHUDPhysicsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDPhysicsDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDPhysicsDialog, rows, float, 15) + ATTRIB(XonoticHUDPhysicsDialog, columns, float, 4) + ATTRIB(XonoticHUDPhysicsDialog, name, string, "HUDphysics") + ATTRIB(XonoticHUDPhysicsDialog, sliderTopspeedTime, entity, NULL) + ATTRIB(XonoticHUDPhysicsDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDPhysicsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDPhysicsDialog_fill(entity me) +{ + entity e; + string panelname = "physics"; + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextSlider("hud_panel_physics")); + e.addValue(e, _("Panel disabled"), "0"); + e.addValue(e, _("Panel enabled"), "1"); + e.addValue(e, _("Panel enabled even observing"), "2"); + e.addValue(e, _("Panel enabled only in Race/CTS"), "3"); + e.configureXonoticTextSliderValues(e); + + DIALOG_HUDPANEL_COMMON_NOTOGGLE(); + + me.TR(me); + me.TD(me, 1, 1.4, e = makeXonoticCheckBox(0, "hud_panel_physics_progressbar", _("Status bar"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_physics_baralign")); + e.addValue(e, _("Left align") , "0"); + e.addValue(e, _("Right align") , "1"); + e.addValue(e, _("Inward align") , "2"); + e.addValue(e, _("Outward align"), "3"); + e.configureXonoticTextSliderValues(e); + setDependent(e, "hud_panel_physics_progressbar", 1, 3); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_physics_flip", _("Flip speed/acceleration positions"))); + +//speed + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Speed:"))); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "hud_panel_physics_speed_vertical", _("Include vertical speed"))); + // me.TR(me); + // me.TDempty(me, 0.2); + // me.TD(me, 1, 1.8, e = makeXonoticTextLabel(0, _("Full status bar at:"))); + // setDependent(e, "hud_panel_physics_progressbar", 1, 1); + // me.TD(me, 1, 1, e = makeXonoticInputBox(1, "hud_panel_physics_speed_max")); + // setDependent(e, "hud_panel_physics_progressbar", 1, 1); + // me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("qu/s"))); + // setDependent(e, "hud_panel_physics_progressbar", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Speed unit:"))); + me.TD(me, 1, 2.6/3*2, e = makeXonoticTextSlider("hud_panel_physics_speed_unit")); + e.addValue(e, _("qu/s") , "1"); + e.addValue(e, _("m/s") , "2"); + e.addValue(e, _("km/h") , "3"); + e.addValue(e, _("mph") , "4"); + e.addValue(e, _("knots"), "5"); + e.configureXonoticTextSliderValues(e); + me.TD(me, 1, 2.6/3, e = makeXonoticCheckBox(0, "hud_panel_physics_speed_unit_show", _("Show"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8/2, e = makeXonoticCheckBox(0, "hud_panel_physics_topspeed", _("Top speed"))); + me.TD(me, 1, 3.8/2, e = makeXonoticSlider(1, 10, 1, "hud_panel_physics_topspeed_time")); + setDependent(e, "hud_panel_physics_topspeed", 1, 1); + +//acceleration + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Acceleration:"))); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "hud_panel_physics_acceleration_vertical", _("Include vertical acceleration"))); + // me.TR(me); + // me.TDempty(me, 0.2); + // me.TD(me, 1, 1.8, e = makeXonoticTextLabel(0, _("Full status bar at:"))); + // setDependent(e, "hud_panel_physics_progressbar", 1, 1); + // me.TD(me, 1, 0.6, e = makeXonoticInputBox(1, "hud_panel_physics_acceleration_max")); + // setDependent(e, "hud_panel_physics_progressbar", 1, 1); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_powerups.c b/qcsrc/menu/xonotic/dialog_hudpanel_powerups.c deleted file mode 100644 index 17bfe04aa..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_powerups.c +++ /dev/null @@ -1,48 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDPowerupsDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDPowerupsDialog, fill, void(entity)) - ATTRIB(XonoticHUDPowerupsDialog, title, string, _("Powerups Panel")) - ATTRIB(XonoticHUDPowerupsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDPowerupsDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDPowerupsDialog, rows, float, 15) - ATTRIB(XonoticHUDPowerupsDialog, columns, float, 4) - ATTRIB(XonoticHUDPowerupsDialog, name, string, "HUDpowerups") - ATTRIB(XonoticHUDPowerupsDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDPowerupsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDPowerupsDialog_fill(entity me) -{ - entity e; - string panelname = "powerups"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_powerups_progressbar", _("Enable status bar"))); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Status bar alignment:"))); - setDependent(e, "hud_panel_powerups_progressbar", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_powerups_baralign", "0", _("Left"))); - setDependent(e, "hud_panel_powerups_progressbar", 1, 1); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_powerups_baralign", "1", _("Right"))); - setDependent(e, "hud_panel_powerups_progressbar", 1, 1); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_powerups_baralign", "2", _("Inward"))); - setDependent(e, "hud_panel_powerups_progressbar", 1, 1); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_powerups_baralign", "3", _("Outward"))); - setDependent(e, "hud_panel_powerups_progressbar", 1, 1); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Icon alignment:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "0", _("Left"))); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "1", _("Right"))); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "2", _("Inward"))); - me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "3", _("Outward"))); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_powerups_flip", _("Flip strength and shield positions"))); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc b/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc new file mode 100644 index 000000000..17bfe04aa --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc @@ -0,0 +1,48 @@ +#ifdef INTERFACE +CLASS(XonoticHUDPowerupsDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDPowerupsDialog, fill, void(entity)) + ATTRIB(XonoticHUDPowerupsDialog, title, string, _("Powerups Panel")) + ATTRIB(XonoticHUDPowerupsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDPowerupsDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDPowerupsDialog, rows, float, 15) + ATTRIB(XonoticHUDPowerupsDialog, columns, float, 4) + ATTRIB(XonoticHUDPowerupsDialog, name, string, "HUDpowerups") + ATTRIB(XonoticHUDPowerupsDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDPowerupsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDPowerupsDialog_fill(entity me) +{ + entity e; + string panelname = "powerups"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_powerups_progressbar", _("Enable status bar"))); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Status bar alignment:"))); + setDependent(e, "hud_panel_powerups_progressbar", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_powerups_baralign", "0", _("Left"))); + setDependent(e, "hud_panel_powerups_progressbar", 1, 1); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_powerups_baralign", "1", _("Right"))); + setDependent(e, "hud_panel_powerups_progressbar", 1, 1); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_powerups_baralign", "2", _("Inward"))); + setDependent(e, "hud_panel_powerups_progressbar", 1, 1); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(2, "hud_panel_powerups_baralign", "3", _("Outward"))); + setDependent(e, "hud_panel_powerups_progressbar", 1, 1); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Icon alignment:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "0", _("Left"))); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "1", _("Right"))); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "2", _("Inward"))); + me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "3", _("Outward"))); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_powerups_flip", _("Flip strength and shield positions"))); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.c b/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.c deleted file mode 100644 index 2e301cc37..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.c +++ /dev/null @@ -1,34 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDPressedKeysDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDPressedKeysDialog, fill, void(entity)) - ATTRIB(XonoticHUDPressedKeysDialog, title, string, _("Pressed Keys Panel")) - ATTRIB(XonoticHUDPressedKeysDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDPressedKeysDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDPressedKeysDialog, rows, float, 15) - ATTRIB(XonoticHUDPressedKeysDialog, columns, float, 4) - ATTRIB(XonoticHUDPressedKeysDialog, name, string, "HUDpressedkeys") - ATTRIB(XonoticHUDPressedKeysDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDPressedKeysDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDPressedKeysDialog_fill(entity me) -{ - entity e; - string panelname = "pressedkeys"; - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextSlider("hud_panel_pressedkeys")); - e.addValue(e, _("Panel disabled"), "0"); - e.addValue(e, _("Panel enabled when spectating"), "1"); - e.addValue(e, _("Panel always enabled"), "2"); - e.configureXonoticTextSliderValues(e); - - DIALOG_HUDPANEL_COMMON_NOTOGGLE(); - - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Forced aspect:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(0.2, 4, 0.1, "hud_panel_pressedkeys_aspect")); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc b/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc new file mode 100644 index 000000000..2e301cc37 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc @@ -0,0 +1,34 @@ +#ifdef INTERFACE +CLASS(XonoticHUDPressedKeysDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDPressedKeysDialog, fill, void(entity)) + ATTRIB(XonoticHUDPressedKeysDialog, title, string, _("Pressed Keys Panel")) + ATTRIB(XonoticHUDPressedKeysDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDPressedKeysDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDPressedKeysDialog, rows, float, 15) + ATTRIB(XonoticHUDPressedKeysDialog, columns, float, 4) + ATTRIB(XonoticHUDPressedKeysDialog, name, string, "HUDpressedkeys") + ATTRIB(XonoticHUDPressedKeysDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDPressedKeysDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDPressedKeysDialog_fill(entity me) +{ + entity e; + string panelname = "pressedkeys"; + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextSlider("hud_panel_pressedkeys")); + e.addValue(e, _("Panel disabled"), "0"); + e.addValue(e, _("Panel enabled when spectating"), "1"); + e.addValue(e, _("Panel always enabled"), "2"); + e.configureXonoticTextSliderValues(e); + + DIALOG_HUDPANEL_COMMON_NOTOGGLE(); + + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Forced aspect:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(0.2, 4, 0.1, "hud_panel_pressedkeys_aspect")); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.c b/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.c deleted file mode 100644 index 6b2badf1c..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.c +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDRaceTimerDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDRaceTimerDialog, fill, void(entity)) - ATTRIB(XonoticHUDRaceTimerDialog, title, string, _("Race Timer Panel")) - ATTRIB(XonoticHUDRaceTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDRaceTimerDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDRaceTimerDialog, rows, float, 15) - ATTRIB(XonoticHUDRaceTimerDialog, columns, float, 4) - ATTRIB(XonoticHUDRaceTimerDialog, name, string, "HUDracetimer") - ATTRIB(XonoticHUDRaceTimerDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDRaceTimerDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDRaceTimerDialog_fill(entity me) -{ - entity e; - string panelname = "racetimer"; - - DIALOG_HUDPANEL_COMMON(); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc b/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc new file mode 100644 index 000000000..6b2badf1c --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc @@ -0,0 +1,22 @@ +#ifdef INTERFACE +CLASS(XonoticHUDRaceTimerDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDRaceTimerDialog, fill, void(entity)) + ATTRIB(XonoticHUDRaceTimerDialog, title, string, _("Race Timer Panel")) + ATTRIB(XonoticHUDRaceTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDRaceTimerDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDRaceTimerDialog, rows, float, 15) + ATTRIB(XonoticHUDRaceTimerDialog, columns, float, 4) + ATTRIB(XonoticHUDRaceTimerDialog, name, string, "HUDracetimer") + ATTRIB(XonoticHUDRaceTimerDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDRaceTimerDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDRaceTimerDialog_fill(entity me) +{ + entity e; + string panelname = "racetimer"; + + DIALOG_HUDPANEL_COMMON(); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_radar.c b/qcsrc/menu/xonotic/dialog_hudpanel_radar.c deleted file mode 100644 index 6ad57fa13..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_radar.c +++ /dev/null @@ -1,59 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDRadarDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDRadarDialog, fill, void(entity)) - ATTRIB(XonoticHUDRadarDialog, title, string, _("Radar Panel")) - ATTRIB(XonoticHUDRadarDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDRadarDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDRadarDialog, rows, float, 15) - ATTRIB(XonoticHUDRadarDialog, columns, float, 4) - ATTRIB(XonoticHUDRadarDialog, name, string, "HUDradar") - ATTRIB(XonoticHUDRadarDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDRadarDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDRadarDialog_fill(entity me) -{ - entity e; - string panelname = "radar"; - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextSlider("hud_panel_radar")); - e.addValue(e, _("Panel disabled"), "0"); - e.addValue(e, _("Panel enabled in teamgames"), "1"); - e.addValue(e, _("Panel always enabled"), "2"); - e.configureXonoticTextSliderValues(e); - - DIALOG_HUDPANEL_COMMON_NOTOGGLE(); - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Radar:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Alpha:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(0.1, 1, 0.1, "hud_panel_radar_foreground_alpha")); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Rotation:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_radar_rotation")); - e.addValue(e, _("Forward"), "0"); - e.addValue(e, _("West"), "1"); - e.addValue(e, _("South"), "2"); - e.addValue(e, _("East"), "3"); - e.addValue(e, _("North"), "4"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Scale:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(1024, 8192, 512, "hud_panel_radar_scale")); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Zoom mode:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_radar_zoommode")); - e.addValue(e, _("Zoomed in"), "0"); - e.addValue(e, _("Zoomed out"), "1"); - e.addValue(e, _("Always zoomed"), "2"); - e.addValue(e, _("Never zoomed"), "3"); - e.configureXonoticTextSliderValues(e); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc b/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc new file mode 100644 index 000000000..6ad57fa13 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc @@ -0,0 +1,59 @@ +#ifdef INTERFACE +CLASS(XonoticHUDRadarDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDRadarDialog, fill, void(entity)) + ATTRIB(XonoticHUDRadarDialog, title, string, _("Radar Panel")) + ATTRIB(XonoticHUDRadarDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDRadarDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDRadarDialog, rows, float, 15) + ATTRIB(XonoticHUDRadarDialog, columns, float, 4) + ATTRIB(XonoticHUDRadarDialog, name, string, "HUDradar") + ATTRIB(XonoticHUDRadarDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDRadarDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDRadarDialog_fill(entity me) +{ + entity e; + string panelname = "radar"; + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextSlider("hud_panel_radar")); + e.addValue(e, _("Panel disabled"), "0"); + e.addValue(e, _("Panel enabled in teamgames"), "1"); + e.addValue(e, _("Panel always enabled"), "2"); + e.configureXonoticTextSliderValues(e); + + DIALOG_HUDPANEL_COMMON_NOTOGGLE(); + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Radar:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Alpha:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(0.1, 1, 0.1, "hud_panel_radar_foreground_alpha")); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Rotation:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_radar_rotation")); + e.addValue(e, _("Forward"), "0"); + e.addValue(e, _("West"), "1"); + e.addValue(e, _("South"), "2"); + e.addValue(e, _("East"), "3"); + e.addValue(e, _("North"), "4"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Scale:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(1024, 8192, 512, "hud_panel_radar_scale")); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Zoom mode:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_radar_zoommode")); + e.addValue(e, _("Zoomed in"), "0"); + e.addValue(e, _("Zoomed out"), "1"); + e.addValue(e, _("Always zoomed"), "2"); + e.addValue(e, _("Never zoomed"), "3"); + e.configureXonoticTextSliderValues(e); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_score.c b/qcsrc/menu/xonotic/dialog_hudpanel_score.c deleted file mode 100644 index 676830f80..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_score.c +++ /dev/null @@ -1,31 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDScoreDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDScoreDialog, fill, void(entity)) - ATTRIB(XonoticHUDScoreDialog, title, string, _("Score Panel")) - ATTRIB(XonoticHUDScoreDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDScoreDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDScoreDialog, rows, float, 15) - ATTRIB(XonoticHUDScoreDialog, columns, float, 4) - ATTRIB(XonoticHUDScoreDialog, name, string, "HUDscore") - ATTRIB(XonoticHUDScoreDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDScoreDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDScoreDialog_fill(entity me) -{ - entity e; - string panelname = "score"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Score:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Rankings:"))); - me.TD(me, 1, 2.6/3, e = makeXonoticRadioButton(1, "hud_panel_score_rankings", "0", _("Off"))); - me.TD(me, 1, 2.6/3, e = makeXonoticRadioButton(1, "hud_panel_score_rankings", "1", _("And me"))); - me.TD(me, 1, 2.6/3, e = makeXonoticRadioButton(1, "hud_panel_score_rankings", "2", _("Pure"))); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_score.qc b/qcsrc/menu/xonotic/dialog_hudpanel_score.qc new file mode 100644 index 000000000..676830f80 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_score.qc @@ -0,0 +1,31 @@ +#ifdef INTERFACE +CLASS(XonoticHUDScoreDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDScoreDialog, fill, void(entity)) + ATTRIB(XonoticHUDScoreDialog, title, string, _("Score Panel")) + ATTRIB(XonoticHUDScoreDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDScoreDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDScoreDialog, rows, float, 15) + ATTRIB(XonoticHUDScoreDialog, columns, float, 4) + ATTRIB(XonoticHUDScoreDialog, name, string, "HUDscore") + ATTRIB(XonoticHUDScoreDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDScoreDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDScoreDialog_fill(entity me) +{ + entity e; + string panelname = "score"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Score:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Rankings:"))); + me.TD(me, 1, 2.6/3, e = makeXonoticRadioButton(1, "hud_panel_score_rankings", "0", _("Off"))); + me.TD(me, 1, 2.6/3, e = makeXonoticRadioButton(1, "hud_panel_score_rankings", "1", _("And me"))); + me.TD(me, 1, 2.6/3, e = makeXonoticRadioButton(1, "hud_panel_score_rankings", "2", _("Pure"))); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_timer.c b/qcsrc/menu/xonotic/dialog_hudpanel_timer.c deleted file mode 100644 index 2624a7ecd..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_timer.c +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDTimerDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDTimerDialog, fill, void(entity)) - ATTRIB(XonoticHUDTimerDialog, title, string, _("Timer Panel")) - ATTRIB(XonoticHUDTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDTimerDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDTimerDialog, rows, float, 15) - ATTRIB(XonoticHUDTimerDialog, columns, float, 4) - ATTRIB(XonoticHUDTimerDialog, name, string, "HUDtimer") - ATTRIB(XonoticHUDTimerDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDTimerDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDTimerDialog_fill(entity me) -{ - entity e; - string panelname = "timer"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Timer:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_timer_increment", _("Show elapsed time"))); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc b/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc new file mode 100644 index 000000000..2624a7ecd --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc @@ -0,0 +1,28 @@ +#ifdef INTERFACE +CLASS(XonoticHUDTimerDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDTimerDialog, fill, void(entity)) + ATTRIB(XonoticHUDTimerDialog, title, string, _("Timer Panel")) + ATTRIB(XonoticHUDTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDTimerDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDTimerDialog, rows, float, 15) + ATTRIB(XonoticHUDTimerDialog, columns, float, 4) + ATTRIB(XonoticHUDTimerDialog, name, string, "HUDtimer") + ATTRIB(XonoticHUDTimerDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDTimerDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDTimerDialog_fill(entity me) +{ + entity e; + string panelname = "timer"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Timer:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_timer_increment", _("Show elapsed time"))); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_vote.c b/qcsrc/menu/xonotic/dialog_hudpanel_vote.c deleted file mode 100644 index 4e4931e15..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_vote.c +++ /dev/null @@ -1,26 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDVoteDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDVoteDialog, fill, void(entity)) - ATTRIB(XonoticHUDVoteDialog, title, string, _("Vote Panel")) - ATTRIB(XonoticHUDVoteDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDVoteDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDVoteDialog, rows, float, 15) - ATTRIB(XonoticHUDVoteDialog, columns, float, 4) - ATTRIB(XonoticHUDVoteDialog, name, string, "HUDvote") - ATTRIB(XonoticHUDVoteDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDVoteDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDVoteDialog_fill(entity me) -{ - entity e; - string panelname = "vote"; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Alpha after voting:"))); - me.TD(me, 1, 2.6, e = makeXonoticSlider(0.1, 1, 0.1, "hud_panel_vote_alreadyvoted_alpha")); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc b/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc new file mode 100644 index 000000000..4e4931e15 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc @@ -0,0 +1,26 @@ +#ifdef INTERFACE +CLASS(XonoticHUDVoteDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDVoteDialog, fill, void(entity)) + ATTRIB(XonoticHUDVoteDialog, title, string, _("Vote Panel")) + ATTRIB(XonoticHUDVoteDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDVoteDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDVoteDialog, rows, float, 15) + ATTRIB(XonoticHUDVoteDialog, columns, float, 4) + ATTRIB(XonoticHUDVoteDialog, name, string, "HUDvote") + ATTRIB(XonoticHUDVoteDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDVoteDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDVoteDialog_fill(entity me) +{ + entity e; + string panelname = "vote"; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Alpha after voting:"))); + me.TD(me, 1, 2.6, e = makeXonoticSlider(0.1, 1, 0.1, "hud_panel_vote_alreadyvoted_alpha")); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.c b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.c deleted file mode 100644 index 64c9cf43a..000000000 --- a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.c +++ /dev/null @@ -1,74 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDWeaponsDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDWeaponsDialog, fill, void(entity)) - ATTRIB(XonoticHUDWeaponsDialog, title, string, _("Weapons Panel")) - ATTRIB(XonoticHUDWeaponsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDWeaponsDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDWeaponsDialog, rows, float, 19) - ATTRIB(XonoticHUDWeaponsDialog, columns, float, 4) - ATTRIB(XonoticHUDWeaponsDialog, name, string, "HUDweapons") - ATTRIB(XonoticHUDWeaponsDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDWeaponsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDWeaponsDialog_fill(entity me) -{ - entity e; - string panelname = "weapons"; - float i; - - DIALOG_HUDPANEL_COMMON(); - - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Fade out after:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider(strzone(strcat("hud_panel_", panelname, "_timeout")))); - e.addValue(e, _("Never"), "0"); - for(i = 1; i <= 10; ++i) - e.addValue(e, strzone(sprintf(_("%ds"), i)), strzone(ftos(i))); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Fade effect:"))); - setDependentStringNotEqual(e, strzone(strcat("hud_panel_", panelname, "_timeout")), "0"); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider(strzone(strcat("hud_panel_", panelname, "_timeout_effect")))); - e.addValue(e, ZCTX(_("EF^None")), "0"); - e.addValue(e, _("Alpha"), "1"); - e.addValue(e, _("Slide"), "2"); - e.addValue(e, ZCTX(_("EF^Both")), "3"); - e.configureXonoticTextSliderValues(e); - setDependentStringNotEqual(e, strzone(strcat("hud_panel_", panelname, "_timeout")), "0"); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Weapon icons:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_weapons_onlyowned", _("Show only owned weapons"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Show weapon ID as:"))); - me.TD(me, 1, 0.8, e = makeXonoticRadioButton(2, "hud_panel_weapons_label", "0", ZCTX(_("SHOWAS^None")))); - me.TD(me, 1, 0.8, e = makeXonoticRadioButton(2, "hud_panel_weapons_label", "1", _("Number"))); - me.TD(me, 1, 0.8, e = makeXonoticRadioButton(2, "hud_panel_weapons_label", "2", _("Bind"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Weapon ID scale:"))); - me.TD(me, 1, 2.4, e = makeXonoticSlider(0.1, 1, 0.05, "hud_panel_weapons_label_scale")); - setDependent(e, "hud_panel_weapons_label", 1, 2); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8/2, e = makeXonoticCheckBox(0, "hud_panel_weapons_accuracy", _("Show Accuracy"))); - me.TD(me, 1, 3.8/2, e = makeXonoticCheckBox(0, "hud_panel_weapons_ammo", _("Show Ammo"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Ammo bar alpha:"))); - me.TD(me, 1, 2.4, e = makeXonoticSlider(0.1, 1, 0.1, "hud_panel_weapons_ammo_alpha")); - setDependent(e, "hud_panel_weapons_ammo", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Ammo bar color:"))); - me.TD(me, 2, 2.4, e = makeXonoticColorpickerString("hud_panel_weapons_ammo_color", "hud_panel_weapons_ammo_color")); - setDependent(e, "hud_panel_weapons_ammo", 1, 1); - me.TR(me); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc new file mode 100644 index 000000000..64c9cf43a --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc @@ -0,0 +1,74 @@ +#ifdef INTERFACE +CLASS(XonoticHUDWeaponsDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDWeaponsDialog, fill, void(entity)) + ATTRIB(XonoticHUDWeaponsDialog, title, string, _("Weapons Panel")) + ATTRIB(XonoticHUDWeaponsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDWeaponsDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDWeaponsDialog, rows, float, 19) + ATTRIB(XonoticHUDWeaponsDialog, columns, float, 4) + ATTRIB(XonoticHUDWeaponsDialog, name, string, "HUDweapons") + ATTRIB(XonoticHUDWeaponsDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDWeaponsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDWeaponsDialog_fill(entity me) +{ + entity e; + string panelname = "weapons"; + float i; + + DIALOG_HUDPANEL_COMMON(); + + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Fade out after:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider(strzone(strcat("hud_panel_", panelname, "_timeout")))); + e.addValue(e, _("Never"), "0"); + for(i = 1; i <= 10; ++i) + e.addValue(e, strzone(sprintf(_("%ds"), i)), strzone(ftos(i))); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Fade effect:"))); + setDependentStringNotEqual(e, strzone(strcat("hud_panel_", panelname, "_timeout")), "0"); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider(strzone(strcat("hud_panel_", panelname, "_timeout_effect")))); + e.addValue(e, ZCTX(_("EF^None")), "0"); + e.addValue(e, _("Alpha"), "1"); + e.addValue(e, _("Slide"), "2"); + e.addValue(e, ZCTX(_("EF^Both")), "3"); + e.configureXonoticTextSliderValues(e); + setDependentStringNotEqual(e, strzone(strcat("hud_panel_", panelname, "_timeout")), "0"); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Weapon icons:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_weapons_onlyowned", _("Show only owned weapons"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Show weapon ID as:"))); + me.TD(me, 1, 0.8, e = makeXonoticRadioButton(2, "hud_panel_weapons_label", "0", ZCTX(_("SHOWAS^None")))); + me.TD(me, 1, 0.8, e = makeXonoticRadioButton(2, "hud_panel_weapons_label", "1", _("Number"))); + me.TD(me, 1, 0.8, e = makeXonoticRadioButton(2, "hud_panel_weapons_label", "2", _("Bind"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Weapon ID scale:"))); + me.TD(me, 1, 2.4, e = makeXonoticSlider(0.1, 1, 0.05, "hud_panel_weapons_label_scale")); + setDependent(e, "hud_panel_weapons_label", 1, 2); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8/2, e = makeXonoticCheckBox(0, "hud_panel_weapons_accuracy", _("Show Accuracy"))); + me.TD(me, 1, 3.8/2, e = makeXonoticCheckBox(0, "hud_panel_weapons_ammo", _("Show Ammo"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Ammo bar alpha:"))); + me.TD(me, 1, 2.4, e = makeXonoticSlider(0.1, 1, 0.1, "hud_panel_weapons_ammo_alpha")); + setDependent(e, "hud_panel_weapons_ammo", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Ammo bar color:"))); + me.TD(me, 2, 2.4, e = makeXonoticColorpickerString("hud_panel_weapons_ammo_color", "hud_panel_weapons_ammo_color")); + setDependent(e, "hud_panel_weapons_ammo", 1, 1); + me.TR(me); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_hudsetup_exit.c b/qcsrc/menu/xonotic/dialog_hudsetup_exit.c deleted file mode 100644 index 09e6c5339..000000000 --- a/qcsrc/menu/xonotic/dialog_hudsetup_exit.c +++ /dev/null @@ -1,120 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDExitDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticHUDExitDialog, fill, void(entity)) - ATTRIB(XonoticHUDExitDialog, title, string, _("Panel HUD Setup")) - ATTRIB(XonoticHUDExitDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticHUDExitDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDExitDialog, rows, float, 18) - ATTRIB(XonoticHUDExitDialog, columns, float, 4) - ATTRIB(XonoticHUDExitDialog, name, string, "HUDExit") - ATTRIB(XonoticHUDExitDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticHUDExitDialog) - -#endif - -#ifdef IMPLEMENTATION -void XonoticHUDExitDialog_fill(entity me) -{ - entity e; - float i; - - me.TR(me); - me.TD(me, 1, 4, makeXonoticTextLabel(0, _("Panel background defaults:"))); - me.TR(me); - me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Background:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg")); - e.addValue(e, _("Disable"), "0"); - e.addValue(e, "border_default", "border_default"); // this is a file name! - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Color:"))); - me.TD(me, 2, 2.6, e = makeXonoticColorpickerString("hud_panel_bg_color", "hud_panel_bg_color")); - me.TR(me); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Border size:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg_border")); - e.addValue(e, _("Disable"), "0"); - for(i = 1; i <= 10; ++i) - e.addValue(e, strzone(ftos_decimals(i * 2, 0)), strzone(ftos(i * 2))); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Alpha:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg_alpha")); - for(i = 1; i <= 10; ++i) - e.addValue(e, strzone(ftos_decimals(i/10, 1)), strzone(ftos(i/10))); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Team color:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg_color_team")); - e.addValue(e, _("Disable"), "0"); - for(i = 1; i <= 10; ++i) - e.addValue(e, strzone(ftos_decimals(i/10, 1)), strzone(ftos(i/10))); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TDempty(me, 0.4); - me.TD(me, 1, 3.6, e = makeXonoticCheckBox(0, "hud_configure_teamcolorforced", _("Test team color in configure mode"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Padding:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg_padding")); - for(i = 0; i <= 10; ++i) - e.addValue(e, strzone(ftos_decimals(i - 5, 0)), strzone(ftos(i - 5))); - e.configureXonoticTextSliderValues(e); - - me.TR(me); - me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("HUD Dock:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_dock")); - e.addValue(e, ZCTX(_("DOCK^Disabled")), "0"); - e.addValue(e, ZCTX(_("DOCK^Small")), "dock_small"); - e.addValue(e, ZCTX(_("DOCK^Medium")), "dock_medium"); - e.addValue(e, ZCTX(_("DOCK^Large")), "dock_large"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Color:"))); - me.TD(me, 2, 2.6, e = makeXonoticColorpickerString("hud_dock_color", "hud_dock_color")); - me.TR(me); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Alpha:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_dock_alpha")); - for(i = 1; i <= 10; ++i) - e.addValue(e, strzone(ftos_decimals(i/10, 1)), strzone(ftos(i/10))); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Team color:"))); - me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_dock_color_team")); - e.addValue(e, _("Disable"), "0"); - for(i = 1; i <= 10; ++i) - e.addValue(e, strzone(ftos_decimals(i/10, 1)), strzone(ftos(i/10))); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 4, makeXonoticTextLabel(0, _("Grid settings:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_configure_grid", _("Snap panels to grid"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Grid size:"))); - me.TD(me, 1, 0.2, e = makeXonoticTextLabel(0, _("X:"))); - me.TD(me, 1, 1.1, e = makeXonoticTextSlider("hud_configure_grid_xsize")); - for(i = 1; i <= 14; ++i) - e.addValue(e, strzone(ftos_decimals(i/200, 3)), strzone(ftos(i/200))); - e.configureXonoticTextSliderValues(e); - setDependent(e, "hud_configure_grid", 1, 1); - me.TD(me, 1, 0.2, e = makeXonoticTextLabel(0, _("Y:"))); - me.TD(me, 1, 1.1, e = makeXonoticTextSlider("hud_configure_grid_ysize")); - for(i = 1; i <= 14; ++i) - e.addValue(e, strzone(ftos_decimals(i/200, 3)), strzone(ftos(i/200))); - e.configureXonoticTextSliderValues(e); - setDependent(e, "hud_configure_grid", 1, 1); - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticCommandButton(_("Exit setup"), '0 0 0', "_hud_configure 0", 1)); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc b/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc new file mode 100644 index 000000000..09e6c5339 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc @@ -0,0 +1,120 @@ +#ifdef INTERFACE +CLASS(XonoticHUDExitDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticHUDExitDialog, fill, void(entity)) + ATTRIB(XonoticHUDExitDialog, title, string, _("Panel HUD Setup")) + ATTRIB(XonoticHUDExitDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticHUDExitDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticHUDExitDialog, rows, float, 18) + ATTRIB(XonoticHUDExitDialog, columns, float, 4) + ATTRIB(XonoticHUDExitDialog, name, string, "HUDExit") + ATTRIB(XonoticHUDExitDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticHUDExitDialog) + +#endif + +#ifdef IMPLEMENTATION +void XonoticHUDExitDialog_fill(entity me) +{ + entity e; + float i; + + me.TR(me); + me.TD(me, 1, 4, makeXonoticTextLabel(0, _("Panel background defaults:"))); + me.TR(me); + me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Background:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg")); + e.addValue(e, _("Disable"), "0"); + e.addValue(e, "border_default", "border_default"); // this is a file name! + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Color:"))); + me.TD(me, 2, 2.6, e = makeXonoticColorpickerString("hud_panel_bg_color", "hud_panel_bg_color")); + me.TR(me); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Border size:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg_border")); + e.addValue(e, _("Disable"), "0"); + for(i = 1; i <= 10; ++i) + e.addValue(e, strzone(ftos_decimals(i * 2, 0)), strzone(ftos(i * 2))); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Alpha:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg_alpha")); + for(i = 1; i <= 10; ++i) + e.addValue(e, strzone(ftos_decimals(i/10, 1)), strzone(ftos(i/10))); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Team color:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg_color_team")); + e.addValue(e, _("Disable"), "0"); + for(i = 1; i <= 10; ++i) + e.addValue(e, strzone(ftos_decimals(i/10, 1)), strzone(ftos(i/10))); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.4); + me.TD(me, 1, 3.6, e = makeXonoticCheckBox(0, "hud_configure_teamcolorforced", _("Test team color in configure mode"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Padding:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_bg_padding")); + for(i = 0; i <= 10; ++i) + e.addValue(e, strzone(ftos_decimals(i - 5, 0)), strzone(ftos(i - 5))); + e.configureXonoticTextSliderValues(e); + + me.TR(me); + me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("HUD Dock:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_dock")); + e.addValue(e, ZCTX(_("DOCK^Disabled")), "0"); + e.addValue(e, ZCTX(_("DOCK^Small")), "dock_small"); + e.addValue(e, ZCTX(_("DOCK^Medium")), "dock_medium"); + e.addValue(e, ZCTX(_("DOCK^Large")), "dock_large"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Color:"))); + me.TD(me, 2, 2.6, e = makeXonoticColorpickerString("hud_dock_color", "hud_dock_color")); + me.TR(me); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Alpha:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_dock_alpha")); + for(i = 1; i <= 10; ++i) + e.addValue(e, strzone(ftos_decimals(i/10, 1)), strzone(ftos(i/10))); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Team color:"))); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_dock_color_team")); + e.addValue(e, _("Disable"), "0"); + for(i = 1; i <= 10; ++i) + e.addValue(e, strzone(ftos_decimals(i/10, 1)), strzone(ftos(i/10))); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 4, makeXonoticTextLabel(0, _("Grid settings:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_configure_grid", _("Snap panels to grid"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Grid size:"))); + me.TD(me, 1, 0.2, e = makeXonoticTextLabel(0, _("X:"))); + me.TD(me, 1, 1.1, e = makeXonoticTextSlider("hud_configure_grid_xsize")); + for(i = 1; i <= 14; ++i) + e.addValue(e, strzone(ftos_decimals(i/200, 3)), strzone(ftos(i/200))); + e.configureXonoticTextSliderValues(e); + setDependent(e, "hud_configure_grid", 1, 1); + me.TD(me, 1, 0.2, e = makeXonoticTextLabel(0, _("Y:"))); + me.TD(me, 1, 1.1, e = makeXonoticTextSlider("hud_configure_grid_ysize")); + for(i = 1; i <= 14; ++i) + e.addValue(e, strzone(ftos_decimals(i/200, 3)), strzone(ftos(i/200))); + e.configureXonoticTextSliderValues(e); + setDependent(e, "hud_configure_grid", 1, 1); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticCommandButton(_("Exit setup"), '0 0 0', "_hud_configure 0", 1)); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_monstertools.c b/qcsrc/menu/xonotic/dialog_monstertools.c deleted file mode 100644 index 8b67094a7..000000000 --- a/qcsrc/menu/xonotic/dialog_monstertools.c +++ /dev/null @@ -1,50 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticMonsterToolsDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticMonsterToolsDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls - ATTRIB(XonoticMonsterToolsDialog, title, string, _("Monster Tools")) - ATTRIB(XonoticMonsterToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS) - ATTRIB(XonoticMonsterToolsDialog, intendedWidth, float, 0.8) - ATTRIB(XonoticMonsterToolsDialog, rows, float, 16) - ATTRIB(XonoticMonsterToolsDialog, columns, float, 4) - ATTRIB(XonoticMonsterToolsDialog, name, string, "MonsterTools") -ENDCLASS(XonoticMonsterToolsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticMonsterToolsDialog_fill(entity me) -{ - entity e; - - me.TR(me); - me.TD(me, 1, 0.25, e = makeXonoticTextLabel(0, _("Monster:"))); - me.TR(me); - me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "zombie", _("Zombie"))); - me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "spider", _("Spider"))); - me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "shambler", _("Shambler"))); - me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "mage", _("Mage"))); - me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "wyvern", _("Wyvern"))); - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Spawn"), '0 0 0', "cmd mobspawn $menu_monsters_edit_spawn $menu_monsters_edit_movetarget", 0)); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Remove"), '0 0 0', "cmd mobkill", 0)); - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Move target:"), '0 0 0', "editmob movetarget $menu_monsters_edit_movetarget", 0)); - me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_monsters_edit_movetarget", "1", _("Follow"))); - me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_monsters_edit_movetarget", "2", _("Wander"))); - me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_monsters_edit_movetarget", "3", _("Spawnpoint"))); - me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_monsters_edit_movetarget", "4", _("No moving"))); - me.TR(me); - me.TD(me, 1, 1.5, e = makeXonoticTextLabel(0, _("Colors:"))); - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set skin:"), '0 0 0', "editmob skin $menu_monsters_edit_skin", 0)); - me.TD(me, 1, 1.5, e = makeXonoticSlider(0, 99, 1, "menu_monsters_edit_skin")); - me.TR(me); - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -#endif - -/* Click. The c-word is here so you can grep for it :-) */ diff --git a/qcsrc/menu/xonotic/dialog_monstertools.qc b/qcsrc/menu/xonotic/dialog_monstertools.qc new file mode 100644 index 000000000..8b67094a7 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_monstertools.qc @@ -0,0 +1,50 @@ +#ifdef INTERFACE +CLASS(XonoticMonsterToolsDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticMonsterToolsDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls + ATTRIB(XonoticMonsterToolsDialog, title, string, _("Monster Tools")) + ATTRIB(XonoticMonsterToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS) + ATTRIB(XonoticMonsterToolsDialog, intendedWidth, float, 0.8) + ATTRIB(XonoticMonsterToolsDialog, rows, float, 16) + ATTRIB(XonoticMonsterToolsDialog, columns, float, 4) + ATTRIB(XonoticMonsterToolsDialog, name, string, "MonsterTools") +ENDCLASS(XonoticMonsterToolsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticMonsterToolsDialog_fill(entity me) +{ + entity e; + + me.TR(me); + me.TD(me, 1, 0.25, e = makeXonoticTextLabel(0, _("Monster:"))); + me.TR(me); + me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "zombie", _("Zombie"))); + me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "spider", _("Spider"))); + me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "shambler", _("Shambler"))); + me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "mage", _("Mage"))); + me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "wyvern", _("Wyvern"))); + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Spawn"), '0 0 0', "cmd mobspawn $menu_monsters_edit_spawn $menu_monsters_edit_movetarget", 0)); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Remove"), '0 0 0', "cmd mobkill", 0)); + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Move target:"), '0 0 0', "editmob movetarget $menu_monsters_edit_movetarget", 0)); + me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_monsters_edit_movetarget", "1", _("Follow"))); + me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_monsters_edit_movetarget", "2", _("Wander"))); + me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_monsters_edit_movetarget", "3", _("Spawnpoint"))); + me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_monsters_edit_movetarget", "4", _("No moving"))); + me.TR(me); + me.TD(me, 1, 1.5, e = makeXonoticTextLabel(0, _("Colors:"))); + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set skin:"), '0 0 0', "editmob skin $menu_monsters_edit_skin", 0)); + me.TD(me, 1, 1.5, e = makeXonoticSlider(0, 99, 1, "menu_monsters_edit_skin")); + me.TR(me); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +#endif + +/* Click. The c-word is here so you can grep for it :-) */ diff --git a/qcsrc/menu/xonotic/dialog_multiplayer.c b/qcsrc/menu/xonotic/dialog_multiplayer.c deleted file mode 100644 index 7d234c7fe..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer.c +++ /dev/null @@ -1,29 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticMultiplayerDialog) EXTENDS(XonoticDialog) - METHOD(XonoticMultiplayerDialog, fill, void(entity)) - ATTRIB(XonoticMultiplayerDialog, title, string, _("Multiplayer")) - ATTRIB(XonoticMultiplayerDialog, color, vector, SKINCOLOR_DIALOG_MULTIPLAYER) - ATTRIB(XonoticMultiplayerDialog, intendedWidth, float, 0.96) - ATTRIB(XonoticMultiplayerDialog, rows, float, 24) - ATTRIB(XonoticMultiplayerDialog, columns, float, 4) -ENDCLASS(XonoticMultiplayerDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticMultiplayerDialog_fill(entity me) -{ - entity mc, e; - mc = makeXonoticTabController(me.rows - 1); - me.TR(me); - me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Servers"), makeXonoticServerListTab())); - me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Create"), makeXonoticServerCreateTab())); - //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Demos"), makeXonoticDemoBrowserTab())); - //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Screenshots"), makeXonoticScreenshotBrowserTab())); - //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Players"), makeXonoticDemoBrowserTab())); - me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Media"), makeXonoticMediaTab())); - me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Profile"), makeXonoticProfileTab())); - - me.TR(me); - me.TD(me, me.rows - 1, me.columns, mc); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer.qc b/qcsrc/menu/xonotic/dialog_multiplayer.qc new file mode 100644 index 000000000..7d234c7fe --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer.qc @@ -0,0 +1,29 @@ +#ifdef INTERFACE +CLASS(XonoticMultiplayerDialog) EXTENDS(XonoticDialog) + METHOD(XonoticMultiplayerDialog, fill, void(entity)) + ATTRIB(XonoticMultiplayerDialog, title, string, _("Multiplayer")) + ATTRIB(XonoticMultiplayerDialog, color, vector, SKINCOLOR_DIALOG_MULTIPLAYER) + ATTRIB(XonoticMultiplayerDialog, intendedWidth, float, 0.96) + ATTRIB(XonoticMultiplayerDialog, rows, float, 24) + ATTRIB(XonoticMultiplayerDialog, columns, float, 4) +ENDCLASS(XonoticMultiplayerDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticMultiplayerDialog_fill(entity me) +{ + entity mc, e; + mc = makeXonoticTabController(me.rows - 1); + me.TR(me); + me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Servers"), makeXonoticServerListTab())); + me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Create"), makeXonoticServerCreateTab())); + //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Demos"), makeXonoticDemoBrowserTab())); + //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Screenshots"), makeXonoticScreenshotBrowserTab())); + //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Players"), makeXonoticDemoBrowserTab())); + me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Media"), makeXonoticMediaTab())); + me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Profile"), makeXonoticProfileTab())); + + me.TR(me); + me.TD(me, me.rows - 1, me.columns, mc); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create.c b/qcsrc/menu/xonotic/dialog_multiplayer_create.c deleted file mode 100644 index bbffb5276..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create.c +++ /dev/null @@ -1,217 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticServerCreateTab) EXTENDS(XonoticTab) - METHOD(XonoticServerCreateTab, fill, void(entity)) - METHOD(XonoticServerCreateTab, gameTypeChangeNotify, void(entity)) - METHOD(XonoticServerCreateTab, gameTypeSelectNotify, void(entity)) - ATTRIB(XonoticServerCreateTab, title, string, _("Create")) - ATTRIB(XonoticServerCreateTab, intendedWidth, float, 0.9) - ATTRIB(XonoticServerCreateTab, rows, float, 23) - ATTRIB(XonoticServerCreateTab, columns, float, 6.2) // added extra .2 for center space - - ATTRIB(XonoticServerCreateTab, mapListBox, entity, NULL) - ATTRIB(XonoticServerCreateTab, sliderFraglimit, entity, NULL) - ATTRIB(XonoticServerCreateTab, sliderTeams, entity, NULL) - ATTRIB(XonoticServerCreateTab, sliderTimelimit, entity, NULL) - ATTRIB(XonoticServerCreateTab, labelFraglimit, entity, NULL) - ATTRIB(XonoticServerCreateTab, labelTeams, entity, NULL) -ENDCLASS(XonoticServerCreateTab) -entity makeXonoticServerCreateTab(); -#endif - -#ifdef IMPLEMENTATION - -void GameType_ConfigureSliders(entity e, entity l, string pLabel, float pMin, float pMax, float pStep, string pCvar) -{ - if(pCvar == "") - { - e.configureXonoticTextSlider(e, string_null); - l.setText(l, pLabel); - e.disabled = l.disabled = TRUE; - } - else - { - e.configureXonoticTextSlider(e, pCvar); - - // clear old values - float i; - for(i = 0; i <= e.nValues; ++i); - { - if(e.(valueStrings[i])) { strunzone(e.(valueStrings[i])); } - if(e.(valueIdentifiers[i])) { strunzone(e.(valueIdentifiers[i])); } - } - e.clearValues(e); - - // set new values - e.addValue(e, strzone(_("Default")), strzone("-1")); - for(i = pMin; i <= pMax; i += pStep) { e.addValue(e, strzone(ftos(i)), strzone(ftos(i))); } - e.addValue(e, strzone(_("Unlimited")), strzone("0")); - e.configureXonoticTextSliderValues(e); - - // set text field - l.setText(l, pLabel); - e.disabled = l.disabled = FALSE; - } -} - -entity makeXonoticServerCreateTab() -{ - entity me; - me = spawnXonoticServerCreateTab(); - me.configureDialog(me); - return me; -} - -void XonoticServerCreateTab_fill(entity me) -{ - entity e, e0; - - me.gotoRC(me, 0.5, 0); - me.TD(me, 1, 3, makeXonoticHeaderLabel(_("Gametype"))); - me.TR(me); - me.TD(me, 10.5, 3, e = makeXonoticGametypeList()); - - me.gotoRC(me, 12.5, 0); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Time limit:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("timelimit_override")); - e.addValue(e, ZCTX(_("TIMLIM^Default")), "-1"); - e.addValue(e, ZCTX(_("TIMLIM^1 minute")), "1"); - e.addValue(e, ZCTX(_("TIMLIM^2 minutes")), "2"); - e.addValue(e, ZCTX(_("TIMLIM^3 minutes")), "3"); - e.addValue(e, ZCTX(_("TIMLIM^4 minutes")), "4"); - e.addValue(e, ZCTX(_("TIMLIM^5 minutes")), "5"); - e.addValue(e, ZCTX(_("TIMLIM^6 minutes")), "6"); - e.addValue(e, ZCTX(_("TIMLIM^7 minutes")), "7"); - e.addValue(e, ZCTX(_("TIMLIM^8 minutes")), "8"); - e.addValue(e, ZCTX(_("TIMLIM^9 minutes")), "9"); - e.addValue(e, ZCTX(_("TIMLIM^10 minutes")), "10"); - e.addValue(e, ZCTX(_("TIMLIM^15 minutes")), "15"); - e.addValue(e, ZCTX(_("TIMLIM^20 minutes")), "20"); - e.addValue(e, ZCTX(_("TIMLIM^25 minutes")), "25"); - e.addValue(e, ZCTX(_("TIMLIM^30 minutes")), "30"); - e.addValue(e, ZCTX(_("TIMLIM^40 minutes")), "40"); - e.addValue(e, ZCTX(_("TIMLIM^50 minutes")), "50"); - e.addValue(e, ZCTX(_("TIMLIM^60 minutes")), "60"); - e.addValue(e, ZCTX(_("TIMLIM^Infinite")), "0"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, me.labelFraglimit = makeXonoticTextLabel(0, _("Frag limit:"))); - me.TD(me, 1, 2, me.sliderFraglimit = makeXonoticTextSlider("fraglimit_override")); - GameType_ConfigureSliders(me.sliderFraglimit, me.labelFraglimit, _("Frag limit:"), 5, 100, 5, "fraglimit_override"); - - me.gotoRC(me, 15, 0); - me.TD(me, 1, 1, me.labelTeams = makeXonoticTextLabel(0, _("Teams:"))); - me.TD(me, 1, 2, e = me.sliderTeams = makeXonoticTextSlider(string_null)); - e.addValue(e, _("Default"), "0"); - e.addValue(e, _("2 teams"), "2"); - e.addValue(e, _("3 teams"), "3"); - e.addValue(e, _("4 teams"), "4"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Player slots:"))); - me.TD(me, 1, 2, makeXonoticSlider(1, 32, 1, "menu_maxplayers")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Number of bots:"))); - me.TD(me, 1, 2, makeXonoticSlider(0, 9, 1, "bot_number")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Bot skill:"))); - setDependent(e, "bot_number", 0, -1); - me.TD(me, 1, 2, e = makeXonoticTextSlider("skill")); - e.addValue(e, _("Botlike"), "0"); - e.addValue(e, _("Beginner"), "1"); - e.addValue(e, _("You will win"), "2"); - e.addValue(e, _("You can win"), "3"); - e.addValue(e, _("You might win"), "4"); - e.addValue(e, _("Advanced"), "5"); - e.addValue(e, _("Expert"), "6"); - e.addValue(e, _("Pro"), "7"); - e.addValue(e, _("Assassin"), "8"); - e.addValue(e, _("Unhuman"), "9"); - e.addValue(e, _("Godlike"), "10"); - e.configureXonoticTextSliderValues(e); - setDependent(e, "bot_number", 0, -1); - - me.gotoRC(me, me.rows - 3.5, 0); - me.TD(me, 1, 3, e0 = makeXonoticTextLabel(0.5, string_null)); - e0.textEntity = main.mutatorsDialog; - e0.allowCut = 1; - //e0.allowWrap = 1; - me.TR(me); - me.TDempty(me, 0.5); - me.TD(me, 1, 2, e = makeXonoticButton(_("Mutators"), '0 0 0')); - e.onClick = DialogOpenButton_Click; - e.onClickEntity = main.mutatorsDialog; - main.mutatorsDialog.refilterEntity = me.mapListBox; - - me.gotoRC(me, 0.5, 3.2); me.setFirstColumn(me, me.currentColumn); - me.mapListBox = makeXonoticMapList(); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Maplist"))); - makeCallback(e, me.mapListBox, me.mapListBox.refilterCallback); - me.TR(me); - me.TD(me, me.rows - 4, 3, me.mapListBox); - me.gotoRC(me, me.rows - 2.5, 3.2); - me.TDempty(me, 0.375); - me.TD(me, 1, 1.125, e = makeXonoticButton(_("Select all"), '0 0 0')); - e.onClick = MapList_All; - e.onClickEntity = me.mapListBox; - me.TD(me, 1, 1.125, e = makeXonoticButton(_("Select none"), '0 0 0')); - e.onClick = MapList_None; - e.onClickEntity = me.mapListBox; - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("Start Multiplayer!"), '0 0 0')); - e.onClick = MapList_LoadMap; - e.onClickEntity = me.mapListBox; - me.mapListBox.startButton = e; - - me.gameTypeChangeNotify(me); -} - -void XonoticServerCreateTab_gameTypeChangeNotify(entity me) -{ - // tell the map list to update - float gt; - entity e, l; - gt = MapInfo_CurrentGametype(); - e = me.sliderFraglimit; - l = me.labelFraglimit; - - switch(gt) - { - case MAPINFO_TYPE_CTF: GameType_ConfigureSliders(e, l, _("Capture limit:"), 1, 20, 1, "capturelimit_override"); break; - case MAPINFO_TYPE_DOMINATION: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, "g_domination_point_limit"); break; - case MAPINFO_TYPE_KEYHUNT: GameType_ConfigureSliders(e, l, _("Point limit:"), 200, 1500, 50, "g_keyhunt_point_limit"); break; - case MAPINFO_TYPE_LMS: GameType_ConfigureSliders(e, l, _("Lives:"), 3, 50, 1, "g_lms_lives_override"); break; - case MAPINFO_TYPE_RACE: GameType_ConfigureSliders(e, l, _("Laps:"), 1, 25, 1, "g_race_laps_limit"); break; - case MAPINFO_TYPE_NEXBALL: GameType_ConfigureSliders(e, l, _("Goals:"), 1, 50, 1, "g_nexball_goallimit"); break; - case MAPINFO_TYPE_ASSAULT: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, ""); break; - case MAPINFO_TYPE_ONSLAUGHT: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, ""); break; - case MAPINFO_TYPE_CTS: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, ""); break; - case MAPINFO_TYPE_INVASION: GameType_ConfigureSliders(e, l, _("Point limit:"), 5, 0, 5, ""); break; - default: GameType_ConfigureSliders(e, l, _("Frag limit:"), 5, 100, 5, "fraglimit_override"); break; - } - - string x = string_null; - e = me.sliderTeams; - switch(gt) - { - case MAPINFO_TYPE_CA: x = "g_ca_teams_override"; break; - case MAPINFO_TYPE_DOMINATION: x = "g_domination_teams_override"; break; - case MAPINFO_TYPE_FREEZETAG: x = "g_freezetag_teams_override"; break; - case MAPINFO_TYPE_KEYHUNT: x = "g_keyhunt_teams_override"; break; - case MAPINFO_TYPE_TEAM_DEATHMATCH: x = "g_tdm_teams_override"; break; - } - e.configureXonoticTextSlider(e, x); - e.configureXonoticTextSliderValues(e); - if(!x) - e.value = 0; - me.sliderTeams.disabled = me.labelTeams.disabled = !x; - - me.mapListBox.refilter(me.mapListBox); -} - -void XonoticServerCreateTab_gameTypeSelectNotify(entity me) -{ - me.setFocus(me, me.mapListBox); -} - -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create.qc new file mode 100644 index 000000000..bbffb5276 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create.qc @@ -0,0 +1,217 @@ +#ifdef INTERFACE +CLASS(XonoticServerCreateTab) EXTENDS(XonoticTab) + METHOD(XonoticServerCreateTab, fill, void(entity)) + METHOD(XonoticServerCreateTab, gameTypeChangeNotify, void(entity)) + METHOD(XonoticServerCreateTab, gameTypeSelectNotify, void(entity)) + ATTRIB(XonoticServerCreateTab, title, string, _("Create")) + ATTRIB(XonoticServerCreateTab, intendedWidth, float, 0.9) + ATTRIB(XonoticServerCreateTab, rows, float, 23) + ATTRIB(XonoticServerCreateTab, columns, float, 6.2) // added extra .2 for center space + + ATTRIB(XonoticServerCreateTab, mapListBox, entity, NULL) + ATTRIB(XonoticServerCreateTab, sliderFraglimit, entity, NULL) + ATTRIB(XonoticServerCreateTab, sliderTeams, entity, NULL) + ATTRIB(XonoticServerCreateTab, sliderTimelimit, entity, NULL) + ATTRIB(XonoticServerCreateTab, labelFraglimit, entity, NULL) + ATTRIB(XonoticServerCreateTab, labelTeams, entity, NULL) +ENDCLASS(XonoticServerCreateTab) +entity makeXonoticServerCreateTab(); +#endif + +#ifdef IMPLEMENTATION + +void GameType_ConfigureSliders(entity e, entity l, string pLabel, float pMin, float pMax, float pStep, string pCvar) +{ + if(pCvar == "") + { + e.configureXonoticTextSlider(e, string_null); + l.setText(l, pLabel); + e.disabled = l.disabled = TRUE; + } + else + { + e.configureXonoticTextSlider(e, pCvar); + + // clear old values + float i; + for(i = 0; i <= e.nValues; ++i); + { + if(e.(valueStrings[i])) { strunzone(e.(valueStrings[i])); } + if(e.(valueIdentifiers[i])) { strunzone(e.(valueIdentifiers[i])); } + } + e.clearValues(e); + + // set new values + e.addValue(e, strzone(_("Default")), strzone("-1")); + for(i = pMin; i <= pMax; i += pStep) { e.addValue(e, strzone(ftos(i)), strzone(ftos(i))); } + e.addValue(e, strzone(_("Unlimited")), strzone("0")); + e.configureXonoticTextSliderValues(e); + + // set text field + l.setText(l, pLabel); + e.disabled = l.disabled = FALSE; + } +} + +entity makeXonoticServerCreateTab() +{ + entity me; + me = spawnXonoticServerCreateTab(); + me.configureDialog(me); + return me; +} + +void XonoticServerCreateTab_fill(entity me) +{ + entity e, e0; + + me.gotoRC(me, 0.5, 0); + me.TD(me, 1, 3, makeXonoticHeaderLabel(_("Gametype"))); + me.TR(me); + me.TD(me, 10.5, 3, e = makeXonoticGametypeList()); + + me.gotoRC(me, 12.5, 0); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Time limit:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("timelimit_override")); + e.addValue(e, ZCTX(_("TIMLIM^Default")), "-1"); + e.addValue(e, ZCTX(_("TIMLIM^1 minute")), "1"); + e.addValue(e, ZCTX(_("TIMLIM^2 minutes")), "2"); + e.addValue(e, ZCTX(_("TIMLIM^3 minutes")), "3"); + e.addValue(e, ZCTX(_("TIMLIM^4 minutes")), "4"); + e.addValue(e, ZCTX(_("TIMLIM^5 minutes")), "5"); + e.addValue(e, ZCTX(_("TIMLIM^6 minutes")), "6"); + e.addValue(e, ZCTX(_("TIMLIM^7 minutes")), "7"); + e.addValue(e, ZCTX(_("TIMLIM^8 minutes")), "8"); + e.addValue(e, ZCTX(_("TIMLIM^9 minutes")), "9"); + e.addValue(e, ZCTX(_("TIMLIM^10 minutes")), "10"); + e.addValue(e, ZCTX(_("TIMLIM^15 minutes")), "15"); + e.addValue(e, ZCTX(_("TIMLIM^20 minutes")), "20"); + e.addValue(e, ZCTX(_("TIMLIM^25 minutes")), "25"); + e.addValue(e, ZCTX(_("TIMLIM^30 minutes")), "30"); + e.addValue(e, ZCTX(_("TIMLIM^40 minutes")), "40"); + e.addValue(e, ZCTX(_("TIMLIM^50 minutes")), "50"); + e.addValue(e, ZCTX(_("TIMLIM^60 minutes")), "60"); + e.addValue(e, ZCTX(_("TIMLIM^Infinite")), "0"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, me.labelFraglimit = makeXonoticTextLabel(0, _("Frag limit:"))); + me.TD(me, 1, 2, me.sliderFraglimit = makeXonoticTextSlider("fraglimit_override")); + GameType_ConfigureSliders(me.sliderFraglimit, me.labelFraglimit, _("Frag limit:"), 5, 100, 5, "fraglimit_override"); + + me.gotoRC(me, 15, 0); + me.TD(me, 1, 1, me.labelTeams = makeXonoticTextLabel(0, _("Teams:"))); + me.TD(me, 1, 2, e = me.sliderTeams = makeXonoticTextSlider(string_null)); + e.addValue(e, _("Default"), "0"); + e.addValue(e, _("2 teams"), "2"); + e.addValue(e, _("3 teams"), "3"); + e.addValue(e, _("4 teams"), "4"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Player slots:"))); + me.TD(me, 1, 2, makeXonoticSlider(1, 32, 1, "menu_maxplayers")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Number of bots:"))); + me.TD(me, 1, 2, makeXonoticSlider(0, 9, 1, "bot_number")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Bot skill:"))); + setDependent(e, "bot_number", 0, -1); + me.TD(me, 1, 2, e = makeXonoticTextSlider("skill")); + e.addValue(e, _("Botlike"), "0"); + e.addValue(e, _("Beginner"), "1"); + e.addValue(e, _("You will win"), "2"); + e.addValue(e, _("You can win"), "3"); + e.addValue(e, _("You might win"), "4"); + e.addValue(e, _("Advanced"), "5"); + e.addValue(e, _("Expert"), "6"); + e.addValue(e, _("Pro"), "7"); + e.addValue(e, _("Assassin"), "8"); + e.addValue(e, _("Unhuman"), "9"); + e.addValue(e, _("Godlike"), "10"); + e.configureXonoticTextSliderValues(e); + setDependent(e, "bot_number", 0, -1); + + me.gotoRC(me, me.rows - 3.5, 0); + me.TD(me, 1, 3, e0 = makeXonoticTextLabel(0.5, string_null)); + e0.textEntity = main.mutatorsDialog; + e0.allowCut = 1; + //e0.allowWrap = 1; + me.TR(me); + me.TDempty(me, 0.5); + me.TD(me, 1, 2, e = makeXonoticButton(_("Mutators"), '0 0 0')); + e.onClick = DialogOpenButton_Click; + e.onClickEntity = main.mutatorsDialog; + main.mutatorsDialog.refilterEntity = me.mapListBox; + + me.gotoRC(me, 0.5, 3.2); me.setFirstColumn(me, me.currentColumn); + me.mapListBox = makeXonoticMapList(); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Maplist"))); + makeCallback(e, me.mapListBox, me.mapListBox.refilterCallback); + me.TR(me); + me.TD(me, me.rows - 4, 3, me.mapListBox); + me.gotoRC(me, me.rows - 2.5, 3.2); + me.TDempty(me, 0.375); + me.TD(me, 1, 1.125, e = makeXonoticButton(_("Select all"), '0 0 0')); + e.onClick = MapList_All; + e.onClickEntity = me.mapListBox; + me.TD(me, 1, 1.125, e = makeXonoticButton(_("Select none"), '0 0 0')); + e.onClick = MapList_None; + e.onClickEntity = me.mapListBox; + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("Start Multiplayer!"), '0 0 0')); + e.onClick = MapList_LoadMap; + e.onClickEntity = me.mapListBox; + me.mapListBox.startButton = e; + + me.gameTypeChangeNotify(me); +} + +void XonoticServerCreateTab_gameTypeChangeNotify(entity me) +{ + // tell the map list to update + float gt; + entity e, l; + gt = MapInfo_CurrentGametype(); + e = me.sliderFraglimit; + l = me.labelFraglimit; + + switch(gt) + { + case MAPINFO_TYPE_CTF: GameType_ConfigureSliders(e, l, _("Capture limit:"), 1, 20, 1, "capturelimit_override"); break; + case MAPINFO_TYPE_DOMINATION: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, "g_domination_point_limit"); break; + case MAPINFO_TYPE_KEYHUNT: GameType_ConfigureSliders(e, l, _("Point limit:"), 200, 1500, 50, "g_keyhunt_point_limit"); break; + case MAPINFO_TYPE_LMS: GameType_ConfigureSliders(e, l, _("Lives:"), 3, 50, 1, "g_lms_lives_override"); break; + case MAPINFO_TYPE_RACE: GameType_ConfigureSliders(e, l, _("Laps:"), 1, 25, 1, "g_race_laps_limit"); break; + case MAPINFO_TYPE_NEXBALL: GameType_ConfigureSliders(e, l, _("Goals:"), 1, 50, 1, "g_nexball_goallimit"); break; + case MAPINFO_TYPE_ASSAULT: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, ""); break; + case MAPINFO_TYPE_ONSLAUGHT: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, ""); break; + case MAPINFO_TYPE_CTS: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, ""); break; + case MAPINFO_TYPE_INVASION: GameType_ConfigureSliders(e, l, _("Point limit:"), 5, 0, 5, ""); break; + default: GameType_ConfigureSliders(e, l, _("Frag limit:"), 5, 100, 5, "fraglimit_override"); break; + } + + string x = string_null; + e = me.sliderTeams; + switch(gt) + { + case MAPINFO_TYPE_CA: x = "g_ca_teams_override"; break; + case MAPINFO_TYPE_DOMINATION: x = "g_domination_teams_override"; break; + case MAPINFO_TYPE_FREEZETAG: x = "g_freezetag_teams_override"; break; + case MAPINFO_TYPE_KEYHUNT: x = "g_keyhunt_teams_override"; break; + case MAPINFO_TYPE_TEAM_DEATHMATCH: x = "g_tdm_teams_override"; break; + } + e.configureXonoticTextSlider(e, x); + e.configureXonoticTextSliderValues(e); + if(!x) + e.value = 0; + me.sliderTeams.disabled = me.labelTeams.disabled = !x; + + me.mapListBox.refilter(me.mapListBox); +} + +void XonoticServerCreateTab_gameTypeSelectNotify(entity me) +{ + me.setFocus(me, me.mapListBox); +} + +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c deleted file mode 100644 index 9baf36127..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c +++ /dev/null @@ -1,119 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticMapInfoDialog) EXTENDS(XonoticDialog) - METHOD(XonoticMapInfoDialog, fill, void(entity)) - METHOD(XonoticMapInfoDialog, loadMapInfo, void(entity, float, entity)) - ATTRIB(XonoticMapInfoDialog, title, string, _("Map Information")) - ATTRIB(XonoticMapInfoDialog, color, vector, SKINCOLOR_DIALOG_MAPINFO) - ATTRIB(XonoticMapInfoDialog, intendedWidth, float, 1.0) - ATTRIB(XonoticMapInfoDialog, rows, float, 11) - ATTRIB(XonoticMapInfoDialog, columns, float, 10) - - ATTRIB(XonoticMapInfoDialog, previewImage, entity, NULL) - ATTRIB(XonoticMapInfoDialog, titleLabel, entity, NULL) - ATTRIB(XonoticMapInfoDialog, authorLabel, entity, NULL) - ATTRIB(XonoticMapInfoDialog, descriptionLabel, entity, NULL) - ATTRIB(XonoticMapInfoDialog, featuresLabel, entity, NULL) - - ATTRIBARRAY(XonoticMapInfoDialog, typeLabels, entity, 24) - - ATTRIB(XonoticMapInfoDialog, currentMapIndex, float, 0) - ATTRIB(XonoticMapInfoDialog, currentMapBSPName, string, string_null) - ATTRIB(XonoticMapInfoDialog, currentMapTitle, string, string_null) - ATTRIB(XonoticMapInfoDialog, currentMapAuthor, string, string_null) - ATTRIB(XonoticMapInfoDialog, currentMapDescription, string, string_null) - ATTRIB(XonoticMapInfoDialog, currentMapPreviewImage, string, string_null) -ENDCLASS(XonoticMapInfoDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticMapInfoDialog_loadMapInfo(entity me, float i, entity mlb) -{ - me.currentMapIndex = i; - me.startButton.onClickEntity = mlb; - MapInfo_Get_ByID(i); - - if(me.currentMapBSPName) - { - strunzone(me.currentMapBSPName); - strunzone(me.currentMapTitle); - strunzone(me.currentMapAuthor); - strunzone(me.currentMapDescription); - strunzone(me.currentMapPreviewImage); - } - me.currentMapBSPName = strzone(MapInfo_Map_bspname); - me.currentMapTitle = strzone(strdecolorize(MapInfo_Map_title)); - me.currentMapAuthor = strzone(strdecolorize(MapInfo_Map_author)); - me.currentMapDescription = strzone(MapInfo_Map_description); - me.currentMapPreviewImage = strzone(strcat("/maps/", MapInfo_Map_bspname)); - - me.frame.setText(me.frame, me.currentMapBSPName); - me.titleLabel.setText(me.titleLabel, me.currentMapTitle); - me.authorLabel.setText(me.authorLabel, me.currentMapAuthor); - me.descriptionLabel.setText(me.descriptionLabel, me.currentMapDescription); - if(draw_PictureSize(me.currentMapPreviewImage) == '0 0 0') - me.previewImage.src = "nopreview_map"; - else - me.previewImage.src = me.currentMapPreviewImage; - - for(i = 0; i < GameType_GetCount(); ++i) - { - entity e; - e = me.(typeLabels[i]); - e.disabled = !(MapInfo_Map_supportedGametypes & GameType_GetID(i)); - } - - MapInfo_ClearTemps(); -} -void XonoticMapInfoDialog_fill(entity me) -{ - entity e; - float w, wgt, i, n; - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, me.rows - 2, 3, e = makeXonoticImage(string_null, 4.0/3.0)); - me.previewImage = e; - me.gotoRC(me, 0, 3.5); me.setFirstColumn(me, me.currentColumn); - w = me.columns - me.currentColumn; - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Title:"))); - me.TD(me, 1, w-1, e = makeXonoticTextLabel(0, "")); - e.colorL = SKINCOLOR_MAPLIST_TITLE; - e.allowCut = 1; - me.titleLabel = e; - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Author:"))); - me.TD(me, 1, w-1, e = makeXonoticTextLabel(0, "")); - e.colorL = SKINCOLOR_MAPLIST_AUTHOR; - e.allowCut = 1; - me.authorLabel = e; - me.TR(me); - me.TD(me, 1, w, e = makeXonoticTextLabel(0, _("Game types:"))); - - n = ceil(GameType_GetCount() / (me.rows - 6)); - wgt = (w - 0.2) / n; - for(i = 0; i < GameType_GetCount(); ++i) - { - if(mod(i, n) == 0) - { - me.TR(me); - me.TDempty(me, 0.2); - } - me.TD(me, 1, wgt, e = makeXonoticTextLabel(0, MapInfo_Type_ToText(GameType_GetID(i)))); - me.(typeLabels[i]) = e; - } - - me.gotoRC(me, me.rows - 2, 0); - me.TD(me, 1, me.columns, e = makeXonoticTextLabel(0.5, "")); - e.allowCut = 1; - me.descriptionLabel = e; - - me.gotoRC(me, me.rows - 1, 0); - me.TDempty(me, 0.5); - - me.TD(me, 1, me.columns - 5.5, e = makeXonoticButton(_("Close"), '0 0 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; - me.TD(me, 1, me.columns - 5.5, me.startButton = e = makeXonoticButton(ZCTX(_("MAP^Play")), '0 0 0')); - me.startButton.onClick = MapList_LoadMap; - me.startButton.onClickEntity = NULL; // filled later -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc new file mode 100644 index 000000000..9baf36127 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc @@ -0,0 +1,119 @@ +#ifdef INTERFACE +CLASS(XonoticMapInfoDialog) EXTENDS(XonoticDialog) + METHOD(XonoticMapInfoDialog, fill, void(entity)) + METHOD(XonoticMapInfoDialog, loadMapInfo, void(entity, float, entity)) + ATTRIB(XonoticMapInfoDialog, title, string, _("Map Information")) + ATTRIB(XonoticMapInfoDialog, color, vector, SKINCOLOR_DIALOG_MAPINFO) + ATTRIB(XonoticMapInfoDialog, intendedWidth, float, 1.0) + ATTRIB(XonoticMapInfoDialog, rows, float, 11) + ATTRIB(XonoticMapInfoDialog, columns, float, 10) + + ATTRIB(XonoticMapInfoDialog, previewImage, entity, NULL) + ATTRIB(XonoticMapInfoDialog, titleLabel, entity, NULL) + ATTRIB(XonoticMapInfoDialog, authorLabel, entity, NULL) + ATTRIB(XonoticMapInfoDialog, descriptionLabel, entity, NULL) + ATTRIB(XonoticMapInfoDialog, featuresLabel, entity, NULL) + + ATTRIBARRAY(XonoticMapInfoDialog, typeLabels, entity, 24) + + ATTRIB(XonoticMapInfoDialog, currentMapIndex, float, 0) + ATTRIB(XonoticMapInfoDialog, currentMapBSPName, string, string_null) + ATTRIB(XonoticMapInfoDialog, currentMapTitle, string, string_null) + ATTRIB(XonoticMapInfoDialog, currentMapAuthor, string, string_null) + ATTRIB(XonoticMapInfoDialog, currentMapDescription, string, string_null) + ATTRIB(XonoticMapInfoDialog, currentMapPreviewImage, string, string_null) +ENDCLASS(XonoticMapInfoDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticMapInfoDialog_loadMapInfo(entity me, float i, entity mlb) +{ + me.currentMapIndex = i; + me.startButton.onClickEntity = mlb; + MapInfo_Get_ByID(i); + + if(me.currentMapBSPName) + { + strunzone(me.currentMapBSPName); + strunzone(me.currentMapTitle); + strunzone(me.currentMapAuthor); + strunzone(me.currentMapDescription); + strunzone(me.currentMapPreviewImage); + } + me.currentMapBSPName = strzone(MapInfo_Map_bspname); + me.currentMapTitle = strzone(strdecolorize(MapInfo_Map_title)); + me.currentMapAuthor = strzone(strdecolorize(MapInfo_Map_author)); + me.currentMapDescription = strzone(MapInfo_Map_description); + me.currentMapPreviewImage = strzone(strcat("/maps/", MapInfo_Map_bspname)); + + me.frame.setText(me.frame, me.currentMapBSPName); + me.titleLabel.setText(me.titleLabel, me.currentMapTitle); + me.authorLabel.setText(me.authorLabel, me.currentMapAuthor); + me.descriptionLabel.setText(me.descriptionLabel, me.currentMapDescription); + if(draw_PictureSize(me.currentMapPreviewImage) == '0 0 0') + me.previewImage.src = "nopreview_map"; + else + me.previewImage.src = me.currentMapPreviewImage; + + for(i = 0; i < GameType_GetCount(); ++i) + { + entity e; + e = me.(typeLabels[i]); + e.disabled = !(MapInfo_Map_supportedGametypes & GameType_GetID(i)); + } + + MapInfo_ClearTemps(); +} +void XonoticMapInfoDialog_fill(entity me) +{ + entity e; + float w, wgt, i, n; + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, me.rows - 2, 3, e = makeXonoticImage(string_null, 4.0/3.0)); + me.previewImage = e; + me.gotoRC(me, 0, 3.5); me.setFirstColumn(me, me.currentColumn); + w = me.columns - me.currentColumn; + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Title:"))); + me.TD(me, 1, w-1, e = makeXonoticTextLabel(0, "")); + e.colorL = SKINCOLOR_MAPLIST_TITLE; + e.allowCut = 1; + me.titleLabel = e; + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Author:"))); + me.TD(me, 1, w-1, e = makeXonoticTextLabel(0, "")); + e.colorL = SKINCOLOR_MAPLIST_AUTHOR; + e.allowCut = 1; + me.authorLabel = e; + me.TR(me); + me.TD(me, 1, w, e = makeXonoticTextLabel(0, _("Game types:"))); + + n = ceil(GameType_GetCount() / (me.rows - 6)); + wgt = (w - 0.2) / n; + for(i = 0; i < GameType_GetCount(); ++i) + { + if(mod(i, n) == 0) + { + me.TR(me); + me.TDempty(me, 0.2); + } + me.TD(me, 1, wgt, e = makeXonoticTextLabel(0, MapInfo_Type_ToText(GameType_GetID(i)))); + me.(typeLabels[i]) = e; + } + + me.gotoRC(me, me.rows - 2, 0); + me.TD(me, 1, me.columns, e = makeXonoticTextLabel(0.5, "")); + e.allowCut = 1; + me.descriptionLabel = e; + + me.gotoRC(me, me.rows - 1, 0); + me.TDempty(me, 0.5); + + me.TD(me, 1, me.columns - 5.5, e = makeXonoticButton(_("Close"), '0 0 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; + me.TD(me, 1, me.columns - 5.5, me.startButton = e = makeXonoticButton(ZCTX(_("MAP^Play")), '0 0 0')); + me.startButton.onClick = MapList_LoadMap; + me.startButton.onClickEntity = NULL; // filled later +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c deleted file mode 100644 index a4e052f45..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c +++ /dev/null @@ -1,289 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticMutatorsDialog) EXTENDS(XonoticDialog) - METHOD(XonoticMutatorsDialog, toString, string(entity)) - METHOD(XonoticMutatorsDialog, fill, void(entity)) - METHOD(XonoticMutatorsDialog, showNotify, void(entity)) - METHOD(XonoticMutatorsDialog, close, void(entity)) - ATTRIB(XonoticMutatorsDialog, title, string, _("Mutators")) - ATTRIB(XonoticMutatorsDialog, color, vector, SKINCOLOR_DIALOG_MUTATORS) - ATTRIB(XonoticMutatorsDialog, intendedWidth, float, 0.9) - ATTRIB(XonoticMutatorsDialog, rows, float, 20) - ATTRIB(XonoticMutatorsDialog, columns, float, 6) - ATTRIB(XonoticMutatorsDialog, refilterEntity, entity, NULL) -ENDCLASS(XonoticMutatorsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticMutatorsDialog_showNotify(entity me) -{ - loadAllCvars(me); -} - -string weaponarenastring; -string weaponarenastring_cvar; -string WeaponArenaString() -{ - string s; - float n, i, j; - entity e; - s = cvar_string("g_weaponarena"); - if(s == "0") - return ""; - if(s == "all" || s == "1") - return _("All Weapons Arena"); - if(s == "most") - return _("Most Weapons Arena"); - if(s == weaponarenastring_cvar) - return weaponarenastring; - if(weaponarenastring) - strunzone(weaponarenastring); - if(weaponarenastring_cvar) - strunzone(weaponarenastring_cvar); - - weaponarenastring_cvar = strzone(s); - - n = tokenize_console(s); - s = ""; - for(i = 0; i < n; ++i) - { - for(j = WEP_FIRST; j <= WEP_LAST; ++j) - { - e = get_weaponinfo(j); - if(argv(i) == e.netname) - s = strcat(s, " & ", e.message); - } - } - s = sprintf(_("%s Arena"), substring(s, 3, strlen(s) - 3)); - - weaponarenastring = strzone(s); - - return weaponarenastring; -} - -string XonoticMutatorsDialog_toString(entity me) -{ - string s; - s = ""; - if(cvar("g_dodging")) - s = strcat(s, ", ", _("Dodging")); - if(cvar("g_instagib")) - s = strcat(s, ", ", _("InstaGib")); - if(cvar("g_new_toys")) - s = strcat(s, ", ", _("New Toys")); - if(cvar("g_nix")) - s = strcat(s, ", ", _("NIX")); - if(cvar("g_rocket_flying")) - s = strcat(s, ", ", _("Rocket Flying")); - if(cvar("g_invincible_projectiles")) - s = strcat(s, ", ", _("Invincible Projectiles")); - if(cvar_string("g_weaponarena") != "0") - s = strcat(s, ", ", WeaponArenaString()); - if(cvar("g_balance_blaster_weaponstart") == 0) - s = strcat(s, ", ", _("No start weapons")); - if(cvar("sv_gravity") < stof(cvar_defstring("sv_gravity"))) - s = strcat(s, ", ", _("Low gravity")); - if(cvar("g_cloaked")) - s = strcat(s, ", ", _("Cloaked")); - if(cvar("g_grappling_hook")) - s = strcat(s, ", ", _("Hook")); - if(cvar("g_midair")) - s = strcat(s, ", ", _("Midair")); - if(cvar("g_vampire")) - s = strcat(s, ", ", _("Vampire")); - if(cvar("g_pinata")) - s = strcat(s, ", ", _("Piñata")); - if(cvar("g_weapon_stay")) - s = strcat(s, ", ", _("Weapons stay")); - if(cvar("g_bloodloss") > 0) - s = strcat(s, ", ", _("Blood loss")); - if(cvar("g_jetpack")) - s = strcat(s, ", ", _("Jet pack")); - if(cvar("g_buffs")) - s = strcat(s, ", ", _("Buffs")); - if(cvar("g_overkill")) - s = strcat(s, ", ", _("Overkill")); - if(cvar("g_powerups") == 0) - s = strcat(s, ", ", _("No powerups")); - if(cvar("g_powerups") > 0) - s = strcat(s, ", ", _("Powerups")); - if(cvar("g_touchexplode") > 0) - s = strcat(s, ", ", _("Touch explode")); - if(s == "") - return ZCTX(_("MUT^None")); - else - return substring(s, 2, strlen(s) - 2); -} - -float checkCompatibility_pinata(entity me) -{ - if(cvar("g_instagib")) - return 0; - if(cvar("g_nix")) - return 0; - if(cvar_string("g_weaponarena") != "0") - return 0; - return 1; -} -float checkCompatibility_weaponstay(entity me) -{ - return checkCompatibility_pinata(me); -} -float checkCompatibility_newtoys(entity me) -{ - if(cvar("g_instagib")) - return 0; - if(cvar_string("g_weaponarena") == "most") - return 1; - if(cvar_string("g_weaponarena") == "all" || cvar_string("g_weaponarena") == "1") - return 1; - if(cvar_string("g_weaponarena") != "0") - return 0; - return 1; -} -float checkCompatibility_weaponarena_weapon(entity me) -{ - if(cvar("g_instagib")) - return 0; - if(cvar_string("g_weaponarena") == "most") - return 0; - if(cvar_string("g_weaponarena") == "all" || cvar_string("g_weaponarena") == "1") - return 0; - if(cvar_string("g_weaponarena") == "0") - return 0; - if(cvar_string("g_balance_blaster_weaponstart") == "0") - return 0; - return 1; -} - -void XonoticMutatorsDialog_fill(entity me) -{ - entity e, s, w; - float i, j; - me.TR(me); - me.TD(me, 1, 2, makeXonoticTextLabel(0, _("Gameplay mutators:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_dodging", _("Dodging"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_touchexplode", _("Touch explode"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_cloaked", _("Cloaked"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_buffs", _("Buffs"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_midair", _("Midair"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_vampire", _("Vampire"))); - setDependent(e, "g_instagib", 0, 0); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticSlider(10, 50, 1, "g_bloodloss"); - me.TD(me, 1, 1.8, e = makeXonoticSliderCheckBox(0, 1, s, _("Blood loss"))); - setDependent(e, "g_instagib", 0, 0); - me.TR(me); - me.TDempty(me, 0.4); - me.TD(me, 1, 1.6, s); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticSlider(80, 400, 8, "sv_gravity"); - s.valueDigits = 0; - s.valueDisplayMultiplier = 0.125; // show gravity in percent - me.TD(me, 1, 1.8, e = makeXonoticSliderCheckBox(800, 1, s, _("Low gravity"))); - e.savedValue = 200; // good on silvercity - me.TR(me); - me.TDempty(me, 0.4); - me.TD(me, 1, 1.6, s); - me.TR(me); - me.TD(me, 1, 2, makeXonoticTextLabel(0, _("Weapon & item mutators:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_grappling_hook", _("Grappling hook"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_jetpack", _("Jet pack"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_invincible_projectiles", _("Invincible Projectiles"))); - setDependent(e, "g_instagib", 0, 0); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_new_toys", _("New Toys"))); - setDependentWeird(e, checkCompatibility_newtoys); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_rocket_flying", _("Rocket Flying"))); - setDependent(e, "g_instagib", 0, 0); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_pinata", _("Piñata"))); - setDependentWeird(e, checkCompatibility_pinata); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_weapon_stay", _("Weapons stay"))); - setDependentWeird(e, checkCompatibility_weaponstay); - me.TR(me); - - me.gotoRC(me, 0, 2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 2, e = makeXonoticRadioButton(1, string_null, string_null, _("Regular (no arena)"))); - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticRadioButton(1, "g_weaponarena", "menu_weaponarena", _("Weapon arenas:"))); - e.getCvarValueFromCvar = TRUE; - e.cvarOffValue = "0"; - for(i = WEP_FIRST, j = 0; i <= WEP_LAST; ++i) - { - w = get_weaponinfo(i); - if(w.spawnflags & WEP_FLAG_HIDDEN) - continue; - if((j & 1) == 0) - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticWeaponarenaCheckBox(strzone(w.netname), strzone(w.message))); - setDependentWeird(e, checkCompatibility_weaponarena_weapon); - ++j; - } - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_weaponarena", "most", _("Most weapons"))); - e.cvarOffValue = "0"; - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_weaponarena", "all", _("All weapons"))); - e.cvarOffValue = "0"; - me.TR(me); - me.TD(me, 1, 4, makeXonoticTextLabel(0, _("Special arenas:"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_instagib", "1", _("InstaGib"))); - e.cvarOffValue = "0"; - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_nix", "1", _("NIX"))); - e.cvarOffValue = "0"; - me.TR(me); - me.TDempty(me, 0.4); - me.TD(me, 1, 1.6, e = makeXonoticCheckBox(0, "g_nix_with_blaster", _("with blaster"))); - setDependent(e, "g_nix", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_balance_blaster_weaponstart", "0", _("No start weapons"))); - e.cvarOffValue = "-1"; - makeMulti(e, "g_balance_shotgun_weaponstart g_balance_machinegun_weaponstart g_balance_devastator_weaponstart g_balance_minelayer_weaponstart g_balance_electro_weaponstart g_balance_crylink_weaponstart g_balance_hagar_weaponstart g_balance_porto_weaponstart g_balance_vaporizer_weaponstart g_balance_hook_weaponstart g_balance_rifle_weaponstart g_balance_fireball_weaponstart g_balance_seeker_weaponstart g_balance_tuba_weaponstart g_balance_arc_weaponstart g_balance_vortex_weaponstart g_balance_mortar_weaponstart"); - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} - -void XonoticMutatorsDialog_close(entity me) -{ - if(me.refilterEntity) - me.refilterEntity.refilter(me.refilterEntity); - SUPER(XonoticMutatorsDialog).close(me); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc new file mode 100644 index 000000000..a4e052f45 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc @@ -0,0 +1,289 @@ +#ifdef INTERFACE +CLASS(XonoticMutatorsDialog) EXTENDS(XonoticDialog) + METHOD(XonoticMutatorsDialog, toString, string(entity)) + METHOD(XonoticMutatorsDialog, fill, void(entity)) + METHOD(XonoticMutatorsDialog, showNotify, void(entity)) + METHOD(XonoticMutatorsDialog, close, void(entity)) + ATTRIB(XonoticMutatorsDialog, title, string, _("Mutators")) + ATTRIB(XonoticMutatorsDialog, color, vector, SKINCOLOR_DIALOG_MUTATORS) + ATTRIB(XonoticMutatorsDialog, intendedWidth, float, 0.9) + ATTRIB(XonoticMutatorsDialog, rows, float, 20) + ATTRIB(XonoticMutatorsDialog, columns, float, 6) + ATTRIB(XonoticMutatorsDialog, refilterEntity, entity, NULL) +ENDCLASS(XonoticMutatorsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticMutatorsDialog_showNotify(entity me) +{ + loadAllCvars(me); +} + +string weaponarenastring; +string weaponarenastring_cvar; +string WeaponArenaString() +{ + string s; + float n, i, j; + entity e; + s = cvar_string("g_weaponarena"); + if(s == "0") + return ""; + if(s == "all" || s == "1") + return _("All Weapons Arena"); + if(s == "most") + return _("Most Weapons Arena"); + if(s == weaponarenastring_cvar) + return weaponarenastring; + if(weaponarenastring) + strunzone(weaponarenastring); + if(weaponarenastring_cvar) + strunzone(weaponarenastring_cvar); + + weaponarenastring_cvar = strzone(s); + + n = tokenize_console(s); + s = ""; + for(i = 0; i < n; ++i) + { + for(j = WEP_FIRST; j <= WEP_LAST; ++j) + { + e = get_weaponinfo(j); + if(argv(i) == e.netname) + s = strcat(s, " & ", e.message); + } + } + s = sprintf(_("%s Arena"), substring(s, 3, strlen(s) - 3)); + + weaponarenastring = strzone(s); + + return weaponarenastring; +} + +string XonoticMutatorsDialog_toString(entity me) +{ + string s; + s = ""; + if(cvar("g_dodging")) + s = strcat(s, ", ", _("Dodging")); + if(cvar("g_instagib")) + s = strcat(s, ", ", _("InstaGib")); + if(cvar("g_new_toys")) + s = strcat(s, ", ", _("New Toys")); + if(cvar("g_nix")) + s = strcat(s, ", ", _("NIX")); + if(cvar("g_rocket_flying")) + s = strcat(s, ", ", _("Rocket Flying")); + if(cvar("g_invincible_projectiles")) + s = strcat(s, ", ", _("Invincible Projectiles")); + if(cvar_string("g_weaponarena") != "0") + s = strcat(s, ", ", WeaponArenaString()); + if(cvar("g_balance_blaster_weaponstart") == 0) + s = strcat(s, ", ", _("No start weapons")); + if(cvar("sv_gravity") < stof(cvar_defstring("sv_gravity"))) + s = strcat(s, ", ", _("Low gravity")); + if(cvar("g_cloaked")) + s = strcat(s, ", ", _("Cloaked")); + if(cvar("g_grappling_hook")) + s = strcat(s, ", ", _("Hook")); + if(cvar("g_midair")) + s = strcat(s, ", ", _("Midair")); + if(cvar("g_vampire")) + s = strcat(s, ", ", _("Vampire")); + if(cvar("g_pinata")) + s = strcat(s, ", ", _("Piñata")); + if(cvar("g_weapon_stay")) + s = strcat(s, ", ", _("Weapons stay")); + if(cvar("g_bloodloss") > 0) + s = strcat(s, ", ", _("Blood loss")); + if(cvar("g_jetpack")) + s = strcat(s, ", ", _("Jet pack")); + if(cvar("g_buffs")) + s = strcat(s, ", ", _("Buffs")); + if(cvar("g_overkill")) + s = strcat(s, ", ", _("Overkill")); + if(cvar("g_powerups") == 0) + s = strcat(s, ", ", _("No powerups")); + if(cvar("g_powerups") > 0) + s = strcat(s, ", ", _("Powerups")); + if(cvar("g_touchexplode") > 0) + s = strcat(s, ", ", _("Touch explode")); + if(s == "") + return ZCTX(_("MUT^None")); + else + return substring(s, 2, strlen(s) - 2); +} + +float checkCompatibility_pinata(entity me) +{ + if(cvar("g_instagib")) + return 0; + if(cvar("g_nix")) + return 0; + if(cvar_string("g_weaponarena") != "0") + return 0; + return 1; +} +float checkCompatibility_weaponstay(entity me) +{ + return checkCompatibility_pinata(me); +} +float checkCompatibility_newtoys(entity me) +{ + if(cvar("g_instagib")) + return 0; + if(cvar_string("g_weaponarena") == "most") + return 1; + if(cvar_string("g_weaponarena") == "all" || cvar_string("g_weaponarena") == "1") + return 1; + if(cvar_string("g_weaponarena") != "0") + return 0; + return 1; +} +float checkCompatibility_weaponarena_weapon(entity me) +{ + if(cvar("g_instagib")) + return 0; + if(cvar_string("g_weaponarena") == "most") + return 0; + if(cvar_string("g_weaponarena") == "all" || cvar_string("g_weaponarena") == "1") + return 0; + if(cvar_string("g_weaponarena") == "0") + return 0; + if(cvar_string("g_balance_blaster_weaponstart") == "0") + return 0; + return 1; +} + +void XonoticMutatorsDialog_fill(entity me) +{ + entity e, s, w; + float i, j; + me.TR(me); + me.TD(me, 1, 2, makeXonoticTextLabel(0, _("Gameplay mutators:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_dodging", _("Dodging"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_touchexplode", _("Touch explode"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_cloaked", _("Cloaked"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_buffs", _("Buffs"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_midair", _("Midair"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_vampire", _("Vampire"))); + setDependent(e, "g_instagib", 0, 0); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticSlider(10, 50, 1, "g_bloodloss"); + me.TD(me, 1, 1.8, e = makeXonoticSliderCheckBox(0, 1, s, _("Blood loss"))); + setDependent(e, "g_instagib", 0, 0); + me.TR(me); + me.TDempty(me, 0.4); + me.TD(me, 1, 1.6, s); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticSlider(80, 400, 8, "sv_gravity"); + s.valueDigits = 0; + s.valueDisplayMultiplier = 0.125; // show gravity in percent + me.TD(me, 1, 1.8, e = makeXonoticSliderCheckBox(800, 1, s, _("Low gravity"))); + e.savedValue = 200; // good on silvercity + me.TR(me); + me.TDempty(me, 0.4); + me.TD(me, 1, 1.6, s); + me.TR(me); + me.TD(me, 1, 2, makeXonoticTextLabel(0, _("Weapon & item mutators:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_grappling_hook", _("Grappling hook"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_jetpack", _("Jet pack"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_invincible_projectiles", _("Invincible Projectiles"))); + setDependent(e, "g_instagib", 0, 0); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_new_toys", _("New Toys"))); + setDependentWeird(e, checkCompatibility_newtoys); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_rocket_flying", _("Rocket Flying"))); + setDependent(e, "g_instagib", 0, 0); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_pinata", _("Piñata"))); + setDependentWeird(e, checkCompatibility_pinata); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_weapon_stay", _("Weapons stay"))); + setDependentWeird(e, checkCompatibility_weaponstay); + me.TR(me); + + me.gotoRC(me, 0, 2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 2, e = makeXonoticRadioButton(1, string_null, string_null, _("Regular (no arena)"))); + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticRadioButton(1, "g_weaponarena", "menu_weaponarena", _("Weapon arenas:"))); + e.getCvarValueFromCvar = TRUE; + e.cvarOffValue = "0"; + for(i = WEP_FIRST, j = 0; i <= WEP_LAST; ++i) + { + w = get_weaponinfo(i); + if(w.spawnflags & WEP_FLAG_HIDDEN) + continue; + if((j & 1) == 0) + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticWeaponarenaCheckBox(strzone(w.netname), strzone(w.message))); + setDependentWeird(e, checkCompatibility_weaponarena_weapon); + ++j; + } + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_weaponarena", "most", _("Most weapons"))); + e.cvarOffValue = "0"; + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_weaponarena", "all", _("All weapons"))); + e.cvarOffValue = "0"; + me.TR(me); + me.TD(me, 1, 4, makeXonoticTextLabel(0, _("Special arenas:"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_instagib", "1", _("InstaGib"))); + e.cvarOffValue = "0"; + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_nix", "1", _("NIX"))); + e.cvarOffValue = "0"; + me.TR(me); + me.TDempty(me, 0.4); + me.TD(me, 1, 1.6, e = makeXonoticCheckBox(0, "g_nix_with_blaster", _("with blaster"))); + setDependent(e, "g_nix", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_balance_blaster_weaponstart", "0", _("No start weapons"))); + e.cvarOffValue = "-1"; + makeMulti(e, "g_balance_shotgun_weaponstart g_balance_machinegun_weaponstart g_balance_devastator_weaponstart g_balance_minelayer_weaponstart g_balance_electro_weaponstart g_balance_crylink_weaponstart g_balance_hagar_weaponstart g_balance_porto_weaponstart g_balance_vaporizer_weaponstart g_balance_hook_weaponstart g_balance_rifle_weaponstart g_balance_fireball_weaponstart g_balance_seeker_weaponstart g_balance_tuba_weaponstart g_balance_arc_weaponstart g_balance_vortex_weaponstart g_balance_mortar_weaponstart"); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} + +void XonoticMutatorsDialog_close(entity me) +{ + if(me.refilterEntity) + me.refilterEntity.refilter(me.refilterEntity); + SUPER(XonoticMutatorsDialog).close(me); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join.c b/qcsrc/menu/xonotic/dialog_multiplayer_join.c deleted file mode 100644 index 4636ebbdb..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_join.c +++ /dev/null @@ -1,79 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticServerListTab) EXTENDS(XonoticTab) - METHOD(XonoticServerListTab, fill, void(entity)) - ATTRIB(XonoticServerListTab, title, string, _("Join")) - ATTRIB(XonoticServerListTab, intendedWidth, float, 0.9) - ATTRIB(XonoticServerListTab, rows, float, 23) - ATTRIB(XonoticServerListTab, columns, float, 6.5) -ENDCLASS(XonoticServerListTab) -entity makeXonoticServerListTab(); -#endif - -#ifdef IMPLEMENTATION - -entity makeXonoticServerListTab() -{ - entity me; - me = spawnXonoticServerListTab(); - me.configureDialog(me); - return me; -} -void XonoticServerListTab_fill(entity me) -{ - entity e, slist; - - slist = makeXonoticServerList(); - - me.gotoRC(me, 0.5, 0); - me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:"))); - me.TD(me, 1, 2.8, e = makeXonoticInputBox(0, string_null)); - e.onChange = ServerList_Filter_Change; - e.onChangeEntity = slist; - slist.controlledTextbox = e; - - me.gotoRC(me, 0.5, 3.6); - me.TD(me, 1, 0.9, e = makeXonoticCheckBox(0, "menu_slist_categories", ZCTX(_("SRVS^Categories")))); - e.onClickEntity = slist; - e.onClick = ServerList_Categories_Click; - me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showempty", ZCTX(_("SRVS^Empty")))); - slist.filterShowEmpty = e.checked; - e.onClickEntity = slist; - e.onClick = ServerList_ShowEmpty_Click; - me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showfull", ZCTX(_("SRVS^Full")))); - slist.filterShowFull = e.checked; - e.onClickEntity = slist; - e.onClick = ServerList_ShowFull_Click; - me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "net_slist_pause", _("Pause"))); - - me.gotoRC(me, 2, 0); - me.TD(me, 1, 1, slist.sortButton1 = makeXonoticButton(string_null, '0 0 0')); - me.TD(me, 1, 1, slist.sortButton2 = makeXonoticButton(string_null, '0 0 0')); - me.TD(me, 1, 1, slist.sortButton3 = makeXonoticButton(string_null, '0 0 0')); - me.TD(me, 1, 1, slist.sortButton4 = makeXonoticButton(string_null, '0 0 0')); - me.TD(me, 1, 1, slist.sortButton5 = makeXonoticButton(string_null, '0 0 0')); - me.TR(me); - me.TD(me, me.rows - 5, me.columns, slist); - - me.gotoRC(me, me.rows - 2, 0); - me.TD(me, 1, 0.6, e = makeXonoticTextLabel(0, _("Address:"))); - me.TD(me, 1, 2.9, e = makeXonoticInputBox(0, string_null)); - e.onEnter = ServerList_Connect_Click; - e.onEnterEntity = slist; - e.onChange = ServerList_Update_favoriteButton; - e.onChangeEntity = slist; - slist.ipAddressBox = e; - me.TD(me, 1, 1.5, e = makeXonoticButton("", '0 0 0')); - e.onClick = ServerList_Favorite_Click; - e.onClickEntity = slist; - slist.favoriteButton = e; - me.TD(me, 1, 1.5, e = makeXonoticButton(_("Info..."), '0 0 0')); - e.onClick = ServerList_Info_Click; - e.onClickEntity = slist; - slist.infoButton = e; - me.TR(me); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("Join!"), '0 0 0')); - e.onClick = ServerList_Connect_Click; - e.onClickEntity = slist; - slist.connectButton = e; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join.qc new file mode 100644 index 000000000..4636ebbdb --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_join.qc @@ -0,0 +1,79 @@ +#ifdef INTERFACE +CLASS(XonoticServerListTab) EXTENDS(XonoticTab) + METHOD(XonoticServerListTab, fill, void(entity)) + ATTRIB(XonoticServerListTab, title, string, _("Join")) + ATTRIB(XonoticServerListTab, intendedWidth, float, 0.9) + ATTRIB(XonoticServerListTab, rows, float, 23) + ATTRIB(XonoticServerListTab, columns, float, 6.5) +ENDCLASS(XonoticServerListTab) +entity makeXonoticServerListTab(); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticServerListTab() +{ + entity me; + me = spawnXonoticServerListTab(); + me.configureDialog(me); + return me; +} +void XonoticServerListTab_fill(entity me) +{ + entity e, slist; + + slist = makeXonoticServerList(); + + me.gotoRC(me, 0.5, 0); + me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:"))); + me.TD(me, 1, 2.8, e = makeXonoticInputBox(0, string_null)); + e.onChange = ServerList_Filter_Change; + e.onChangeEntity = slist; + slist.controlledTextbox = e; + + me.gotoRC(me, 0.5, 3.6); + me.TD(me, 1, 0.9, e = makeXonoticCheckBox(0, "menu_slist_categories", ZCTX(_("SRVS^Categories")))); + e.onClickEntity = slist; + e.onClick = ServerList_Categories_Click; + me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showempty", ZCTX(_("SRVS^Empty")))); + slist.filterShowEmpty = e.checked; + e.onClickEntity = slist; + e.onClick = ServerList_ShowEmpty_Click; + me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showfull", ZCTX(_("SRVS^Full")))); + slist.filterShowFull = e.checked; + e.onClickEntity = slist; + e.onClick = ServerList_ShowFull_Click; + me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "net_slist_pause", _("Pause"))); + + me.gotoRC(me, 2, 0); + me.TD(me, 1, 1, slist.sortButton1 = makeXonoticButton(string_null, '0 0 0')); + me.TD(me, 1, 1, slist.sortButton2 = makeXonoticButton(string_null, '0 0 0')); + me.TD(me, 1, 1, slist.sortButton3 = makeXonoticButton(string_null, '0 0 0')); + me.TD(me, 1, 1, slist.sortButton4 = makeXonoticButton(string_null, '0 0 0')); + me.TD(me, 1, 1, slist.sortButton5 = makeXonoticButton(string_null, '0 0 0')); + me.TR(me); + me.TD(me, me.rows - 5, me.columns, slist); + + me.gotoRC(me, me.rows - 2, 0); + me.TD(me, 1, 0.6, e = makeXonoticTextLabel(0, _("Address:"))); + me.TD(me, 1, 2.9, e = makeXonoticInputBox(0, string_null)); + e.onEnter = ServerList_Connect_Click; + e.onEnterEntity = slist; + e.onChange = ServerList_Update_favoriteButton; + e.onChangeEntity = slist; + slist.ipAddressBox = e; + me.TD(me, 1, 1.5, e = makeXonoticButton("", '0 0 0')); + e.onClick = ServerList_Favorite_Click; + e.onClickEntity = slist; + slist.favoriteButton = e; + me.TD(me, 1, 1.5, e = makeXonoticButton(_("Info..."), '0 0 0')); + e.onClick = ServerList_Info_Click; + e.onClickEntity = slist; + slist.infoButton = e; + me.TR(me); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("Join!"), '0 0 0')); + e.onClick = ServerList_Connect_Click; + e.onClickEntity = slist; + slist.connectButton = e; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.c b/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.c deleted file mode 100644 index fa5e30682..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.c +++ /dev/null @@ -1,345 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticServerInfoDialog) EXTENDS(XonoticDialog) - METHOD(XonoticServerInfoDialog, fill, void(entity)) - METHOD(XonoticServerInfoDialog, loadServerInfo, void(entity, float)) - ATTRIB(XonoticServerInfoDialog, title, string, _("Server Information")) - ATTRIB(XonoticServerInfoDialog, color, vector, SKINCOLOR_DIALOG_SERVERINFO) - ATTRIB(XonoticServerInfoDialog, intendedWidth, float, 0.8) - ATTRIB(XonoticServerInfoDialog, rows, float, 18) - ATTRIB(XonoticServerInfoDialog, columns, float, 6.2) - - ATTRIB(XonoticServerInfoDialog, currentServerName, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerCName, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerType, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerMap, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerPlayers, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerNumPlayers, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerNumBots, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerNumFreeSlots, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerMod, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerVersion, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerKey, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerID, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerEncrypt, string, string_null) - ATTRIB(XonoticServerInfoDialog, currentServerPure, string, string_null) - - ATTRIB(XonoticServerInfoDialog, nameLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, cnameLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, typeLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, mapLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, rawPlayerList, entity, NULL) - ATTRIB(XonoticServerInfoDialog, numPlayersLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, numBotsLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, numFreeSlotsLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, modLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, versionLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, keyLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, idLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, encryptLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, canConnectLabel, entity, NULL) - ATTRIB(XonoticServerInfoDialog, pureLabel, entity, NULL) -ENDCLASS(XonoticServerInfoDialog) - -void Join_Click(entity btn, entity me); -#endif - -#ifdef IMPLEMENTATION -void XonoticServerInfoDialog_loadServerInfo(entity me, float i) -{ - float m, pure, freeslots, j, numh, maxp, numb, sflags; - string s, typestr, versionstr, k, v, modname; - - // ==================================== - // First clear and unzone the strings - // ==================================== - if(me.currentServerName) - strunzone(me.currentServerName); - me.currentServerName = string_null; - - if(me.currentServerCName) - strunzone(me.currentServerCName); - me.currentServerCName = string_null; - - if(me.currentServerType) - strunzone(me.currentServerType); - me.currentServerType = string_null; - - if(me.currentServerMap) - strunzone(me.currentServerMap); - me.currentServerMap = string_null; - - if(me.currentServerPlayers) - strunzone(me.currentServerPlayers); - me.currentServerPlayers = string_null; - - if(me.currentServerNumPlayers) - strunzone(me.currentServerNumPlayers); - me.currentServerNumPlayers = string_null; - - if(me.currentServerNumBots) - strunzone(me.currentServerNumBots); - me.currentServerNumBots = string_null; - - if(me.currentServerNumFreeSlots) - strunzone(me.currentServerNumFreeSlots); - me.currentServerNumFreeSlots = string_null; - - if(me.currentServerMod) - strunzone(me.currentServerMod); - me.currentServerMod = string_null; - - if(me.currentServerVersion) - strunzone(me.currentServerVersion); - me.currentServerVersion = string_null; - - // not zoned! - //if(me.currentServerEncrypt) - // strunzone(me.currentServerEncrypt); - //me.currentServerEncrypt = string_null; - if(me.currentServerPure) - strunzone(me.currentServerPure); - me.currentServerPure = string_null; - - if(me.currentServerKey) - strunzone(me.currentServerKey); - me.currentServerKey = string_null; - - if(me.currentServerID) - strunzone(me.currentServerID); - me.currentServerID = string_null; - - // ========================== - // Now, fill in the strings - // ========================== - me.currentServerName = strzone(gethostcachestring(SLIST_FIELD_NAME, i)); - me.nameLabel.setText(me.nameLabel, me.currentServerName); - - me.currentServerCName = strzone(gethostcachestring(SLIST_FIELD_CNAME, i)); - me.cnameLabel.setText(me.cnameLabel, me.currentServerCName); - - pure = -1; - typestr = _("N/A"); - versionstr = _("N/A"); - - s = gethostcachestring(SLIST_FIELD_QCSTATUS, i); - m = tokenizebyseparator(s, ":"); - if(m >= 2) - { - typestr = argv(0); - versionstr = argv(1); - } - freeslots = -1; - sflags = -1; - modname = ""; - for(j = 2; j < m; ++j) - { - if(argv(j) == "") - break; - k = substring(argv(j), 0, 1); - v = substring(argv(j), 1, -1); - if(k == "P") - pure = stof(v); - else if(k == "S") - freeslots = stof(v); - else if(k == "F") - sflags = stof(v); - else if(k == "M") - modname = v; - } - -#ifdef COMPAT_NO_MOD_IS_XONOTIC - if(modname == "") - modname = "Xonotic"; -#endif - - s = gethostcachestring(SLIST_FIELD_MOD, i); - if(s != "data") - modname = sprintf("%s (%s)", modname, s); - - j = MapInfo_Type_FromString(typestr); // try and get the real name of the game type - if(j) { typestr = MapInfo_Type_ToText(j); } // only set it if we actually found it - - me.currentServerType = strzone(typestr); - me.typeLabel.setText(me.typeLabel, me.currentServerType); - - me.currentServerMap = strzone(gethostcachestring(SLIST_FIELD_MAP, i)); - me.mapLabel.setText(me.mapLabel, me.currentServerMap); - - me.currentServerPlayers = strzone(gethostcachestring(SLIST_FIELD_PLAYERS, i)); - me.rawPlayerList.setPlayerList(me.rawPlayerList, me.currentServerPlayers); - - numh = gethostcachenumber(SLIST_FIELD_NUMHUMANS, i); - maxp = gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i); - numb = gethostcachenumber(SLIST_FIELD_NUMBOTS, i); - me.currentServerNumPlayers = strzone(sprintf("%d/%d", numh, maxp)); - me.numPlayersLabel.setText(me.numPlayersLabel, me.currentServerNumPlayers); - - s = ftos(numb); - me.currentServerNumBots = strzone(s); - me.numBotsLabel.setText(me.numBotsLabel, me.currentServerNumBots); - - if(freeslots < 0) { freeslots = maxp - numh - numb; } - s = ftos(freeslots); - me.currentServerNumFreeSlots = strzone(s); - me.numFreeSlotsLabel.setText(me.numFreeSlotsLabel, me.currentServerNumFreeSlots); - - me.currentServerMod = ((modname == "Xonotic") ? _("Default") : modname); - me.currentServerMod = strzone(me.currentServerMod); - me.modLabel.setText(me.modLabel, me.currentServerMod); - - me.currentServerVersion = strzone(versionstr); - me.versionLabel.setText(me.versionLabel, me.currentServerVersion); - - me.currentServerPure = ((pure < 0) ? _("N/A") : (pure == 0) ? _("Official") : sprintf(_("%d modified"), pure)); - me.currentServerPure = strzone(me.currentServerPure); - me.pureLabel.setText(me.pureLabel, me.currentServerPure); - - s = crypto_getencryptlevel(me.currentServerCName); - if(s == "") - { - if(cvar("crypto_aeslevel") >= 3) - me.currentServerEncrypt = _("N/A (auth library missing, can't connect)"); - else - me.currentServerEncrypt = _("N/A (auth library missing)"); - } - else switch(stof(substring(s, 0, 1))) - { - case 0: - if(cvar("crypto_aeslevel") >= 3) - me.currentServerEncrypt = _("Not supported (can't connect)"); - else - me.currentServerEncrypt = _("Not supported (won't encrypt)"); - break; - case 1: - if(cvar("crypto_aeslevel") >= 2) - me.currentServerEncrypt = _("Supported (will encrypt)"); - else - me.currentServerEncrypt = _("Supported (won't encrypt)"); - break; - case 2: - if(cvar("crypto_aeslevel") >= 1) - me.currentServerEncrypt = _("Requested (will encrypt)"); - else - me.currentServerEncrypt = _("Requested (won't encrypt)"); - break; - case 3: - if(cvar("crypto_aeslevel") <= 0) - me.currentServerEncrypt = _("Required (can't connect)"); - else - me.currentServerEncrypt = _("Required (will encrypt)"); - break; - } - me.encryptLabel.setText(me.encryptLabel, me.currentServerEncrypt); - - s = crypto_getidfp(me.currentServerCName); - if (!s) { s = _("N/A"); } - me.currentServerID = strzone(s); - me.idLabel.setText(me.idLabel, me.currentServerID); - - s = crypto_getkeyfp(me.currentServerCName); - if (!s) { s = _("N/A"); } - me.currentServerKey = strzone(s); - me.keyLabel.setText(me.keyLabel, me.currentServerKey); -} - -void XonoticServerInfoDialog_fill(entity me) -{ - entity e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Hostname:"))); - me.TD(me, 1, 4.6, e = makeXonoticTextLabel(0.5, "")); - e.colorL = SKINCOLOR_SERVERINFO_NAME; - e.allowCut = 1; - me.nameLabel = e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Address:"))); - me.TD(me, 1, 4.6, e = makeXonoticTextLabel(0.5, "")); - e.colorL = SKINCOLOR_SERVERINFO_IP; - e.allowCut = 1; - me.cnameLabel = e; - - me.TR(me); - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Gametype:"))); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.typeLabel = e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Map:"))); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.mapLabel = e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Mod:"))); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.modLabel = e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Version:"))); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.versionLabel = e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Settings:"))); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.pureLabel = e; - - me.TR(me); - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Players:"))); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.numPlayersLabel = e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Bots:"))); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.numBotsLabel = e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Free slots:"))); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.numFreeSlotsLabel = e; - - me.gotoRC(me, me.rows - 5, 0); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Encryption:"))); - me.TD(me, 1, 5.4, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.encryptLabel = e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("ID:"))); - me.TD(me, 1, 5.4, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.keyLabel = e; - me.TR(me); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Key:"))); - me.TD(me, 1, 5.4, e = makeXonoticTextLabel(0, "")); - e.allowCut = 1; - me.idLabel = e; - - me.gotoRC(me, 2, 2.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticTextLabel(0, _("Players:"))); - me.TR(me); - me.TD(me, me.rows - 8, 4, e = makeXonoticPlayerList()); - me.rawPlayerList = e; - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns/2, e = makeXonoticButton(_("Close"), '0 0 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; - //me.TD(me, 1, me.columns/3, e = makeXonoticButton("", '0 0 0')); // TODO: Add bookmark button here - // e.onClick = ServerList_Favorite_Click; - // e.onClickEntity = slist; - // slist.favoriteButton = e; - me.TD(me, 1, me.columns/2, e = makeXonoticButton(_("Join!"), '0 0 0')); - e.onClick = Join_Click; - e.onClickEntity = me; -} - -void Join_Click(entity btn, entity me) -{ - localcmd("connect ", me.currentServerCName, "\n"); -} - -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc new file mode 100644 index 000000000..fa5e30682 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc @@ -0,0 +1,345 @@ +#ifdef INTERFACE +CLASS(XonoticServerInfoDialog) EXTENDS(XonoticDialog) + METHOD(XonoticServerInfoDialog, fill, void(entity)) + METHOD(XonoticServerInfoDialog, loadServerInfo, void(entity, float)) + ATTRIB(XonoticServerInfoDialog, title, string, _("Server Information")) + ATTRIB(XonoticServerInfoDialog, color, vector, SKINCOLOR_DIALOG_SERVERINFO) + ATTRIB(XonoticServerInfoDialog, intendedWidth, float, 0.8) + ATTRIB(XonoticServerInfoDialog, rows, float, 18) + ATTRIB(XonoticServerInfoDialog, columns, float, 6.2) + + ATTRIB(XonoticServerInfoDialog, currentServerName, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerCName, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerType, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerMap, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerPlayers, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerNumPlayers, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerNumBots, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerNumFreeSlots, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerMod, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerVersion, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerKey, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerID, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerEncrypt, string, string_null) + ATTRIB(XonoticServerInfoDialog, currentServerPure, string, string_null) + + ATTRIB(XonoticServerInfoDialog, nameLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, cnameLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, typeLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, mapLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, rawPlayerList, entity, NULL) + ATTRIB(XonoticServerInfoDialog, numPlayersLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, numBotsLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, numFreeSlotsLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, modLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, versionLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, keyLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, idLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, encryptLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, canConnectLabel, entity, NULL) + ATTRIB(XonoticServerInfoDialog, pureLabel, entity, NULL) +ENDCLASS(XonoticServerInfoDialog) + +void Join_Click(entity btn, entity me); +#endif + +#ifdef IMPLEMENTATION +void XonoticServerInfoDialog_loadServerInfo(entity me, float i) +{ + float m, pure, freeslots, j, numh, maxp, numb, sflags; + string s, typestr, versionstr, k, v, modname; + + // ==================================== + // First clear and unzone the strings + // ==================================== + if(me.currentServerName) + strunzone(me.currentServerName); + me.currentServerName = string_null; + + if(me.currentServerCName) + strunzone(me.currentServerCName); + me.currentServerCName = string_null; + + if(me.currentServerType) + strunzone(me.currentServerType); + me.currentServerType = string_null; + + if(me.currentServerMap) + strunzone(me.currentServerMap); + me.currentServerMap = string_null; + + if(me.currentServerPlayers) + strunzone(me.currentServerPlayers); + me.currentServerPlayers = string_null; + + if(me.currentServerNumPlayers) + strunzone(me.currentServerNumPlayers); + me.currentServerNumPlayers = string_null; + + if(me.currentServerNumBots) + strunzone(me.currentServerNumBots); + me.currentServerNumBots = string_null; + + if(me.currentServerNumFreeSlots) + strunzone(me.currentServerNumFreeSlots); + me.currentServerNumFreeSlots = string_null; + + if(me.currentServerMod) + strunzone(me.currentServerMod); + me.currentServerMod = string_null; + + if(me.currentServerVersion) + strunzone(me.currentServerVersion); + me.currentServerVersion = string_null; + + // not zoned! + //if(me.currentServerEncrypt) + // strunzone(me.currentServerEncrypt); + //me.currentServerEncrypt = string_null; + if(me.currentServerPure) + strunzone(me.currentServerPure); + me.currentServerPure = string_null; + + if(me.currentServerKey) + strunzone(me.currentServerKey); + me.currentServerKey = string_null; + + if(me.currentServerID) + strunzone(me.currentServerID); + me.currentServerID = string_null; + + // ========================== + // Now, fill in the strings + // ========================== + me.currentServerName = strzone(gethostcachestring(SLIST_FIELD_NAME, i)); + me.nameLabel.setText(me.nameLabel, me.currentServerName); + + me.currentServerCName = strzone(gethostcachestring(SLIST_FIELD_CNAME, i)); + me.cnameLabel.setText(me.cnameLabel, me.currentServerCName); + + pure = -1; + typestr = _("N/A"); + versionstr = _("N/A"); + + s = gethostcachestring(SLIST_FIELD_QCSTATUS, i); + m = tokenizebyseparator(s, ":"); + if(m >= 2) + { + typestr = argv(0); + versionstr = argv(1); + } + freeslots = -1; + sflags = -1; + modname = ""; + for(j = 2; j < m; ++j) + { + if(argv(j) == "") + break; + k = substring(argv(j), 0, 1); + v = substring(argv(j), 1, -1); + if(k == "P") + pure = stof(v); + else if(k == "S") + freeslots = stof(v); + else if(k == "F") + sflags = stof(v); + else if(k == "M") + modname = v; + } + +#ifdef COMPAT_NO_MOD_IS_XONOTIC + if(modname == "") + modname = "Xonotic"; +#endif + + s = gethostcachestring(SLIST_FIELD_MOD, i); + if(s != "data") + modname = sprintf("%s (%s)", modname, s); + + j = MapInfo_Type_FromString(typestr); // try and get the real name of the game type + if(j) { typestr = MapInfo_Type_ToText(j); } // only set it if we actually found it + + me.currentServerType = strzone(typestr); + me.typeLabel.setText(me.typeLabel, me.currentServerType); + + me.currentServerMap = strzone(gethostcachestring(SLIST_FIELD_MAP, i)); + me.mapLabel.setText(me.mapLabel, me.currentServerMap); + + me.currentServerPlayers = strzone(gethostcachestring(SLIST_FIELD_PLAYERS, i)); + me.rawPlayerList.setPlayerList(me.rawPlayerList, me.currentServerPlayers); + + numh = gethostcachenumber(SLIST_FIELD_NUMHUMANS, i); + maxp = gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i); + numb = gethostcachenumber(SLIST_FIELD_NUMBOTS, i); + me.currentServerNumPlayers = strzone(sprintf("%d/%d", numh, maxp)); + me.numPlayersLabel.setText(me.numPlayersLabel, me.currentServerNumPlayers); + + s = ftos(numb); + me.currentServerNumBots = strzone(s); + me.numBotsLabel.setText(me.numBotsLabel, me.currentServerNumBots); + + if(freeslots < 0) { freeslots = maxp - numh - numb; } + s = ftos(freeslots); + me.currentServerNumFreeSlots = strzone(s); + me.numFreeSlotsLabel.setText(me.numFreeSlotsLabel, me.currentServerNumFreeSlots); + + me.currentServerMod = ((modname == "Xonotic") ? _("Default") : modname); + me.currentServerMod = strzone(me.currentServerMod); + me.modLabel.setText(me.modLabel, me.currentServerMod); + + me.currentServerVersion = strzone(versionstr); + me.versionLabel.setText(me.versionLabel, me.currentServerVersion); + + me.currentServerPure = ((pure < 0) ? _("N/A") : (pure == 0) ? _("Official") : sprintf(_("%d modified"), pure)); + me.currentServerPure = strzone(me.currentServerPure); + me.pureLabel.setText(me.pureLabel, me.currentServerPure); + + s = crypto_getencryptlevel(me.currentServerCName); + if(s == "") + { + if(cvar("crypto_aeslevel") >= 3) + me.currentServerEncrypt = _("N/A (auth library missing, can't connect)"); + else + me.currentServerEncrypt = _("N/A (auth library missing)"); + } + else switch(stof(substring(s, 0, 1))) + { + case 0: + if(cvar("crypto_aeslevel") >= 3) + me.currentServerEncrypt = _("Not supported (can't connect)"); + else + me.currentServerEncrypt = _("Not supported (won't encrypt)"); + break; + case 1: + if(cvar("crypto_aeslevel") >= 2) + me.currentServerEncrypt = _("Supported (will encrypt)"); + else + me.currentServerEncrypt = _("Supported (won't encrypt)"); + break; + case 2: + if(cvar("crypto_aeslevel") >= 1) + me.currentServerEncrypt = _("Requested (will encrypt)"); + else + me.currentServerEncrypt = _("Requested (won't encrypt)"); + break; + case 3: + if(cvar("crypto_aeslevel") <= 0) + me.currentServerEncrypt = _("Required (can't connect)"); + else + me.currentServerEncrypt = _("Required (will encrypt)"); + break; + } + me.encryptLabel.setText(me.encryptLabel, me.currentServerEncrypt); + + s = crypto_getidfp(me.currentServerCName); + if (!s) { s = _("N/A"); } + me.currentServerID = strzone(s); + me.idLabel.setText(me.idLabel, me.currentServerID); + + s = crypto_getkeyfp(me.currentServerCName); + if (!s) { s = _("N/A"); } + me.currentServerKey = strzone(s); + me.keyLabel.setText(me.keyLabel, me.currentServerKey); +} + +void XonoticServerInfoDialog_fill(entity me) +{ + entity e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Hostname:"))); + me.TD(me, 1, 4.6, e = makeXonoticTextLabel(0.5, "")); + e.colorL = SKINCOLOR_SERVERINFO_NAME; + e.allowCut = 1; + me.nameLabel = e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Address:"))); + me.TD(me, 1, 4.6, e = makeXonoticTextLabel(0.5, "")); + e.colorL = SKINCOLOR_SERVERINFO_IP; + e.allowCut = 1; + me.cnameLabel = e; + + me.TR(me); + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Gametype:"))); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.typeLabel = e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Map:"))); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.mapLabel = e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Mod:"))); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.modLabel = e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Version:"))); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.versionLabel = e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Settings:"))); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.pureLabel = e; + + me.TR(me); + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Players:"))); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.numPlayersLabel = e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Bots:"))); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.numBotsLabel = e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Free slots:"))); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.numFreeSlotsLabel = e; + + me.gotoRC(me, me.rows - 5, 0); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Encryption:"))); + me.TD(me, 1, 5.4, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.encryptLabel = e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("ID:"))); + me.TD(me, 1, 5.4, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.keyLabel = e; + me.TR(me); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Key:"))); + me.TD(me, 1, 5.4, e = makeXonoticTextLabel(0, "")); + e.allowCut = 1; + me.idLabel = e; + + me.gotoRC(me, 2, 2.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticTextLabel(0, _("Players:"))); + me.TR(me); + me.TD(me, me.rows - 8, 4, e = makeXonoticPlayerList()); + me.rawPlayerList = e; + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns/2, e = makeXonoticButton(_("Close"), '0 0 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; + //me.TD(me, 1, me.columns/3, e = makeXonoticButton("", '0 0 0')); // TODO: Add bookmark button here + // e.onClick = ServerList_Favorite_Click; + // e.onClickEntity = slist; + // slist.favoriteButton = e; + me.TD(me, 1, me.columns/2, e = makeXonoticButton(_("Join!"), '0 0 0')); + e.onClick = Join_Click; + e.onClickEntity = me; +} + +void Join_Click(entity btn, entity me) +{ + localcmd("connect ", me.currentServerCName, "\n"); +} + +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media.c b/qcsrc/menu/xonotic/dialog_multiplayer_media.c deleted file mode 100644 index a0b49b1f6..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media.c +++ /dev/null @@ -1,34 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticMediaTab) EXTENDS(XonoticTab) - METHOD(XonoticMediaTab, fill, void(entity)) - ATTRIB(XonoticMediaTab, title, string, _("Media")) - ATTRIB(XonoticMediaTab, intendedWidth, float, 0.9) - ATTRIB(XonoticMediaTab, rows, float, 23) - ATTRIB(XonoticMediaTab, columns, float, 3) - ATTRIB(XonoticMediaTab, name, string, "Media") -ENDCLASS(XonoticMediaTab) -entity makeXonoticMediaTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticMediaTab() -{ - entity me; - me = spawnXonoticMediaTab(); - me.configureDialog(me); - return me; -} -void XonoticMediaTab_fill(entity me) -{ - entity mc, e; - mc = makeXonoticTabController(me.rows - 2); - - me.gotoRC(me, 0.5, 0); - me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Demos"), makeXonoticDemoBrowserTab())); - me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Screenshots"), makeXonoticScreenshotBrowserTab())); - me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Music Player"), makeXonoticMusicPlayerTab())); - - me.gotoRC(me, 3, 0); - me.TD(me, me.rows - 2, me.columns, mc); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media.qc new file mode 100644 index 000000000..a0b49b1f6 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media.qc @@ -0,0 +1,34 @@ +#ifdef INTERFACE +CLASS(XonoticMediaTab) EXTENDS(XonoticTab) + METHOD(XonoticMediaTab, fill, void(entity)) + ATTRIB(XonoticMediaTab, title, string, _("Media")) + ATTRIB(XonoticMediaTab, intendedWidth, float, 0.9) + ATTRIB(XonoticMediaTab, rows, float, 23) + ATTRIB(XonoticMediaTab, columns, float, 3) + ATTRIB(XonoticMediaTab, name, string, "Media") +ENDCLASS(XonoticMediaTab) +entity makeXonoticMediaTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticMediaTab() +{ + entity me; + me = spawnXonoticMediaTab(); + me.configureDialog(me); + return me; +} +void XonoticMediaTab_fill(entity me) +{ + entity mc, e; + mc = makeXonoticTabController(me.rows - 2); + + me.gotoRC(me, 0.5, 0); + me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Demos"), makeXonoticDemoBrowserTab())); + me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Screenshots"), makeXonoticScreenshotBrowserTab())); + me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Music Player"), makeXonoticMusicPlayerTab())); + + me.gotoRC(me, 3, 0); + me.TD(me, me.rows - 2, me.columns, mc); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.c b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.c deleted file mode 100644 index 092355126..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.c +++ /dev/null @@ -1,73 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticDemoBrowserTab) EXTENDS(XonoticTab) - METHOD(XonoticDemoBrowserTab, fill, void(entity)) - ATTRIB(XonoticDemoBrowserTab, title, string, _("Demo")) - ATTRIB(XonoticDemoBrowserTab, intendedWidth, float, 0.9) - ATTRIB(XonoticDemoBrowserTab, rows, float, 21) - ATTRIB(XonoticDemoBrowserTab, columns, float, 6.5) - ATTRIB(XonoticDemoBrowserTab, name, string, "DemoBrowser") - ATTRIB(XonoticDemoBrowserTab, democlicktype, float, 0) -ENDCLASS(XonoticDemoBrowserTab) -entity makeXonoticDemoBrowserTab(); -const float DMO_PLAY = 1; -const float DMO_TIME = 2; -#endif - -#ifdef IMPLEMENTATION -void DemoConfirm_Check_Gamestatus(entity btn, entity me) -{ - if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) // we're not in a match, lets watch the demo - { - if(btn.democlicktype == DMO_PLAY) - { demolist.startDemo(demolist); } - else if(btn.democlicktype == DMO_TIME) - { demolist.timeDemo(demolist); } - } - else // already in a match, player has to confirm - { - if(btn.democlicktype == DMO_PLAY) - { DialogOpenButton_Click(btn, main.demostartconfirmDialog); } - else if(btn.democlicktype == DMO_TIME) - { DialogOpenButton_Click(btn, main.demotimeconfirmDialog); } - } -} - -entity makeXonoticDemoBrowserTab() -{ - entity me; - me = spawnXonoticDemoBrowserTab(); - me.configureDialog(me); - return me; -} -void XonoticDemoBrowserTab_fill(entity me) -{ - entity e; - demolist = makeXonoticDemoList(); - - me.TR(me); - me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:"))); - me.TD(me, 1, 2.9, e = makeXonoticInputBox(0, string_null)); - e.onChange = DemoList_Filter_Change; - e.onChangeEntity = demolist; - demolist.controlledTextbox = e; - - me.gotoRC(me, 0, 3.7); - me.TD(me, 1, 1.5, e = makeXonoticCheckBox(0, "cl_autodemo", _("Auto record demos"))); - me.TD(me, 1, 1, e = makeXonoticButton(_("Refresh"), '0 0 0')); - e.onClick = DemoList_Refresh_Click; - e.onClickEntity = demolist; - - me.gotoRC(me, 1.5, 0); - me.TD(me, me.rows - 2.5, me.columns, demolist); - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns / 2, e = makeXonoticButton(_("Timedemo"), '0 0 0')); - e.democlicktype = DMO_TIME; - e.onClick = DemoConfirm_Check_Gamestatus; - e.onClickEntity = me; // demolist is global anyway - me.TD(me, 1, me.columns / 2, e = makeXonoticButton(ZCTX(_("DEMO^Play")), '0 0 0')); - e.democlicktype = DMO_PLAY; - e.onClick = DemoConfirm_Check_Gamestatus; - e.onClickEntity = me; // demolist is global anyway -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc new file mode 100644 index 000000000..092355126 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc @@ -0,0 +1,73 @@ +#ifdef INTERFACE +CLASS(XonoticDemoBrowserTab) EXTENDS(XonoticTab) + METHOD(XonoticDemoBrowserTab, fill, void(entity)) + ATTRIB(XonoticDemoBrowserTab, title, string, _("Demo")) + ATTRIB(XonoticDemoBrowserTab, intendedWidth, float, 0.9) + ATTRIB(XonoticDemoBrowserTab, rows, float, 21) + ATTRIB(XonoticDemoBrowserTab, columns, float, 6.5) + ATTRIB(XonoticDemoBrowserTab, name, string, "DemoBrowser") + ATTRIB(XonoticDemoBrowserTab, democlicktype, float, 0) +ENDCLASS(XonoticDemoBrowserTab) +entity makeXonoticDemoBrowserTab(); +const float DMO_PLAY = 1; +const float DMO_TIME = 2; +#endif + +#ifdef IMPLEMENTATION +void DemoConfirm_Check_Gamestatus(entity btn, entity me) +{ + if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) // we're not in a match, lets watch the demo + { + if(btn.democlicktype == DMO_PLAY) + { demolist.startDemo(demolist); } + else if(btn.democlicktype == DMO_TIME) + { demolist.timeDemo(demolist); } + } + else // already in a match, player has to confirm + { + if(btn.democlicktype == DMO_PLAY) + { DialogOpenButton_Click(btn, main.demostartconfirmDialog); } + else if(btn.democlicktype == DMO_TIME) + { DialogOpenButton_Click(btn, main.demotimeconfirmDialog); } + } +} + +entity makeXonoticDemoBrowserTab() +{ + entity me; + me = spawnXonoticDemoBrowserTab(); + me.configureDialog(me); + return me; +} +void XonoticDemoBrowserTab_fill(entity me) +{ + entity e; + demolist = makeXonoticDemoList(); + + me.TR(me); + me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:"))); + me.TD(me, 1, 2.9, e = makeXonoticInputBox(0, string_null)); + e.onChange = DemoList_Filter_Change; + e.onChangeEntity = demolist; + demolist.controlledTextbox = e; + + me.gotoRC(me, 0, 3.7); + me.TD(me, 1, 1.5, e = makeXonoticCheckBox(0, "cl_autodemo", _("Auto record demos"))); + me.TD(me, 1, 1, e = makeXonoticButton(_("Refresh"), '0 0 0')); + e.onClick = DemoList_Refresh_Click; + e.onClickEntity = demolist; + + me.gotoRC(me, 1.5, 0); + me.TD(me, me.rows - 2.5, me.columns, demolist); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns / 2, e = makeXonoticButton(_("Timedemo"), '0 0 0')); + e.democlicktype = DMO_TIME; + e.onClick = DemoConfirm_Check_Gamestatus; + e.onClickEntity = me; // demolist is global anyway + me.TD(me, 1, me.columns / 2, e = makeXonoticButton(ZCTX(_("DEMO^Play")), '0 0 0')); + e.democlicktype = DMO_PLAY; + e.onClick = DemoConfirm_Check_Gamestatus; + e.onClickEntity = me; // demolist is global anyway +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.c b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.c deleted file mode 100644 index a5a97c550..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.c +++ /dev/null @@ -1,31 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticDemoStartConfirmDialog) EXTENDS(XonoticDialog) - METHOD(XonoticDemoStartConfirmDialog, fill, void(entity)) - ATTRIB(XonoticDemoStartConfirmDialog, title, string, _("Disconnect")) - ATTRIB(XonoticDemoStartConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) - ATTRIB(XonoticDemoStartConfirmDialog, intendedWidth, float, 0.5) - ATTRIB(XonoticDemoStartConfirmDialog, rows, float, 4) - ATTRIB(XonoticDemoStartConfirmDialog, columns, float, 2) -ENDCLASS(XonoticDemoStartConfirmDialog) -#endif - -#ifdef IMPLEMENTATION -void Handle_StartDemo_Click(entity unused, entity me) { demolist.startDemo(demolist); } -void XonoticDemoStartConfirmDialog_fill(entity me) -{ - entity e; - - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Playing a demo will disconnect you from the current match."))); - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Do you really wish to disconnect now?"))); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("DMCNFRM^Yes")), '1 0 0')); - e.onClick = Handle_StartDemo_Click; - e.onClickEntity = demolist; - me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("DMCNFRM^No")), '0 1 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc new file mode 100644 index 000000000..a5a97c550 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc @@ -0,0 +1,31 @@ +#ifdef INTERFACE +CLASS(XonoticDemoStartConfirmDialog) EXTENDS(XonoticDialog) + METHOD(XonoticDemoStartConfirmDialog, fill, void(entity)) + ATTRIB(XonoticDemoStartConfirmDialog, title, string, _("Disconnect")) + ATTRIB(XonoticDemoStartConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) + ATTRIB(XonoticDemoStartConfirmDialog, intendedWidth, float, 0.5) + ATTRIB(XonoticDemoStartConfirmDialog, rows, float, 4) + ATTRIB(XonoticDemoStartConfirmDialog, columns, float, 2) +ENDCLASS(XonoticDemoStartConfirmDialog) +#endif + +#ifdef IMPLEMENTATION +void Handle_StartDemo_Click(entity unused, entity me) { demolist.startDemo(demolist); } +void XonoticDemoStartConfirmDialog_fill(entity me) +{ + entity e; + + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Playing a demo will disconnect you from the current match."))); + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Do you really wish to disconnect now?"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("DMCNFRM^Yes")), '1 0 0')); + e.onClick = Handle_StartDemo_Click; + e.onClickEntity = demolist; + me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("DMCNFRM^No")), '0 1 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.c b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.c deleted file mode 100644 index 5510710c2..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.c +++ /dev/null @@ -1,31 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticDemoTimeConfirmDialog) EXTENDS(XonoticDialog) - METHOD(XonoticDemoTimeConfirmDialog, fill, void(entity)) - ATTRIB(XonoticDemoTimeConfirmDialog, title, string, _("Disconnect")) - ATTRIB(XonoticDemoTimeConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) - ATTRIB(XonoticDemoTimeConfirmDialog, intendedWidth, float, 0.5) - ATTRIB(XonoticDemoTimeConfirmDialog, rows, float, 4) - ATTRIB(XonoticDemoTimeConfirmDialog, columns, float, 2) -ENDCLASS(XonoticDemoTimeConfirmDialog) -#endif - -#ifdef IMPLEMENTATION -void Handle_TimeDemo_Click(entity unused, entity unused) { demolist.timeDemo(demolist); } -void XonoticDemoTimeConfirmDialog_fill(entity me) -{ - entity e; - - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Timing a demo will disconnect you from the current match."))); - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Do you really wish to disconnect now?"))); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("DMCNFRM^Yes")), '1 0 0')); - e.onClick = Handle_TimeDemo_Click; - e.onClickEntity = demolist; - me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("DMCNFRM^No")), '0 1 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc new file mode 100644 index 000000000..5510710c2 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc @@ -0,0 +1,31 @@ +#ifdef INTERFACE +CLASS(XonoticDemoTimeConfirmDialog) EXTENDS(XonoticDialog) + METHOD(XonoticDemoTimeConfirmDialog, fill, void(entity)) + ATTRIB(XonoticDemoTimeConfirmDialog, title, string, _("Disconnect")) + ATTRIB(XonoticDemoTimeConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) + ATTRIB(XonoticDemoTimeConfirmDialog, intendedWidth, float, 0.5) + ATTRIB(XonoticDemoTimeConfirmDialog, rows, float, 4) + ATTRIB(XonoticDemoTimeConfirmDialog, columns, float, 2) +ENDCLASS(XonoticDemoTimeConfirmDialog) +#endif + +#ifdef IMPLEMENTATION +void Handle_TimeDemo_Click(entity unused, entity unused) { demolist.timeDemo(demolist); } +void XonoticDemoTimeConfirmDialog_fill(entity me) +{ + entity e; + + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Timing a demo will disconnect you from the current match."))); + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Do you really wish to disconnect now?"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("DMCNFRM^Yes")), '1 0 0')); + e.onClick = Handle_TimeDemo_Click; + e.onClickEntity = demolist; + me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("DMCNFRM^No")), '0 1 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.c b/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.c deleted file mode 100644 index 0b7e4231c..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.c +++ /dev/null @@ -1,87 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticMusicPlayerTab) EXTENDS(XonoticTab) - METHOD(XonoticMusicPlayerTab, fill, void(entity)) - ATTRIB(XonoticMusicPlayerTab, title, string, _("Music")) - ATTRIB(XonoticMusicPlayerTab, intendedWidth, float, 0.9) - ATTRIB(XonoticMusicPlayerTab, rows, float, 21) - ATTRIB(XonoticMusicPlayerTab, columns, float, 6.5) - ATTRIB(XonoticMusicPlayerTab, name, string, "MusicPlayer") -ENDCLASS(XonoticMusicPlayerTab) -entity makeXonoticMusicPlayerTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticMusicPlayerTab() -{ - entity me; - me = spawnXonoticMusicPlayerTab(); - me.configureDialog(me); - return me; -} -void XonoticMusicPlayerTab_fill(entity me) -{ - entity e; - entity soundList, playList; - float columns_nospacing = (me.columns - 0.2); - - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticTextLabel(0, _("Filter:"))); - me.TD(me, 1, 2.5, e = makeXonoticInputBox(0, string_null)); - soundList = makeXonoticSoundList(); - e.onChange = SoundList_Filter_Change; - e.onChangeEntity = soundList; - soundList.controlledTextbox = e; - playList = makeXonoticPlayList(); - soundList.playlist = playList; - - me.TR(me); - me.TD(me, me.rows - 4, columns_nospacing / 2, soundList); - - me.gotoRC(me, me.rows - 3, 0); - me.TD(me, 1, columns_nospacing / 4, e = makeXonoticButton(ZCTX(_("MUSICPL^Add")), '0 0 0')); - e.onClick = SoundList_Add; - e.onClickEntity = soundList; - me.TD(me, 1, columns_nospacing / 4, e = makeXonoticButton(ZCTX(_("MUSICPL^Add all")), '0 0 0')); - e.onClick = SoundList_Add_All; - e.onClickEntity = soundList; - me.TR(me); - me.TD(me, 1, columns_nospacing / 2, e = makeXonoticButton(_("Set as menu track"), '0 0 0')); - e.onClick = SoundList_Menu_Track_Change; - e.onClickEntity = soundList; - me.TR(me); - me.TD(me, 1, columns_nospacing / 2, e = makeXonoticButton(_("Reset default menu track"), '0 0 0')); - e.onClick = SoundList_Menu_Track_Reset; - e.onClickEntity = soundList; - me.TR(me); - me.TR(me); - me.gotoRC(me, 0, columns_nospacing / 2 + 0.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, columns_nospacing / 4, e = makeXonoticTextLabel(0, _("Playlist:"))); - me.TD(me, 1, columns_nospacing / 4, e = makeXonoticCheckBox(0, "music_playlist_random0", _("Random order"))); - me.TR(me); - me.TD(me, me.rows - 3, columns_nospacing / 2, playList); - - me.gotoRC(me, me.rows - 2, columns_nospacing / 2 + 0.2); - me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Stop")), '0 0 0')); - e.onClick = StopSound_Click; - e.onClickEntity = playList; - me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Play")), '0 0 0')); - e.onClick = StartSound_Click; - e.onClickEntity = playList; - me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Pause")), '0 0 0')); - e.onClick = PauseSound_Click; - e.onClickEntity = playList; - me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Prev")), '0 0 0')); - e.onClick = PrevSound_Click; - e.onClickEntity = playList; - me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Next")), '0 0 0')); - e.onClick = NextSound_Click; - e.onClickEntity = playList; - me.TR(me); - me.TD(me, 1, columns_nospacing / 4, e = makeXonoticButton(ZCTX(_("MUSICPL^Remove")), '0 0 0')); - e.onClick = PlayList_Remove; - e.onClickEntity = playList; - me.TD(me, 1, columns_nospacing / 4, e = makeXonoticButton(ZCTX(_("MUSICPL^Remove all")), '0 0 0')); - e.onClick = PlayList_Remove_All; - e.onClickEntity = playList; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc new file mode 100644 index 000000000..0b7e4231c --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc @@ -0,0 +1,87 @@ +#ifdef INTERFACE +CLASS(XonoticMusicPlayerTab) EXTENDS(XonoticTab) + METHOD(XonoticMusicPlayerTab, fill, void(entity)) + ATTRIB(XonoticMusicPlayerTab, title, string, _("Music")) + ATTRIB(XonoticMusicPlayerTab, intendedWidth, float, 0.9) + ATTRIB(XonoticMusicPlayerTab, rows, float, 21) + ATTRIB(XonoticMusicPlayerTab, columns, float, 6.5) + ATTRIB(XonoticMusicPlayerTab, name, string, "MusicPlayer") +ENDCLASS(XonoticMusicPlayerTab) +entity makeXonoticMusicPlayerTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticMusicPlayerTab() +{ + entity me; + me = spawnXonoticMusicPlayerTab(); + me.configureDialog(me); + return me; +} +void XonoticMusicPlayerTab_fill(entity me) +{ + entity e; + entity soundList, playList; + float columns_nospacing = (me.columns - 0.2); + + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticTextLabel(0, _("Filter:"))); + me.TD(me, 1, 2.5, e = makeXonoticInputBox(0, string_null)); + soundList = makeXonoticSoundList(); + e.onChange = SoundList_Filter_Change; + e.onChangeEntity = soundList; + soundList.controlledTextbox = e; + playList = makeXonoticPlayList(); + soundList.playlist = playList; + + me.TR(me); + me.TD(me, me.rows - 4, columns_nospacing / 2, soundList); + + me.gotoRC(me, me.rows - 3, 0); + me.TD(me, 1, columns_nospacing / 4, e = makeXonoticButton(ZCTX(_("MUSICPL^Add")), '0 0 0')); + e.onClick = SoundList_Add; + e.onClickEntity = soundList; + me.TD(me, 1, columns_nospacing / 4, e = makeXonoticButton(ZCTX(_("MUSICPL^Add all")), '0 0 0')); + e.onClick = SoundList_Add_All; + e.onClickEntity = soundList; + me.TR(me); + me.TD(me, 1, columns_nospacing / 2, e = makeXonoticButton(_("Set as menu track"), '0 0 0')); + e.onClick = SoundList_Menu_Track_Change; + e.onClickEntity = soundList; + me.TR(me); + me.TD(me, 1, columns_nospacing / 2, e = makeXonoticButton(_("Reset default menu track"), '0 0 0')); + e.onClick = SoundList_Menu_Track_Reset; + e.onClickEntity = soundList; + me.TR(me); + me.TR(me); + me.gotoRC(me, 0, columns_nospacing / 2 + 0.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, columns_nospacing / 4, e = makeXonoticTextLabel(0, _("Playlist:"))); + me.TD(me, 1, columns_nospacing / 4, e = makeXonoticCheckBox(0, "music_playlist_random0", _("Random order"))); + me.TR(me); + me.TD(me, me.rows - 3, columns_nospacing / 2, playList); + + me.gotoRC(me, me.rows - 2, columns_nospacing / 2 + 0.2); + me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Stop")), '0 0 0')); + e.onClick = StopSound_Click; + e.onClickEntity = playList; + me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Play")), '0 0 0')); + e.onClick = StartSound_Click; + e.onClickEntity = playList; + me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Pause")), '0 0 0')); + e.onClick = PauseSound_Click; + e.onClickEntity = playList; + me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Prev")), '0 0 0')); + e.onClick = PrevSound_Click; + e.onClickEntity = playList; + me.TD(me, 1, columns_nospacing / 10, e = makeXonoticButton(ZCTX(_("MUSICPL^Next")), '0 0 0')); + e.onClick = NextSound_Click; + e.onClickEntity = playList; + me.TR(me); + me.TD(me, 1, columns_nospacing / 4, e = makeXonoticButton(ZCTX(_("MUSICPL^Remove")), '0 0 0')); + e.onClick = PlayList_Remove; + e.onClickEntity = playList; + me.TD(me, 1, columns_nospacing / 4, e = makeXonoticButton(ZCTX(_("MUSICPL^Remove all")), '0 0 0')); + e.onClick = PlayList_Remove_All; + e.onClickEntity = playList; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.c b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.c deleted file mode 100644 index 6132719db..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.c +++ /dev/null @@ -1,82 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticScreenshotBrowserTab) EXTENDS(XonoticTab) - METHOD(XonoticScreenshotBrowserTab, fill, void(entity)) - ATTRIB(XonoticScreenshotBrowserTab, title, string, "Screenshot") - ATTRIB(XonoticScreenshotBrowserTab, intendedWidth, float, 1) - ATTRIB(XonoticScreenshotBrowserTab, rows, float, 21) - ATTRIB(XonoticScreenshotBrowserTab, columns, float, 6.5) - ATTRIB(XonoticScreenshotBrowserTab, name, string, "ScreenshotBrowser") - - METHOD(XonoticScreenshotBrowserTab, loadPreviewScreenshot, void(entity, string)) - ATTRIB(XonoticScreenshotBrowserTab, screenshotImage, entity, NULL) - ATTRIB(XonoticScreenshotBrowserTab, currentScrPath, string, string_null) -ENDCLASS(XonoticScreenshotBrowserTab) -entity makeXonoticScreenshotBrowserTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticScreenshotBrowserTab() -{ - entity me; - me = spawnXonoticScreenshotBrowserTab(); - me.configureDialog(me); - return me; -} -void XonoticScreenshotBrowserTab_loadPreviewScreenshot(entity me, string scrImage) -{ - if (me.currentScrPath == scrImage) - return; - if (me.currentScrPath) - strunzone(me.currentScrPath); - me.currentScrPath = strzone(scrImage); - me.screenshotImage.load(me.screenshotImage, me.currentScrPath); -} -void XonoticScreenshotBrowserTab_fill(entity me) -{ - entity e, slist; - slist = makeXonoticScreenshotList(); - float slist_height = me.rows - 2; - - - me.TR(me); - me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:"))); - me.TD(me, 1, 2.4, e = makeXonoticInputBox(0, string_null)); - e.onChange = ScreenshotList_Filter_Would_Change; - e.onChangeEntity = slist; - slist.screenshotViewerDialog = main.screenshotViewerDialog; - main.screenshotViewerDialog.scrList = slist; - - me.gotoRC(me, 0, 3.1); - me.TD(me, 1, 1.9, e = makeXonoticCheckBoxEx(2, 1, "cl_autoscreenshot", _("Auto screenshot scoreboard"))); - me.TD(me, 1, 1, e = makeXonoticButton(_("Refresh"), '0 0 0')); - e.onClick = ScreenshotList_Refresh_Click; - e.onClickEntity = slist; - - /*me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticTextLabel(0, "Filter:")); - me.TD(me, 1, me.columns - 1.5, e = makeXonoticInputBox(0, string_null)); - e.onChange = ScreenshotList_Filter_Would_Change; - e.onChangeEntity = slist; - slist.screenshotViewerDialog = main.screenshotViewerDialog; - main.screenshotViewerDialog.scrList = slist; - me.TD(me, 1, 1, e = makeXonoticButton(_("Refresh"), '0 0 0')); - e.onClick = ScreenshotList_Refresh_Click; - e.onClickEntity = slist;*/ - - me.gotoRC(me, 1.5, 0); - me.TD(me, me.rows - 2.5, me.columns, slist); - - me.gotoRC(me, slist_height + 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("Open in the viewer"), '0 0 0')); - e.onClick = StartScreenshot_Click; - e.onClickEntity = slist; -/* - me.TR(me); - me.TD(me, me.rows - me.currentRow, me.columns, e = makeXonoticScreenshotImage()); - e.showTitle = 0; - me.screenshotImage = e; - slist.screenshotPreview = e; - slist.screenshotBrowserDialog = me; -*/ -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc new file mode 100644 index 000000000..6132719db --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc @@ -0,0 +1,82 @@ +#ifdef INTERFACE +CLASS(XonoticScreenshotBrowserTab) EXTENDS(XonoticTab) + METHOD(XonoticScreenshotBrowserTab, fill, void(entity)) + ATTRIB(XonoticScreenshotBrowserTab, title, string, "Screenshot") + ATTRIB(XonoticScreenshotBrowserTab, intendedWidth, float, 1) + ATTRIB(XonoticScreenshotBrowserTab, rows, float, 21) + ATTRIB(XonoticScreenshotBrowserTab, columns, float, 6.5) + ATTRIB(XonoticScreenshotBrowserTab, name, string, "ScreenshotBrowser") + + METHOD(XonoticScreenshotBrowserTab, loadPreviewScreenshot, void(entity, string)) + ATTRIB(XonoticScreenshotBrowserTab, screenshotImage, entity, NULL) + ATTRIB(XonoticScreenshotBrowserTab, currentScrPath, string, string_null) +ENDCLASS(XonoticScreenshotBrowserTab) +entity makeXonoticScreenshotBrowserTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticScreenshotBrowserTab() +{ + entity me; + me = spawnXonoticScreenshotBrowserTab(); + me.configureDialog(me); + return me; +} +void XonoticScreenshotBrowserTab_loadPreviewScreenshot(entity me, string scrImage) +{ + if (me.currentScrPath == scrImage) + return; + if (me.currentScrPath) + strunzone(me.currentScrPath); + me.currentScrPath = strzone(scrImage); + me.screenshotImage.load(me.screenshotImage, me.currentScrPath); +} +void XonoticScreenshotBrowserTab_fill(entity me) +{ + entity e, slist; + slist = makeXonoticScreenshotList(); + float slist_height = me.rows - 2; + + + me.TR(me); + me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:"))); + me.TD(me, 1, 2.4, e = makeXonoticInputBox(0, string_null)); + e.onChange = ScreenshotList_Filter_Would_Change; + e.onChangeEntity = slist; + slist.screenshotViewerDialog = main.screenshotViewerDialog; + main.screenshotViewerDialog.scrList = slist; + + me.gotoRC(me, 0, 3.1); + me.TD(me, 1, 1.9, e = makeXonoticCheckBoxEx(2, 1, "cl_autoscreenshot", _("Auto screenshot scoreboard"))); + me.TD(me, 1, 1, e = makeXonoticButton(_("Refresh"), '0 0 0')); + e.onClick = ScreenshotList_Refresh_Click; + e.onClickEntity = slist; + + /*me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticTextLabel(0, "Filter:")); + me.TD(me, 1, me.columns - 1.5, e = makeXonoticInputBox(0, string_null)); + e.onChange = ScreenshotList_Filter_Would_Change; + e.onChangeEntity = slist; + slist.screenshotViewerDialog = main.screenshotViewerDialog; + main.screenshotViewerDialog.scrList = slist; + me.TD(me, 1, 1, e = makeXonoticButton(_("Refresh"), '0 0 0')); + e.onClick = ScreenshotList_Refresh_Click; + e.onClickEntity = slist;*/ + + me.gotoRC(me, 1.5, 0); + me.TD(me, me.rows - 2.5, me.columns, slist); + + me.gotoRC(me, slist_height + 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("Open in the viewer"), '0 0 0')); + e.onClick = StartScreenshot_Click; + e.onClickEntity = slist; +/* + me.TR(me); + me.TD(me, me.rows - me.currentRow, me.columns, e = makeXonoticScreenshotImage()); + e.showTitle = 0; + me.screenshotImage = e; + slist.screenshotPreview = e; + slist.screenshotBrowserDialog = me; +*/ +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.c b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.c deleted file mode 100644 index 146f496be..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.c +++ /dev/null @@ -1,171 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticScreenshotViewerDialog) EXTENDS(XonoticDialog) - METHOD(XonoticScreenshotViewerDialog, fill, void(entity)) - METHOD(XonoticScreenshotViewerDialog, keyDown, float(entity, float, float, float)) - METHOD(XonoticScreenshotViewerDialog, loadScreenshot, void(entity, string)) - METHOD(XonoticScreenshotViewerDialog, close, void(entity)) - ATTRIB(XonoticScreenshotViewerDialog, title, string, "Screenshot Viewer") - ATTRIB(XonoticScreenshotViewerDialog, name, string, "ScreenshotViewer") - ATTRIB(XonoticScreenshotViewerDialog, intendedWidth, float, 1) - ATTRIB(XonoticScreenshotViewerDialog, rows, float, 25) - ATTRIB(XonoticScreenshotViewerDialog, columns, float, 4) - ATTRIB(XonoticScreenshotViewerDialog, color, vector, SKINCOLOR_DIALOG_SCREENSHOTVIEWER) - ATTRIB(XonoticScreenshotViewerDialog, scrList, entity, NULL) - ATTRIB(XonoticScreenshotViewerDialog, screenshotImage, entity, NULL) - ATTRIB(XonoticScreenshotViewerDialog, slideShowButton, entity, NULL) - ATTRIB(XonoticScreenshotViewerDialog, currentScrPath, string, string_null) -ENDCLASS(XonoticScreenshotViewerDialog) -#endif - -#ifdef IMPLEMENTATION -float music_playlist_index_backup; -void XonoticScreenshotViewerDialog_loadScreenshot(entity me, string scrImage) -{ - // disable music as it can lag depending on image loading time - if(!cvar("menu_screenshotviewer_enablemusic")) - if(cvar("music_playlist_index") != 999) // if the playlist isn't paused - { - // pause music - if(cvar("music_playlist_index") != -1) - { - music_playlist_index_backup = cvar("music_playlist_index"); - cvar_set("music_playlist_sampleposition0", "0"); - cvar_set("music_playlist_index", "999"); - } - else - localcmd("\ncd pause\n"); - } - - if (me.currentScrPath == scrImage) - return; - if (me.currentScrPath) - strunzone(me.currentScrPath); - me.currentScrPath = strzone(scrImage); - me.screenshotImage.load(me.screenshotImage, me.currentScrPath); - me.frame.setText(me.frame, me.screenshotImage.screenshotTitle); -} -void prevScreenshot_Click(entity btn, entity me) -{ - me.scrList.goScreenshot(me.scrList, -1); -} -void nextScreenshot_Click(entity btn, entity me) -{ - me.scrList.goScreenshot(me.scrList, +1); -} -void increaseZoom_Click(entity btn, entity me) -{ - me.screenshotImage.setZoom(me.screenshotImage, -2, FALSE); -} -void decreaseZoom_Click(entity btn, entity me) -{ - me.screenshotImage.setZoom(me.screenshotImage, -1/2, FALSE); -} -void resetZoom_Click(entity btn, entity me) -{ - me.screenshotImage.setZoom(me.screenshotImage, 0, FALSE); -} -void toggleSlideShow_Click(entity btn, entity me) -{ - if (me.slideShowButton.forcePressed) - { - me.scrList.stopSlideShow(me.scrList); - me.slideShowButton.forcePressed = 0; - } - else - { - me.scrList.startSlideShow(me.scrList); - me.slideShowButton.forcePressed = 1; - } -} -float XonoticScreenshotViewerDialog_keyDown(entity me, float key, float ascii, float shift) -{ - switch(key) - { - case K_KP_LEFTARROW: - case K_LEFTARROW: - me.scrList.goScreenshot(me.scrList, -1); - return 1; - case K_KP_RIGHTARROW: - case K_RIGHTARROW: - me.scrList.goScreenshot(me.scrList, +1); - return 1; - case K_KP_ENTER: - case K_ENTER: - case K_SPACE: - // we cannot use SPACE/ENTER directly, as in a dialog they are needed - // to press buttons while browsing with only the keyboard - if (shift & S_CTRL) - { - toggleSlideShow_Click(world, me); - return 1; - } - return SUPER(XonoticScreenshotViewerDialog).keyDown(me, key, ascii, shift); - default: - if (key == K_MWHEELUP || ascii == '+') - { - me.screenshotImage.setZoom(me.screenshotImage, -2, (key == K_MWHEELUP)); - return 1; - } - else if (key == K_MWHEELDOWN || ascii == '-') - { - me.screenshotImage.setZoom(me.screenshotImage, -1/2, (key == K_MWHEELDOWN)); - return 1; - } - if (me.scrList.keyDown(me.scrList, key, ascii, shift)) - { - // keyDown has already changed the selected item - me.scrList.goScreenshot(me.scrList, 0); - return 1; - } - return SUPER(XonoticScreenshotViewerDialog).keyDown(me, key, ascii, shift); - } -} -void XonoticScreenshotViewerDialog_close(entity me) -{ - // resume music - if(!cvar("menu_screenshotviewer_enablemusic")) - if(cvar("music_playlist_index") == 999) - { - cvar_set("music_playlist_index", ftos(music_playlist_index_backup)); - } - else - localcmd("\ncd resume\n"); - - me.scrList.stopSlideShow(me.scrList); - me.slideShowButton.forcePressed = 0; - SUPER(XonoticScreenshotViewerDialog).close(me); -} -void XonoticScreenshotViewerDialog_fill(entity me) -{ - entity e; - me.TR(me); - me.TD(me, me.rows - 1, me.columns, e = makeXonoticScreenshotImage()); - e.showTitle = 0; // dialog title is enough - me.screenshotImage = e; - me.gotoRC(me, me.rows - 1, 0); - me.TDempty(me, 1/20 * me.columns); - me.TD(me, 1, 1/20 * me.columns, e = makeXonoticButton("-", '0 0 0')); - e.onClick = decreaseZoom_Click; - e.onClickEntity = me; - me.TD(me, 1, 1/20 * me.columns, e = makeXonoticButton("+", '0 0 0')); - e.onClick = increaseZoom_Click; - e.onClickEntity = me; - me.TD(me, 1, 2/20 * me.columns, e = makeXonoticButton(_("Reset"), '0 0 0')); - e.onClick = resetZoom_Click; - e.onClickEntity = me; - - me.TDempty(me, 2/20 * me.columns); - me.TD(me, 1, 3/20 * me.columns, e = makeXonoticButton(_("Previous"), '0 0 0')); - e.onClick = prevScreenshot_Click; - e.onClickEntity = me; - me.TD(me, 1, 3/20 * me.columns, e = makeXonoticButton(_("Next"), '0 0 0')); - e.onClick = nextScreenshot_Click; - e.onClickEntity = me; - - me.TDempty(me, 2/20 * me.columns); - me.TD(me, 1, 4/20 * me.columns, e = makeXonoticButton(_("Slide show"), '0 0 0')); - e.onClick = toggleSlideShow_Click; - e.onClickEntity = me; - me.slideShowButton = e; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc new file mode 100644 index 000000000..146f496be --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc @@ -0,0 +1,171 @@ +#ifdef INTERFACE +CLASS(XonoticScreenshotViewerDialog) EXTENDS(XonoticDialog) + METHOD(XonoticScreenshotViewerDialog, fill, void(entity)) + METHOD(XonoticScreenshotViewerDialog, keyDown, float(entity, float, float, float)) + METHOD(XonoticScreenshotViewerDialog, loadScreenshot, void(entity, string)) + METHOD(XonoticScreenshotViewerDialog, close, void(entity)) + ATTRIB(XonoticScreenshotViewerDialog, title, string, "Screenshot Viewer") + ATTRIB(XonoticScreenshotViewerDialog, name, string, "ScreenshotViewer") + ATTRIB(XonoticScreenshotViewerDialog, intendedWidth, float, 1) + ATTRIB(XonoticScreenshotViewerDialog, rows, float, 25) + ATTRIB(XonoticScreenshotViewerDialog, columns, float, 4) + ATTRIB(XonoticScreenshotViewerDialog, color, vector, SKINCOLOR_DIALOG_SCREENSHOTVIEWER) + ATTRIB(XonoticScreenshotViewerDialog, scrList, entity, NULL) + ATTRIB(XonoticScreenshotViewerDialog, screenshotImage, entity, NULL) + ATTRIB(XonoticScreenshotViewerDialog, slideShowButton, entity, NULL) + ATTRIB(XonoticScreenshotViewerDialog, currentScrPath, string, string_null) +ENDCLASS(XonoticScreenshotViewerDialog) +#endif + +#ifdef IMPLEMENTATION +float music_playlist_index_backup; +void XonoticScreenshotViewerDialog_loadScreenshot(entity me, string scrImage) +{ + // disable music as it can lag depending on image loading time + if(!cvar("menu_screenshotviewer_enablemusic")) + if(cvar("music_playlist_index") != 999) // if the playlist isn't paused + { + // pause music + if(cvar("music_playlist_index") != -1) + { + music_playlist_index_backup = cvar("music_playlist_index"); + cvar_set("music_playlist_sampleposition0", "0"); + cvar_set("music_playlist_index", "999"); + } + else + localcmd("\ncd pause\n"); + } + + if (me.currentScrPath == scrImage) + return; + if (me.currentScrPath) + strunzone(me.currentScrPath); + me.currentScrPath = strzone(scrImage); + me.screenshotImage.load(me.screenshotImage, me.currentScrPath); + me.frame.setText(me.frame, me.screenshotImage.screenshotTitle); +} +void prevScreenshot_Click(entity btn, entity me) +{ + me.scrList.goScreenshot(me.scrList, -1); +} +void nextScreenshot_Click(entity btn, entity me) +{ + me.scrList.goScreenshot(me.scrList, +1); +} +void increaseZoom_Click(entity btn, entity me) +{ + me.screenshotImage.setZoom(me.screenshotImage, -2, FALSE); +} +void decreaseZoom_Click(entity btn, entity me) +{ + me.screenshotImage.setZoom(me.screenshotImage, -1/2, FALSE); +} +void resetZoom_Click(entity btn, entity me) +{ + me.screenshotImage.setZoom(me.screenshotImage, 0, FALSE); +} +void toggleSlideShow_Click(entity btn, entity me) +{ + if (me.slideShowButton.forcePressed) + { + me.scrList.stopSlideShow(me.scrList); + me.slideShowButton.forcePressed = 0; + } + else + { + me.scrList.startSlideShow(me.scrList); + me.slideShowButton.forcePressed = 1; + } +} +float XonoticScreenshotViewerDialog_keyDown(entity me, float key, float ascii, float shift) +{ + switch(key) + { + case K_KP_LEFTARROW: + case K_LEFTARROW: + me.scrList.goScreenshot(me.scrList, -1); + return 1; + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + me.scrList.goScreenshot(me.scrList, +1); + return 1; + case K_KP_ENTER: + case K_ENTER: + case K_SPACE: + // we cannot use SPACE/ENTER directly, as in a dialog they are needed + // to press buttons while browsing with only the keyboard + if (shift & S_CTRL) + { + toggleSlideShow_Click(world, me); + return 1; + } + return SUPER(XonoticScreenshotViewerDialog).keyDown(me, key, ascii, shift); + default: + if (key == K_MWHEELUP || ascii == '+') + { + me.screenshotImage.setZoom(me.screenshotImage, -2, (key == K_MWHEELUP)); + return 1; + } + else if (key == K_MWHEELDOWN || ascii == '-') + { + me.screenshotImage.setZoom(me.screenshotImage, -1/2, (key == K_MWHEELDOWN)); + return 1; + } + if (me.scrList.keyDown(me.scrList, key, ascii, shift)) + { + // keyDown has already changed the selected item + me.scrList.goScreenshot(me.scrList, 0); + return 1; + } + return SUPER(XonoticScreenshotViewerDialog).keyDown(me, key, ascii, shift); + } +} +void XonoticScreenshotViewerDialog_close(entity me) +{ + // resume music + if(!cvar("menu_screenshotviewer_enablemusic")) + if(cvar("music_playlist_index") == 999) + { + cvar_set("music_playlist_index", ftos(music_playlist_index_backup)); + } + else + localcmd("\ncd resume\n"); + + me.scrList.stopSlideShow(me.scrList); + me.slideShowButton.forcePressed = 0; + SUPER(XonoticScreenshotViewerDialog).close(me); +} +void XonoticScreenshotViewerDialog_fill(entity me) +{ + entity e; + me.TR(me); + me.TD(me, me.rows - 1, me.columns, e = makeXonoticScreenshotImage()); + e.showTitle = 0; // dialog title is enough + me.screenshotImage = e; + me.gotoRC(me, me.rows - 1, 0); + me.TDempty(me, 1/20 * me.columns); + me.TD(me, 1, 1/20 * me.columns, e = makeXonoticButton("-", '0 0 0')); + e.onClick = decreaseZoom_Click; + e.onClickEntity = me; + me.TD(me, 1, 1/20 * me.columns, e = makeXonoticButton("+", '0 0 0')); + e.onClick = increaseZoom_Click; + e.onClickEntity = me; + me.TD(me, 1, 2/20 * me.columns, e = makeXonoticButton(_("Reset"), '0 0 0')); + e.onClick = resetZoom_Click; + e.onClickEntity = me; + + me.TDempty(me, 2/20 * me.columns); + me.TD(me, 1, 3/20 * me.columns, e = makeXonoticButton(_("Previous"), '0 0 0')); + e.onClick = prevScreenshot_Click; + e.onClickEntity = me; + me.TD(me, 1, 3/20 * me.columns, e = makeXonoticButton(_("Next"), '0 0 0')); + e.onClick = nextScreenshot_Click; + e.onClickEntity = me; + + me.TDempty(me, 2/20 * me.columns); + me.TD(me, 1, 4/20 * me.columns, e = makeXonoticButton(_("Slide show"), '0 0 0')); + e.onClick = toggleSlideShow_Click; + e.onClickEntity = me; + me.slideShowButton = e; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_profile.c b/qcsrc/menu/xonotic/dialog_multiplayer_profile.c deleted file mode 100644 index a316be73b..000000000 --- a/qcsrc/menu/xonotic/dialog_multiplayer_profile.c +++ /dev/null @@ -1,164 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticProfileTab) EXTENDS(XonoticTab) - METHOD(XonoticProfileTab, fill, void(entity)) - METHOD(XonoticProfileTab, draw, void(entity)) - ATTRIB(XonoticProfileTab, title, string, _("Profile")) - ATTRIB(XonoticProfileTab, intendedWidth, float, 0.9) - ATTRIB(XonoticProfileTab, rows, float, 23) - ATTRIB(XonoticProfileTab, columns, float, 6.1) // added extra .2 for center space - ATTRIB(XonoticProfileTab, playerNameLabel, entity, NULL) - ATTRIB(XonoticProfileTab, playerNameLabelAlpha, float, SKINALPHA_HEADER) -ENDCLASS(XonoticProfileTab) -entity makeXonoticProfileTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticProfileTab() -{ - entity me; - me = spawnXonoticProfileTab(); - me.configureDialog(me); - return me; -} -void XonoticProfileTab_draw(entity me) -{ - if(cvar_string("_cl_name") == "Player") - me.playerNameLabel.alpha = ((mod(time * 2, 2) < 1) ? 1 : 0); - else - me.playerNameLabel.alpha = me.playerNameLabelAlpha; - SUPER(XonoticProfileTab).draw(me); -} -void XonoticProfileTab_fill(entity me) -{ - entity e, pms, label, box; - float i; - - // ============== - // NAME SECTION - // ============== - me.gotoRC(me, 0.5, 0); - me.TD(me, 1, 3, me.playerNameLabel = makeXonoticHeaderLabel(_("Name"))); - - me.gotoRC(me, 1.5, 0); - me.TD(me, 1, 3, label = makeXonoticTextLabel(0.5, string_null)); - label.allowCut = 1; - label.allowColors = 1; - label.alpha = 1; - label.isBold = TRUE; - label.fontSize = SKINFONTSIZE_TITLE; - - me.gotoRC(me, 2.5, 0); - me.TD(me, 1, 3.0, box = makeXonoticInputBox(1, "_cl_name")); - box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved - box.maxLength = -127; // negative means encoded length in bytes - box.saveImmediately = 1; - box.enableClearButton = 0; - label.textEntity = box; - me.TR(me); - me.TD(me, 5, 1, e = makeXonoticColorpicker(box)); - me.TD(me, 5, 2, e = makeXonoticCharmap(box)); - - // =============== - // MODEL SECTION - // =============== - //me.gotoRC(me, 0.5, 3.1); me.setFirstColumn(me, me.currentColumn); // TOP RIGHT - //me.gotoRC(me, 9, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM RIGHT - me.gotoRC(me, 9, 0); me.setFirstColumn(me, me.currentColumn); // BOTTOM LEFT - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Model"))); - - me.TR(me); - //me.TDempty(me, 0); // MODEL LEFT, COLOR RIGHT - me.TDempty(me, 1); // MODEL RIGHT, COLOR LEFT - pms = makeXonoticPlayerModelSelector(); - me.TD(me, 1, 0.3, e = makeXonoticButton("<<", '0 0 0')); - e.onClick = PlayerModelSelector_Prev_Click; - e.onClickEntity = pms; - me.TD(me, 11.5, 1.4, pms); - me.TD(me, 1, 0.3, e = makeXonoticButton(">>", '0 0 0')); - e.onClick = PlayerModelSelector_Next_Click; - e.onClickEntity = pms; - - //me.setFirstColumn(me, me.currentColumn + 2); // MODEL LEFT, COLOR RIGHT - me.gotoRC(me, me.currentRow, 0); me.setFirstColumn(me, me.currentColumn); // MODEL RIGHT, COLOR LEFT - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticHeaderLabel(_("Glowing color"))); - for(i = 0; i < 15; ++i) - { - if(mod(i, 5) == 0) - me.TR(me); - me.TDNoMargin(me, 1, 0.2, e = makeXonoticColorButton(1, 0, i), '0 1 0'); - } - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticHeaderLabel(_("Detail color"))); - for(i = 0; i < 15; ++i) - { - if(mod(i, 5) == 0) - me.TR(me); - me.TDNoMargin(me, 1, 0.2, e = makeXonoticColorButton(2, 1, i), '0 1 0'); - } - - // ==================== - // STATISTICS SECTION - // ==================== - me.gotoRC(me, 0.5, 3.1); me.setFirstColumn(me, me.currentColumn); // TOP RIGHT - //me.gotoRC(me, 9, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM RIGHT - //me.gotoRC(me, 9, 0); me.setFirstColumn(me, me.currentColumn); // BOTTOM LEFT - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Statistics"))); - - me.TR(me); - me.TDempty(me, 0.25); - me.TD(me, 1, 2.5, e = makeXonoticCheckBox(0, "cl_allow_uidtracking", _("Allow player statistics to track your client"))); - me.TR(me); - me.TDempty(me, 0.25); - me.TD(me, 1, 2.5, e = makeXonoticCheckBox(0, "cl_allow_uid2name", _("Allow player statistics to use your nickname"))); - setDependent(e, "cl_allow_uidtracking", 1, 1); - me.gotoRC(me, 4, 3.1); // TOP RIGHT - //me.gotoRC(me, 12.5, 3.1); // BOTTOM RIGHT - //me.gotoRC(me, 12.5, 0); // BOTTOM LEFT - me.TDempty(me, 0.25); - me.TD(me, 9, 2.5, statslist = makeXonoticStatsList()); - //setDependent(statslist, "cl_allow_uidtracking", 1, 1); - - // ================= - // COUNTRY SECTION - // ================= - me.gotoRC(me, 16, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM SECTION, TOP POS - //me.gotoRC(me, 13.5, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM SECTION, TOP POS - //me.gotoRC(me, 0.5, 3.1); me.setFirstColumn(me, me.currentColumn); // TOP SECTION, TOP POS - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Country"))); - - me.TR(me); - me.TDempty(me, 0.5); - me.TD(me, 4.5, 2, e = makeXonoticLanguageList()); // todo: cl_country: create proper country list - - - // ================ - // GENDER SECTION - // ================ - me.gotoRC(me, 13.5, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM SECTION, TOP POS - //me.gotoRC(me, 19.5, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM SECTION, BOTTOM POS - //me.gotoRC(me, 6.5, 3.1); me.setFirstColumn(me, me.currentColumn); // TOP SECTION, BOTTOM POS - #if 0 - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Gender:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_gender")); - e.addValue(e, ZCTX(_("GENDER^Undisclosed")), "0"); - e.addValue(e, ZCTX(_("GENDER^Female")), "1"); - e.addValue(e, ZCTX(_("GENDER^Male")), "2"); - e.configureXonoticTextSliderValues(e); - #else - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Gender"))); - me.TR(me); - #define GENDERWIDTH_OFFSET 0.25 - #define GENDERWIDTH_LENGTH 2.5 - #define GENDERWIDTH_ITEM (GENDERWIDTH_LENGTH / 3) - me.TDempty(me, GENDERWIDTH_OFFSET); - me.TD(me, 1, GENDERWIDTH_ITEM, e = makeXonoticRadioButton(3, "cl_gender", "2", _("Female"))); - me.TD(me, 1, GENDERWIDTH_ITEM, e = makeXonoticRadioButton(3, "cl_gender", "1", _("Male"))); - me.TD(me, 1, GENDERWIDTH_ITEM, e = makeXonoticRadioButton(3, "cl_gender", "0", _("Undisclosed"))); - #endif - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "color -1 -1;name \"$_cl_name\";sendcvar cl_weaponpriority;sendcvar cl_autoswitch;sendcvar cl_forceplayermodels;sendcvar cl_forceplayermodelsfromxonotic;playermodel $_cl_playermodel;playerskin $_cl_playerskin", COMMANDBUTTON_APPLY)); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc b/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc new file mode 100644 index 000000000..a316be73b --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc @@ -0,0 +1,164 @@ +#ifdef INTERFACE +CLASS(XonoticProfileTab) EXTENDS(XonoticTab) + METHOD(XonoticProfileTab, fill, void(entity)) + METHOD(XonoticProfileTab, draw, void(entity)) + ATTRIB(XonoticProfileTab, title, string, _("Profile")) + ATTRIB(XonoticProfileTab, intendedWidth, float, 0.9) + ATTRIB(XonoticProfileTab, rows, float, 23) + ATTRIB(XonoticProfileTab, columns, float, 6.1) // added extra .2 for center space + ATTRIB(XonoticProfileTab, playerNameLabel, entity, NULL) + ATTRIB(XonoticProfileTab, playerNameLabelAlpha, float, SKINALPHA_HEADER) +ENDCLASS(XonoticProfileTab) +entity makeXonoticProfileTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticProfileTab() +{ + entity me; + me = spawnXonoticProfileTab(); + me.configureDialog(me); + return me; +} +void XonoticProfileTab_draw(entity me) +{ + if(cvar_string("_cl_name") == "Player") + me.playerNameLabel.alpha = ((mod(time * 2, 2) < 1) ? 1 : 0); + else + me.playerNameLabel.alpha = me.playerNameLabelAlpha; + SUPER(XonoticProfileTab).draw(me); +} +void XonoticProfileTab_fill(entity me) +{ + entity e, pms, label, box; + float i; + + // ============== + // NAME SECTION + // ============== + me.gotoRC(me, 0.5, 0); + me.TD(me, 1, 3, me.playerNameLabel = makeXonoticHeaderLabel(_("Name"))); + + me.gotoRC(me, 1.5, 0); + me.TD(me, 1, 3, label = makeXonoticTextLabel(0.5, string_null)); + label.allowCut = 1; + label.allowColors = 1; + label.alpha = 1; + label.isBold = TRUE; + label.fontSize = SKINFONTSIZE_TITLE; + + me.gotoRC(me, 2.5, 0); + me.TD(me, 1, 3.0, box = makeXonoticInputBox(1, "_cl_name")); + box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved + box.maxLength = -127; // negative means encoded length in bytes + box.saveImmediately = 1; + box.enableClearButton = 0; + label.textEntity = box; + me.TR(me); + me.TD(me, 5, 1, e = makeXonoticColorpicker(box)); + me.TD(me, 5, 2, e = makeXonoticCharmap(box)); + + // =============== + // MODEL SECTION + // =============== + //me.gotoRC(me, 0.5, 3.1); me.setFirstColumn(me, me.currentColumn); // TOP RIGHT + //me.gotoRC(me, 9, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM RIGHT + me.gotoRC(me, 9, 0); me.setFirstColumn(me, me.currentColumn); // BOTTOM LEFT + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Model"))); + + me.TR(me); + //me.TDempty(me, 0); // MODEL LEFT, COLOR RIGHT + me.TDempty(me, 1); // MODEL RIGHT, COLOR LEFT + pms = makeXonoticPlayerModelSelector(); + me.TD(me, 1, 0.3, e = makeXonoticButton("<<", '0 0 0')); + e.onClick = PlayerModelSelector_Prev_Click; + e.onClickEntity = pms; + me.TD(me, 11.5, 1.4, pms); + me.TD(me, 1, 0.3, e = makeXonoticButton(">>", '0 0 0')); + e.onClick = PlayerModelSelector_Next_Click; + e.onClickEntity = pms; + + //me.setFirstColumn(me, me.currentColumn + 2); // MODEL LEFT, COLOR RIGHT + me.gotoRC(me, me.currentRow, 0); me.setFirstColumn(me, me.currentColumn); // MODEL RIGHT, COLOR LEFT + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticHeaderLabel(_("Glowing color"))); + for(i = 0; i < 15; ++i) + { + if(mod(i, 5) == 0) + me.TR(me); + me.TDNoMargin(me, 1, 0.2, e = makeXonoticColorButton(1, 0, i), '0 1 0'); + } + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticHeaderLabel(_("Detail color"))); + for(i = 0; i < 15; ++i) + { + if(mod(i, 5) == 0) + me.TR(me); + me.TDNoMargin(me, 1, 0.2, e = makeXonoticColorButton(2, 1, i), '0 1 0'); + } + + // ==================== + // STATISTICS SECTION + // ==================== + me.gotoRC(me, 0.5, 3.1); me.setFirstColumn(me, me.currentColumn); // TOP RIGHT + //me.gotoRC(me, 9, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM RIGHT + //me.gotoRC(me, 9, 0); me.setFirstColumn(me, me.currentColumn); // BOTTOM LEFT + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Statistics"))); + + me.TR(me); + me.TDempty(me, 0.25); + me.TD(me, 1, 2.5, e = makeXonoticCheckBox(0, "cl_allow_uidtracking", _("Allow player statistics to track your client"))); + me.TR(me); + me.TDempty(me, 0.25); + me.TD(me, 1, 2.5, e = makeXonoticCheckBox(0, "cl_allow_uid2name", _("Allow player statistics to use your nickname"))); + setDependent(e, "cl_allow_uidtracking", 1, 1); + me.gotoRC(me, 4, 3.1); // TOP RIGHT + //me.gotoRC(me, 12.5, 3.1); // BOTTOM RIGHT + //me.gotoRC(me, 12.5, 0); // BOTTOM LEFT + me.TDempty(me, 0.25); + me.TD(me, 9, 2.5, statslist = makeXonoticStatsList()); + //setDependent(statslist, "cl_allow_uidtracking", 1, 1); + + // ================= + // COUNTRY SECTION + // ================= + me.gotoRC(me, 16, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM SECTION, TOP POS + //me.gotoRC(me, 13.5, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM SECTION, TOP POS + //me.gotoRC(me, 0.5, 3.1); me.setFirstColumn(me, me.currentColumn); // TOP SECTION, TOP POS + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Country"))); + + me.TR(me); + me.TDempty(me, 0.5); + me.TD(me, 4.5, 2, e = makeXonoticLanguageList()); // todo: cl_country: create proper country list + + + // ================ + // GENDER SECTION + // ================ + me.gotoRC(me, 13.5, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM SECTION, TOP POS + //me.gotoRC(me, 19.5, 3.1); me.setFirstColumn(me, me.currentColumn); // BOTTOM SECTION, BOTTOM POS + //me.gotoRC(me, 6.5, 3.1); me.setFirstColumn(me, me.currentColumn); // TOP SECTION, BOTTOM POS + #if 0 + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Gender:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_gender")); + e.addValue(e, ZCTX(_("GENDER^Undisclosed")), "0"); + e.addValue(e, ZCTX(_("GENDER^Female")), "1"); + e.addValue(e, ZCTX(_("GENDER^Male")), "2"); + e.configureXonoticTextSliderValues(e); + #else + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Gender"))); + me.TR(me); + #define GENDERWIDTH_OFFSET 0.25 + #define GENDERWIDTH_LENGTH 2.5 + #define GENDERWIDTH_ITEM (GENDERWIDTH_LENGTH / 3) + me.TDempty(me, GENDERWIDTH_OFFSET); + me.TD(me, 1, GENDERWIDTH_ITEM, e = makeXonoticRadioButton(3, "cl_gender", "2", _("Female"))); + me.TD(me, 1, GENDERWIDTH_ITEM, e = makeXonoticRadioButton(3, "cl_gender", "1", _("Male"))); + me.TD(me, 1, GENDERWIDTH_ITEM, e = makeXonoticRadioButton(3, "cl_gender", "0", _("Undisclosed"))); + #endif + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "color -1 -1;name \"$_cl_name\";sendcvar cl_weaponpriority;sendcvar cl_autoswitch;sendcvar cl_forceplayermodels;sendcvar cl_forceplayermodelsfromxonotic;playermodel $_cl_playermodel;playerskin $_cl_playerskin", COMMANDBUTTON_APPLY)); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_quit.c b/qcsrc/menu/xonotic/dialog_quit.c deleted file mode 100644 index 71de59dac..000000000 --- a/qcsrc/menu/xonotic/dialog_quit.c +++ /dev/null @@ -1,26 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticQuitDialog) EXTENDS(XonoticDialog) - METHOD(XonoticQuitDialog, fill, void(entity)) - ATTRIB(XonoticQuitDialog, title, string, _("Quit")) - ATTRIB(XonoticQuitDialog, color, vector, SKINCOLOR_DIALOG_QUIT) - ATTRIB(XonoticQuitDialog, intendedWidth, float, 0.5) - ATTRIB(XonoticQuitDialog, rows, float, 3) - ATTRIB(XonoticQuitDialog, columns, float, 2) - ATTRIB(XonoticQuitDialog, name, string, "Quit") -ENDCLASS(XonoticQuitDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticQuitDialog_fill(entity me) -{ - entity e; - me.TR(me); - me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("Are you sure you want to quit?"))); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCommandButton(_("Yes"), '1 0 0', "echo ]quit\nquit", 0)); - me.TD(me, 1, 1, e = makeXonoticButton(_("No"), '0 1 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_quit.qc b/qcsrc/menu/xonotic/dialog_quit.qc new file mode 100644 index 000000000..71de59dac --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_quit.qc @@ -0,0 +1,26 @@ +#ifdef INTERFACE +CLASS(XonoticQuitDialog) EXTENDS(XonoticDialog) + METHOD(XonoticQuitDialog, fill, void(entity)) + ATTRIB(XonoticQuitDialog, title, string, _("Quit")) + ATTRIB(XonoticQuitDialog, color, vector, SKINCOLOR_DIALOG_QUIT) + ATTRIB(XonoticQuitDialog, intendedWidth, float, 0.5) + ATTRIB(XonoticQuitDialog, rows, float, 3) + ATTRIB(XonoticQuitDialog, columns, float, 2) + ATTRIB(XonoticQuitDialog, name, string, "Quit") +ENDCLASS(XonoticQuitDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticQuitDialog_fill(entity me) +{ + entity e; + me.TR(me); + me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("Are you sure you want to quit?"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCommandButton(_("Yes"), '1 0 0', "echo ]quit\nquit", 0)); + me.TD(me, 1, 1, e = makeXonoticButton(_("No"), '0 1 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_sandboxtools.c b/qcsrc/menu/xonotic/dialog_sandboxtools.c deleted file mode 100644 index 033336dc9..000000000 --- a/qcsrc/menu/xonotic/dialog_sandboxtools.c +++ /dev/null @@ -1,96 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticSandboxToolsDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticSandboxToolsDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls - ATTRIB(XonoticSandboxToolsDialog, title, string, _("Sandbox Tools")) // ;) - ATTRIB(XonoticSandboxToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS) - ATTRIB(XonoticSandboxToolsDialog, intendedWidth, float, 0.8) - ATTRIB(XonoticSandboxToolsDialog, rows, float, 16) - ATTRIB(XonoticSandboxToolsDialog, columns, float, 4) - ATTRIB(XonoticSandboxToolsDialog, name, string, "SandboxTools") - ATTRIB(XonoticSandboxToolsDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticSandboxToolsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticSandboxToolsDialog_fill(entity me) -{ - entity e, box; - - me.TR(me); - me.TD(me, 1, 0.25, e = makeXonoticTextLabel(0, _("Model:"))); - me.TD(me, 1, 1.5, box = makeXonoticInputBox(1, "menu_sandbox_spawn_model")); - box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved - box.maxLength = -127; // negative means encoded length in bytes - box.saveImmediately = 1; - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Spawn"), '0 0 0', "sandbox object_spawn \"$menu_sandbox_spawn_model\"", 0)); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Remove *"), '0 0 0', "sandbox object_remove", 0)); - me.TDempty(me, 0.1); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Copy *"), '0 0 0', "sandbox object_duplicate copy cl_sandbox_clipboard", 0)); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Paste"), '0 0 0', "sandbox object_duplicate paste \"$cl_sandbox_clipboard\"", 0)); - me.TR(me); - me.TD(me, 1, 0.25, e = makeXonoticTextLabel(0, _("Bone:"))); - me.TD(me, 1, 1.5, box = makeXonoticInputBox(1, "menu_sandbox_attach_bone")); - box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved - box.maxLength = -127; // negative means encoded length in bytes - box.saveImmediately = 1; - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set * as child"), '0 0 0', "sandbox object_attach get", 0)); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Attach to *"), '0 0 0', "sandbox object_attach set \"$menu_sandbox_attach_bone\"", 0)); - me.TDempty(me, 0.1); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Detach from *"), '0 0 0', "sandbox object_attach remove", 0)); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1.5, e = makeXonoticTextLabel(0, _("Visual object properties for *:"))); - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set skin:"), '0 0 0', "sandbox object_edit skin $menu_sandbox_edit_skin", 0)); - me.TD(me, 1, 1.5, e = makeXonoticSlider(0, 99, 1, "menu_sandbox_edit_skin")); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set alpha:"), '0 0 0', "sandbox object_edit alpha $menu_sandbox_edit_alpha", 0)); - me.TD(me, 1, 1.5, e = makeXonoticSlider(0.1, 1, 0.05, "menu_sandbox_edit_alpha")); - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set color main:"), '0 0 0', "sandbox object_edit color_main \"$menu_sandbox_edit_color_main\"", 0)); - me.TD(me, 2, 1.5, e = makeXonoticColorpickerString("menu_sandbox_edit_color_main", "menu_sandbox_edit_color_main")); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set color glow:"), '0 0 0', "sandbox object_edit color_glow \"$menu_sandbox_edit_color_glow\"", 0)); - me.TD(me, 2, 1.5, e = makeXonoticColorpickerString("menu_sandbox_edit_color_glow", "menu_sandbox_edit_color_glow")); - me.TR(me); - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set frame:"), '0 0 0', "sandbox object_edit frame $menu_sandbox_edit_frame", 0)); - me.TD(me, 1, 1.5, e = makeXonoticSlider(0, 99, 1, "menu_sandbox_edit_frame")); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1.5, e = makeXonoticTextLabel(0, _("Physical object properties for *:"))); - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set material:"), '0 0 0', "sandbox object_edit material \"$menu_sandbox_edit_material\"", 0)); - me.TD(me, 1, 1.5, box = makeXonoticInputBox(1, "menu_sandbox_edit_material")); - box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved - box.maxLength = -127; // negative means encoded length in bytes - box.saveImmediately = 1; - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set solidity:"), '0 0 0', "sandbox object_edit solidity $menu_sandbox_edit_solidity", 0)); - me.TD(me, 1, 0.75, e = makeXonoticRadioButton(1, "menu_sandbox_edit_solidity", "0", _("Non-solid"))); - me.TD(me, 1, 0.75, e = makeXonoticRadioButton(1, "menu_sandbox_edit_solidity", "1", _("Solid"))); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set physics:"), '0 0 0', "sandbox object_edit physics $menu_sandbox_edit_physics", 0)); - me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_sandbox_edit_physics", "0", _("Static"))); - me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_sandbox_edit_physics", "1", _("Movable"))); - me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_sandbox_edit_physics", "2", _("Physical"))); - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set scale:"), '0 0 0', "sandbox object_edit scale $menu_sandbox_edit_scale", 0)); - me.TD(me, 1, 1.5, e = makeXonoticSlider(0.25, 2, 0.05, "menu_sandbox_edit_scale")); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set force:"), '0 0 0', "sandbox object_edit force $menu_sandbox_edit_force", 0)); - me.TD(me, 1, 1.5, e = makeXonoticSlider(0, 10, 0.5, "menu_sandbox_edit_force")); - me.TR(me); - me.TR(me); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Claim *"), '0 0 0', "sandbox object_claim", 0)); - me.TDempty(me, 0.5); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("* object info"), '1 1 0.5', "sandbox object_info object; toggleconsole", 0)); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("* mesh info"), '1 1 0.5', "sandbox object_info mesh; toggleconsole", 0)); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("* attachment info"), '1 1 0.5', "sandbox object_info attachments; toggleconsole", 0)); - me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Show help"), '1 0.5 0.5', "sandbox help; toggleconsole", 0)); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("* is the object you are facing"))); - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -#endif - -/* Click. The c-word is here so you can grep for it :-) */ diff --git a/qcsrc/menu/xonotic/dialog_sandboxtools.qc b/qcsrc/menu/xonotic/dialog_sandboxtools.qc new file mode 100644 index 000000000..033336dc9 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_sandboxtools.qc @@ -0,0 +1,96 @@ +#ifdef INTERFACE +CLASS(XonoticSandboxToolsDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticSandboxToolsDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls + ATTRIB(XonoticSandboxToolsDialog, title, string, _("Sandbox Tools")) // ;) + ATTRIB(XonoticSandboxToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS) + ATTRIB(XonoticSandboxToolsDialog, intendedWidth, float, 0.8) + ATTRIB(XonoticSandboxToolsDialog, rows, float, 16) + ATTRIB(XonoticSandboxToolsDialog, columns, float, 4) + ATTRIB(XonoticSandboxToolsDialog, name, string, "SandboxTools") + ATTRIB(XonoticSandboxToolsDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticSandboxToolsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticSandboxToolsDialog_fill(entity me) +{ + entity e, box; + + me.TR(me); + me.TD(me, 1, 0.25, e = makeXonoticTextLabel(0, _("Model:"))); + me.TD(me, 1, 1.5, box = makeXonoticInputBox(1, "menu_sandbox_spawn_model")); + box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved + box.maxLength = -127; // negative means encoded length in bytes + box.saveImmediately = 1; + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Spawn"), '0 0 0', "sandbox object_spawn \"$menu_sandbox_spawn_model\"", 0)); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Remove *"), '0 0 0', "sandbox object_remove", 0)); + me.TDempty(me, 0.1); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Copy *"), '0 0 0', "sandbox object_duplicate copy cl_sandbox_clipboard", 0)); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Paste"), '0 0 0', "sandbox object_duplicate paste \"$cl_sandbox_clipboard\"", 0)); + me.TR(me); + me.TD(me, 1, 0.25, e = makeXonoticTextLabel(0, _("Bone:"))); + me.TD(me, 1, 1.5, box = makeXonoticInputBox(1, "menu_sandbox_attach_bone")); + box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved + box.maxLength = -127; // negative means encoded length in bytes + box.saveImmediately = 1; + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set * as child"), '0 0 0', "sandbox object_attach get", 0)); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Attach to *"), '0 0 0', "sandbox object_attach set \"$menu_sandbox_attach_bone\"", 0)); + me.TDempty(me, 0.1); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Detach from *"), '0 0 0', "sandbox object_attach remove", 0)); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1.5, e = makeXonoticTextLabel(0, _("Visual object properties for *:"))); + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set skin:"), '0 0 0', "sandbox object_edit skin $menu_sandbox_edit_skin", 0)); + me.TD(me, 1, 1.5, e = makeXonoticSlider(0, 99, 1, "menu_sandbox_edit_skin")); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set alpha:"), '0 0 0', "sandbox object_edit alpha $menu_sandbox_edit_alpha", 0)); + me.TD(me, 1, 1.5, e = makeXonoticSlider(0.1, 1, 0.05, "menu_sandbox_edit_alpha")); + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set color main:"), '0 0 0', "sandbox object_edit color_main \"$menu_sandbox_edit_color_main\"", 0)); + me.TD(me, 2, 1.5, e = makeXonoticColorpickerString("menu_sandbox_edit_color_main", "menu_sandbox_edit_color_main")); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set color glow:"), '0 0 0', "sandbox object_edit color_glow \"$menu_sandbox_edit_color_glow\"", 0)); + me.TD(me, 2, 1.5, e = makeXonoticColorpickerString("menu_sandbox_edit_color_glow", "menu_sandbox_edit_color_glow")); + me.TR(me); + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set frame:"), '0 0 0', "sandbox object_edit frame $menu_sandbox_edit_frame", 0)); + me.TD(me, 1, 1.5, e = makeXonoticSlider(0, 99, 1, "menu_sandbox_edit_frame")); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1.5, e = makeXonoticTextLabel(0, _("Physical object properties for *:"))); + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set material:"), '0 0 0', "sandbox object_edit material \"$menu_sandbox_edit_material\"", 0)); + me.TD(me, 1, 1.5, box = makeXonoticInputBox(1, "menu_sandbox_edit_material")); + box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved + box.maxLength = -127; // negative means encoded length in bytes + box.saveImmediately = 1; + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set solidity:"), '0 0 0', "sandbox object_edit solidity $menu_sandbox_edit_solidity", 0)); + me.TD(me, 1, 0.75, e = makeXonoticRadioButton(1, "menu_sandbox_edit_solidity", "0", _("Non-solid"))); + me.TD(me, 1, 0.75, e = makeXonoticRadioButton(1, "menu_sandbox_edit_solidity", "1", _("Solid"))); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set physics:"), '0 0 0', "sandbox object_edit physics $menu_sandbox_edit_physics", 0)); + me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_sandbox_edit_physics", "0", _("Static"))); + me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_sandbox_edit_physics", "1", _("Movable"))); + me.TD(me, 1, 0.5, e = makeXonoticRadioButton(2, "menu_sandbox_edit_physics", "2", _("Physical"))); + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set scale:"), '0 0 0', "sandbox object_edit scale $menu_sandbox_edit_scale", 0)); + me.TD(me, 1, 1.5, e = makeXonoticSlider(0.25, 2, 0.05, "menu_sandbox_edit_scale")); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Set force:"), '0 0 0', "sandbox object_edit force $menu_sandbox_edit_force", 0)); + me.TD(me, 1, 1.5, e = makeXonoticSlider(0, 10, 0.5, "menu_sandbox_edit_force")); + me.TR(me); + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Claim *"), '0 0 0', "sandbox object_claim", 0)); + me.TDempty(me, 0.5); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("* object info"), '1 1 0.5', "sandbox object_info object; toggleconsole", 0)); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("* mesh info"), '1 1 0.5', "sandbox object_info mesh; toggleconsole", 0)); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("* attachment info"), '1 1 0.5', "sandbox object_info attachments; toggleconsole", 0)); + me.TD(me, 1, 0.5, e = makeXonoticCommandButton(_("Show help"), '1 0.5 0.5', "sandbox help; toggleconsole", 0)); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("* is the object you are facing"))); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +#endif + +/* Click. The c-word is here so you can grep for it :-) */ diff --git a/qcsrc/menu/xonotic/dialog_settings.c b/qcsrc/menu/xonotic/dialog_settings.c deleted file mode 100644 index a992e8059..000000000 --- a/qcsrc/menu/xonotic/dialog_settings.c +++ /dev/null @@ -1,29 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticSettingsDialog) EXTENDS(XonoticDialog) - METHOD(XonoticSettingsDialog, fill, void(entity)) - ATTRIB(XonoticSettingsDialog, title, string, _("Settings")) - ATTRIB(XonoticSettingsDialog, color, vector, SKINCOLOR_DIALOG_SETTINGS) - ATTRIB(XonoticSettingsDialog, intendedWidth, float, 0.96) - ATTRIB(XonoticSettingsDialog, rows, float, 18) - ATTRIB(XonoticSettingsDialog, columns, float, 6) -ENDCLASS(XonoticSettingsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticSettingsDialog_fill(entity me) -{ - entity mc; - mc = makeXonoticTabController(me.rows - 2.5); - me.TR(me); - me.TD(me, 1, 2, mc.makeTabButton(mc, _("Video"), makeXonoticVideoSettingsTab())); - me.TD(me, 1, 2, mc.makeTabButton(mc, _("Effects"), makeXonoticEffectsSettingsTab())); - me.TD(me, 1, 2, mc.makeTabButton(mc, _("Audio"), makeXonoticAudioSettingsTab())); - me.TR(me); - me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Game"), makeXonoticGameSettingsTab())); - me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Input"), makeXonoticInputSettingsTab())); - me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("User"), makeXonoticUserSettingsTab())); - me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Misc"), makeXonoticMiscSettingsTab())); - me.gotoRC(me, 2.5, 0); - me.TD(me, me.rows - 2.5, me.columns, mc); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings.qc b/qcsrc/menu/xonotic/dialog_settings.qc new file mode 100644 index 000000000..a992e8059 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings.qc @@ -0,0 +1,29 @@ +#ifdef INTERFACE +CLASS(XonoticSettingsDialog) EXTENDS(XonoticDialog) + METHOD(XonoticSettingsDialog, fill, void(entity)) + ATTRIB(XonoticSettingsDialog, title, string, _("Settings")) + ATTRIB(XonoticSettingsDialog, color, vector, SKINCOLOR_DIALOG_SETTINGS) + ATTRIB(XonoticSettingsDialog, intendedWidth, float, 0.96) + ATTRIB(XonoticSettingsDialog, rows, float, 18) + ATTRIB(XonoticSettingsDialog, columns, float, 6) +ENDCLASS(XonoticSettingsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticSettingsDialog_fill(entity me) +{ + entity mc; + mc = makeXonoticTabController(me.rows - 2.5); + me.TR(me); + me.TD(me, 1, 2, mc.makeTabButton(mc, _("Video"), makeXonoticVideoSettingsTab())); + me.TD(me, 1, 2, mc.makeTabButton(mc, _("Effects"), makeXonoticEffectsSettingsTab())); + me.TD(me, 1, 2, mc.makeTabButton(mc, _("Audio"), makeXonoticAudioSettingsTab())); + me.TR(me); + me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Game"), makeXonoticGameSettingsTab())); + me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Input"), makeXonoticInputSettingsTab())); + me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("User"), makeXonoticUserSettingsTab())); + me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Misc"), makeXonoticMiscSettingsTab())); + me.gotoRC(me, 2.5, 0); + me.TD(me, me.rows - 2.5, me.columns, mc); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_audio.c b/qcsrc/menu/xonotic/dialog_settings_audio.c deleted file mode 100644 index 39bee3242..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_audio.c +++ /dev/null @@ -1,166 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticAudioSettingsTab) EXTENDS(XonoticTab) - METHOD(XonoticAudioSettingsTab, fill, void(entity)) - ATTRIB(XonoticAudioSettingsTab, title, string, _("Audio")) - ATTRIB(XonoticAudioSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticAudioSettingsTab, rows, float, 15.5) - ATTRIB(XonoticAudioSettingsTab, columns, float, 6.2) // added extra .2 for center space -ENDCLASS(XonoticAudioSettingsTab) -entity makeXonoticAudioSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticAudioSettingsTab() -{ - entity me; - me = spawnXonoticAudioSettingsTab(); - me.configureDialog(me); - return me; -} - -void XonoticAudioSettingsTab_fill(entity me) -{ - entity e, s; - - me.TR(me); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "mastervolume"); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Master:"))); - me.TD(me, 1, 2, s); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "bgmvolume"); - makeMulti(s, "snd_channel8volume"); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Music:"))); - me.TD(me, 1, 2, s); - setDependentStringNotEqual(e, "mastervolume", "0"); - setDependentStringNotEqual(s, "mastervolume", "0"); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_staticvolume"); - makeMulti(s, "snd_channel9volume"); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, ZCTX(_("VOL^Ambient:")))); - me.TD(me, 1, 2, s); - setDependentStringNotEqual(e, "mastervolume", "0"); - setDependentStringNotEqual(s, "mastervolume", "0"); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel0volume"); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Info:"))); - me.TD(me, 1, 2, s); - setDependentStringNotEqual(e, "mastervolume", "0"); - setDependentStringNotEqual(s, "mastervolume", "0"); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel3volume"); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Items:"))); - me.TD(me, 1, 2, s); - setDependentStringNotEqual(e, "mastervolume", "0"); - setDependentStringNotEqual(s, "mastervolume", "0"); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel6volume"); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Pain:"))); - me.TD(me, 1, 2, s); - setDependentStringNotEqual(e, "mastervolume", "0"); - setDependentStringNotEqual(s, "mastervolume", "0"); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel7volume"); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Player:"))); - me.TD(me, 1, 2, s); - setDependentStringNotEqual(e, "mastervolume", "0"); - setDependentStringNotEqual(s, "mastervolume", "0"); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel4volume"); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Shots:"))); - me.TD(me, 1, 2, s); - setDependentStringNotEqual(e, "mastervolume", "0"); - setDependentStringNotEqual(s, "mastervolume", "0"); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel2volume"); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Voice:"))); - me.TD(me, 1, 2, s); - setDependentStringNotEqual(e, "mastervolume", "0"); - setDependentStringNotEqual(s, "mastervolume", "0"); - me.TR(me); - me.TDempty(me, 0.2); - s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel1volume"); - makeMulti(s, "snd_channel5volume"); // @!#%'n Tuba - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Weapons:"))); - me.TD(me, 1, 2, s); - setDependentStringNotEqual(e, "mastervolume", "0"); - setDependentStringNotEqual(s, "mastervolume", "0"); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, makeXonoticCheckBox(0, "menu_snd_attenuation_method", _("New style sound attenuation"))); - me.TR(me); - me.TD(me, 1, 3, makeXonoticCheckBox(0, "snd_mutewhenidle", _("Mute sounds when not active"))); - - me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Frequency:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("snd_speed")); - e.addValue(e, _("8 kHz"), "8000"); - e.addValue(e, _("11.025 kHz"), "11025"); - e.addValue(e, _("16 kHz"), "16000"); - e.addValue(e, _("22.05 kHz"), "22050"); - e.addValue(e, _("24 kHz"), "24000"); - e.addValue(e, _("32 kHz"), "32000"); - e.addValue(e, _("44.1 kHz"), "44100"); - e.addValue(e, _("48 kHz"), "48000"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Channels:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("snd_channels")); - e.addValue(e, _("Mono"), "1"); - e.addValue(e, _("Stereo"), "2"); - e.addValue(e, _("2.1"), "3"); - e.addValue(e, _("4"), "4"); - e.addValue(e, _("5"), "5"); - e.addValue(e, _("5.1"), "6"); - e.addValue(e, _("6.1"), "7"); - e.addValue(e, _("7.1"), "8"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "snd_swapstereo", _("Swap stereo output channels"))); - setDependent(e, "snd_channels", 1.5, 0.5); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "snd_spatialization_control", _("Headphone friendly mode"))); - setDependent(e, "snd_channels", 1.5, 0.5); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, makeXonoticCheckBox(0, "cl_hitsound", _("Hit indication sound"))); - e.sendCvars = TRUE; - me.TR(me); - me.TD(me, 1, 3, makeXonoticCheckBox(0, "con_chatsound", _("Chat message sound"))); - me.TR(me); - me.TD(me, 1, 3, makeXonoticCheckBoxEx(2, 0, "menu_sounds", _("Menu sounds"))); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Time announcer:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_announcer_maptime")); - e.addValue(e, ZCTX(_("WRN^Disabled")), "0"); - e.addValue(e, _("1 minute"), "1"); - e.addValue(e, _("5 minutes"), "2"); - e.addValue(e, ZCTX(_("WRN^Both")), "3"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Automatic taunts:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_autotaunt")); - e.addValue(e, _("Never"), "0"); - e.addValue(e, _("Sometimes"), "0.35"); - e.addValue(e, _("Often"), "0.65"); - e.addValue(e, _("Always"), "1"); - e.configureXonoticTextSliderValues(e); - e.sendCvars = TRUE; - me.TR(me); - me.TR(me); - if(cvar("developer")) - me.TD(me, 1, 3, makeXonoticCheckBox(0, "showsound", _("Debug info about sounds"))); - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "snd_restart; snd_attenuation_method_${menu_snd_attenuation_method}", COMMANDBUTTON_APPLY)); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_audio.qc b/qcsrc/menu/xonotic/dialog_settings_audio.qc new file mode 100644 index 000000000..39bee3242 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_audio.qc @@ -0,0 +1,166 @@ +#ifdef INTERFACE +CLASS(XonoticAudioSettingsTab) EXTENDS(XonoticTab) + METHOD(XonoticAudioSettingsTab, fill, void(entity)) + ATTRIB(XonoticAudioSettingsTab, title, string, _("Audio")) + ATTRIB(XonoticAudioSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticAudioSettingsTab, rows, float, 15.5) + ATTRIB(XonoticAudioSettingsTab, columns, float, 6.2) // added extra .2 for center space +ENDCLASS(XonoticAudioSettingsTab) +entity makeXonoticAudioSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticAudioSettingsTab() +{ + entity me; + me = spawnXonoticAudioSettingsTab(); + me.configureDialog(me); + return me; +} + +void XonoticAudioSettingsTab_fill(entity me) +{ + entity e, s; + + me.TR(me); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "mastervolume"); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Master:"))); + me.TD(me, 1, 2, s); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "bgmvolume"); + makeMulti(s, "snd_channel8volume"); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Music:"))); + me.TD(me, 1, 2, s); + setDependentStringNotEqual(e, "mastervolume", "0"); + setDependentStringNotEqual(s, "mastervolume", "0"); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_staticvolume"); + makeMulti(s, "snd_channel9volume"); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, ZCTX(_("VOL^Ambient:")))); + me.TD(me, 1, 2, s); + setDependentStringNotEqual(e, "mastervolume", "0"); + setDependentStringNotEqual(s, "mastervolume", "0"); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel0volume"); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Info:"))); + me.TD(me, 1, 2, s); + setDependentStringNotEqual(e, "mastervolume", "0"); + setDependentStringNotEqual(s, "mastervolume", "0"); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel3volume"); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Items:"))); + me.TD(me, 1, 2, s); + setDependentStringNotEqual(e, "mastervolume", "0"); + setDependentStringNotEqual(s, "mastervolume", "0"); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel6volume"); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Pain:"))); + me.TD(me, 1, 2, s); + setDependentStringNotEqual(e, "mastervolume", "0"); + setDependentStringNotEqual(s, "mastervolume", "0"); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel7volume"); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Player:"))); + me.TD(me, 1, 2, s); + setDependentStringNotEqual(e, "mastervolume", "0"); + setDependentStringNotEqual(s, "mastervolume", "0"); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel4volume"); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Shots:"))); + me.TD(me, 1, 2, s); + setDependentStringNotEqual(e, "mastervolume", "0"); + setDependentStringNotEqual(s, "mastervolume", "0"); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel2volume"); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Voice:"))); + me.TD(me, 1, 2, s); + setDependentStringNotEqual(e, "mastervolume", "0"); + setDependentStringNotEqual(s, "mastervolume", "0"); + me.TR(me); + me.TDempty(me, 0.2); + s = makeXonoticDecibelsSlider(-40, 0, 0.4, "snd_channel1volume"); + makeMulti(s, "snd_channel5volume"); // @!#%'n Tuba + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Weapons:"))); + me.TD(me, 1, 2, s); + setDependentStringNotEqual(e, "mastervolume", "0"); + setDependentStringNotEqual(s, "mastervolume", "0"); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, makeXonoticCheckBox(0, "menu_snd_attenuation_method", _("New style sound attenuation"))); + me.TR(me); + me.TD(me, 1, 3, makeXonoticCheckBox(0, "snd_mutewhenidle", _("Mute sounds when not active"))); + + me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Frequency:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("snd_speed")); + e.addValue(e, _("8 kHz"), "8000"); + e.addValue(e, _("11.025 kHz"), "11025"); + e.addValue(e, _("16 kHz"), "16000"); + e.addValue(e, _("22.05 kHz"), "22050"); + e.addValue(e, _("24 kHz"), "24000"); + e.addValue(e, _("32 kHz"), "32000"); + e.addValue(e, _("44.1 kHz"), "44100"); + e.addValue(e, _("48 kHz"), "48000"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Channels:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("snd_channels")); + e.addValue(e, _("Mono"), "1"); + e.addValue(e, _("Stereo"), "2"); + e.addValue(e, _("2.1"), "3"); + e.addValue(e, _("4"), "4"); + e.addValue(e, _("5"), "5"); + e.addValue(e, _("5.1"), "6"); + e.addValue(e, _("6.1"), "7"); + e.addValue(e, _("7.1"), "8"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "snd_swapstereo", _("Swap stereo output channels"))); + setDependent(e, "snd_channels", 1.5, 0.5); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "snd_spatialization_control", _("Headphone friendly mode"))); + setDependent(e, "snd_channels", 1.5, 0.5); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, makeXonoticCheckBox(0, "cl_hitsound", _("Hit indication sound"))); + e.sendCvars = TRUE; + me.TR(me); + me.TD(me, 1, 3, makeXonoticCheckBox(0, "con_chatsound", _("Chat message sound"))); + me.TR(me); + me.TD(me, 1, 3, makeXonoticCheckBoxEx(2, 0, "menu_sounds", _("Menu sounds"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Time announcer:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_announcer_maptime")); + e.addValue(e, ZCTX(_("WRN^Disabled")), "0"); + e.addValue(e, _("1 minute"), "1"); + e.addValue(e, _("5 minutes"), "2"); + e.addValue(e, ZCTX(_("WRN^Both")), "3"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Automatic taunts:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_autotaunt")); + e.addValue(e, _("Never"), "0"); + e.addValue(e, _("Sometimes"), "0.35"); + e.addValue(e, _("Often"), "0.65"); + e.addValue(e, _("Always"), "1"); + e.configureXonoticTextSliderValues(e); + e.sendCvars = TRUE; + me.TR(me); + me.TR(me); + if(cvar("developer")) + me.TD(me, 1, 3, makeXonoticCheckBox(0, "showsound", _("Debug info about sounds"))); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "snd_restart; snd_attenuation_method_${menu_snd_attenuation_method}", COMMANDBUTTON_APPLY)); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_effects.c b/qcsrc/menu/xonotic/dialog_settings_effects.c deleted file mode 100644 index 59b4860af..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_effects.c +++ /dev/null @@ -1,215 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticEffectsSettingsTab) EXTENDS(XonoticTab) - METHOD(XonoticEffectsSettingsTab, fill, void(entity)) - ATTRIB(XonoticEffectsSettingsTab, title, string, _("Effects")) - ATTRIB(XonoticEffectsSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticEffectsSettingsTab, rows, float, 15.5) - ATTRIB(XonoticEffectsSettingsTab, columns, float, 6.2) // added extra .2 for center space -ENDCLASS(XonoticEffectsSettingsTab) -entity makeXonoticEffectsSettingsTab(); -float updateCompression(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticEffectsSettingsTab() -{ - entity me; - me = spawnXonoticEffectsSettingsTab(); - me.configureDialog(me); - return me; -} - -float someShadowCvarIsEnabled(entity box) -{ - if(cvar("r_shadow_realtime_dlight")) - if(cvar("r_shadow_realtime_dlight_shadows")) - return TRUE; - if(cvar("r_shadow_realtime_world")) - if(cvar("r_shadow_realtime_world_shadows")) - return TRUE; - return FALSE; -} - -void XonoticEffectsSettingsTab_fill(entity me) -{ - entity e, s; - float n; - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Quality preset:"))); - n = 5 + 2 * !!cvar("developer"); - if(cvar("developer")) - me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^OMG!")), '1 0 1', "exec effects-omg.cfg", 0)); - me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Low")), '0 0 0', "exec effects-low.cfg", 0)); - me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Medium")), '0 0 0', "exec effects-med.cfg", 0)); - me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Normal")), '0 0 0', "exec effects-normal.cfg", 0)); - me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^High")), '0 0 0', "exec effects-high.cfg", 0)); - me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Ultra")), '0 0 0', "exec effects-ultra.cfg", 0)); - if(cvar("developer")) - me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Ultimate")), '0.5 0 0', "exec effects-ultimate.cfg", 0)); - - me.gotoRC(me, 1.25, 0); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Geometry detail:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("r_subdivisions_tolerance")); - e.addValue(e, ZCTX(_("DET^Lowest")), "16"); - e.addValue(e, ZCTX(_("DET^Low")), "8"); - e.addValue(e, ZCTX(_("DET^Normal")), "4"); - e.addValue(e, ZCTX(_("DET^Good")), "3"); - e.addValue(e, ZCTX(_("DET^Best")), "2"); - e.addValue(e, ZCTX(_("DET^Insane")), "1"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Player detail:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_playerdetailreduction")); - e.addValue(e, ZCTX(_("PDET^Low")), "4"); - e.addValue(e, ZCTX(_("PDET^Medium")), "3"); - e.addValue(e, ZCTX(_("PDET^Normal")), "2"); - e.addValue(e, ZCTX(_("PDET^Good")), "1"); - e.addValue(e, ZCTX(_("PDET^Best")), "0"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Texture resolution:"))); - setDependent(e, "r_showsurfaces", 0, 0); - me.TD(me, 1, 2, e = makeXonoticPicmipSlider()); - if(cvar("developer")) - e.addValue(e, ZCTX(_("RES^Leet")), "1337"); - e.addValue(e, ZCTX(_("RES^Lowest")), "3"); - e.addValue(e, ZCTX(_("RES^Very low")), "2"); - e.addValue(e, ZCTX(_("RES^Low")), "1"); - e.addValue(e, ZCTX(_("RES^Normal")), "0"); - e.addValue(e, ZCTX(_("RES^Good")), "-1"); - e.addValue(e, ZCTX(_("RES^Best")), "-2"); - e.configureXonoticTextSliderValues(e); - setDependent(e, "r_showsurfaces", 0, 0); - me.TR(me); - me.TDempty(me, 0.2); - { - // detect texture compression method - float f; - f = updateCompression(); - switch(f) - { - case 0: - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(1, "r_texture_dds_load", _("Avoid lossy texture compression"))); - e.disabled = 1; // just show the checkbox anyway, but with no ability to control it - break; - case 1: - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(1, "r_texture_dds_load", _("Avoid lossy texture compression"))); - setDependent(e, "r_showsurfaces", 0, 0); - break; - case 2: - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(1, "r_texture_dds_load", _("Avoid lossy texture compression"))); - setDependent(e, "r_showsurfaces", 0, 0); - makeMulti(e, "gl_texturecompression"); - break; - } - } - me.TR(me); - if(cvar("developer")) - { - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(3, 0, "r_showsurfaces", _("Show surfaces"))); - } - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCheckBox(1, "mod_q3bsp_nolightmaps", _("Use lightmaps"))); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_glsl_deluxemapping", _("Deluxe mapping"))); - setDependentAND(e, "vid_gl20", 1, 1, "mod_q3bsp_nolightmaps", 0, 0); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_shadow_gloss", _("Gloss"))); - setDependentAND3(e, "vid_gl20", 1, 1, "mod_q3bsp_nolightmaps", 0, 0, "r_glsl_deluxemapping", 1, 1); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_glsl_offsetmapping", _("Offset mapping"))); - setDependent(e, "vid_gl20", 1, 1); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_glsl_offsetmapping_reliefmapping", _("Relief mapping"))); - setDependentAND(e, "vid_gl20", 1, 1, "r_glsl_offsetmapping", 1, 1); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_water", _("Reflections:"))); - setDependent(e, "vid_gl20", 1, 1); - me.TD(me, 1, 2, e = makeXonoticTextSlider("r_water_resolutionmultiplier")); - e.addValue(e, _("Blurred"), "0.25"); - e.addValue(e, ZCTX(_("REFL^Good")), "0.5"); - e.addValue(e, _("Sharp"), "1"); - e.configureXonoticTextSliderValues(e); - setDependentAND(e, "vid_gl20", 1, 1, "r_water", 1, 1); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_decals", _("Decals"))); - me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_decals_models", _("Decals on models"))); - setDependent(e, "cl_decals", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Distance:"))); - setDependent(e, "cl_decals", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(200, 500, 20, "r_drawdecals_drawdistance")); - setDependent(e, "cl_decals", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Time:"))); - setDependent(e, "cl_decals", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(1, 20, 1, "cl_decals_fadetime")); - setDependent(e, "cl_decals", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Damage effects:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_damageeffect")); - e.addValue(e, _("Disabled"), "0"); - e.addValue(e, _("Skeletal"), "1"); - e.addValue(e, _("All"), "2"); - e.configureXonoticTextSliderValues(e); - - me.gotoRC(me, 1.25, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "r_coronas", "0", _("No dynamic lighting"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "gl_flashblend", string_null, _("Fake corona lighting"))); - makeMulti(e, "r_coronas"); - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticRadioButton(1, "r_shadow_realtime_dlight", string_null, _("Realtime dynamic lighting"))); - makeMulti(e, "r_coronas"); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_shadow_realtime_dlight_shadows", _("Shadows"))); - setDependent(e, "r_shadow_realtime_dlight", 1, 1); - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "r_shadow_realtime_world", _("Realtime world lighting"))); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_shadow_realtime_world_shadows", _("Shadows"))); - setDependent(e, "r_shadow_realtime_world", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "r_shadow_usenormalmap", _("Use normal maps"))); - setDependentOR(e, "r_shadow_realtime_dlight", 1, 1, "r_shadow_realtime_world", 1, 1); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_shadow_shadowmapping", _("Soft shadows"))); - setDependentWeird(e, someShadowCvarIsEnabled); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "r_coronas_occlusionquery", _("Fade corona according to visibility"))); - setDependent(e, "r_coronas", 1, 1); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_bloom", _("Bloom"))); - me.TD(me, 1, 2, e = makeXonoticCheckBoxEx(0.5, 0, "hud_postprocessing_maxbluralpha", _("Extra postprocessing effects"))); - makeMulti(e, "hud_powerup"); - setDependent(e, "vid_gl20", 1, 1); - me.TR(me); - s = makeXonoticSlider(0.1, 1, 0.1, "r_motionblur"); - me.TD(me, 1, 1, e = makeXonoticSliderCheckBox(0, 1, s, _("Motion blur:"))); - if(s.value != e.savedValue) - e.savedValue = 0.4; // default - me.TD(me, 1, 2, s); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_particles", _("Particles"))); - me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_spawn_point_particles", _("Spawnpoint effects"))); - makeMulti(e, "cl_spawn_event_particles"); - setDependent(e, "cl_particles", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Quality:"))); - setDependent(e, "cl_particles", 1, 1); - me.TD(me, 1, 2, e = makeXonoticParticlesSlider()); - setDependent(e, "cl_particles", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Distance:"))); - setDependent(e, "cl_particles", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(200, 500, 20, "r_drawparticles_drawdistance")); - setDependent(e, "cl_particles", 1, 1); - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "vid_restart", COMMANDBUTTON_APPLY)); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_effects.qc b/qcsrc/menu/xonotic/dialog_settings_effects.qc new file mode 100644 index 000000000..59b4860af --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_effects.qc @@ -0,0 +1,215 @@ +#ifdef INTERFACE +CLASS(XonoticEffectsSettingsTab) EXTENDS(XonoticTab) + METHOD(XonoticEffectsSettingsTab, fill, void(entity)) + ATTRIB(XonoticEffectsSettingsTab, title, string, _("Effects")) + ATTRIB(XonoticEffectsSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticEffectsSettingsTab, rows, float, 15.5) + ATTRIB(XonoticEffectsSettingsTab, columns, float, 6.2) // added extra .2 for center space +ENDCLASS(XonoticEffectsSettingsTab) +entity makeXonoticEffectsSettingsTab(); +float updateCompression(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticEffectsSettingsTab() +{ + entity me; + me = spawnXonoticEffectsSettingsTab(); + me.configureDialog(me); + return me; +} + +float someShadowCvarIsEnabled(entity box) +{ + if(cvar("r_shadow_realtime_dlight")) + if(cvar("r_shadow_realtime_dlight_shadows")) + return TRUE; + if(cvar("r_shadow_realtime_world")) + if(cvar("r_shadow_realtime_world_shadows")) + return TRUE; + return FALSE; +} + +void XonoticEffectsSettingsTab_fill(entity me) +{ + entity e, s; + float n; + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Quality preset:"))); + n = 5 + 2 * !!cvar("developer"); + if(cvar("developer")) + me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^OMG!")), '1 0 1', "exec effects-omg.cfg", 0)); + me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Low")), '0 0 0', "exec effects-low.cfg", 0)); + me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Medium")), '0 0 0', "exec effects-med.cfg", 0)); + me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Normal")), '0 0 0', "exec effects-normal.cfg", 0)); + me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^High")), '0 0 0', "exec effects-high.cfg", 0)); + me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Ultra")), '0 0 0', "exec effects-ultra.cfg", 0)); + if(cvar("developer")) + me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Ultimate")), '0.5 0 0', "exec effects-ultimate.cfg", 0)); + + me.gotoRC(me, 1.25, 0); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Geometry detail:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("r_subdivisions_tolerance")); + e.addValue(e, ZCTX(_("DET^Lowest")), "16"); + e.addValue(e, ZCTX(_("DET^Low")), "8"); + e.addValue(e, ZCTX(_("DET^Normal")), "4"); + e.addValue(e, ZCTX(_("DET^Good")), "3"); + e.addValue(e, ZCTX(_("DET^Best")), "2"); + e.addValue(e, ZCTX(_("DET^Insane")), "1"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Player detail:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_playerdetailreduction")); + e.addValue(e, ZCTX(_("PDET^Low")), "4"); + e.addValue(e, ZCTX(_("PDET^Medium")), "3"); + e.addValue(e, ZCTX(_("PDET^Normal")), "2"); + e.addValue(e, ZCTX(_("PDET^Good")), "1"); + e.addValue(e, ZCTX(_("PDET^Best")), "0"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Texture resolution:"))); + setDependent(e, "r_showsurfaces", 0, 0); + me.TD(me, 1, 2, e = makeXonoticPicmipSlider()); + if(cvar("developer")) + e.addValue(e, ZCTX(_("RES^Leet")), "1337"); + e.addValue(e, ZCTX(_("RES^Lowest")), "3"); + e.addValue(e, ZCTX(_("RES^Very low")), "2"); + e.addValue(e, ZCTX(_("RES^Low")), "1"); + e.addValue(e, ZCTX(_("RES^Normal")), "0"); + e.addValue(e, ZCTX(_("RES^Good")), "-1"); + e.addValue(e, ZCTX(_("RES^Best")), "-2"); + e.configureXonoticTextSliderValues(e); + setDependent(e, "r_showsurfaces", 0, 0); + me.TR(me); + me.TDempty(me, 0.2); + { + // detect texture compression method + float f; + f = updateCompression(); + switch(f) + { + case 0: + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(1, "r_texture_dds_load", _("Avoid lossy texture compression"))); + e.disabled = 1; // just show the checkbox anyway, but with no ability to control it + break; + case 1: + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(1, "r_texture_dds_load", _("Avoid lossy texture compression"))); + setDependent(e, "r_showsurfaces", 0, 0); + break; + case 2: + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(1, "r_texture_dds_load", _("Avoid lossy texture compression"))); + setDependent(e, "r_showsurfaces", 0, 0); + makeMulti(e, "gl_texturecompression"); + break; + } + } + me.TR(me); + if(cvar("developer")) + { + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(3, 0, "r_showsurfaces", _("Show surfaces"))); + } + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCheckBox(1, "mod_q3bsp_nolightmaps", _("Use lightmaps"))); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_glsl_deluxemapping", _("Deluxe mapping"))); + setDependentAND(e, "vid_gl20", 1, 1, "mod_q3bsp_nolightmaps", 0, 0); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_shadow_gloss", _("Gloss"))); + setDependentAND3(e, "vid_gl20", 1, 1, "mod_q3bsp_nolightmaps", 0, 0, "r_glsl_deluxemapping", 1, 1); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_glsl_offsetmapping", _("Offset mapping"))); + setDependent(e, "vid_gl20", 1, 1); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_glsl_offsetmapping_reliefmapping", _("Relief mapping"))); + setDependentAND(e, "vid_gl20", 1, 1, "r_glsl_offsetmapping", 1, 1); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_water", _("Reflections:"))); + setDependent(e, "vid_gl20", 1, 1); + me.TD(me, 1, 2, e = makeXonoticTextSlider("r_water_resolutionmultiplier")); + e.addValue(e, _("Blurred"), "0.25"); + e.addValue(e, ZCTX(_("REFL^Good")), "0.5"); + e.addValue(e, _("Sharp"), "1"); + e.configureXonoticTextSliderValues(e); + setDependentAND(e, "vid_gl20", 1, 1, "r_water", 1, 1); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_decals", _("Decals"))); + me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_decals_models", _("Decals on models"))); + setDependent(e, "cl_decals", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Distance:"))); + setDependent(e, "cl_decals", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(200, 500, 20, "r_drawdecals_drawdistance")); + setDependent(e, "cl_decals", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Time:"))); + setDependent(e, "cl_decals", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(1, 20, 1, "cl_decals_fadetime")); + setDependent(e, "cl_decals", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Damage effects:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_damageeffect")); + e.addValue(e, _("Disabled"), "0"); + e.addValue(e, _("Skeletal"), "1"); + e.addValue(e, _("All"), "2"); + e.configureXonoticTextSliderValues(e); + + me.gotoRC(me, 1.25, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "r_coronas", "0", _("No dynamic lighting"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "gl_flashblend", string_null, _("Fake corona lighting"))); + makeMulti(e, "r_coronas"); + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticRadioButton(1, "r_shadow_realtime_dlight", string_null, _("Realtime dynamic lighting"))); + makeMulti(e, "r_coronas"); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_shadow_realtime_dlight_shadows", _("Shadows"))); + setDependent(e, "r_shadow_realtime_dlight", 1, 1); + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "r_shadow_realtime_world", _("Realtime world lighting"))); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_shadow_realtime_world_shadows", _("Shadows"))); + setDependent(e, "r_shadow_realtime_world", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "r_shadow_usenormalmap", _("Use normal maps"))); + setDependentOR(e, "r_shadow_realtime_dlight", 1, 1, "r_shadow_realtime_world", 1, 1); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_shadow_shadowmapping", _("Soft shadows"))); + setDependentWeird(e, someShadowCvarIsEnabled); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "r_coronas_occlusionquery", _("Fade corona according to visibility"))); + setDependent(e, "r_coronas", 1, 1); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "r_bloom", _("Bloom"))); + me.TD(me, 1, 2, e = makeXonoticCheckBoxEx(0.5, 0, "hud_postprocessing_maxbluralpha", _("Extra postprocessing effects"))); + makeMulti(e, "hud_powerup"); + setDependent(e, "vid_gl20", 1, 1); + me.TR(me); + s = makeXonoticSlider(0.1, 1, 0.1, "r_motionblur"); + me.TD(me, 1, 1, e = makeXonoticSliderCheckBox(0, 1, s, _("Motion blur:"))); + if(s.value != e.savedValue) + e.savedValue = 0.4; // default + me.TD(me, 1, 2, s); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_particles", _("Particles"))); + me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_spawn_point_particles", _("Spawnpoint effects"))); + makeMulti(e, "cl_spawn_event_particles"); + setDependent(e, "cl_particles", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Quality:"))); + setDependent(e, "cl_particles", 1, 1); + me.TD(me, 1, 2, e = makeXonoticParticlesSlider()); + setDependent(e, "cl_particles", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Distance:"))); + setDependent(e, "cl_particles", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(200, 500, 20, "r_drawparticles_drawdistance")); + setDependent(e, "cl_particles", 1, 1); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "vid_restart", COMMANDBUTTON_APPLY)); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game.c b/qcsrc/menu/xonotic/dialog_settings_game.c deleted file mode 100644 index 2f48c2a50..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_game.c +++ /dev/null @@ -1,54 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticGameSettingsTab) EXTENDS(XonoticTab) - METHOD(XonoticGameSettingsTab, fill, void(entity)) - ATTRIB(XonoticGameSettingsTab, title, string, _("Game")) - ATTRIB(XonoticGameSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticGameSettingsTab, rows, float, 15.5) - ATTRIB(XonoticGameSettingsTab, columns, float, 6.5) -ENDCLASS(XonoticGameSettingsTab) -entity makeXonoticGameSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticGameSettingsTab() -{ - entity me; - me = spawnXonoticGameSettingsTab(); - me.configureDialog(me); - return me; -} - -void XonoticGameSettingsTab_fill(entity me) -{ - entity mc; - mc = makeXonoticTabController(me.rows - 2.5); - - me.TR(me); - me.TDempty(me, 0.25); - me.TD(me, 1, 1, mc.makeTabButton(mc, _("View"), makeXonoticGameViewSettingsTab())); - me.TD(me, 1, 1, mc.makeTabButton(mc, _("Crosshair"), makeXonoticGameCrosshairSettingsTab())); - me.TD(me, 1, 1, mc.makeTabButton(mc, _("HUD"), makeXonoticGameHUDSettingsTab())); - me.TD(me, 1, 1, mc.makeTabButton(mc, _("Messages"), makeXonoticGameMessageSettingsTab())); - me.TD(me, 1, 1, mc.makeTabButton(mc, _("Weapons"), makeXonoticGameWeaponsSettingsTab())); - me.TD(me, 1, 1, mc.makeTabButton(mc, _("Models"), makeXonoticGameModelSettingsTab())); - - me.gotoRC(me, 1.5, 0); - me.TD(me, me.rows - 1.5, me.columns, mc); - - /* - - makeXonoticGameViewSettingsTab())); - makeXonoticGameGeneralSettingsTab())); - makeXonoticGameCrosshairSettingsTab())); - - makeXonoticGameWeaponSettingsTab())); - l"), makeXonoticGamePlayermodelSettingsTab())); - makeXonoticGameHUDSettingsTab())); - on"), makeXonoticGameNotificationSettingsTab())); - - - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_gentle", _("Disable gore effects and harsh language"))); // also set sv_gentle - */ -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game.qc b/qcsrc/menu/xonotic/dialog_settings_game.qc new file mode 100644 index 000000000..2f48c2a50 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_game.qc @@ -0,0 +1,54 @@ +#ifdef INTERFACE +CLASS(XonoticGameSettingsTab) EXTENDS(XonoticTab) + METHOD(XonoticGameSettingsTab, fill, void(entity)) + ATTRIB(XonoticGameSettingsTab, title, string, _("Game")) + ATTRIB(XonoticGameSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticGameSettingsTab, rows, float, 15.5) + ATTRIB(XonoticGameSettingsTab, columns, float, 6.5) +ENDCLASS(XonoticGameSettingsTab) +entity makeXonoticGameSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticGameSettingsTab() +{ + entity me; + me = spawnXonoticGameSettingsTab(); + me.configureDialog(me); + return me; +} + +void XonoticGameSettingsTab_fill(entity me) +{ + entity mc; + mc = makeXonoticTabController(me.rows - 2.5); + + me.TR(me); + me.TDempty(me, 0.25); + me.TD(me, 1, 1, mc.makeTabButton(mc, _("View"), makeXonoticGameViewSettingsTab())); + me.TD(me, 1, 1, mc.makeTabButton(mc, _("Crosshair"), makeXonoticGameCrosshairSettingsTab())); + me.TD(me, 1, 1, mc.makeTabButton(mc, _("HUD"), makeXonoticGameHUDSettingsTab())); + me.TD(me, 1, 1, mc.makeTabButton(mc, _("Messages"), makeXonoticGameMessageSettingsTab())); + me.TD(me, 1, 1, mc.makeTabButton(mc, _("Weapons"), makeXonoticGameWeaponsSettingsTab())); + me.TD(me, 1, 1, mc.makeTabButton(mc, _("Models"), makeXonoticGameModelSettingsTab())); + + me.gotoRC(me, 1.5, 0); + me.TD(me, me.rows - 1.5, me.columns, mc); + + /* + + makeXonoticGameViewSettingsTab())); + makeXonoticGameGeneralSettingsTab())); + makeXonoticGameCrosshairSettingsTab())); + + makeXonoticGameWeaponSettingsTab())); + l"), makeXonoticGamePlayermodelSettingsTab())); + makeXonoticGameHUDSettingsTab())); + on"), makeXonoticGameNotificationSettingsTab())); + + + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_gentle", _("Disable gore effects and harsh language"))); // also set sv_gentle + */ +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.c b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.c deleted file mode 100644 index 3e164c11f..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.c +++ /dev/null @@ -1,163 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticGameCrosshairSettingsTab) EXTENDS(XonoticTab) - //METHOD(XonoticGameCrosshairSettingsTab, toString, string(entity)) - METHOD(XonoticGameCrosshairSettingsTab, fill, void(entity)) - METHOD(XonoticGameCrosshairSettingsTab, showNotify, void(entity)) - ATTRIB(XonoticGameCrosshairSettingsTab, title, string, _("Crosshair")) - ATTRIB(XonoticGameCrosshairSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticGameCrosshairSettingsTab, rows, float, 13) - ATTRIB(XonoticGameCrosshairSettingsTab, columns, float, 6.2) -ENDCLASS(XonoticGameCrosshairSettingsTab) -entity makeXonoticGameCrosshairSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -void XonoticGameCrosshairSettingsTab_showNotify(entity me) -{ - loadAllCvars(me); -} -entity makeXonoticGameCrosshairSettingsTab() -{ - entity me; - me = spawnXonoticGameCrosshairSettingsTab(); - me.configureDialog(me); - return me; -} - -void XonoticGameCrosshairSettingsTab_fill(entity me) -{ - entity e; - float i; - - // crosshair_enabled: 0 = no crosshair options, 1 = no crosshair selection, but everything else enabled, 2 = all crosshair options enabled - // FIXME: In the future, perhaps make one global crosshair_type cvar which has 0 for disabled, 1 for custom, 2 for per weapon, etc? - me.TR(me); //me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 1, e = makeXonoticRadioButton(3, "crosshair_enabled", "0", _("No crosshair"))); - //me.TR(me); - me.TD(me, 1, 1, e = makeXonoticRadioButton(3, "crosshair_per_weapon", string_null, _("Per weapon"))); - makeMulti(e, "crosshair_enabled"); - //me.TR(me); - me.TD(me, 1, 1, e = makeXonoticRadioButton(3, "crosshair_enabled", "2", _("Custom"))); - me.TR(me); - me.TDempty(me, 0.1); - for(i = 1; i <= 14; ++i) { - me.TDNoMargin(me, 1, 2 / 14, e = makeXonoticCrosshairButton(4, i), '1 1 0'); - setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); - } - // show a larger preview of the selected crosshair - me.TDempty(me, 0.1); - me.TDNoMargin(me, 3, 0.8, e = makeXonoticCrosshairButton(7, -1), '1 1 0'); // crosshair -1 makes this a preview - setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); - me.TR(me); - me.TDempty(me, 0.1); - for(i = 15; i <= 28; ++i) { - me.TDNoMargin(me, 1, 2 / 14, e = makeXonoticCrosshairButton(4, i), '1 1 0'); - setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); - } - me.TR(me); - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Crosshair size:"))); - setDependent(e, "crosshair_enabled", 1, 2); - me.TD(me, 1, 1.9, e = makeXonoticSlider(0.1, 1.0, 0.01, "crosshair_size")); - setDependent(e, "crosshair_enabled", 1, 2); - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Crosshair alpha:"))); - setDependent(e, "crosshair_enabled", 1, 2); - me.TD(me, 1, 1.9, e = makeXonoticSlider(0, 1, 0.1, "crosshair_alpha")); - setDependent(e, "crosshair_enabled", 1, 2); - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Crosshair color:"))); - setDependent(e, "crosshair_enabled", 1, 2); - me.TD(me, 1, 0.9, e = makeXonoticRadioButton(5, "crosshair_color_special", "1", _("Per weapon"))); - setDependent(e, "crosshair_enabled", 1, 2); - me.TD(me, 1, 1, e = makeXonoticRadioButton(5, "crosshair_color_special", "2", _("By health"))); - setDependent(e, "crosshair_enabled", 1, 2); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticRadioButton(5, "crosshair_color_special", "0", _("Custom"))); - setDependent(e, "crosshair_enabled", 1, 2); - me.TD(me, 2, 2, e = makeXonoticColorpickerString("crosshair_color", "crosshair_color")); - setDependentAND(e, "crosshair_color_special", 0, 0, "crosshair_enabled", 1, 2); - me.TR(me); - me.TR(me); - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 2.9, e = makeXonoticCheckBox(0, "crosshair_ring", _("Use rings to indicate weapon status"))); - makeMulti(e, "crosshair_ring_reload"); - setDependent(e, "crosshair_enabled", 1, 2); - //me.TR(me); - // me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Ring size:"))); - // setDependentAND(e, "crosshair_ring", 1, 1, "crosshair_enabled", 1, 2); - // me.TD(me, 1, 2, e = makeXonoticSlider(2, 4, 0.1, "crosshair_ring_size")); - // setDependentAND(e, "crosshair_ring", 1, 1, "crosshair_enabled", 1, 2); - me.TR(me); - me.TDempty(me, 0.3); - me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Ring alpha:"))); - setDependentAND(e, "crosshair_ring", 1, 1, "crosshair_enabled", 1, 2); - me.TD(me, 1, 1.8, e = makeXonoticSlider(0.1, 1, 0.1, "crosshair_ring_alpha")); - setDependentAND(e, "crosshair_ring", 1, 1, "crosshair_enabled", 1, 2); - - me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_dot", _("Enable center crosshair dot"))); - setDependent(e, "crosshair_enabled", 1, 2); - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Dot size:"))); - setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); - me.TD(me, 1, 2, e = makeXonoticSlider(0.2, 2, 0.1, "crosshair_dot_size")); - setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Dot alpha:"))); - setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); - me.TD(me, 1, 2, e = makeXonoticSlider(0.1, 1, 0.1, "crosshair_dot_alpha")); - setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Dot color:"))); - setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); - me.TD(me, 1, 2, e = makeXonoticRadioButton(1, "crosshair_dot_color_custom", "0", _("Use normal crosshair color"))); - setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticRadioButton(1, "crosshair_dot_color_custom", "1", _("Custom"))); - setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); - me.TD(me, 2, 2, e = makeXonoticColorpickerString("crosshair_dot_color", "crosshair_dot_color")); - setDependentAND3(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2, "crosshair_dot_color_custom", 1, 1); - me.TR(me); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_effect_scalefade", _("Smooth effects of crosshairs"))); - setDependent(e, "crosshair_enabled", 1, 2); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_hittest_blur", _("Blur crosshair if the shot is obstructed"))); - setDependentAND(e, "crosshair_hittest", 1, 100, "crosshair_enabled", 1, 2); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(1.25, 0, "crosshair_hittest_scale", _("Enlarge crosshair if targeting an enemy"))); - setDependentAND(e, "crosshair_hittest", 1, 100, "crosshair_enabled", 1, 2); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(0.5, 0, "crosshair_hitindication", _("Animate crosshair when hitting an enemy"))); - setDependent(e, "crosshair_enabled", 1, 2); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(0.25, 0, "crosshair_pickup", _("Animate crosshair when picking up an item"))); - setDependent(e, "crosshair_enabled", 1, 2); - /*me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Hit testing:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("crosshair_hittest")); - e.addValue(e, ZCTX(_("HTTST^Disabled")), "0"); - e.addValue(e, ZCTX(_("HTTST^TrueAim")), "1"); - e.addValue(e, ZCTX(_("HTTST^Enemies")), "1.25"); - e.configureXonoticTextSliderValues(e); - setDependent(e, "crosshair_enabled", 1, 2);*/ - - /*me.TR(me); - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me;*/ -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc new file mode 100644 index 000000000..3e164c11f --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc @@ -0,0 +1,163 @@ +#ifdef INTERFACE +CLASS(XonoticGameCrosshairSettingsTab) EXTENDS(XonoticTab) + //METHOD(XonoticGameCrosshairSettingsTab, toString, string(entity)) + METHOD(XonoticGameCrosshairSettingsTab, fill, void(entity)) + METHOD(XonoticGameCrosshairSettingsTab, showNotify, void(entity)) + ATTRIB(XonoticGameCrosshairSettingsTab, title, string, _("Crosshair")) + ATTRIB(XonoticGameCrosshairSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticGameCrosshairSettingsTab, rows, float, 13) + ATTRIB(XonoticGameCrosshairSettingsTab, columns, float, 6.2) +ENDCLASS(XonoticGameCrosshairSettingsTab) +entity makeXonoticGameCrosshairSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +void XonoticGameCrosshairSettingsTab_showNotify(entity me) +{ + loadAllCvars(me); +} +entity makeXonoticGameCrosshairSettingsTab() +{ + entity me; + me = spawnXonoticGameCrosshairSettingsTab(); + me.configureDialog(me); + return me; +} + +void XonoticGameCrosshairSettingsTab_fill(entity me) +{ + entity e; + float i; + + // crosshair_enabled: 0 = no crosshair options, 1 = no crosshair selection, but everything else enabled, 2 = all crosshair options enabled + // FIXME: In the future, perhaps make one global crosshair_type cvar which has 0 for disabled, 1 for custom, 2 for per weapon, etc? + me.TR(me); //me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 1, e = makeXonoticRadioButton(3, "crosshair_enabled", "0", _("No crosshair"))); + //me.TR(me); + me.TD(me, 1, 1, e = makeXonoticRadioButton(3, "crosshair_per_weapon", string_null, _("Per weapon"))); + makeMulti(e, "crosshair_enabled"); + //me.TR(me); + me.TD(me, 1, 1, e = makeXonoticRadioButton(3, "crosshair_enabled", "2", _("Custom"))); + me.TR(me); + me.TDempty(me, 0.1); + for(i = 1; i <= 14; ++i) { + me.TDNoMargin(me, 1, 2 / 14, e = makeXonoticCrosshairButton(4, i), '1 1 0'); + setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); + } + // show a larger preview of the selected crosshair + me.TDempty(me, 0.1); + me.TDNoMargin(me, 3, 0.8, e = makeXonoticCrosshairButton(7, -1), '1 1 0'); // crosshair -1 makes this a preview + setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); + me.TR(me); + me.TDempty(me, 0.1); + for(i = 15; i <= 28; ++i) { + me.TDNoMargin(me, 1, 2 / 14, e = makeXonoticCrosshairButton(4, i), '1 1 0'); + setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2); + } + me.TR(me); + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Crosshair size:"))); + setDependent(e, "crosshair_enabled", 1, 2); + me.TD(me, 1, 1.9, e = makeXonoticSlider(0.1, 1.0, 0.01, "crosshair_size")); + setDependent(e, "crosshair_enabled", 1, 2); + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Crosshair alpha:"))); + setDependent(e, "crosshair_enabled", 1, 2); + me.TD(me, 1, 1.9, e = makeXonoticSlider(0, 1, 0.1, "crosshair_alpha")); + setDependent(e, "crosshair_enabled", 1, 2); + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Crosshair color:"))); + setDependent(e, "crosshair_enabled", 1, 2); + me.TD(me, 1, 0.9, e = makeXonoticRadioButton(5, "crosshair_color_special", "1", _("Per weapon"))); + setDependent(e, "crosshair_enabled", 1, 2); + me.TD(me, 1, 1, e = makeXonoticRadioButton(5, "crosshair_color_special", "2", _("By health"))); + setDependent(e, "crosshair_enabled", 1, 2); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticRadioButton(5, "crosshair_color_special", "0", _("Custom"))); + setDependent(e, "crosshair_enabled", 1, 2); + me.TD(me, 2, 2, e = makeXonoticColorpickerString("crosshair_color", "crosshair_color")); + setDependentAND(e, "crosshair_color_special", 0, 0, "crosshair_enabled", 1, 2); + me.TR(me); + me.TR(me); + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 2.9, e = makeXonoticCheckBox(0, "crosshair_ring", _("Use rings to indicate weapon status"))); + makeMulti(e, "crosshair_ring_reload"); + setDependent(e, "crosshair_enabled", 1, 2); + //me.TR(me); + // me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Ring size:"))); + // setDependentAND(e, "crosshair_ring", 1, 1, "crosshair_enabled", 1, 2); + // me.TD(me, 1, 2, e = makeXonoticSlider(2, 4, 0.1, "crosshair_ring_size")); + // setDependentAND(e, "crosshair_ring", 1, 1, "crosshair_enabled", 1, 2); + me.TR(me); + me.TDempty(me, 0.3); + me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Ring alpha:"))); + setDependentAND(e, "crosshair_ring", 1, 1, "crosshair_enabled", 1, 2); + me.TD(me, 1, 1.8, e = makeXonoticSlider(0.1, 1, 0.1, "crosshair_ring_alpha")); + setDependentAND(e, "crosshair_ring", 1, 1, "crosshair_enabled", 1, 2); + + me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_dot", _("Enable center crosshair dot"))); + setDependent(e, "crosshair_enabled", 1, 2); + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Dot size:"))); + setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); + me.TD(me, 1, 2, e = makeXonoticSlider(0.2, 2, 0.1, "crosshair_dot_size")); + setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Dot alpha:"))); + setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); + me.TD(me, 1, 2, e = makeXonoticSlider(0.1, 1, 0.1, "crosshair_dot_alpha")); + setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Dot color:"))); + setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); + me.TD(me, 1, 2, e = makeXonoticRadioButton(1, "crosshair_dot_color_custom", "0", _("Use normal crosshair color"))); + setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticRadioButton(1, "crosshair_dot_color_custom", "1", _("Custom"))); + setDependentAND(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2); + me.TD(me, 2, 2, e = makeXonoticColorpickerString("crosshair_dot_color", "crosshair_dot_color")); + setDependentAND3(e, "crosshair_dot", 1, 1, "crosshair_enabled", 1, 2, "crosshair_dot_color_custom", 1, 1); + me.TR(me); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_effect_scalefade", _("Smooth effects of crosshairs"))); + setDependent(e, "crosshair_enabled", 1, 2); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_hittest_blur", _("Blur crosshair if the shot is obstructed"))); + setDependentAND(e, "crosshair_hittest", 1, 100, "crosshair_enabled", 1, 2); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(1.25, 0, "crosshair_hittest_scale", _("Enlarge crosshair if targeting an enemy"))); + setDependentAND(e, "crosshair_hittest", 1, 100, "crosshair_enabled", 1, 2); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(0.5, 0, "crosshair_hitindication", _("Animate crosshair when hitting an enemy"))); + setDependent(e, "crosshair_enabled", 1, 2); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(0.25, 0, "crosshair_pickup", _("Animate crosshair when picking up an item"))); + setDependent(e, "crosshair_enabled", 1, 2); + /*me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Hit testing:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("crosshair_hittest")); + e.addValue(e, ZCTX(_("HTTST^Disabled")), "0"); + e.addValue(e, ZCTX(_("HTTST^TrueAim")), "1"); + e.addValue(e, ZCTX(_("HTTST^Enemies")), "1.25"); + e.configureXonoticTextSliderValues(e); + setDependent(e, "crosshair_enabled", 1, 2);*/ + + /*me.TR(me); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me;*/ +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hud.c b/qcsrc/menu/xonotic/dialog_settings_game_hud.c deleted file mode 100644 index fc7e3a136..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_game_hud.c +++ /dev/null @@ -1,173 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticGameHUDSettingsTab) EXTENDS(XonoticTab) - //METHOD(XonoticGameHUDSettingsTab, toString, string(entity)) - METHOD(XonoticGameHUDSettingsTab, fill, void(entity)) - METHOD(XonoticGameHUDSettingsTab, showNotify, void(entity)) - ATTRIB(XonoticGameHUDSettingsTab, title, string, _("HUD")) - ATTRIB(XonoticGameHUDSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticGameHUDSettingsTab, rows, float, 13) - ATTRIB(XonoticGameHUDSettingsTab, columns, float, 6.2) -ENDCLASS(XonoticGameHUDSettingsTab) -entity makeXonoticGameHUDSettingsTab(); -void HUDSetup_Start(entity me, entity btn); -#endif - -#ifdef IMPLEMENTATION -void HUDSetup_Check_Gamestatus(entity me, entity btn) -{ - if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) // we're not in a match, ask the player if they want to start one anyway - { - DialogOpenButton_Click(me, main.hudconfirmDialog); - } - else // already in a match, lets just cut to the point and open up the hud editor directly - { - HUDSetup_Start(me, btn); - } -} -void XonoticGameHUDSettingsTab_showNotify(entity me) -{ - loadAllCvars(me); -} -entity makeXonoticGameHUDSettingsTab() -{ - entity me; - me = spawnXonoticGameHUDSettingsTab(); - me.configureDialog(me); - return me; -} - -void XonoticGameHUDSettingsTab_fill(entity me) -{ - entity e; - - // todo: - // threshold: hud_damage_pain_threshold_lower_health - // scoreboard_alpha* - - //me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Scoreboard"))); - //me.TR(me); - // me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Alpha:"))); - // me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.05, "scoreboard_alpha_bg")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Fading speed:"))); - me.TD(me, 1, 2, e = makeXonoticScoreboardFadeTimeSlider()); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Side padding:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(0.05, 0.3, 0.01, "scoreboard_offset_left")); - makeMulti(e, "scoreboard_offset_right"); - - me.TR(me); - //me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "scoreboard_respawntime_decimals", _("Show decimals in respawn countdown"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "scoreboard_accuracy", _("Show accuracy underneath scoreboard"))); - - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Waypoints"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(1, "cl_hidewaypoints", _("Display waypoint markers for objectives on the map"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Alpha:"))); - setDependent(e, "cl_hidewaypoints", 0, 0); - me.TD(me, 1, 2, e = makeXonoticSlider(0.1, 1, 0.05, "g_waypointsprite_alpha")); - setDependent(e, "cl_hidewaypoints", 0, 0); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Fontsize:"))); - setDependent(e, "cl_hidewaypoints", 0, 0); - me.TD(me, 1, 2, e = makeXonoticSlider(5, 16, 1, "g_waypointsprite_fontsize")); - setDependent(e, "cl_hidewaypoints", 0, 0); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Edge offset:"))); - setDependent(e, "cl_hidewaypoints", 0, 0); - me.TD(me, 1, 2, e = makeXonoticSlider(0, 0.3, 0.01, "g_waypointsprite_edgeoffset_bottom")); - makeMulti(e, "g_waypointsprite_edgeoffset_top g_waypointsprite_edgeoffset_left g_waypointsprite_edgeoffset_right"); - setDependent(e, "cl_hidewaypoints", 0, 0); - - me.TR(me); - //me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(0.25, 1, "g_waypointsprite_crosshairfadealpha", _("Fade when near the crosshair"))); - setDependent(e, "cl_hidewaypoints", 0, 0); - - #if 0 - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Damage"))); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Overlay:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.05, "hud_damage")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Factor:"))); - setDependent(e, "hud_damage", 0.001, 100); - me.TD(me, 1, 2, e = makeXonoticSlider(0.025, 0.1, 0.025, "hud_damage_factor")); - setDependent(e, "hud_damage", 0.001, 100); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Fade rate:"))); - setDependent(e, "hud_damage", 0.001, 100); - me.TD(me, 1, 2, e = makeXonoticSlider(0.25, 1, 0.05, "hud_damage_fade_rate")); - setDependent(e, "hud_damage", 0.001, 100); - me.TR(me); - #endif - - me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Player Names"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "hud_shownames", _("Show names above players"))); - - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Alpha:"))); - setDependent(e, "hud_shownames", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(0.1, 1, 0.05, "hud_shownames_alpha")); - setDependent(e, "hud_shownames", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Fontsize:"))); - setDependent(e, "hud_shownames", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(5, 16, 1, "hud_shownames_fontsize")); - setDependent(e, "hud_shownames", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Max distance:"))); - setDependent(e, "hud_shownames", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(2000, 10000, 500, "hud_shownames_maxdistance")); - setDependent(e, "hud_shownames", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Decolorize:"))); - setDependent(e, "hud_shownames", 1, 1); - me.TD(me, 1, 2, e = makeXonoticTextSlider("hud_shownames_decolorize")); - e.addValue(e, ZCTX(_("Never")), "0"); - e.addValue(e, ZCTX(_("Teamplay")), "1"); - e.addValue(e, ZCTX(_("Always")), "2"); - e.configureXonoticTextSliderValues(e); - setDependent(e, "hud_shownames", 1, 1); - - me.TR(me); - //me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(25, 0, "hud_shownames_crosshairdistance", _("Only when near crosshair"))); - setDependent(e, "hud_shownames", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "hud_shownames_status", _("Display health and armor"))); - setDependent(e, "hud_shownames", 1, 1); - - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Damage overlay:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.05, "hud_damage")); - me.TR(me); - me.TR(me); - me.TDempty(me, 0.5); - me.TD(me, 1, 2, e = makeXonoticButton(_("Enter HUD editor"), '0 0 0')); - e.onClick = HUDSetup_Check_Gamestatus; - e.onClickEntity = me; - // TODO: show hud config name with text here -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hud.qc b/qcsrc/menu/xonotic/dialog_settings_game_hud.qc new file mode 100644 index 000000000..fc7e3a136 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_game_hud.qc @@ -0,0 +1,173 @@ +#ifdef INTERFACE +CLASS(XonoticGameHUDSettingsTab) EXTENDS(XonoticTab) + //METHOD(XonoticGameHUDSettingsTab, toString, string(entity)) + METHOD(XonoticGameHUDSettingsTab, fill, void(entity)) + METHOD(XonoticGameHUDSettingsTab, showNotify, void(entity)) + ATTRIB(XonoticGameHUDSettingsTab, title, string, _("HUD")) + ATTRIB(XonoticGameHUDSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticGameHUDSettingsTab, rows, float, 13) + ATTRIB(XonoticGameHUDSettingsTab, columns, float, 6.2) +ENDCLASS(XonoticGameHUDSettingsTab) +entity makeXonoticGameHUDSettingsTab(); +void HUDSetup_Start(entity me, entity btn); +#endif + +#ifdef IMPLEMENTATION +void HUDSetup_Check_Gamestatus(entity me, entity btn) +{ + if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) // we're not in a match, ask the player if they want to start one anyway + { + DialogOpenButton_Click(me, main.hudconfirmDialog); + } + else // already in a match, lets just cut to the point and open up the hud editor directly + { + HUDSetup_Start(me, btn); + } +} +void XonoticGameHUDSettingsTab_showNotify(entity me) +{ + loadAllCvars(me); +} +entity makeXonoticGameHUDSettingsTab() +{ + entity me; + me = spawnXonoticGameHUDSettingsTab(); + me.configureDialog(me); + return me; +} + +void XonoticGameHUDSettingsTab_fill(entity me) +{ + entity e; + + // todo: + // threshold: hud_damage_pain_threshold_lower_health + // scoreboard_alpha* + + //me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Scoreboard"))); + //me.TR(me); + // me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Alpha:"))); + // me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.05, "scoreboard_alpha_bg")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Fading speed:"))); + me.TD(me, 1, 2, e = makeXonoticScoreboardFadeTimeSlider()); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Side padding:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(0.05, 0.3, 0.01, "scoreboard_offset_left")); + makeMulti(e, "scoreboard_offset_right"); + + me.TR(me); + //me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "scoreboard_respawntime_decimals", _("Show decimals in respawn countdown"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "scoreboard_accuracy", _("Show accuracy underneath scoreboard"))); + + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Waypoints"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(1, "cl_hidewaypoints", _("Display waypoint markers for objectives on the map"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Alpha:"))); + setDependent(e, "cl_hidewaypoints", 0, 0); + me.TD(me, 1, 2, e = makeXonoticSlider(0.1, 1, 0.05, "g_waypointsprite_alpha")); + setDependent(e, "cl_hidewaypoints", 0, 0); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Fontsize:"))); + setDependent(e, "cl_hidewaypoints", 0, 0); + me.TD(me, 1, 2, e = makeXonoticSlider(5, 16, 1, "g_waypointsprite_fontsize")); + setDependent(e, "cl_hidewaypoints", 0, 0); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Edge offset:"))); + setDependent(e, "cl_hidewaypoints", 0, 0); + me.TD(me, 1, 2, e = makeXonoticSlider(0, 0.3, 0.01, "g_waypointsprite_edgeoffset_bottom")); + makeMulti(e, "g_waypointsprite_edgeoffset_top g_waypointsprite_edgeoffset_left g_waypointsprite_edgeoffset_right"); + setDependent(e, "cl_hidewaypoints", 0, 0); + + me.TR(me); + //me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(0.25, 1, "g_waypointsprite_crosshairfadealpha", _("Fade when near the crosshair"))); + setDependent(e, "cl_hidewaypoints", 0, 0); + + #if 0 + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Damage"))); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Overlay:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.05, "hud_damage")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Factor:"))); + setDependent(e, "hud_damage", 0.001, 100); + me.TD(me, 1, 2, e = makeXonoticSlider(0.025, 0.1, 0.025, "hud_damage_factor")); + setDependent(e, "hud_damage", 0.001, 100); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Fade rate:"))); + setDependent(e, "hud_damage", 0.001, 100); + me.TD(me, 1, 2, e = makeXonoticSlider(0.25, 1, 0.05, "hud_damage_fade_rate")); + setDependent(e, "hud_damage", 0.001, 100); + me.TR(me); + #endif + + me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Player Names"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "hud_shownames", _("Show names above players"))); + + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Alpha:"))); + setDependent(e, "hud_shownames", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(0.1, 1, 0.05, "hud_shownames_alpha")); + setDependent(e, "hud_shownames", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Fontsize:"))); + setDependent(e, "hud_shownames", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(5, 16, 1, "hud_shownames_fontsize")); + setDependent(e, "hud_shownames", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Max distance:"))); + setDependent(e, "hud_shownames", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(2000, 10000, 500, "hud_shownames_maxdistance")); + setDependent(e, "hud_shownames", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Decolorize:"))); + setDependent(e, "hud_shownames", 1, 1); + me.TD(me, 1, 2, e = makeXonoticTextSlider("hud_shownames_decolorize")); + e.addValue(e, ZCTX(_("Never")), "0"); + e.addValue(e, ZCTX(_("Teamplay")), "1"); + e.addValue(e, ZCTX(_("Always")), "2"); + e.configureXonoticTextSliderValues(e); + setDependent(e, "hud_shownames", 1, 1); + + me.TR(me); + //me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(25, 0, "hud_shownames_crosshairdistance", _("Only when near crosshair"))); + setDependent(e, "hud_shownames", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "hud_shownames_status", _("Display health and armor"))); + setDependent(e, "hud_shownames", 1, 1); + + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Damage overlay:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.05, "hud_damage")); + me.TR(me); + me.TR(me); + me.TDempty(me, 0.5); + me.TD(me, 1, 2, e = makeXonoticButton(_("Enter HUD editor"), '0 0 0')); + e.onClick = HUDSetup_Check_Gamestatus; + e.onClickEntity = me; + // TODO: show hud config name with text here +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.c b/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.c deleted file mode 100644 index 7749a148d..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.c +++ /dev/null @@ -1,40 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticHUDConfirmDialog) EXTENDS(XonoticDialog) - METHOD(XonoticHUDConfirmDialog, fill, void(entity)) - ATTRIB(XonoticHUDConfirmDialog, title, string, _("Enter HUD editor")) - ATTRIB(XonoticHUDConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) - ATTRIB(XonoticHUDConfirmDialog, intendedWidth, float, 0.5) - ATTRIB(XonoticHUDConfirmDialog, rows, float, 4) - ATTRIB(XonoticHUDConfirmDialog, columns, float, 2) -ENDCLASS(XonoticHUDConfirmDialog) -#endif - -#ifdef IMPLEMENTATION -void HUDSetup_Start(entity me, entity btn) -{ - if (!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) - localcmd("map hudsetup/hudsetup", "\n"); - else - localcmd("togglemenu 0\n"); - - localcmd("_hud_configure 1", "\n"); -} - -void XonoticHUDConfirmDialog_fill(entity me) -{ - entity e; - - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("In order for the HUD editor to show, you must first be in game."))); - me.TR(me); - me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Do you wish to start a local game to set up the HUD?"))); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("HDCNFRM^Yes")), '1 0 0')); - e.onClick = HUDSetup_Start; - e.onClickEntity = me; - me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("HDCNFRM^No")), '0 1 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc b/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc new file mode 100644 index 000000000..7749a148d --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc @@ -0,0 +1,40 @@ +#ifdef INTERFACE +CLASS(XonoticHUDConfirmDialog) EXTENDS(XonoticDialog) + METHOD(XonoticHUDConfirmDialog, fill, void(entity)) + ATTRIB(XonoticHUDConfirmDialog, title, string, _("Enter HUD editor")) + ATTRIB(XonoticHUDConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) + ATTRIB(XonoticHUDConfirmDialog, intendedWidth, float, 0.5) + ATTRIB(XonoticHUDConfirmDialog, rows, float, 4) + ATTRIB(XonoticHUDConfirmDialog, columns, float, 2) +ENDCLASS(XonoticHUDConfirmDialog) +#endif + +#ifdef IMPLEMENTATION +void HUDSetup_Start(entity me, entity btn) +{ + if (!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) + localcmd("map hudsetup/hudsetup", "\n"); + else + localcmd("togglemenu 0\n"); + + localcmd("_hud_configure 1", "\n"); +} + +void XonoticHUDConfirmDialog_fill(entity me) +{ + entity e; + + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("In order for the HUD editor to show, you must first be in game."))); + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Do you wish to start a local game to set up the HUD?"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("HDCNFRM^Yes")), '1 0 0')); + e.onClick = HUDSetup_Start; + e.onClickEntity = me; + me.TD(me, 1, 1, e = makeXonoticButton(ZCTX(_("HDCNFRM^No")), '0 1 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_messages.c b/qcsrc/menu/xonotic/dialog_settings_game_messages.c deleted file mode 100644 index 6f605ccbc..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_game_messages.c +++ /dev/null @@ -1,119 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticGameMessageSettingsTab) EXTENDS(XonoticTab) - //METHOD(XonoticGameWeaponsSettingsTab, toString, string(entity)) - METHOD(XonoticGameMessageSettingsTab, fill, void(entity)) - METHOD(XonoticGameMessageSettingsTab, showNotify, void(entity)) - ATTRIB(XonoticGameMessageSettingsTab, title, string, _("Messages")) - ATTRIB(XonoticGameMessageSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticGameMessageSettingsTab, rows, float, 13) - ATTRIB(XonoticGameMessageSettingsTab, columns, float, 6) - ATTRIB(XonoticGameMessageSettingsTab, weaponsList, entity, NULL) -ENDCLASS(XonoticGameMessageSettingsTab) -entity makeXonoticGameMessageSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -void XonoticGameMessageSettingsTab_showNotify(entity me) -{ - loadAllCvars(me); -} -entity makeXonoticGameMessageSettingsTab() -{ - entity me; - me = spawnXonoticGameMessageSettingsTab(); - me.configureDialog(me); - return me; -} - -void XonoticGameMessageSettingsTab_fill(entity me) -{ - entity e; - - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Frag Information"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_show_sprees", _("Display information about killing sprees"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "notification_show_sprees_info_specialonly", _("Only display sprees if they are achievements"))); - makeMulti(e, "notification_show_sprees_center_specialonly"); - setDependent(e, "notification_show_sprees", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "notification_show_sprees_center", _("Show spree information in centerprints"))); - setDependent(e, "notification_show_sprees", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(3, 0, "notification_show_sprees_info", _("Show spree information in death messages"))); - setDependent(e, "notification_show_sprees", 1, 1); - #if 0 - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Sprees in info messages:"))); - setDependent(e, "notification_show_sprees", 1, 1); - me.TD(me, 1, 2, e = makeXonoticTextSlider("notification_show_sprees_info")); - e.addValue(e, ZCTX(_("Disabled")), "0"); - e.addValue(e, ZCTX(_("Target")), "1"); - e.addValue(e, ZCTX(_("Attacker")), "2"); - e.addValue(e, ZCTX(_("Both")), "3"); - e.configureXonoticTextSliderValues(e); - setDependent(e, "notification_show_sprees", 1, 1); - #endif - me.TR(me); - me.TDempty(me, 0.4); - me.TD(me, 1, 2.6, e = makeXonoticCheckBox(0, "notification_show_sprees_info_newline", _("Print on a seperate line"))); - setDependent(e, "notification_show_sprees", 1, 1); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_CHOICE_FRAG", _("Add extra frag information to centerprint when available"))); - makeMulti(e, "notification_CHOICE_FRAGGED notification_CHOICE_TYPEFRAG notification_CHOICE_TYPEFRAGGED"); - e.sendCvars = TRUE; - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_show_location", _("Add frag location to death messages when available"))); - - me.gotoRC(me, 9, 0); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Gamemode Settings"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_CHOICE_CTF_CAPTURE_TIME_RED", _("Display capture times in Capture The Flag"))); - makeMulti(e, "notification_CHOICE_CTF_CAPTURE_TIME_BLUE notification_CHOICE_CTF_CAPTURE_BROKEN_RED notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE "); - e.sendCvars = TRUE; - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_CHOICE_CTF_PICKUP_ENEMY", _("Display name of flag stealer in Capture The Flag"))); - makeMulti(e, "notification_CHOICE_CTF_PICKUP_TEAM"); - e.sendCvars = TRUE; - - me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Other"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(4, 1, "con_notify", _("Display console messages in the top left corner"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_allow_chatboxprint", _("Display all info messages in the chatbox"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_INFO_QUIT_DISCONNECT", _("Display player statuses in the chatbox"))); - makeMulti(e, "notification_INFO_QUIT_KICK_IDLING notification_INFO_JOIN_CONNECT_TEAM_BLUE notification_INFO_JOIN_CONNECT_TEAM_PINK notification_INFO_JOIN_CONNECT_TEAM_RED notification_INFO_JOIN_CONNECT_TEAM_YELLOW"); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_CENTER_POWERUP_INVISIBILITY", _("Powerup notifications"))); - makeMulti(e, "notification_CENTER_POWERUP_SHIELD notification_CENTER_POWERUP_SPEED notification_CENTER_POWERUP_STRENGTH notification_CENTER_POWERDOWN_INVISIBILITY notification_CENTER_POWERDOWN_SHIELD notification_CENTER_POWERDOWN_SPEED notification_CENTER_POWERDOWN_STRENGTH notification_CENTER_SUPERWEAPON_BROKEN notification_CENTER_SUPERWEAPON_LOST notification_CENTER_SUPERWEAPON_PICKUP notification_INFO_POWERUP_INVISIBILITY notification_INFO_POWERUP_SHIELD notification_INFO_POWERUP_SPEED notification_INFO_POWERUP_STRENGTH"); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_CENTER_ITEM_WEAPON_DONTHAVE", _("Weapon centerprint notifications"))); - makeMulti(e, "notification_CENTER_ITEM_WEAPON_DROP notification_CENTER_ITEM_WEAPON_GOT notification_CENTER_ITEM_WEAPON_NOAMMO notification_CENTER_ITEM_WEAPON_PRIMORSEC notification_CENTER_ITEM_WEAPON_UNAVAILABLE"); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_INFO_ITEM_WEAPON_DONTHAVE", _("Weapon info message notifications"))); - makeMulti(e, "notification_INFO_ITEM_WEAPON_DROP notification_INFO_ITEM_WEAPON_GOT notification_INFO_ITEM_WEAPON_NOAMMO notification_INFO_ITEM_WEAPON_PRIMORSEC notification_INFO_ITEM_WEAPON_UNAVAILABLE"); - - me.gotoRC(me, 9, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Announcers"))); - #if 0 - // there's just not enough room for this, and it's not important enough to justify... - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 0, "notification_ANNCE_NUM_RESPAWN_1", _("Respawn countdown sounds"))); - makeMulti(e, "notification_ANNCE_NUM_RESPAWN_2 notification_ANNCE_NUM_RESPAWN_3 notification_ANNCE_NUM_RESPAWN_4 notification_ANNCE_NUM_RESPAWN_5 notification_ANNCE_NUM_RESPAWN_6 notification_ANNCE_NUM_RESPAWN_7 notification_ANNCE_NUM_RESPAWN_8 notification_ANNCE_NUM_RESPAWN_9 notification_ANNCE_NUM_RESPAWN_10"); - #endif - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(1, 0, "notification_ANNCE_KILLSTREAK_03", _("Killstreak sounds"))); - makeMulti(e, "notification_ANNCE_KILLSTREAK_05 notification_ANNCE_KILLSTREAK_10 notification_ANNCE_KILLSTREAK_15 notification_ANNCE_KILLSTREAK_20 notification_ANNCE_KILLSTREAK_25 notification_ANNCE_KILLSTREAK_30"); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(1, 0, "notification_ANNCE_ACHIEVEMENT_AIRSHOT", _("Achievement sounds"))); - makeMulti(e, "notification_ANNCE_ACHIEVEMENT_AMAZING notification_ANNCE_ACHIEVEMENT_AWESOME notification_ANNCE_ACHIEVEMENT_BOTLIKE notification_ANNCE_ACHIEVEMENT_ELECTROBITCH notification_ANNCE_ACHIEVEMENT_IMPRESSIVE notification_ANNCE_ACHIEVEMENT_YODA"); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_messages.qc b/qcsrc/menu/xonotic/dialog_settings_game_messages.qc new file mode 100644 index 000000000..6f605ccbc --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_game_messages.qc @@ -0,0 +1,119 @@ +#ifdef INTERFACE +CLASS(XonoticGameMessageSettingsTab) EXTENDS(XonoticTab) + //METHOD(XonoticGameWeaponsSettingsTab, toString, string(entity)) + METHOD(XonoticGameMessageSettingsTab, fill, void(entity)) + METHOD(XonoticGameMessageSettingsTab, showNotify, void(entity)) + ATTRIB(XonoticGameMessageSettingsTab, title, string, _("Messages")) + ATTRIB(XonoticGameMessageSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticGameMessageSettingsTab, rows, float, 13) + ATTRIB(XonoticGameMessageSettingsTab, columns, float, 6) + ATTRIB(XonoticGameMessageSettingsTab, weaponsList, entity, NULL) +ENDCLASS(XonoticGameMessageSettingsTab) +entity makeXonoticGameMessageSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +void XonoticGameMessageSettingsTab_showNotify(entity me) +{ + loadAllCvars(me); +} +entity makeXonoticGameMessageSettingsTab() +{ + entity me; + me = spawnXonoticGameMessageSettingsTab(); + me.configureDialog(me); + return me; +} + +void XonoticGameMessageSettingsTab_fill(entity me) +{ + entity e; + + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Frag Information"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_show_sprees", _("Display information about killing sprees"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "notification_show_sprees_info_specialonly", _("Only display sprees if they are achievements"))); + makeMulti(e, "notification_show_sprees_center_specialonly"); + setDependent(e, "notification_show_sprees", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "notification_show_sprees_center", _("Show spree information in centerprints"))); + setDependent(e, "notification_show_sprees", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(3, 0, "notification_show_sprees_info", _("Show spree information in death messages"))); + setDependent(e, "notification_show_sprees", 1, 1); + #if 0 + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Sprees in info messages:"))); + setDependent(e, "notification_show_sprees", 1, 1); + me.TD(me, 1, 2, e = makeXonoticTextSlider("notification_show_sprees_info")); + e.addValue(e, ZCTX(_("Disabled")), "0"); + e.addValue(e, ZCTX(_("Target")), "1"); + e.addValue(e, ZCTX(_("Attacker")), "2"); + e.addValue(e, ZCTX(_("Both")), "3"); + e.configureXonoticTextSliderValues(e); + setDependent(e, "notification_show_sprees", 1, 1); + #endif + me.TR(me); + me.TDempty(me, 0.4); + me.TD(me, 1, 2.6, e = makeXonoticCheckBox(0, "notification_show_sprees_info_newline", _("Print on a seperate line"))); + setDependent(e, "notification_show_sprees", 1, 1); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_CHOICE_FRAG", _("Add extra frag information to centerprint when available"))); + makeMulti(e, "notification_CHOICE_FRAGGED notification_CHOICE_TYPEFRAG notification_CHOICE_TYPEFRAGGED"); + e.sendCvars = TRUE; + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_show_location", _("Add frag location to death messages when available"))); + + me.gotoRC(me, 9, 0); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Gamemode Settings"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_CHOICE_CTF_CAPTURE_TIME_RED", _("Display capture times in Capture The Flag"))); + makeMulti(e, "notification_CHOICE_CTF_CAPTURE_TIME_BLUE notification_CHOICE_CTF_CAPTURE_BROKEN_RED notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE "); + e.sendCvars = TRUE; + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_CHOICE_CTF_PICKUP_ENEMY", _("Display name of flag stealer in Capture The Flag"))); + makeMulti(e, "notification_CHOICE_CTF_PICKUP_TEAM"); + e.sendCvars = TRUE; + + me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Other"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(4, 1, "con_notify", _("Display console messages in the top left corner"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_allow_chatboxprint", _("Display all info messages in the chatbox"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "notification_INFO_QUIT_DISCONNECT", _("Display player statuses in the chatbox"))); + makeMulti(e, "notification_INFO_QUIT_KICK_IDLING notification_INFO_JOIN_CONNECT_TEAM_BLUE notification_INFO_JOIN_CONNECT_TEAM_PINK notification_INFO_JOIN_CONNECT_TEAM_RED notification_INFO_JOIN_CONNECT_TEAM_YELLOW"); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_CENTER_POWERUP_INVISIBILITY", _("Powerup notifications"))); + makeMulti(e, "notification_CENTER_POWERUP_SHIELD notification_CENTER_POWERUP_SPEED notification_CENTER_POWERUP_STRENGTH notification_CENTER_POWERDOWN_INVISIBILITY notification_CENTER_POWERDOWN_SHIELD notification_CENTER_POWERDOWN_SPEED notification_CENTER_POWERDOWN_STRENGTH notification_CENTER_SUPERWEAPON_BROKEN notification_CENTER_SUPERWEAPON_LOST notification_CENTER_SUPERWEAPON_PICKUP notification_INFO_POWERUP_INVISIBILITY notification_INFO_POWERUP_SHIELD notification_INFO_POWERUP_SPEED notification_INFO_POWERUP_STRENGTH"); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_CENTER_ITEM_WEAPON_DONTHAVE", _("Weapon centerprint notifications"))); + makeMulti(e, "notification_CENTER_ITEM_WEAPON_DROP notification_CENTER_ITEM_WEAPON_GOT notification_CENTER_ITEM_WEAPON_NOAMMO notification_CENTER_ITEM_WEAPON_PRIMORSEC notification_CENTER_ITEM_WEAPON_UNAVAILABLE"); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "notification_INFO_ITEM_WEAPON_DONTHAVE", _("Weapon info message notifications"))); + makeMulti(e, "notification_INFO_ITEM_WEAPON_DROP notification_INFO_ITEM_WEAPON_GOT notification_INFO_ITEM_WEAPON_NOAMMO notification_INFO_ITEM_WEAPON_PRIMORSEC notification_INFO_ITEM_WEAPON_UNAVAILABLE"); + + me.gotoRC(me, 9, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Announcers"))); + #if 0 + // there's just not enough room for this, and it's not important enough to justify... + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 0, "notification_ANNCE_NUM_RESPAWN_1", _("Respawn countdown sounds"))); + makeMulti(e, "notification_ANNCE_NUM_RESPAWN_2 notification_ANNCE_NUM_RESPAWN_3 notification_ANNCE_NUM_RESPAWN_4 notification_ANNCE_NUM_RESPAWN_5 notification_ANNCE_NUM_RESPAWN_6 notification_ANNCE_NUM_RESPAWN_7 notification_ANNCE_NUM_RESPAWN_8 notification_ANNCE_NUM_RESPAWN_9 notification_ANNCE_NUM_RESPAWN_10"); + #endif + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(1, 0, "notification_ANNCE_KILLSTREAK_03", _("Killstreak sounds"))); + makeMulti(e, "notification_ANNCE_KILLSTREAK_05 notification_ANNCE_KILLSTREAK_10 notification_ANNCE_KILLSTREAK_15 notification_ANNCE_KILLSTREAK_20 notification_ANNCE_KILLSTREAK_25 notification_ANNCE_KILLSTREAK_30"); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(1, 0, "notification_ANNCE_ACHIEVEMENT_AIRSHOT", _("Achievement sounds"))); + makeMulti(e, "notification_ANNCE_ACHIEVEMENT_AMAZING notification_ANNCE_ACHIEVEMENT_AWESOME notification_ANNCE_ACHIEVEMENT_BOTLIKE notification_ANNCE_ACHIEVEMENT_ELECTROBITCH notification_ANNCE_ACHIEVEMENT_IMPRESSIVE notification_ANNCE_ACHIEVEMENT_YODA"); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_model.c b/qcsrc/menu/xonotic/dialog_settings_game_model.c deleted file mode 100644 index c2aedc1f7..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_game_model.c +++ /dev/null @@ -1,74 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticGameModelSettingsTab) EXTENDS(XonoticTab) - //METHOD(XonoticGameModelSettingsTab, toString, string(entity)) - METHOD(XonoticGameModelSettingsTab, fill, void(entity)) - METHOD(XonoticGameModelSettingsTab, showNotify, void(entity)) - ATTRIB(XonoticGameModelSettingsTab, title, string, _("Model")) - ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticGameModelSettingsTab, rows, float, 13) - ATTRIB(XonoticGameModelSettingsTab, columns, float, 5) -ENDCLASS(XonoticGameModelSettingsTab) -entity makeXonoticGameModelSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -void XonoticGameModelSettingsTab_showNotify(entity me) -{ - loadAllCvars(me); -} -entity makeXonoticGameModelSettingsTab() -{ - entity me; - me = spawnXonoticGameModelSettingsTab(); - me.configureDialog(me); - return me; -} - -void XonoticGameModelSettingsTab_fill(entity me) -{ - entity e; - //float i; - - // Note that this is pretty terrible currently due to the lack of options for this tab... - // There is really not many other decent places for these options, additionally - // later I would like quite a few more options in this tab. - - me.gotoRC(me, 0, 1); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Items"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_simple_items", _("Use simple 2D images instead of item models"))); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Unavailable alpha:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.1, "cl_ghost_items")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Unavailable color:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_ghost_items_color")); - e.addValue(e, ZCTX(_("GHOITEMS^Black")), "-1 -1 -1"); - e.addValue(e, ZCTX(_("GHOITEMS^Dark")), "0.1 0.1 0.1"); - e.addValue(e, ZCTX(_("GHOITEMS^Tinted")), "0.6 0.6 0.6"); - e.addValue(e, ZCTX(_("GHOITEMS^Normal")), "1 1 1"); - e.addValue(e, ZCTX(_("GHOITEMS^Blue")), "-1 -1 3"); - e.configureXonoticTextSliderValues(e); - setDependent(e, "cl_ghost_items", 0.001, 1); - - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Players"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_forceplayermodels", _("Force player models to mine"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_forceplayercolors", _("Force player colors to mine"))); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Body fading:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(0, 2, 0.2, "cl_deathglow")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Gibs:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_nogibs")); - e.addValue(e, ZCTX(_("GIBS^None")), "1"); - e.addValue(e, ZCTX(_("GIBS^Few")), "0.75"); - e.addValue(e, ZCTX(_("GIBS^Many")), "0.5"); - e.addValue(e, ZCTX(_("GIBS^Lots")), "0"); - e.configureXonoticTextSliderValues(e); - setDependent(e, "cl_gentle", 0, 0); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_model.qc b/qcsrc/menu/xonotic/dialog_settings_game_model.qc new file mode 100644 index 000000000..c2aedc1f7 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_game_model.qc @@ -0,0 +1,74 @@ +#ifdef INTERFACE +CLASS(XonoticGameModelSettingsTab) EXTENDS(XonoticTab) + //METHOD(XonoticGameModelSettingsTab, toString, string(entity)) + METHOD(XonoticGameModelSettingsTab, fill, void(entity)) + METHOD(XonoticGameModelSettingsTab, showNotify, void(entity)) + ATTRIB(XonoticGameModelSettingsTab, title, string, _("Model")) + ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticGameModelSettingsTab, rows, float, 13) + ATTRIB(XonoticGameModelSettingsTab, columns, float, 5) +ENDCLASS(XonoticGameModelSettingsTab) +entity makeXonoticGameModelSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +void XonoticGameModelSettingsTab_showNotify(entity me) +{ + loadAllCvars(me); +} +entity makeXonoticGameModelSettingsTab() +{ + entity me; + me = spawnXonoticGameModelSettingsTab(); + me.configureDialog(me); + return me; +} + +void XonoticGameModelSettingsTab_fill(entity me) +{ + entity e; + //float i; + + // Note that this is pretty terrible currently due to the lack of options for this tab... + // There is really not many other decent places for these options, additionally + // later I would like quite a few more options in this tab. + + me.gotoRC(me, 0, 1); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Items"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_simple_items", _("Use simple 2D images instead of item models"))); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Unavailable alpha:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.1, "cl_ghost_items")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Unavailable color:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_ghost_items_color")); + e.addValue(e, ZCTX(_("GHOITEMS^Black")), "-1 -1 -1"); + e.addValue(e, ZCTX(_("GHOITEMS^Dark")), "0.1 0.1 0.1"); + e.addValue(e, ZCTX(_("GHOITEMS^Tinted")), "0.6 0.6 0.6"); + e.addValue(e, ZCTX(_("GHOITEMS^Normal")), "1 1 1"); + e.addValue(e, ZCTX(_("GHOITEMS^Blue")), "-1 -1 3"); + e.configureXonoticTextSliderValues(e); + setDependent(e, "cl_ghost_items", 0.001, 1); + + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Players"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_forceplayermodels", _("Force player models to mine"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_forceplayercolors", _("Force player colors to mine"))); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Body fading:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(0, 2, 0.2, "cl_deathglow")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Gibs:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_nogibs")); + e.addValue(e, ZCTX(_("GIBS^None")), "1"); + e.addValue(e, ZCTX(_("GIBS^Few")), "0.75"); + e.addValue(e, ZCTX(_("GIBS^Many")), "0.5"); + e.addValue(e, ZCTX(_("GIBS^Lots")), "0"); + e.configureXonoticTextSliderValues(e); + setDependent(e, "cl_gentle", 0, 0); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_view.c b/qcsrc/menu/xonotic/dialog_settings_game_view.c deleted file mode 100644 index 3fd451265..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_game_view.c +++ /dev/null @@ -1,124 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticGameViewSettingsTab) EXTENDS(XonoticTab) - //METHOD(XonoticGameCrosshairSettingsTab, toString, string(entity)) - METHOD(XonoticGameViewSettingsTab, fill, void(entity)) - METHOD(XonoticGameViewSettingsTab, showNotify, void(entity)) - ATTRIB(XonoticGameViewSettingsTab, title, string, _("View")) - ATTRIB(XonoticGameViewSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticGameViewSettingsTab, rows, float, 13) - ATTRIB(XonoticGameViewSettingsTab, columns, float, 6.2) -ENDCLASS(XonoticGameViewSettingsTab) -entity makeXonoticGameViewSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -void XonoticGameViewSettingsTab_showNotify(entity me) -{ - loadAllCvars(me); -} -entity makeXonoticGameViewSettingsTab() -{ - entity me; - me = spawnXonoticGameViewSettingsTab(); - me.configureDialog(me); - return me; -} - -void XonoticGameViewSettingsTab_fill(entity me) -{ - entity e; - - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "chase_active", "0", _("1st person perspective"))); - makeMulti(e, "crosshair_hittest_showimpact"); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_eventchase_death", _("Slide to third person upon death"))); - setDependent(e, "chase_active", -1, 0); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(0.05, 0, "cl_bobfall", _("Smooth the view when landing from a jump"))); - setDependent(e, "chase_active", -1, 0); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(0.05, 0, "cl_smoothviewheight", _("Smooth the view while crouching"))); - setDependent(e, "chase_active", -1, 0); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(1, 0, "v_idlescale", _("View waving while idle"))); - setDependent(e, "chase_active", -1, 0); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(0.01, 0, "cl_bob", _("View bobbing while walking around"))); - makeMulti(e, "cl_bob2"); - setDependent(e, "chase_active", -1, 0); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "chase_active", "1", _("3rd person perspective"))); - makeMulti(e, "crosshair_hittest_showimpact"); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Back distance"))); - setDependent(e, "chase_active", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(10, 100, 1, "chase_back")); - setDependent(e, "chase_active", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Up distance"))); - setDependent(e, "chase_active", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(10, 50, 1, "chase_up")); - setDependent(e, "chase_active", 1, 1); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(1, "cl_clippedspectating", _("Allow passing through walls while spectating"))); - - me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Field of view:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(60, 130, 5, "fov")); - me.TR(me); - me.TR(me); - //me.TDempty(me, 0.2); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, ZCTX(_("ZOOM^Zoom factor:")))); - me.TD(me, 1, 2, e = makeXonoticSlider(2, 16, 0.5, "cl_zoomfactor")); - me.TR(me); - //me.TDempty(me, 0.2); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, ZCTX(_("ZOOM^Zoom speed:")))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_zoomspeed")); - e.addValue(e, "1", "1"); // Samual: for() loop doesn't work here, even though it would make sense. - e.addValue(e, "2", "2"); - e.addValue(e, "3", "3"); - e.addValue(e, "4", "4"); - e.addValue(e, "5", "5"); - e.addValue(e, "6", "6"); - e.addValue(e, "7", "7"); - e.addValue(e, "8", "8"); - e.addValue(e, ZCTX(_("ZOOM^Instant")), "-1"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - //me.TDempty(me, 0.2); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, ZCTX(_("ZOOM^Zoom sensitivity:")))); - me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.1, "cl_zoomsensitivity")); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_velocityzoom_enabled", _("Velocity zoom"))); - me.TD(me, 1, 2, e = makeXonoticCheckBoxEx(3, 1, "cl_velocityzoom_type", _("Forward movement only"))); - setDependent(e, "cl_velocityzoom_enabled", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, ZCTX(_("VZOOM^Factor")))); - setDependentAND(e, "cl_velocityzoom_enabled", 1, 1, "cl_velocityzoom_type", 1, 3); - me.TD(me, 1, 2, e = makeXonoticSlider(-1, 1, 0.1, "cl_velocityzoom_factor")); - setDependentAND(e, "cl_velocityzoom_enabled", 1, 1, "cl_velocityzoom_type", 1, 3); - me.TR(me); - me.TR(me); - //me.TDempty(me, 0.2); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_reticle", _("Display reticle 2D overlay while zooming"))); - me.TR(me); - //me.TDempty(me, 0.2); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_unpress_zoom_on_death", _("Release zoom when you die or respawn"))); - makeMulti(e, "cl_unpress_zoom_on_spawn"); - me.TR(me); - //me.TDempty(me, 0.2); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_unpress_zoom_on_weapon_switch", _("Release zoom when you switch weapons"))); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_view.qc b/qcsrc/menu/xonotic/dialog_settings_game_view.qc new file mode 100644 index 000000000..3fd451265 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_game_view.qc @@ -0,0 +1,124 @@ +#ifdef INTERFACE +CLASS(XonoticGameViewSettingsTab) EXTENDS(XonoticTab) + //METHOD(XonoticGameCrosshairSettingsTab, toString, string(entity)) + METHOD(XonoticGameViewSettingsTab, fill, void(entity)) + METHOD(XonoticGameViewSettingsTab, showNotify, void(entity)) + ATTRIB(XonoticGameViewSettingsTab, title, string, _("View")) + ATTRIB(XonoticGameViewSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticGameViewSettingsTab, rows, float, 13) + ATTRIB(XonoticGameViewSettingsTab, columns, float, 6.2) +ENDCLASS(XonoticGameViewSettingsTab) +entity makeXonoticGameViewSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +void XonoticGameViewSettingsTab_showNotify(entity me) +{ + loadAllCvars(me); +} +entity makeXonoticGameViewSettingsTab() +{ + entity me; + me = spawnXonoticGameViewSettingsTab(); + me.configureDialog(me); + return me; +} + +void XonoticGameViewSettingsTab_fill(entity me) +{ + entity e; + + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "chase_active", "0", _("1st person perspective"))); + makeMulti(e, "crosshair_hittest_showimpact"); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_eventchase_death", _("Slide to third person upon death"))); + setDependent(e, "chase_active", -1, 0); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(0.05, 0, "cl_bobfall", _("Smooth the view when landing from a jump"))); + setDependent(e, "chase_active", -1, 0); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(0.05, 0, "cl_smoothviewheight", _("Smooth the view while crouching"))); + setDependent(e, "chase_active", -1, 0); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(1, 0, "v_idlescale", _("View waving while idle"))); + setDependent(e, "chase_active", -1, 0); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(0.01, 0, "cl_bob", _("View bobbing while walking around"))); + makeMulti(e, "cl_bob2"); + setDependent(e, "chase_active", -1, 0); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "chase_active", "1", _("3rd person perspective"))); + makeMulti(e, "crosshair_hittest_showimpact"); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Back distance"))); + setDependent(e, "chase_active", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(10, 100, 1, "chase_back")); + setDependent(e, "chase_active", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Up distance"))); + setDependent(e, "chase_active", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(10, 50, 1, "chase_up")); + setDependent(e, "chase_active", 1, 1); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(1, "cl_clippedspectating", _("Allow passing through walls while spectating"))); + + me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Field of view:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(60, 130, 5, "fov")); + me.TR(me); + me.TR(me); + //me.TDempty(me, 0.2); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, ZCTX(_("ZOOM^Zoom factor:")))); + me.TD(me, 1, 2, e = makeXonoticSlider(2, 16, 0.5, "cl_zoomfactor")); + me.TR(me); + //me.TDempty(me, 0.2); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, ZCTX(_("ZOOM^Zoom speed:")))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_zoomspeed")); + e.addValue(e, "1", "1"); // Samual: for() loop doesn't work here, even though it would make sense. + e.addValue(e, "2", "2"); + e.addValue(e, "3", "3"); + e.addValue(e, "4", "4"); + e.addValue(e, "5", "5"); + e.addValue(e, "6", "6"); + e.addValue(e, "7", "7"); + e.addValue(e, "8", "8"); + e.addValue(e, ZCTX(_("ZOOM^Instant")), "-1"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + //me.TDempty(me, 0.2); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, ZCTX(_("ZOOM^Zoom sensitivity:")))); + me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.1, "cl_zoomsensitivity")); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_velocityzoom_enabled", _("Velocity zoom"))); + me.TD(me, 1, 2, e = makeXonoticCheckBoxEx(3, 1, "cl_velocityzoom_type", _("Forward movement only"))); + setDependent(e, "cl_velocityzoom_enabled", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, ZCTX(_("VZOOM^Factor")))); + setDependentAND(e, "cl_velocityzoom_enabled", 1, 1, "cl_velocityzoom_type", 1, 3); + me.TD(me, 1, 2, e = makeXonoticSlider(-1, 1, 0.1, "cl_velocityzoom_factor")); + setDependentAND(e, "cl_velocityzoom_enabled", 1, 1, "cl_velocityzoom_type", 1, 3); + me.TR(me); + me.TR(me); + //me.TDempty(me, 0.2); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_reticle", _("Display reticle 2D overlay while zooming"))); + me.TR(me); + //me.TDempty(me, 0.2); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_unpress_zoom_on_death", _("Release zoom when you die or respawn"))); + makeMulti(e, "cl_unpress_zoom_on_spawn"); + me.TR(me); + //me.TDempty(me, 0.2); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_unpress_zoom_on_weapon_switch", _("Release zoom when you switch weapons"))); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_weapons.c b/qcsrc/menu/xonotic/dialog_settings_game_weapons.c deleted file mode 100644 index bc7cc7d7f..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_game_weapons.c +++ /dev/null @@ -1,77 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticGameWeaponsSettingsTab) EXTENDS(XonoticTab) - //METHOD(XonoticGameWeaponsSettingsTab, toString, string(entity)) - METHOD(XonoticGameWeaponsSettingsTab, fill, void(entity)) - METHOD(XonoticGameWeaponsSettingsTab, showNotify, void(entity)) - ATTRIB(XonoticGameWeaponsSettingsTab, title, string, _("Weapons")) - ATTRIB(XonoticGameWeaponsSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticGameWeaponsSettingsTab, rows, float, 13) - ATTRIB(XonoticGameWeaponsSettingsTab, columns, float, 6) - ATTRIB(XonoticGameWeaponsSettingsTab, weaponsList, entity, NULL) -ENDCLASS(XonoticGameWeaponsSettingsTab) -entity makeXonoticGameWeaponsSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -void XonoticGameWeaponsSettingsTab_showNotify(entity me) -{ - loadAllCvars(me); -} -entity makeXonoticGameWeaponsSettingsTab() -{ - entity me; - me = spawnXonoticGameWeaponsSettingsTab(); - me.configureDialog(me); - return me; -} - -void XonoticGameWeaponsSettingsTab_fill(entity me) -{ - entity e; - - me.TR(me); - me.TDempty(me, 0.25); - me.TD(me, 1, 2.5, e = makeXonoticHeaderLabel(_("Weapon Priority List"))); - me.TR(me); - me.TDempty(me, 0.25); - me.TD(me, 10, 2.5, e = me.weaponsList = makeXonoticWeaponsList()); - me.gotoRC(me, 11, 0.25); - me.TD(me, 1, 1.25, e = makeXonoticButton(_("Up"), '0 0 0')); - e.onClick = WeaponsList_MoveUp_Click; - e.onClickEntity = me.weaponsList; - me.TD(me, 1, 1.25, e = makeXonoticButton(_("Down"), '0 0 0')); - e.onClick = WeaponsList_MoveDown_Click; - e.onClickEntity = me.weaponsList; - - me.gotoRC(me, 0, 3); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_weaponpriority_useforcycling", _("Use priority list for weapon cycling"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(1, "cl_weaponimpulsemode", _("Cycle through only usable weapon selections"))); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_autoswitch", _("Auto switch weapons on pickup"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_unpress_attack_on_weapon_switch", _("Release attack buttons when you switch weapons"))); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "r_drawviewmodel", _("Draw 1st person weapon model"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "cl_gunalign", "4", _("Left align"))); - setDependent(e, "r_drawviewmodel", 1, 1); - me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "cl_gunalign", "1", _("Center"))); - setDependent(e, "r_drawviewmodel", 1, 1); - me.TD(me, 1, 1.0, e = makeXonoticRadioButton(1, "cl_gunalign", "3", _("Right align"))); - setDependent(e, "r_drawviewmodel", 1, 1); - me.TR(me); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_followmodel", _("Gun model swaying"))); - makeMulti(e, "cl_leanmodel"); - setDependent(e, "r_drawviewmodel", 1, 1); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_bobmodel", _("Gun model bobbing"))); - setDependent(e, "r_drawviewmodel", 1, 1); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc b/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc new file mode 100644 index 000000000..bc7cc7d7f --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc @@ -0,0 +1,77 @@ +#ifdef INTERFACE +CLASS(XonoticGameWeaponsSettingsTab) EXTENDS(XonoticTab) + //METHOD(XonoticGameWeaponsSettingsTab, toString, string(entity)) + METHOD(XonoticGameWeaponsSettingsTab, fill, void(entity)) + METHOD(XonoticGameWeaponsSettingsTab, showNotify, void(entity)) + ATTRIB(XonoticGameWeaponsSettingsTab, title, string, _("Weapons")) + ATTRIB(XonoticGameWeaponsSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticGameWeaponsSettingsTab, rows, float, 13) + ATTRIB(XonoticGameWeaponsSettingsTab, columns, float, 6) + ATTRIB(XonoticGameWeaponsSettingsTab, weaponsList, entity, NULL) +ENDCLASS(XonoticGameWeaponsSettingsTab) +entity makeXonoticGameWeaponsSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +void XonoticGameWeaponsSettingsTab_showNotify(entity me) +{ + loadAllCvars(me); +} +entity makeXonoticGameWeaponsSettingsTab() +{ + entity me; + me = spawnXonoticGameWeaponsSettingsTab(); + me.configureDialog(me); + return me; +} + +void XonoticGameWeaponsSettingsTab_fill(entity me) +{ + entity e; + + me.TR(me); + me.TDempty(me, 0.25); + me.TD(me, 1, 2.5, e = makeXonoticHeaderLabel(_("Weapon Priority List"))); + me.TR(me); + me.TDempty(me, 0.25); + me.TD(me, 10, 2.5, e = me.weaponsList = makeXonoticWeaponsList()); + me.gotoRC(me, 11, 0.25); + me.TD(me, 1, 1.25, e = makeXonoticButton(_("Up"), '0 0 0')); + e.onClick = WeaponsList_MoveUp_Click; + e.onClickEntity = me.weaponsList; + me.TD(me, 1, 1.25, e = makeXonoticButton(_("Down"), '0 0 0')); + e.onClick = WeaponsList_MoveDown_Click; + e.onClickEntity = me.weaponsList; + + me.gotoRC(me, 0, 3); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_weaponpriority_useforcycling", _("Use priority list for weapon cycling"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(1, "cl_weaponimpulsemode", _("Cycle through only usable weapon selections"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_autoswitch", _("Auto switch weapons on pickup"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_unpress_attack_on_weapon_switch", _("Release attack buttons when you switch weapons"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "r_drawviewmodel", _("Draw 1st person weapon model"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "cl_gunalign", "4", _("Left align"))); + setDependent(e, "r_drawviewmodel", 1, 1); + me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "cl_gunalign", "1", _("Center"))); + setDependent(e, "r_drawviewmodel", 1, 1); + me.TD(me, 1, 1.0, e = makeXonoticRadioButton(1, "cl_gunalign", "3", _("Right align"))); + setDependent(e, "r_drawviewmodel", 1, 1); + me.TR(me); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_followmodel", _("Gun model swaying"))); + makeMulti(e, "cl_leanmodel"); + setDependent(e, "r_drawviewmodel", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_bobmodel", _("Gun model bobbing"))); + setDependent(e, "r_drawviewmodel", 1, 1); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_input.c b/qcsrc/menu/xonotic/dialog_settings_input.c deleted file mode 100644 index 57b6cef63..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_input.c +++ /dev/null @@ -1,116 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticInputSettingsTab) EXTENDS(XonoticTab) - METHOD(XonoticInputSettingsTab, fill, void(entity)) - ATTRIB(XonoticInputSettingsTab, title, string, _("Input")) - ATTRIB(XonoticInputSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticInputSettingsTab, rows, float, 15.5) - ATTRIB(XonoticInputSettingsTab, columns, float, 6.2) // added extra .2 for center space -ENDCLASS(XonoticInputSettingsTab) -entity makeXonoticInputSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticInputSettingsTab() -{ - entity me; - me = spawnXonoticInputSettingsTab(); - me.configureDialog(me); - return me; -} - -void CheckBox_Click_Redisplay(entity me, entity checkbox) -{ - CheckBox_Click(me, checkbox); - cmd("\ndefer 0.2 \"togglemenu 1\"\n"); - //m_display(); -} -void XonoticInputSettingsTab_fill(entity me) -{ - entity e; - entity kb = makeXonoticKeyBinder(); - - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Key Bindings"))); - me.TR(me); - me.TD(me, me.rows - 3, 3, kb); - me.gotoRC(me, me.rows - 2, 0); - me.TD(me, 1, 1, e = makeXonoticButton(_("Change key..."), '0 0 0')); - e.onClick = KeyBinder_Bind_Change; - e.onClickEntity = kb; - kb.keyGrabButton = e; - me.TD(me, 1, 1, e = makeXonoticButton(_("Edit..."), '0 0 0')); - e.onClick = KeyBinder_Bind_Edit; - e.onClickEntity = kb; - kb.userbindEditButton = e; - kb.userbindEditDialog = main.userbindEditDialog; - main.userbindEditDialog.keybindBox = kb; - me.TD(me, 1, 1, e = makeXonoticButton(_("Clear"), '0 0 0')); - e.onClick = KeyBinder_Bind_Clear; - e.onClickEntity = kb; - kb.clearButton = e; - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticButton(_("Reset all"), '0 0 0')); - e.onClick = KeyBinder_Bind_Reset_All; - e.onClickEntity = kb; - - me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Mouse"))); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Sensitivity:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(1, 32, 0.2, "sensitivity")); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "m_filter", _("Smooth aiming"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(1.022, "m_pitch", _("Invert aiming"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "menu_mouse_absolute", _("Use system mouse positioning"))); - makeMulti(e, "hud_cursormode"); - e.onClick = CheckBox_Click_Redisplay; - e.onClickEntity = e; - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "m_accelerate", _("Enable built in mouse acceleration"))); - me.TR(me); - if(cvar_type("vid_dgamouse") & CVAR_TYPEFLAG_ENGINE) - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "vid_dgamouse", _("Disable system mouse acceleration"))); - else if(cvar_type("apple_mouse_noaccel") & CVAR_TYPEFLAG_ENGINE) - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "apple_mouse_noaccel", _("Disable system mouse acceleration"))); - else - { - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, string_null, _("Disable system mouse acceleration"))); - e.disabled = 1; // the option is never available in this case, just there for show - } - - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Other"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "con_closeontoggleconsole", _("Pressing \"enter console\" key also closes it"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(1, "cl_movement_track_canjump", _("Automatically repeat jumping if holding jump"))); - e.sendCvars = TRUE; - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Jetpack on jump:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_jetpack_jump")); - e.addValue(e, _("Disabled"), "0"); - e.addValue(e, _("Air only"), "1"); - e.addValue(e, _("All"), "2"); - e.configureXonoticTextSliderValues(e); - e.sendCvars = TRUE; - me.TR(me); - if(cvar_type("joy_enable") & CVAR_TYPEFLAG_ENGINE) - { - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "joy_enable", _("Use joystick input"))); - setDependent(e, "joy_detected", 1, 10000000); - } - else if(cvar_type("joystick") & CVAR_TYPEFLAG_ENGINE) - { - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "joystick", _("Use joystick input"))); - setDependent(e, "joy_detected", 1, 10000000); - } - else - { - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, string_null, _("Use joystick input"))); - e.disabled = 1; // the option is never available in this case, just there for show - } -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_input.qc b/qcsrc/menu/xonotic/dialog_settings_input.qc new file mode 100644 index 000000000..57b6cef63 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_input.qc @@ -0,0 +1,116 @@ +#ifdef INTERFACE +CLASS(XonoticInputSettingsTab) EXTENDS(XonoticTab) + METHOD(XonoticInputSettingsTab, fill, void(entity)) + ATTRIB(XonoticInputSettingsTab, title, string, _("Input")) + ATTRIB(XonoticInputSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticInputSettingsTab, rows, float, 15.5) + ATTRIB(XonoticInputSettingsTab, columns, float, 6.2) // added extra .2 for center space +ENDCLASS(XonoticInputSettingsTab) +entity makeXonoticInputSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticInputSettingsTab() +{ + entity me; + me = spawnXonoticInputSettingsTab(); + me.configureDialog(me); + return me; +} + +void CheckBox_Click_Redisplay(entity me, entity checkbox) +{ + CheckBox_Click(me, checkbox); + cmd("\ndefer 0.2 \"togglemenu 1\"\n"); + //m_display(); +} +void XonoticInputSettingsTab_fill(entity me) +{ + entity e; + entity kb = makeXonoticKeyBinder(); + + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Key Bindings"))); + me.TR(me); + me.TD(me, me.rows - 3, 3, kb); + me.gotoRC(me, me.rows - 2, 0); + me.TD(me, 1, 1, e = makeXonoticButton(_("Change key..."), '0 0 0')); + e.onClick = KeyBinder_Bind_Change; + e.onClickEntity = kb; + kb.keyGrabButton = e; + me.TD(me, 1, 1, e = makeXonoticButton(_("Edit..."), '0 0 0')); + e.onClick = KeyBinder_Bind_Edit; + e.onClickEntity = kb; + kb.userbindEditButton = e; + kb.userbindEditDialog = main.userbindEditDialog; + main.userbindEditDialog.keybindBox = kb; + me.TD(me, 1, 1, e = makeXonoticButton(_("Clear"), '0 0 0')); + e.onClick = KeyBinder_Bind_Clear; + e.onClickEntity = kb; + kb.clearButton = e; + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticButton(_("Reset all"), '0 0 0')); + e.onClick = KeyBinder_Bind_Reset_All; + e.onClickEntity = kb; + + me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Mouse"))); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Sensitivity:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(1, 32, 0.2, "sensitivity")); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "m_filter", _("Smooth aiming"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(1.022, "m_pitch", _("Invert aiming"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "menu_mouse_absolute", _("Use system mouse positioning"))); + makeMulti(e, "hud_cursormode"); + e.onClick = CheckBox_Click_Redisplay; + e.onClickEntity = e; + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "m_accelerate", _("Enable built in mouse acceleration"))); + me.TR(me); + if(cvar_type("vid_dgamouse") & CVAR_TYPEFLAG_ENGINE) + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "vid_dgamouse", _("Disable system mouse acceleration"))); + else if(cvar_type("apple_mouse_noaccel") & CVAR_TYPEFLAG_ENGINE) + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "apple_mouse_noaccel", _("Disable system mouse acceleration"))); + else + { + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, string_null, _("Disable system mouse acceleration"))); + e.disabled = 1; // the option is never available in this case, just there for show + } + + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Other"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "con_closeontoggleconsole", _("Pressing \"enter console\" key also closes it"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(1, "cl_movement_track_canjump", _("Automatically repeat jumping if holding jump"))); + e.sendCvars = TRUE; + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Jetpack on jump:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_jetpack_jump")); + e.addValue(e, _("Disabled"), "0"); + e.addValue(e, _("Air only"), "1"); + e.addValue(e, _("All"), "2"); + e.configureXonoticTextSliderValues(e); + e.sendCvars = TRUE; + me.TR(me); + if(cvar_type("joy_enable") & CVAR_TYPEFLAG_ENGINE) + { + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "joy_enable", _("Use joystick input"))); + setDependent(e, "joy_detected", 1, 10000000); + } + else if(cvar_type("joystick") & CVAR_TYPEFLAG_ENGINE) + { + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "joystick", _("Use joystick input"))); + setDependent(e, "joy_detected", 1, 10000000); + } + else + { + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, string_null, _("Use joystick input"))); + e.disabled = 1; // the option is never available in this case, just there for show + } +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_input_userbind.c b/qcsrc/menu/xonotic/dialog_settings_input_userbind.c deleted file mode 100644 index aaf182fcd..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_input_userbind.c +++ /dev/null @@ -1,55 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticUserbindEditDialog) EXTENDS(XonoticDialog) - METHOD(XonoticUserbindEditDialog, loadUserBind, void(entity, string, string, string)) - METHOD(XonoticUserbindEditDialog, fill, void(entity)) - ATTRIB(XonoticUserbindEditDialog, title, string, _("User defined key bind")) - ATTRIB(XonoticUserbindEditDialog, color, vector, SKINCOLOR_DIALOG_USERBIND) - ATTRIB(XonoticUserbindEditDialog, intendedWidth, float, 0.7) - ATTRIB(XonoticUserbindEditDialog, rows, float, 4) - ATTRIB(XonoticUserbindEditDialog, columns, float, 3) - ATTRIB(XonoticUserbindEditDialog, keybindBox, entity, NULL) - - ATTRIB(XonoticUserbindEditDialog, nameBox, entity, NULL) - ATTRIB(XonoticUserbindEditDialog, commandPressBox, entity, NULL) - ATTRIB(XonoticUserbindEditDialog, commandReleaseBox, entity, NULL) -ENDCLASS(XonoticUserbindEditDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticUserbindEditDialog_Save(entity btn, entity me) -{ - me.keybindBox.editUserbind(me.keybindBox, me.nameBox.text, me.commandPressBox.text, me.commandReleaseBox.text); - Dialog_Close(btn, me); -} - -void XonoticUserbindEditDialog_loadUserBind(entity me, string theName, string theCommandPress, string theCommandRelease) -{ - me.nameBox.setText(me.nameBox, theName); - me.nameBox.keyDown(me.nameBox, K_END, 0, 0); - me.commandPressBox.setText(me.commandPressBox, theCommandPress); - me.nameBox.keyDown(me.commandPressBox, K_END, 0, 0); - me.commandReleaseBox.setText(me.commandReleaseBox, theCommandRelease); - me.nameBox.keyDown(me.commandReleaseBox, K_END, 0, 0); -} - -void XonoticUserbindEditDialog_fill(entity me) -{ - entity e; - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Name:"))); - me.TD(me, 1, me.columns - 1, me.nameBox = makeXonoticInputBox(0, string_null)); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Command when pressed:"))); - me.TD(me, 1, me.columns - 1, me.commandPressBox = makeXonoticInputBox(0, string_null)); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Command when released:"))); - me.TD(me, 1, me.columns - 1, me.commandReleaseBox = makeXonoticInputBox(0, string_null)); - me.TR(me); - me.TD(me, 1, me.columns / 2, e = makeXonoticButton(_("Save"), '0 0 0')); - e.onClick = XonoticUserbindEditDialog_Save; - e.onClickEntity = me; - me.TD(me, 1, me.columns / 2, e = makeXonoticButton(_("Cancel"), '0 0 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc b/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc new file mode 100644 index 000000000..aaf182fcd --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc @@ -0,0 +1,55 @@ +#ifdef INTERFACE +CLASS(XonoticUserbindEditDialog) EXTENDS(XonoticDialog) + METHOD(XonoticUserbindEditDialog, loadUserBind, void(entity, string, string, string)) + METHOD(XonoticUserbindEditDialog, fill, void(entity)) + ATTRIB(XonoticUserbindEditDialog, title, string, _("User defined key bind")) + ATTRIB(XonoticUserbindEditDialog, color, vector, SKINCOLOR_DIALOG_USERBIND) + ATTRIB(XonoticUserbindEditDialog, intendedWidth, float, 0.7) + ATTRIB(XonoticUserbindEditDialog, rows, float, 4) + ATTRIB(XonoticUserbindEditDialog, columns, float, 3) + ATTRIB(XonoticUserbindEditDialog, keybindBox, entity, NULL) + + ATTRIB(XonoticUserbindEditDialog, nameBox, entity, NULL) + ATTRIB(XonoticUserbindEditDialog, commandPressBox, entity, NULL) + ATTRIB(XonoticUserbindEditDialog, commandReleaseBox, entity, NULL) +ENDCLASS(XonoticUserbindEditDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticUserbindEditDialog_Save(entity btn, entity me) +{ + me.keybindBox.editUserbind(me.keybindBox, me.nameBox.text, me.commandPressBox.text, me.commandReleaseBox.text); + Dialog_Close(btn, me); +} + +void XonoticUserbindEditDialog_loadUserBind(entity me, string theName, string theCommandPress, string theCommandRelease) +{ + me.nameBox.setText(me.nameBox, theName); + me.nameBox.keyDown(me.nameBox, K_END, 0, 0); + me.commandPressBox.setText(me.commandPressBox, theCommandPress); + me.nameBox.keyDown(me.commandPressBox, K_END, 0, 0); + me.commandReleaseBox.setText(me.commandReleaseBox, theCommandRelease); + me.nameBox.keyDown(me.commandReleaseBox, K_END, 0, 0); +} + +void XonoticUserbindEditDialog_fill(entity me) +{ + entity e; + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Name:"))); + me.TD(me, 1, me.columns - 1, me.nameBox = makeXonoticInputBox(0, string_null)); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Command when pressed:"))); + me.TD(me, 1, me.columns - 1, me.commandPressBox = makeXonoticInputBox(0, string_null)); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Command when released:"))); + me.TD(me, 1, me.columns - 1, me.commandReleaseBox = makeXonoticInputBox(0, string_null)); + me.TR(me); + me.TD(me, 1, me.columns / 2, e = makeXonoticButton(_("Save"), '0 0 0')); + e.onClick = XonoticUserbindEditDialog_Save; + e.onClickEntity = me; + me.TD(me, 1, me.columns / 2, e = makeXonoticButton(_("Cancel"), '0 0 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_misc.c b/qcsrc/menu/xonotic/dialog_settings_misc.c deleted file mode 100644 index 2ea9c1e9c..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_misc.c +++ /dev/null @@ -1,143 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticMiscSettingsTab) EXTENDS(XonoticTab) - METHOD(XonoticMiscSettingsTab, fill, void(entity)) - ATTRIB(XonoticMiscSettingsTab, title, string, _("Misc")) - ATTRIB(XonoticMiscSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticMiscSettingsTab, rows, float, 15.5) - ATTRIB(XonoticMiscSettingsTab, columns, float, 6.2) -ENDCLASS(XonoticMiscSettingsTab) -entity makeXonoticMiscSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticMiscSettingsTab() -{ - entity me; - me = spawnXonoticMiscSettingsTab(); - me.configureDialog(me); - return me; -} -void XonoticMiscSettingsTab_fill(entity me) -{ - entity e; - //entity sk; - - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Network"))); - me.TR(me); - me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Client UDP port:"))); - me.TD(me, 1, 1.5, e = makeXonoticInputBox(0, "cl_port")); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Bandwidth:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("_cl_rate")); - e.addValue(e, _("56k"), "4000"); - e.addValue(e, _("ISDN"), "7000"); - e.addValue(e, _("Slow ADSL"), "15000"); - e.addValue(e, _("Fast ADSL"), "20000"); - e.addValue(e, _("Broadband"), "66666"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Input packets/s:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(20, 100, 5, "cl_netfps")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Server queries/s:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(20, 100, 10, "net_slist_queriespersecond")); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Downloads:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(1, 5, 1, "cl_curl_maxdownloads")); - me.TR(me); - me.TDempty(me, 0.1); - me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Speed (kB/s):"))); - me.TD(me, 1, 2, e = makeXonoticSlider(10, 2000, 50, "cl_curl_maxspeed")); - me.TR(me); - if(cvar("developer")) - { - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Local latency:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(0, 1000, 25, "cl_netlocalping")); - } - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "shownetgraph", _("Show netgraph"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_movement", _("Client-side movement prediction"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_movement_errorcompensation", _("Movement error compensation"))); - setDependent(e, "cl_movement", 1, 1); - me.TR(me); - if(cvar_type("crypto_aeslevel") & CVAR_TYPEFLAG_ENGINE) - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "crypto_aeslevel", _("Use encryption (AES) when available"))); // TODO: move up - - me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Framerate"))); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Maximum:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_maxfps")); - e.addValue(e, ZCTX(_("MAXFPS^5 fps")), "5"); - e.addValue(e, ZCTX(_("MAXFPS^10 fps")), "10"); - e.addValue(e, ZCTX(_("MAXFPS^20 fps")), "20"); - e.addValue(e, ZCTX(_("MAXFPS^30 fps")), "30"); - e.addValue(e, ZCTX(_("MAXFPS^40 fps")), "40"); - e.addValue(e, ZCTX(_("MAXFPS^50 fps")), "50"); - e.addValue(e, ZCTX(_("MAXFPS^60 fps")), "60"); - e.addValue(e, ZCTX(_("MAXFPS^70 fps")), "70"); - e.addValue(e, ZCTX(_("MAXFPS^100 fps")), "100"); - e.addValue(e, ZCTX(_("MAXFPS^125 fps")), "125"); - e.addValue(e, ZCTX(_("MAXFPS^200 fps")), "200"); - e.addValue(e, ZCTX(_("MAXFPS^Unlimited")), "0"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Target:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_minfps")); - e.addValue(e, ZCTX(_("TRGT^Disabled")), "0"); - e.addValue(e, ZCTX(_("TRGT^30 fps")), "30"); - e.addValue(e, ZCTX(_("TRGT^40 fps")), "40"); - e.addValue(e, ZCTX(_("TRGT^50 fps")), "50"); - e.addValue(e, ZCTX(_("TRGT^60 fps")), "60"); - e.addValue(e, ZCTX(_("TRGT^100 fps")), "100"); - e.addValue(e, ZCTX(_("TRGT^125 fps")), "125"); - e.addValue(e, ZCTX(_("TRGT^200 fps")), "200"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Idle limit:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_maxidlefps")); - e.addValue(e, ZCTX(_("IDLFPS^10 fps")), "10"); - e.addValue(e, ZCTX(_("IDLFPS^20 fps")), "20"); - e.addValue(e, ZCTX(_("IDLFPS^30 fps")), "30"); - e.addValue(e, ZCTX(_("IDLFPS^60 fps")), "60"); - e.addValue(e, ZCTX(_("IDLFPS^Unlimited")), "0"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_maxfps_alwayssleep", _("Save processing time for other apps"))); - setDependent(e, "cl_maxfps", 1, 1000); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "showfps", _("Show frames per second"))); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Other"))); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Menu tooltips:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("menu_tooltips")); - e.addValue(e, ZCTX(_("TLTIP^Disabled")), "0"); - e.addValue(e, ZCTX(_("TLTIP^Standard")), "1"); - e.addValue(e, ZCTX(_("TLTIP^Advanced")), "2"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "showtime", _("Show current date and time"))); - makeMulti(e, "showdate"); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "developer", _("Enable developer mode"))); - - me.TR(me); - me.TDempty(me, 0.5); - me.TD(me, 1, 2, e = makeXonoticButton(_("Advanced settings..."), '0 0 0')); - e.onClick = DialogOpenButton_Click; - e.onClickEntity = main.cvarsDialog; - me.TR(me); - me.TDempty(me, 0.5); - me.TD(me, 1, 2, e = makeXonoticButton(_("Factory reset"), '0 0 0')); - e.onClick = DialogOpenButton_Click; - e.onClickEntity = main.resetDialog; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_misc.qc b/qcsrc/menu/xonotic/dialog_settings_misc.qc new file mode 100644 index 000000000..2ea9c1e9c --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_misc.qc @@ -0,0 +1,143 @@ +#ifdef INTERFACE +CLASS(XonoticMiscSettingsTab) EXTENDS(XonoticTab) + METHOD(XonoticMiscSettingsTab, fill, void(entity)) + ATTRIB(XonoticMiscSettingsTab, title, string, _("Misc")) + ATTRIB(XonoticMiscSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticMiscSettingsTab, rows, float, 15.5) + ATTRIB(XonoticMiscSettingsTab, columns, float, 6.2) +ENDCLASS(XonoticMiscSettingsTab) +entity makeXonoticMiscSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticMiscSettingsTab() +{ + entity me; + me = spawnXonoticMiscSettingsTab(); + me.configureDialog(me); + return me; +} +void XonoticMiscSettingsTab_fill(entity me) +{ + entity e; + //entity sk; + + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Network"))); + me.TR(me); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Client UDP port:"))); + me.TD(me, 1, 1.5, e = makeXonoticInputBox(0, "cl_port")); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Bandwidth:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("_cl_rate")); + e.addValue(e, _("56k"), "4000"); + e.addValue(e, _("ISDN"), "7000"); + e.addValue(e, _("Slow ADSL"), "15000"); + e.addValue(e, _("Fast ADSL"), "20000"); + e.addValue(e, _("Broadband"), "66666"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Input packets/s:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(20, 100, 5, "cl_netfps")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Server queries/s:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(20, 100, 10, "net_slist_queriespersecond")); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Downloads:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(1, 5, 1, "cl_curl_maxdownloads")); + me.TR(me); + me.TDempty(me, 0.1); + me.TD(me, 1, 0.9, e = makeXonoticTextLabel(0, _("Speed (kB/s):"))); + me.TD(me, 1, 2, e = makeXonoticSlider(10, 2000, 50, "cl_curl_maxspeed")); + me.TR(me); + if(cvar("developer")) + { + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Local latency:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(0, 1000, 25, "cl_netlocalping")); + } + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "shownetgraph", _("Show netgraph"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_movement", _("Client-side movement prediction"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_movement_errorcompensation", _("Movement error compensation"))); + setDependent(e, "cl_movement", 1, 1); + me.TR(me); + if(cvar_type("crypto_aeslevel") & CVAR_TYPEFLAG_ENGINE) + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 1, "crypto_aeslevel", _("Use encryption (AES) when available"))); // TODO: move up + + me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Framerate"))); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Maximum:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_maxfps")); + e.addValue(e, ZCTX(_("MAXFPS^5 fps")), "5"); + e.addValue(e, ZCTX(_("MAXFPS^10 fps")), "10"); + e.addValue(e, ZCTX(_("MAXFPS^20 fps")), "20"); + e.addValue(e, ZCTX(_("MAXFPS^30 fps")), "30"); + e.addValue(e, ZCTX(_("MAXFPS^40 fps")), "40"); + e.addValue(e, ZCTX(_("MAXFPS^50 fps")), "50"); + e.addValue(e, ZCTX(_("MAXFPS^60 fps")), "60"); + e.addValue(e, ZCTX(_("MAXFPS^70 fps")), "70"); + e.addValue(e, ZCTX(_("MAXFPS^100 fps")), "100"); + e.addValue(e, ZCTX(_("MAXFPS^125 fps")), "125"); + e.addValue(e, ZCTX(_("MAXFPS^200 fps")), "200"); + e.addValue(e, ZCTX(_("MAXFPS^Unlimited")), "0"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Target:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_minfps")); + e.addValue(e, ZCTX(_("TRGT^Disabled")), "0"); + e.addValue(e, ZCTX(_("TRGT^30 fps")), "30"); + e.addValue(e, ZCTX(_("TRGT^40 fps")), "40"); + e.addValue(e, ZCTX(_("TRGT^50 fps")), "50"); + e.addValue(e, ZCTX(_("TRGT^60 fps")), "60"); + e.addValue(e, ZCTX(_("TRGT^100 fps")), "100"); + e.addValue(e, ZCTX(_("TRGT^125 fps")), "125"); + e.addValue(e, ZCTX(_("TRGT^200 fps")), "200"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Idle limit:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_maxidlefps")); + e.addValue(e, ZCTX(_("IDLFPS^10 fps")), "10"); + e.addValue(e, ZCTX(_("IDLFPS^20 fps")), "20"); + e.addValue(e, ZCTX(_("IDLFPS^30 fps")), "30"); + e.addValue(e, ZCTX(_("IDLFPS^60 fps")), "60"); + e.addValue(e, ZCTX(_("IDLFPS^Unlimited")), "0"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_maxfps_alwayssleep", _("Save processing time for other apps"))); + setDependent(e, "cl_maxfps", 1, 1000); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "showfps", _("Show frames per second"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Other"))); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Menu tooltips:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("menu_tooltips")); + e.addValue(e, ZCTX(_("TLTIP^Disabled")), "0"); + e.addValue(e, ZCTX(_("TLTIP^Standard")), "1"); + e.addValue(e, ZCTX(_("TLTIP^Advanced")), "2"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "showtime", _("Show current date and time"))); + makeMulti(e, "showdate"); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "developer", _("Enable developer mode"))); + + me.TR(me); + me.TDempty(me, 0.5); + me.TD(me, 1, 2, e = makeXonoticButton(_("Advanced settings..."), '0 0 0')); + e.onClick = DialogOpenButton_Click; + e.onClickEntity = main.cvarsDialog; + me.TR(me); + me.TDempty(me, 0.5); + me.TD(me, 1, 2, e = makeXonoticButton(_("Factory reset"), '0 0 0')); + e.onClick = DialogOpenButton_Click; + e.onClickEntity = main.resetDialog; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_cvars.c b/qcsrc/menu/xonotic/dialog_settings_misc_cvars.c deleted file mode 100644 index c2ea2a5b6..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_misc_cvars.c +++ /dev/null @@ -1,86 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticCvarsDialog) EXTENDS(XonoticDialog) - METHOD(XonoticCvarsDialog, fill, void(entity)) - METHOD(XonoticCvarsDialog, showNotify, void(entity)) - ATTRIB(XonoticCvarsDialog, title, string, _("Advanced settings")) - ATTRIB(XonoticCvarsDialog, color, vector, SKINCOLOR_DIALOG_CVARS) - ATTRIB(XonoticCvarsDialog, intendedWidth, float, 0.8) - ATTRIB(XonoticCvarsDialog, rows, float, 24) - ATTRIB(XonoticCvarsDialog, columns, float, 6) -ENDCLASS(XonoticCvarsDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticCvarsDialog_showNotify(entity me) -{ - loadAllCvars(me); -} -void XonoticCvarsDialog_fill(entity me) // in this dialog, use SKINCOLOR_CVARLIST_CONTROLS to color ALL controls -{ - - entity e, cvarlist; - - cvarlist = makeXonoticCvarList(); - - cvarlist.color = - cvarlist.colorF = - cvarlist.color2 = - cvarlist.colorC = - SKINCOLOR_CVARLIST_CONTROLS; - - // todo: - // add button which does cvar_resettodefaults_saveonly - - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Cvar filter:"))); - me.TD(me, 1, me.columns - 1, e = makeXonoticInputBox(0, string_null)); - e.color = SKINCOLOR_CVARLIST_CONTROLS; - e.colorF = SKINCOLOR_CVARLIST_CONTROLS; - e.cb_color = SKINCOLOR_CVARLIST_CONTROLS; - e.cb_colorC = SKINCOLOR_CVARLIST_CONTROLS; - e.cb_colorF = SKINCOLOR_CVARLIST_CONTROLS; - e.onChange = CvarList_Filter_Change; - e.onChangeEntity = cvarlist; - cvarlist.controlledTextbox = e; // this COULD also be the Value box, but this leads to accidentally editing stuff - me.TR(me); - me.TD(me, me.rows - me.currentRow - 9, me.columns, cvarlist); - me.gotoRC(me, me.rows - 8, 0); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Setting:"))); - me.TD(me, 1, me.columns - 1, e = makeXonoticTextLabel(0, string_null)); - cvarlist.cvarNameBox = e; - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Type:"))); - me.TD(me, 1, me.columns - 1, e = makeXonoticTextLabel(0, string_null)); - cvarlist.cvarTypeBox = e; - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Value:"))); - me.TD(me, 1, me.columns - 2, e = makeXonoticInputBox(0, string_null)); - cvarlist.cvarValueBox = e; - e.color = SKINCOLOR_CVARLIST_CONTROLS; - e.colorF = SKINCOLOR_CVARLIST_CONTROLS; - e.cb_color = SKINCOLOR_CVARLIST_CONTROLS; - e.cb_colorC = SKINCOLOR_CVARLIST_CONTROLS; - e.cb_colorF = SKINCOLOR_CVARLIST_CONTROLS; - e.onChange = CvarList_Value_Change; - e.onChangeEntity = cvarlist; - e.onEnter = CvarList_End_Editing; - e.onEnterEntity = cvarlist; - me.TD(me, 1, 1, e = makeXonoticButton(string_null, SKINCOLOR_CVARLIST_CONTROLS)); - cvarlist.cvarDefaultBox = e; - e.onClick = CvarList_Revert_Click; - e.onClickEntity = cvarlist; - e.allowCut = 1; - e.marginLeft = e.marginRight = 0.5; - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Description:"))); - me.TD(me, 1, me.columns - 1, e = makeXonoticTextLabel(0, string_null)); - cvarlist.cvarDescriptionBox = e; - e.allowWrap = 1; - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), SKINCOLOR_CVARLIST_CONTROLS)); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} - -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc b/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc new file mode 100644 index 000000000..c2ea2a5b6 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc @@ -0,0 +1,86 @@ +#ifdef INTERFACE +CLASS(XonoticCvarsDialog) EXTENDS(XonoticDialog) + METHOD(XonoticCvarsDialog, fill, void(entity)) + METHOD(XonoticCvarsDialog, showNotify, void(entity)) + ATTRIB(XonoticCvarsDialog, title, string, _("Advanced settings")) + ATTRIB(XonoticCvarsDialog, color, vector, SKINCOLOR_DIALOG_CVARS) + ATTRIB(XonoticCvarsDialog, intendedWidth, float, 0.8) + ATTRIB(XonoticCvarsDialog, rows, float, 24) + ATTRIB(XonoticCvarsDialog, columns, float, 6) +ENDCLASS(XonoticCvarsDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticCvarsDialog_showNotify(entity me) +{ + loadAllCvars(me); +} +void XonoticCvarsDialog_fill(entity me) // in this dialog, use SKINCOLOR_CVARLIST_CONTROLS to color ALL controls +{ + + entity e, cvarlist; + + cvarlist = makeXonoticCvarList(); + + cvarlist.color = + cvarlist.colorF = + cvarlist.color2 = + cvarlist.colorC = + SKINCOLOR_CVARLIST_CONTROLS; + + // todo: + // add button which does cvar_resettodefaults_saveonly + + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Cvar filter:"))); + me.TD(me, 1, me.columns - 1, e = makeXonoticInputBox(0, string_null)); + e.color = SKINCOLOR_CVARLIST_CONTROLS; + e.colorF = SKINCOLOR_CVARLIST_CONTROLS; + e.cb_color = SKINCOLOR_CVARLIST_CONTROLS; + e.cb_colorC = SKINCOLOR_CVARLIST_CONTROLS; + e.cb_colorF = SKINCOLOR_CVARLIST_CONTROLS; + e.onChange = CvarList_Filter_Change; + e.onChangeEntity = cvarlist; + cvarlist.controlledTextbox = e; // this COULD also be the Value box, but this leads to accidentally editing stuff + me.TR(me); + me.TD(me, me.rows - me.currentRow - 9, me.columns, cvarlist); + me.gotoRC(me, me.rows - 8, 0); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Setting:"))); + me.TD(me, 1, me.columns - 1, e = makeXonoticTextLabel(0, string_null)); + cvarlist.cvarNameBox = e; + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Type:"))); + me.TD(me, 1, me.columns - 1, e = makeXonoticTextLabel(0, string_null)); + cvarlist.cvarTypeBox = e; + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Value:"))); + me.TD(me, 1, me.columns - 2, e = makeXonoticInputBox(0, string_null)); + cvarlist.cvarValueBox = e; + e.color = SKINCOLOR_CVARLIST_CONTROLS; + e.colorF = SKINCOLOR_CVARLIST_CONTROLS; + e.cb_color = SKINCOLOR_CVARLIST_CONTROLS; + e.cb_colorC = SKINCOLOR_CVARLIST_CONTROLS; + e.cb_colorF = SKINCOLOR_CVARLIST_CONTROLS; + e.onChange = CvarList_Value_Change; + e.onChangeEntity = cvarlist; + e.onEnter = CvarList_End_Editing; + e.onEnterEntity = cvarlist; + me.TD(me, 1, 1, e = makeXonoticButton(string_null, SKINCOLOR_CVARLIST_CONTROLS)); + cvarlist.cvarDefaultBox = e; + e.onClick = CvarList_Revert_Click; + e.onClickEntity = cvarlist; + e.allowCut = 1; + e.marginLeft = e.marginRight = 0.5; + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Description:"))); + me.TD(me, 1, me.columns - 1, e = makeXonoticTextLabel(0, string_null)); + cvarlist.cvarDescriptionBox = e; + e.allowWrap = 1; + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), SKINCOLOR_CVARLIST_CONTROLS)); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} + +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_reset.c b/qcsrc/menu/xonotic/dialog_settings_misc_reset.c deleted file mode 100644 index 8f6da0a55..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_misc_reset.c +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticResetDialog) EXTENDS(XonoticDialog) - METHOD(XonoticResetDialog, fill, void(entity)) - ATTRIB(XonoticResetDialog, title, string, _("Factory reset")) - ATTRIB(XonoticResetDialog, color, vector, SKINCOLOR_DIALOG_QUIT) - ATTRIB(XonoticResetDialog, intendedWidth, float, 0.5) - ATTRIB(XonoticResetDialog, rows, float, 4) - ATTRIB(XonoticResetDialog, columns, float, 2) - ATTRIB(XonoticResetDialog, name, string, "Factory reset") -ENDCLASS(XonoticResetDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticResetDialog_fill(entity me) -{ - entity e; - me.TR(me); - me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("Are you sure you want to reset all settings?"))); - me.TR(me); - me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("This will create a backup config in your data directory"))); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCommandButton(_("Yes"), '1 0 0', "saveconfig backup.cfg\n;\n exec defaultXonotic.cfg\n", 0)); - me.TD(me, 1, 1, e = makeXonoticButton(_("No"), '0 1 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc b/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc new file mode 100644 index 000000000..8f6da0a55 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc @@ -0,0 +1,28 @@ +#ifdef INTERFACE +CLASS(XonoticResetDialog) EXTENDS(XonoticDialog) + METHOD(XonoticResetDialog, fill, void(entity)) + ATTRIB(XonoticResetDialog, title, string, _("Factory reset")) + ATTRIB(XonoticResetDialog, color, vector, SKINCOLOR_DIALOG_QUIT) + ATTRIB(XonoticResetDialog, intendedWidth, float, 0.5) + ATTRIB(XonoticResetDialog, rows, float, 4) + ATTRIB(XonoticResetDialog, columns, float, 2) + ATTRIB(XonoticResetDialog, name, string, "Factory reset") +ENDCLASS(XonoticResetDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticResetDialog_fill(entity me) +{ + entity e; + me.TR(me); + me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("Are you sure you want to reset all settings?"))); + me.TR(me); + me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("This will create a backup config in your data directory"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCommandButton(_("Yes"), '1 0 0', "saveconfig backup.cfg\n;\n exec defaultXonotic.cfg\n", 0)); + me.TD(me, 1, 1, e = makeXonoticButton(_("No"), '0 1 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_user.c b/qcsrc/menu/xonotic/dialog_settings_user.c deleted file mode 100644 index 180efccb9..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_user.c +++ /dev/null @@ -1,96 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticUserSettingsTab) EXTENDS(XonoticTab) - METHOD(XonoticUserSettingsTab, fill, void(entity)) - ATTRIB(XonoticUserSettingsTab, title, string, _("User")) - ATTRIB(XonoticUserSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticUserSettingsTab, rows, float, 15.5) - ATTRIB(XonoticUserSettingsTab, columns, float, 6) -ENDCLASS(XonoticUserSettingsTab) -entity makeXonoticUserSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticUserSettingsTab() -{ - entity me; - me = spawnXonoticUserSettingsTab(); - me.configureDialog(me); - return me; -} - -void XonoticUserSettingsTab_fill(entity me) -{ - entity e; - entity sk; - - me.TR(me); - me.TDempty(me, 0.25); - me.TD(me, 1, 2.5, e = makeXonoticHeaderLabel(_("Menu Skins"))); - me.TR(me); - me.TDempty(me, 0.25); - me.TD(me, me.rows - 2.5, 2.5, sk = makeXonoticSkinList()); - me.gotoRC(me, me.rows - 1.5, 0.25); - me.TD(me, 1, 2.5, e = makeXonoticButton(_("Set skin"), '0 0 0')); - e.onClick = SetSkin_Click; - e.onClickEntity = sk; - - /* AFTER 0.6 RELEASE TODO: Add a listbox which has fonts too, this way user can select the font they want. - me.gotoRC(me, 0, 2.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Text language:"))); - me.TR(me); - me.TD(me, 6, 1, sk = makeXonoticLanguageList()); - me.TR(me); - me.TR(me); - me.TR(me); - me.TR(me); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticButton(_("Set language"), '0 0 0')); - e.onClick = SetLanguage_Click; - e.onClickEntity = sk; - - me.gotoRC(me, 0, 3.3); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 1.5, e = makeXonoticTextLabel(0, _("Font:"))); - me.TR(me); - me.TD(me, 2, 1.5, sk = makeXonoticLanguageList()); - me.TR(me); - me.TR(me); - me.TR(me); - me.TR(me); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1.5, e = makeXonoticButton(_("Set font"), '0 0 0')); - e.onClick = SetLanguage_Click; - e.onClickEntity = sk;*/ - - me.gotoRC(me, 0, 3.75); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 1.5, e = makeXonoticHeaderLabel(_("Text Language"))); - me.TR(me); - me.TD(me, 8, 1.5, sk = makeXonoticLanguageList()); - - me.gotoRC(me, 9, 3.75); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 1.5, e = makeXonoticButton(_("Set language"), '0 0 0')); - e.onClick = SetLanguage_Click; - e.onClickEntity = sk; - - me.gotoRC(me, 11.5, 3.25); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 2.5, e = makeXonoticCheckBox(0, "cl_gentle", _("Disable gore effects and harsh language"))); - - //me.TR(me); - // me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Menu tooltips:"))); - // me.TD(me, 1, 2, e = makeXonoticTextSlider("menu_tooltips")); - // e.addValue(e, ZCTX(_("TLTIP^Disabled")), "0"); - // e.addValue(e, ZCTX(_("TLTIP^Standard")), "1"); - // e.addValue(e, ZCTX(_("TLTIP^Advanced")), "2"); - // e.configureXonoticTextSliderValues(e); - //me.TR(me); - // me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_allow_uidtracking", _("Allow player statistics to track your client"))); // TODO: move to profile tab - //me.TR(me); - // me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_allow_uid2name", _("Allow player statistics to use your nickname"))); - // setDependent(e, "cl_allow_uidtracking", 1, 1); - - //me.gotoRC(me, me.rows - 1, 2.6); - // me.TD(me, 1, 2, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "sendcvar cl_gentle; sendcvar cl_allow_uidtracking; sendcvar cl_allow_uid2name;", COMMANDBUTTON_APPLY)); - -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_user.qc b/qcsrc/menu/xonotic/dialog_settings_user.qc new file mode 100644 index 000000000..180efccb9 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_user.qc @@ -0,0 +1,96 @@ +#ifdef INTERFACE +CLASS(XonoticUserSettingsTab) EXTENDS(XonoticTab) + METHOD(XonoticUserSettingsTab, fill, void(entity)) + ATTRIB(XonoticUserSettingsTab, title, string, _("User")) + ATTRIB(XonoticUserSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticUserSettingsTab, rows, float, 15.5) + ATTRIB(XonoticUserSettingsTab, columns, float, 6) +ENDCLASS(XonoticUserSettingsTab) +entity makeXonoticUserSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticUserSettingsTab() +{ + entity me; + me = spawnXonoticUserSettingsTab(); + me.configureDialog(me); + return me; +} + +void XonoticUserSettingsTab_fill(entity me) +{ + entity e; + entity sk; + + me.TR(me); + me.TDempty(me, 0.25); + me.TD(me, 1, 2.5, e = makeXonoticHeaderLabel(_("Menu Skins"))); + me.TR(me); + me.TDempty(me, 0.25); + me.TD(me, me.rows - 2.5, 2.5, sk = makeXonoticSkinList()); + me.gotoRC(me, me.rows - 1.5, 0.25); + me.TD(me, 1, 2.5, e = makeXonoticButton(_("Set skin"), '0 0 0')); + e.onClick = SetSkin_Click; + e.onClickEntity = sk; + + /* AFTER 0.6 RELEASE TODO: Add a listbox which has fonts too, this way user can select the font they want. + me.gotoRC(me, 0, 2.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Text language:"))); + me.TR(me); + me.TD(me, 6, 1, sk = makeXonoticLanguageList()); + me.TR(me); + me.TR(me); + me.TR(me); + me.TR(me); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticButton(_("Set language"), '0 0 0')); + e.onClick = SetLanguage_Click; + e.onClickEntity = sk; + + me.gotoRC(me, 0, 3.3); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 1.5, e = makeXonoticTextLabel(0, _("Font:"))); + me.TR(me); + me.TD(me, 2, 1.5, sk = makeXonoticLanguageList()); + me.TR(me); + me.TR(me); + me.TR(me); + me.TR(me); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1.5, e = makeXonoticButton(_("Set font"), '0 0 0')); + e.onClick = SetLanguage_Click; + e.onClickEntity = sk;*/ + + me.gotoRC(me, 0, 3.75); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 1.5, e = makeXonoticHeaderLabel(_("Text Language"))); + me.TR(me); + me.TD(me, 8, 1.5, sk = makeXonoticLanguageList()); + + me.gotoRC(me, 9, 3.75); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 1.5, e = makeXonoticButton(_("Set language"), '0 0 0')); + e.onClick = SetLanguage_Click; + e.onClickEntity = sk; + + me.gotoRC(me, 11.5, 3.25); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 2.5, e = makeXonoticCheckBox(0, "cl_gentle", _("Disable gore effects and harsh language"))); + + //me.TR(me); + // me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Menu tooltips:"))); + // me.TD(me, 1, 2, e = makeXonoticTextSlider("menu_tooltips")); + // e.addValue(e, ZCTX(_("TLTIP^Disabled")), "0"); + // e.addValue(e, ZCTX(_("TLTIP^Standard")), "1"); + // e.addValue(e, ZCTX(_("TLTIP^Advanced")), "2"); + // e.configureXonoticTextSliderValues(e); + //me.TR(me); + // me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_allow_uidtracking", _("Allow player statistics to track your client"))); // TODO: move to profile tab + //me.TR(me); + // me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_allow_uid2name", _("Allow player statistics to use your nickname"))); + // setDependent(e, "cl_allow_uidtracking", 1, 1); + + //me.gotoRC(me, me.rows - 1, 2.6); + // me.TD(me, 1, 2, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "sendcvar cl_gentle; sendcvar cl_allow_uidtracking; sendcvar cl_allow_uid2name;", COMMANDBUTTON_APPLY)); + +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.c b/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.c deleted file mode 100644 index c830b5583..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.c +++ /dev/null @@ -1,26 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticLanguageWarningDialog) EXTENDS(XonoticDialog) - METHOD(XonoticLanguageWarningDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls - ATTRIB(XonoticLanguageWarningDialog, title, string, _("Warning")) - ATTRIB(XonoticLanguageWarningDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) - ATTRIB(XonoticLanguageWarningDialog, intendedWidth, float, 0.6) - ATTRIB(XonoticLanguageWarningDialog, rows, float, 5) - ATTRIB(XonoticLanguageWarningDialog, columns, float, 4) -ENDCLASS(XonoticLanguageWarningDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticLanguageWarningDialog_fill(entity me) -{ - entity e; - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("While connected language changes will be applied only to the menu,"))); - me.TR(me); - me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("full language changes will take effect starting from the next game"))); - me.TR(me); - me.TR(me); - // reconnect command doesn't work properly, otherwise it would replace disconnect - me.TD(me, 1, 2, e = makeXonoticCommandButton(_("Disconnect now"), '0 0 0', "disconnect", 0)); - me.TD(me, 1, 2, e = makeXonoticCommandButton(_("Switch language"), '0 0 0', "prvm_language \"$_menu_prvm_language\"; menu_restart; menu_cmd languageselect", 0)); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc b/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc new file mode 100644 index 000000000..c830b5583 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc @@ -0,0 +1,26 @@ +#ifdef INTERFACE +CLASS(XonoticLanguageWarningDialog) EXTENDS(XonoticDialog) + METHOD(XonoticLanguageWarningDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls + ATTRIB(XonoticLanguageWarningDialog, title, string, _("Warning")) + ATTRIB(XonoticLanguageWarningDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM) + ATTRIB(XonoticLanguageWarningDialog, intendedWidth, float, 0.6) + ATTRIB(XonoticLanguageWarningDialog, rows, float, 5) + ATTRIB(XonoticLanguageWarningDialog, columns, float, 4) +ENDCLASS(XonoticLanguageWarningDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticLanguageWarningDialog_fill(entity me) +{ + entity e; + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("While connected language changes will be applied only to the menu,"))); + me.TR(me); + me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("full language changes will take effect starting from the next game"))); + me.TR(me); + me.TR(me); + // reconnect command doesn't work properly, otherwise it would replace disconnect + me.TD(me, 1, 2, e = makeXonoticCommandButton(_("Disconnect now"), '0 0 0', "disconnect", 0)); + me.TD(me, 1, 2, e = makeXonoticCommandButton(_("Switch language"), '0 0 0', "prvm_language \"$_menu_prvm_language\"; menu_restart; menu_cmd languageselect", 0)); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_video.c b/qcsrc/menu/xonotic/dialog_settings_video.c deleted file mode 100644 index 36929cbd7..000000000 --- a/qcsrc/menu/xonotic/dialog_settings_video.c +++ /dev/null @@ -1,145 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticVideoSettingsTab) EXTENDS(XonoticTab) - METHOD(XonoticVideoSettingsTab, fill, void(entity)) - ATTRIB(XonoticVideoSettingsTab, title, string, _("Video")) - ATTRIB(XonoticVideoSettingsTab, intendedWidth, float, 0.9) - ATTRIB(XonoticVideoSettingsTab, rows, float, 15.5) - ATTRIB(XonoticVideoSettingsTab, columns, float, 6.2) // added extra .2 for center space - ATTRIB(XonoticVideoSettingsTab, name, string, "videosettings") -ENDCLASS(XonoticVideoSettingsTab) -entity makeXonoticVideoSettingsTab(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticVideoSettingsTab() -{ - entity me; - me = spawnXonoticVideoSettingsTab(); - me.configureDialog(me); - return me; -} -void XonoticVideoSettingsTab_fill(entity me) -{ - entity e; - - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Resolution:"))); - me.TD(me, 1, 2, e = makeXonoticResolutionSlider()); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Font/UI size:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("menu_vid_scale")); - e.addValue(e, ZCTX(_("SZ^Unreadable")), "-1"); - e.addValue(e, ZCTX(_("SZ^Tiny")), "-0.75"); - e.addValue(e, ZCTX(_("SZ^Little")), "-0.5"); - e.addValue(e, ZCTX(_("SZ^Small")), "-0.25"); - e.addValue(e, ZCTX(_("SZ^Medium")), "0"); - e.addValue(e, ZCTX(_("SZ^Large")), "0.25"); - e.addValue(e, ZCTX(_("SZ^Huge")), "0.5"); - e.addValue(e, ZCTX(_("SZ^Gigantic")), "0.75"); - e.addValue(e, ZCTX(_("SZ^Colossal")), "1"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Color depth:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("vid_bitsperpixel")); - e.addValue(e, _("16bit"), "16"); - e.addValue(e, _("32bit"), "32"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "vid_fullscreen", _("Full screen"))); - me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "vid_vsync", _("Vertical Synchronization"))); - - me.TR(me); - if(cvar("developer")) - { me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "v_flipped", _("Flip view horizontally"))); } - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Anisotropy:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("gl_texture_anisotropy")); - e.addValue(e, ZCTX(_("ANISO^Disabled")), "1"); - e.addValue(e, _("2x"), "2"); - e.addValue(e, _("4x"), "4"); - e.addValue(e, _("8x"), "8"); - e.addValue(e, _("16x"), "16"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Antialiasing:"))); - setDependent(e, "r_viewfbo", 0, 0); - me.TD(me, 1, 2, e = makeXonoticTextSlider("vid_samples")); - e.addValue(e, ZCTX(_("AA^Disabled")), "1"); - e.addValue(e, _("2x"), "2"); - e.addValue(e, _("4x"), "4"); - e.configureXonoticTextSliderValues(e); - setDependent(e, "r_viewfbo", 0, 0); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 0, "r_viewfbo", _("High-quality frame buffer"))); - setDependent(e, "vid_samples", 1, 1); - - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Depth first:"))); - me.TD(me, 1, 2, e = makeXonoticTextSlider("r_depthfirst")); - e.addValue(e, ZCTX(_("DF^Disabled")), "0"); - e.addValue(e, ZCTX(_("DF^World")), "1"); - e.addValue(e, ZCTX(_("DF^All")), "2"); - e.configureXonoticTextSliderValues(e); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticTextLabel(0, _("Vertex Buffer Objects (VBOs)"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "gl_vbo", "0", ZCTX(_("VBO^Off")))); - me.TD(me, 1, 1.9, e = makeXonoticRadioButton(1, "gl_vbo", "3", _("Vertices, some Tris (compatible)"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "gl_vbo", "2", _("Vertices"))); - me.TD(me, 1, 1.9, e = makeXonoticRadioButton(1, "gl_vbo", "1", _("Vertices and Triangles"))); - - me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Brightness:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(0.0, 0.5, 0.02, "v_brightness")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Contrast:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(1.0, 3.0, 0.05, "v_contrast")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Gamma:"))); - setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(0.5, 2.0, 0.05, "v_gamma")); - setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Contrast boost:"))); - setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(1.0, 5.0, 0.1, "v_contrastboost")); - setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Saturation:"))); - setDependent(e, "vid_gl20", 1, 1); - me.TD(me, 1, 2, e = makeXonoticSlider(0.5, 2.0, 0.05, "r_glsl_saturation")); - setDependent(e, "vid_gl20", 1, 1); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, ZCTX(_("LIT^Ambient:")))); - me.TD(me, 1, 2, e = makeXonoticSlider(0, 20.0, 0.25, "r_ambient")); - me.TR(me); - me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Intensity:"))); - me.TD(me, 1, 2, e = makeXonoticSlider(0.5, 2.0, 0.05, "r_hdr_scenebrightness")); - me.TR(me); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "gl_finish", _("Wait for GPU to finish each frame"))); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "vid_gl20", _("Use OpenGL 2.0 shaders (GLSL)"))); - me.TR(me); - me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "v_glslgamma", _("Use GLSL to handle color control"))); - setDependent(e, "vid_gl20", 1, 1); - if(cvar("developer")) - { - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "v_psycho", _("Psycho coloring (easter egg)"))); - setDependent(e, "vid_gl20", 1, 1); - me.TR(me); - me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "r_trippy", _("Trippy vertices (easter egg)"))); - setDependent(e, "vid_gl20", 1, 1); - } - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "vid_width $_menu_vid_width; vid_height $_menu_vid_height; vid_pixelheight $_menu_vid_pixelheight; vid_desktopfullscreen $_menu_vid_desktopfullscreen; menu_cmd update_conwidths_before_vid_restart; vid_restart; menu_cmd sync", COMMANDBUTTON_APPLY)); -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_settings_video.qc b/qcsrc/menu/xonotic/dialog_settings_video.qc new file mode 100644 index 000000000..36929cbd7 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_settings_video.qc @@ -0,0 +1,145 @@ +#ifdef INTERFACE +CLASS(XonoticVideoSettingsTab) EXTENDS(XonoticTab) + METHOD(XonoticVideoSettingsTab, fill, void(entity)) + ATTRIB(XonoticVideoSettingsTab, title, string, _("Video")) + ATTRIB(XonoticVideoSettingsTab, intendedWidth, float, 0.9) + ATTRIB(XonoticVideoSettingsTab, rows, float, 15.5) + ATTRIB(XonoticVideoSettingsTab, columns, float, 6.2) // added extra .2 for center space + ATTRIB(XonoticVideoSettingsTab, name, string, "videosettings") +ENDCLASS(XonoticVideoSettingsTab) +entity makeXonoticVideoSettingsTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticVideoSettingsTab() +{ + entity me; + me = spawnXonoticVideoSettingsTab(); + me.configureDialog(me); + return me; +} +void XonoticVideoSettingsTab_fill(entity me) +{ + entity e; + + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Resolution:"))); + me.TD(me, 1, 2, e = makeXonoticResolutionSlider()); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Font/UI size:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("menu_vid_scale")); + e.addValue(e, ZCTX(_("SZ^Unreadable")), "-1"); + e.addValue(e, ZCTX(_("SZ^Tiny")), "-0.75"); + e.addValue(e, ZCTX(_("SZ^Little")), "-0.5"); + e.addValue(e, ZCTX(_("SZ^Small")), "-0.25"); + e.addValue(e, ZCTX(_("SZ^Medium")), "0"); + e.addValue(e, ZCTX(_("SZ^Large")), "0.25"); + e.addValue(e, ZCTX(_("SZ^Huge")), "0.5"); + e.addValue(e, ZCTX(_("SZ^Gigantic")), "0.75"); + e.addValue(e, ZCTX(_("SZ^Colossal")), "1"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Color depth:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("vid_bitsperpixel")); + e.addValue(e, _("16bit"), "16"); + e.addValue(e, _("32bit"), "32"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "vid_fullscreen", _("Full screen"))); + me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "vid_vsync", _("Vertical Synchronization"))); + + me.TR(me); + if(cvar("developer")) + { me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "v_flipped", _("Flip view horizontally"))); } + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Anisotropy:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("gl_texture_anisotropy")); + e.addValue(e, ZCTX(_("ANISO^Disabled")), "1"); + e.addValue(e, _("2x"), "2"); + e.addValue(e, _("4x"), "4"); + e.addValue(e, _("8x"), "8"); + e.addValue(e, _("16x"), "16"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Antialiasing:"))); + setDependent(e, "r_viewfbo", 0, 0); + me.TD(me, 1, 2, e = makeXonoticTextSlider("vid_samples")); + e.addValue(e, ZCTX(_("AA^Disabled")), "1"); + e.addValue(e, _("2x"), "2"); + e.addValue(e, _("4x"), "4"); + e.configureXonoticTextSliderValues(e); + setDependent(e, "r_viewfbo", 0, 0); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 0, "r_viewfbo", _("High-quality frame buffer"))); + setDependent(e, "vid_samples", 1, 1); + + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Depth first:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("r_depthfirst")); + e.addValue(e, ZCTX(_("DF^Disabled")), "0"); + e.addValue(e, ZCTX(_("DF^World")), "1"); + e.addValue(e, ZCTX(_("DF^All")), "2"); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticTextLabel(0, _("Vertex Buffer Objects (VBOs)"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "gl_vbo", "0", ZCTX(_("VBO^Off")))); + me.TD(me, 1, 1.9, e = makeXonoticRadioButton(1, "gl_vbo", "3", _("Vertices, some Tris (compatible)"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.9, e = makeXonoticRadioButton(1, "gl_vbo", "2", _("Vertices"))); + me.TD(me, 1, 1.9, e = makeXonoticRadioButton(1, "gl_vbo", "1", _("Vertices and Triangles"))); + + me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Brightness:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(0.0, 0.5, 0.02, "v_brightness")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Contrast:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(1.0, 3.0, 0.05, "v_contrast")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Gamma:"))); + setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(0.5, 2.0, 0.05, "v_gamma")); + setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Contrast boost:"))); + setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(1.0, 5.0, 0.1, "v_contrastboost")); + setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Saturation:"))); + setDependent(e, "vid_gl20", 1, 1); + me.TD(me, 1, 2, e = makeXonoticSlider(0.5, 2.0, 0.05, "r_glsl_saturation")); + setDependent(e, "vid_gl20", 1, 1); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, ZCTX(_("LIT^Ambient:")))); + me.TD(me, 1, 2, e = makeXonoticSlider(0, 20.0, 0.25, "r_ambient")); + me.TR(me); + me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Intensity:"))); + me.TD(me, 1, 2, e = makeXonoticSlider(0.5, 2.0, 0.05, "r_hdr_scenebrightness")); + me.TR(me); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "gl_finish", _("Wait for GPU to finish each frame"))); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "vid_gl20", _("Use OpenGL 2.0 shaders (GLSL)"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "v_glslgamma", _("Use GLSL to handle color control"))); + setDependent(e, "vid_gl20", 1, 1); + if(cvar("developer")) + { + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "v_psycho", _("Psycho coloring (easter egg)"))); + setDependent(e, "vid_gl20", 1, 1); + me.TR(me); + me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "r_trippy", _("Trippy vertices (easter egg)"))); + setDependent(e, "vid_gl20", 1, 1); + } + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "vid_width $_menu_vid_width; vid_height $_menu_vid_height; vid_pixelheight $_menu_vid_pixelheight; vid_desktopfullscreen $_menu_vid_desktopfullscreen; menu_cmd update_conwidths_before_vid_restart; vid_restart; menu_cmd sync", COMMANDBUTTON_APPLY)); +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_singleplayer.c b/qcsrc/menu/xonotic/dialog_singleplayer.c deleted file mode 100644 index 6e13f65b8..000000000 --- a/qcsrc/menu/xonotic/dialog_singleplayer.c +++ /dev/null @@ -1,146 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticSingleplayerDialog) EXTENDS(XonoticDialog) - METHOD(XonoticSingleplayerDialog, fill, void(entity)) - ATTRIB(XonoticSingleplayerDialog, title, string, _("Singleplayer")) - ATTRIB(XonoticSingleplayerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER) - ATTRIB(XonoticSingleplayerDialog, intendedWidth, float, 0.80) - ATTRIB(XonoticSingleplayerDialog, rows, float, 24) - ATTRIB(XonoticSingleplayerDialog, columns, float, 5) - ATTRIB(XonoticSingleplayerDialog, campaignBox, entity, NULL) -ENDCLASS(XonoticSingleplayerDialog) -#endif - -#ifdef IMPLEMENTATION - -void InstantAction_LoadMap(entity btn, entity dummy) -{ - float pmin = 2, pmax = 16, pstep = 1; - - cvar_set("timelimit_override", "10"); - cvar_set("g_lms_lives_override", "9"); - - if(random() < 0.4) // 40% are DM - { - MapInfo_SwitchGameType(MAPINFO_TYPE_DEATHMATCH); - pmin = 2; - pmax = 8; - pstep = 1; - } - else if(random() < 0.5) // half of the remaining 60%, i.e. 30%, are CTF - { - MapInfo_SwitchGameType(MAPINFO_TYPE_CTF); - pmin = 4; - pmax = 12; - pstep = 2; - } - else if(random() < 0.5) // half of the remaining 30%, i.e. 15%, are TDM - { - MapInfo_SwitchGameType(MAPINFO_TYPE_TEAM_DEATHMATCH); - pmin = 4; - pmax = 8; - pstep = 2; - } - else if(random() < 0.666) // 2/3 of the remaining 15%, i.e. 10%, are KH - { - MapInfo_SwitchGameType(MAPINFO_TYPE_KEYHUNT); - pmin = 6; - pmax = 6; - pstep = 6; // works both for 2 and 3 teams - // TODO find team count of map, set pstep=2 or 3, and use 2v2(v2) games at least - } - else // somehow distribute the remaining 5% - { - float r; - r = floor(random() * 4); - switch(r) - { - default: - case 0: - MapInfo_SwitchGameType(MAPINFO_TYPE_LMS); - pmin = 2; - pmax = 6; - pstep = 1; - cvar_set("timelimit_override", "-1"); - break; - case 1: - MapInfo_SwitchGameType(MAPINFO_TYPE_DOMINATION); - pmin = 2; - pmax = 8; - pstep = 2; - break; - case 2: - MapInfo_SwitchGameType(MAPINFO_TYPE_ONSLAUGHT); - pmin = 6; - pmax = 16; - pstep = 2; - break; - case 3: - MapInfo_SwitchGameType(MAPINFO_TYPE_ASSAULT); - pmin = 4; - pmax = 16; - pstep = 2; - break; - // CA, Freezetag: bot AI does not work, add them once it does - } - } - - // find random map - MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); - string s; - do - { - float m; - m = floor(random() * MapInfo_count); - s = MapInfo_BSPName_ByID(m); - } - while(!fexists(sprintf("maps/%s.waypoints", s))); - MapInfo_LoadMap(s, 1); - - // configure bots - float p; - pmin = pstep * ceil(pmin / pstep); - pmax = pstep * floor(pmax / pstep); - p = pmin + pstep * floor(random() * ((pmax - pmin) / pstep + 1)); - cvar_set("bot_number", ftos(p - 1)); - - // make sure we go back to menu - cvar_set("lastlevel", "1"); -} - -void XonoticSingleplayerDialog_fill(entity me) -{ - entity e, btnPrev, btnNext, lblTitle; - - me.TR(me); - me.TDempty(me, (me.columns - 3) / 2); - me.TD(me, 2, 3, e = makeXonoticBigButton(_("Instant action! (random map with bots)"), '0 0 0')); - e.onClick = InstantAction_LoadMap; - e.onClickEntity = NULL; - me.TR(me); - me.TR(me); - me.TR(me); - me.TD(me, 1, 1, btnPrev = makeXonoticButton("<<", '0 0 0')); - me.TD(me, 1, me.columns - 2, lblTitle = makeXonoticTextLabel(0.5, _("???"))); - me.TD(me, 1, 1, btnNext = makeXonoticButton(">>", '0 0 0')); - me.TR(me); - me.TD(me, me.rows - 6, me.columns, me.campaignBox = makeXonoticCampaignList()); - btnPrev.onClick = MultiCampaign_Prev; - btnPrev.onClickEntity = me.campaignBox; - btnNext.onClick = MultiCampaign_Next; - btnNext.onClickEntity = me.campaignBox; - me.campaignBox.buttonNext = btnNext; - me.campaignBox.buttonPrev = btnPrev; - me.campaignBox.labelTitle = lblTitle; - me.campaignBox.campaignGo(me.campaignBox, 0); - - me.gotoRC(me, me.rows - 2, 0); - me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Campaign Difficulty:"))); - me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "-2", ZCTX(_("CSKL^Easy")))); - me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "-1", ZCTX(_("CSKL^Medium")))); - me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "0", ZCTX(_("CSKL^Hard")))); - me.TR(me); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("Start Singleplayer!"), '0 0 0')); - e.onClick = CampaignList_LoadMap; - e.onClickEntity = me.campaignBox; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_singleplayer.qc b/qcsrc/menu/xonotic/dialog_singleplayer.qc new file mode 100644 index 000000000..6e13f65b8 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_singleplayer.qc @@ -0,0 +1,146 @@ +#ifdef INTERFACE +CLASS(XonoticSingleplayerDialog) EXTENDS(XonoticDialog) + METHOD(XonoticSingleplayerDialog, fill, void(entity)) + ATTRIB(XonoticSingleplayerDialog, title, string, _("Singleplayer")) + ATTRIB(XonoticSingleplayerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER) + ATTRIB(XonoticSingleplayerDialog, intendedWidth, float, 0.80) + ATTRIB(XonoticSingleplayerDialog, rows, float, 24) + ATTRIB(XonoticSingleplayerDialog, columns, float, 5) + ATTRIB(XonoticSingleplayerDialog, campaignBox, entity, NULL) +ENDCLASS(XonoticSingleplayerDialog) +#endif + +#ifdef IMPLEMENTATION + +void InstantAction_LoadMap(entity btn, entity dummy) +{ + float pmin = 2, pmax = 16, pstep = 1; + + cvar_set("timelimit_override", "10"); + cvar_set("g_lms_lives_override", "9"); + + if(random() < 0.4) // 40% are DM + { + MapInfo_SwitchGameType(MAPINFO_TYPE_DEATHMATCH); + pmin = 2; + pmax = 8; + pstep = 1; + } + else if(random() < 0.5) // half of the remaining 60%, i.e. 30%, are CTF + { + MapInfo_SwitchGameType(MAPINFO_TYPE_CTF); + pmin = 4; + pmax = 12; + pstep = 2; + } + else if(random() < 0.5) // half of the remaining 30%, i.e. 15%, are TDM + { + MapInfo_SwitchGameType(MAPINFO_TYPE_TEAM_DEATHMATCH); + pmin = 4; + pmax = 8; + pstep = 2; + } + else if(random() < 0.666) // 2/3 of the remaining 15%, i.e. 10%, are KH + { + MapInfo_SwitchGameType(MAPINFO_TYPE_KEYHUNT); + pmin = 6; + pmax = 6; + pstep = 6; // works both for 2 and 3 teams + // TODO find team count of map, set pstep=2 or 3, and use 2v2(v2) games at least + } + else // somehow distribute the remaining 5% + { + float r; + r = floor(random() * 4); + switch(r) + { + default: + case 0: + MapInfo_SwitchGameType(MAPINFO_TYPE_LMS); + pmin = 2; + pmax = 6; + pstep = 1; + cvar_set("timelimit_override", "-1"); + break; + case 1: + MapInfo_SwitchGameType(MAPINFO_TYPE_DOMINATION); + pmin = 2; + pmax = 8; + pstep = 2; + break; + case 2: + MapInfo_SwitchGameType(MAPINFO_TYPE_ONSLAUGHT); + pmin = 6; + pmax = 16; + pstep = 2; + break; + case 3: + MapInfo_SwitchGameType(MAPINFO_TYPE_ASSAULT); + pmin = 4; + pmax = 16; + pstep = 2; + break; + // CA, Freezetag: bot AI does not work, add them once it does + } + } + + // find random map + MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); + string s; + do + { + float m; + m = floor(random() * MapInfo_count); + s = MapInfo_BSPName_ByID(m); + } + while(!fexists(sprintf("maps/%s.waypoints", s))); + MapInfo_LoadMap(s, 1); + + // configure bots + float p; + pmin = pstep * ceil(pmin / pstep); + pmax = pstep * floor(pmax / pstep); + p = pmin + pstep * floor(random() * ((pmax - pmin) / pstep + 1)); + cvar_set("bot_number", ftos(p - 1)); + + // make sure we go back to menu + cvar_set("lastlevel", "1"); +} + +void XonoticSingleplayerDialog_fill(entity me) +{ + entity e, btnPrev, btnNext, lblTitle; + + me.TR(me); + me.TDempty(me, (me.columns - 3) / 2); + me.TD(me, 2, 3, e = makeXonoticBigButton(_("Instant action! (random map with bots)"), '0 0 0')); + e.onClick = InstantAction_LoadMap; + e.onClickEntity = NULL; + me.TR(me); + me.TR(me); + me.TR(me); + me.TD(me, 1, 1, btnPrev = makeXonoticButton("<<", '0 0 0')); + me.TD(me, 1, me.columns - 2, lblTitle = makeXonoticTextLabel(0.5, _("???"))); + me.TD(me, 1, 1, btnNext = makeXonoticButton(">>", '0 0 0')); + me.TR(me); + me.TD(me, me.rows - 6, me.columns, me.campaignBox = makeXonoticCampaignList()); + btnPrev.onClick = MultiCampaign_Prev; + btnPrev.onClickEntity = me.campaignBox; + btnNext.onClick = MultiCampaign_Next; + btnNext.onClickEntity = me.campaignBox; + me.campaignBox.buttonNext = btnNext; + me.campaignBox.buttonPrev = btnPrev; + me.campaignBox.labelTitle = lblTitle; + me.campaignBox.campaignGo(me.campaignBox, 0); + + me.gotoRC(me, me.rows - 2, 0); + me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Campaign Difficulty:"))); + me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "-2", ZCTX(_("CSKL^Easy")))); + me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "-1", ZCTX(_("CSKL^Medium")))); + me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "0", ZCTX(_("CSKL^Hard")))); + me.TR(me); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("Start Singleplayer!"), '0 0 0')); + e.onClick = CampaignList_LoadMap; + e.onClickEntity = me.campaignBox; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_singleplayer_winner.c b/qcsrc/menu/xonotic/dialog_singleplayer_winner.c deleted file mode 100644 index 8e584b8a8..000000000 --- a/qcsrc/menu/xonotic/dialog_singleplayer_winner.c +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticWinnerDialog) EXTENDS(XonoticDialog) - METHOD(XonoticWinnerDialog, fill, void(entity)) - ATTRIB(XonoticWinnerDialog, title, string, _("Winner")) - ATTRIB(XonoticWinnerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER) - ATTRIB(XonoticWinnerDialog, intendedWidth, float, 0.32) - ATTRIB(XonoticWinnerDialog, rows, float, 12) - ATTRIB(XonoticWinnerDialog, columns, float, 3) -ENDCLASS(XonoticWinnerDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticWinnerDialog_fill(entity me) -{ - entity e; - - me.TR(me); - me.TD(me, me.rows - 2, me.columns, e = makeXonoticImage("/gfx/winner", -1)); - - me.gotoRC(me, me.rows - 1, 0); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); - e.onClick = Dialog_Close; - e.onClickEntity = me; -} -#endif diff --git a/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc b/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc new file mode 100644 index 000000000..8e584b8a8 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc @@ -0,0 +1,25 @@ +#ifdef INTERFACE +CLASS(XonoticWinnerDialog) EXTENDS(XonoticDialog) + METHOD(XonoticWinnerDialog, fill, void(entity)) + ATTRIB(XonoticWinnerDialog, title, string, _("Winner")) + ATTRIB(XonoticWinnerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER) + ATTRIB(XonoticWinnerDialog, intendedWidth, float, 0.32) + ATTRIB(XonoticWinnerDialog, rows, float, 12) + ATTRIB(XonoticWinnerDialog, columns, float, 3) +ENDCLASS(XonoticWinnerDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticWinnerDialog_fill(entity me) +{ + entity e; + + me.TR(me); + me.TD(me, me.rows - 2, me.columns, e = makeXonoticImage("/gfx/winner", -1)); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0')); + e.onClick = Dialog_Close; + e.onClickEntity = me; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_teamselect.c b/qcsrc/menu/xonotic/dialog_teamselect.c deleted file mode 100644 index 10efc3c25..000000000 --- a/qcsrc/menu/xonotic/dialog_teamselect.c +++ /dev/null @@ -1,56 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticTeamSelectDialog) EXTENDS(XonoticRootDialog) - METHOD(XonoticTeamSelectDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls - METHOD(XonoticTeamSelectDialog, showNotify, void(entity)) - ATTRIB(XonoticTeamSelectDialog, title, string, _("Team Selection")) // ;) - ATTRIB(XonoticTeamSelectDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) - ATTRIB(XonoticTeamSelectDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticTeamSelectDialog, rows, float, 5) - ATTRIB(XonoticTeamSelectDialog, columns, float, 4) - ATTRIB(XonoticTeamSelectDialog, name, string, "TeamSelect") - ATTRIB(XonoticTeamSelectDialog, team1, entity, NULL) - ATTRIB(XonoticTeamSelectDialog, team2, entity, NULL) - ATTRIB(XonoticTeamSelectDialog, team3, entity, NULL) - ATTRIB(XonoticTeamSelectDialog, team4, entity, NULL) - ATTRIB(XonoticTeamSelectDialog, requiresConnection, float, TRUE) -ENDCLASS(XonoticTeamSelectDialog) -#endif - -#ifdef IMPLEMENTATION -entity makeTeamButton(string theName, vector theColor, string commandtheName) -{ - entity b; - b = makeXonoticBigCommandButton(theName, theColor, commandtheName, 1); - return b; -} - -void XonoticTeamSelectDialog_showNotify(entity me) -{ - float teams, nTeams; - teams = cvar("_teams_available"); - nTeams = 0; - me.team1.disabled = !(teams & 1); nTeams += !!(teams & 1); - me.team2.disabled = !(teams & 2); nTeams += !!(teams & 2); - me.team3.disabled = !(teams & 4); nTeams += !!(teams & 4); - me.team4.disabled = !(teams & 8); nTeams += !!(teams & 8); -} - -void XonoticTeamSelectDialog_fill(entity me) -{ - entity e; - me.TR(me); - me.TD(me, 2, 4, e = makeTeamButton(_("join 'best' team (auto-select)"), '0 0 0', "cmd selectteam auto; cmd join")); - e.preferredFocusPriority = 1; - me.TR(me); - me.TR(me); - me.TD(me, 2, 1, me.team1 = makeTeamButton(_("red"), '1 0.5 0.5', "cmd selectteam red; cmd join")); - me.TD(me, 2, 1, me.team2 = makeTeamButton(_("blue"), '0.5 0.5 1', "cmd selectteam blue; cmd join")); - me.TD(me, 2, 1, me.team3 = makeTeamButton(_("yellow"), '1 1 0.5', "cmd selectteam yellow; cmd join")); - me.TD(me, 2, 1, me.team4 = makeTeamButton(_("pink"), '1 0.5 1', "cmd selectteam pink; cmd join")); - me.TR(me); - me.TR(me); - me.TD(me, 1, 4, makeXonoticCommandButton(_("spectate"), '0 0 0', "cmd spectate", 1)); -} -#endif - -/* Click. The c-word is here so you can grep for it :-) */ diff --git a/qcsrc/menu/xonotic/dialog_teamselect.qc b/qcsrc/menu/xonotic/dialog_teamselect.qc new file mode 100644 index 000000000..10efc3c25 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_teamselect.qc @@ -0,0 +1,56 @@ +#ifdef INTERFACE +CLASS(XonoticTeamSelectDialog) EXTENDS(XonoticRootDialog) + METHOD(XonoticTeamSelectDialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls + METHOD(XonoticTeamSelectDialog, showNotify, void(entity)) + ATTRIB(XonoticTeamSelectDialog, title, string, _("Team Selection")) // ;) + ATTRIB(XonoticTeamSelectDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) + ATTRIB(XonoticTeamSelectDialog, intendedWidth, float, 0.4) + ATTRIB(XonoticTeamSelectDialog, rows, float, 5) + ATTRIB(XonoticTeamSelectDialog, columns, float, 4) + ATTRIB(XonoticTeamSelectDialog, name, string, "TeamSelect") + ATTRIB(XonoticTeamSelectDialog, team1, entity, NULL) + ATTRIB(XonoticTeamSelectDialog, team2, entity, NULL) + ATTRIB(XonoticTeamSelectDialog, team3, entity, NULL) + ATTRIB(XonoticTeamSelectDialog, team4, entity, NULL) + ATTRIB(XonoticTeamSelectDialog, requiresConnection, float, TRUE) +ENDCLASS(XonoticTeamSelectDialog) +#endif + +#ifdef IMPLEMENTATION +entity makeTeamButton(string theName, vector theColor, string commandtheName) +{ + entity b; + b = makeXonoticBigCommandButton(theName, theColor, commandtheName, 1); + return b; +} + +void XonoticTeamSelectDialog_showNotify(entity me) +{ + float teams, nTeams; + teams = cvar("_teams_available"); + nTeams = 0; + me.team1.disabled = !(teams & 1); nTeams += !!(teams & 1); + me.team2.disabled = !(teams & 2); nTeams += !!(teams & 2); + me.team3.disabled = !(teams & 4); nTeams += !!(teams & 4); + me.team4.disabled = !(teams & 8); nTeams += !!(teams & 8); +} + +void XonoticTeamSelectDialog_fill(entity me) +{ + entity e; + me.TR(me); + me.TD(me, 2, 4, e = makeTeamButton(_("join 'best' team (auto-select)"), '0 0 0', "cmd selectteam auto; cmd join")); + e.preferredFocusPriority = 1; + me.TR(me); + me.TR(me); + me.TD(me, 2, 1, me.team1 = makeTeamButton(_("red"), '1 0.5 0.5', "cmd selectteam red; cmd join")); + me.TD(me, 2, 1, me.team2 = makeTeamButton(_("blue"), '0.5 0.5 1', "cmd selectteam blue; cmd join")); + me.TD(me, 2, 1, me.team3 = makeTeamButton(_("yellow"), '1 1 0.5', "cmd selectteam yellow; cmd join")); + me.TD(me, 2, 1, me.team4 = makeTeamButton(_("pink"), '1 0.5 1', "cmd selectteam pink; cmd join")); + me.TR(me); + me.TR(me); + me.TD(me, 1, 4, makeXonoticCommandButton(_("spectate"), '0 0 0', "cmd spectate", 1)); +} +#endif + +/* Click. The c-word is here so you can grep for it :-) */ diff --git a/qcsrc/menu/xonotic/gametypebutton.c b/qcsrc/menu/xonotic/gametypebutton.c deleted file mode 100644 index cc10f3da9..000000000 --- a/qcsrc/menu/xonotic/gametypebutton.c +++ /dev/null @@ -1,73 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticGametypeButton) EXTENDS(RadioButton) - METHOD(XonoticGametypeButton, configureXonoticGametypeButton, void(entity, float, string, string)) - METHOD(XonoticGametypeButton, setChecked, void(entity, float)) - ATTRIB(XonoticGametypeButton, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticGametypeButton, image, string, SKINGFX_BUTTON_BIG) - ATTRIB(XonoticGametypeButton, color, vector, SKINCOLOR_BUTTON_N) - ATTRIB(XonoticGametypeButton, colorC, vector, SKINCOLOR_BUTTON_C) - ATTRIB(XonoticGametypeButton, colorF, vector, SKINCOLOR_BUTTON_F) - ATTRIB(XonoticGametypeButton, colorD, vector, SKINCOLOR_BUTTON_D) - ATTRIB(XonoticGametypeButton, srcMulti, float, 1) - ATTRIB(XonoticGametypeButton, useDownAsChecked, float, 1) - - ATTRIB(XonoticGametypeButton, cvarName, string, string_null) - METHOD(XonoticGametypeButton, loadCvars, void(entity)) - METHOD(XonoticGametypeButton, saveCvars, void(entity)) - - ATTRIB(XonoticGametypeButton, alpha, float, SKINALPHA_TEXT) - ATTRIB(XonoticGametypeButton, disabledAlpha, float, SKINALPHA_DISABLED) -ENDCLASS(XonoticGametypeButton) -entity makeXonoticGametypeButton(float, string, string); -#endif - -#ifdef IMPLEMENTATION -void GameTypeButton_Click(entity me, entity other); -entity makeXonoticGametypeButton(float theGroup, string theCvar, string theText) -{ - entity me; - me = spawnXonoticGametypeButton(); - me.configureXonoticGametypeButton(me, theGroup, theCvar, theText); - return me; -} -void XonoticGametypeButton_configureXonoticGametypeButton(entity me, float theGroup, string theCvar, string theText) -{ - if(theCvar) - { - me.cvarName = theCvar; - me.tooltip = getZonedTooltipForIdentifier(theCvar); - me.loadCvars(me); - } - me.configureRadioButton(me, theText, me.fontSize, me.image, theGroup, 0); - me.align = 0.5; - me.onClick = GameTypeButton_Click; - me.onClickEntity = NULL; -} -void XonoticGametypeButton_setChecked(entity me, float val) -{ - if(val != me.checked) - { - me.checked = val; - me.saveCvars(me); - } -} -void XonoticGametypeButton_loadCvars(entity me) -{ - if (!me.cvarName) - return; - - me.checked = cvar(me.cvarName); -} -void XonoticGametypeButton_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - cvar_set(me.cvarName, ftos(me.checked)); -} -void GameTypeButton_Click(entity me, entity other) -{ - RadioButton_Click(me, other); - me.parent.gameTypeChangeNotify(me.parent); -} -#endif diff --git a/qcsrc/menu/xonotic/gametypebutton.qc b/qcsrc/menu/xonotic/gametypebutton.qc new file mode 100644 index 000000000..cc10f3da9 --- /dev/null +++ b/qcsrc/menu/xonotic/gametypebutton.qc @@ -0,0 +1,73 @@ +#ifdef INTERFACE +CLASS(XonoticGametypeButton) EXTENDS(RadioButton) + METHOD(XonoticGametypeButton, configureXonoticGametypeButton, void(entity, float, string, string)) + METHOD(XonoticGametypeButton, setChecked, void(entity, float)) + ATTRIB(XonoticGametypeButton, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticGametypeButton, image, string, SKINGFX_BUTTON_BIG) + ATTRIB(XonoticGametypeButton, color, vector, SKINCOLOR_BUTTON_N) + ATTRIB(XonoticGametypeButton, colorC, vector, SKINCOLOR_BUTTON_C) + ATTRIB(XonoticGametypeButton, colorF, vector, SKINCOLOR_BUTTON_F) + ATTRIB(XonoticGametypeButton, colorD, vector, SKINCOLOR_BUTTON_D) + ATTRIB(XonoticGametypeButton, srcMulti, float, 1) + ATTRIB(XonoticGametypeButton, useDownAsChecked, float, 1) + + ATTRIB(XonoticGametypeButton, cvarName, string, string_null) + METHOD(XonoticGametypeButton, loadCvars, void(entity)) + METHOD(XonoticGametypeButton, saveCvars, void(entity)) + + ATTRIB(XonoticGametypeButton, alpha, float, SKINALPHA_TEXT) + ATTRIB(XonoticGametypeButton, disabledAlpha, float, SKINALPHA_DISABLED) +ENDCLASS(XonoticGametypeButton) +entity makeXonoticGametypeButton(float, string, string); +#endif + +#ifdef IMPLEMENTATION +void GameTypeButton_Click(entity me, entity other); +entity makeXonoticGametypeButton(float theGroup, string theCvar, string theText) +{ + entity me; + me = spawnXonoticGametypeButton(); + me.configureXonoticGametypeButton(me, theGroup, theCvar, theText); + return me; +} +void XonoticGametypeButton_configureXonoticGametypeButton(entity me, float theGroup, string theCvar, string theText) +{ + if(theCvar) + { + me.cvarName = theCvar; + me.tooltip = getZonedTooltipForIdentifier(theCvar); + me.loadCvars(me); + } + me.configureRadioButton(me, theText, me.fontSize, me.image, theGroup, 0); + me.align = 0.5; + me.onClick = GameTypeButton_Click; + me.onClickEntity = NULL; +} +void XonoticGametypeButton_setChecked(entity me, float val) +{ + if(val != me.checked) + { + me.checked = val; + me.saveCvars(me); + } +} +void XonoticGametypeButton_loadCvars(entity me) +{ + if (!me.cvarName) + return; + + me.checked = cvar(me.cvarName); +} +void XonoticGametypeButton_saveCvars(entity me) +{ + if (!me.cvarName) + return; + + cvar_set(me.cvarName, ftos(me.checked)); +} +void GameTypeButton_Click(entity me, entity other) +{ + RadioButton_Click(me, other); + me.parent.gameTypeChangeNotify(me.parent); +} +#endif diff --git a/qcsrc/menu/xonotic/gametypelist.c b/qcsrc/menu/xonotic/gametypelist.c deleted file mode 100644 index e3df84467..000000000 --- a/qcsrc/menu/xonotic/gametypelist.c +++ /dev/null @@ -1,125 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticGametypeList) EXTENDS(XonoticListBox) - METHOD(XonoticGametypeList, configureXonoticGametypeList, void(entity)) - ATTRIB(XonoticGametypeList, rowsPerItem, float, 2) - METHOD(XonoticGametypeList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticGametypeList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticGametypeList, setSelected, void(entity, float)) - METHOD(XonoticGametypeList, loadCvars, void(entity)) - METHOD(XonoticGametypeList, saveCvars, void(entity)) - METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float)) - - ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticGametypeList, realUpperMargin, float, 0) - ATTRIB(XonoticGametypeList, columnIconOrigin, float, 0) - ATTRIB(XonoticGametypeList, columnIconSize, float, 0) - ATTRIB(XonoticGametypeList, columnNameOrigin, float, 0) - ATTRIB(XonoticGametypeList, columnNameSize, float, 0) -ENDCLASS(XonoticGametypeList) -entity makeXonoticGametypeList(); -#endif - -#ifdef IMPLEMENTATION - -entity makeXonoticGametypeList(void) -{ - entity me; - me = spawnXonoticGametypeList(); - me.configureXonoticGametypeList(me); - return me; -} -void XonoticGametypeList_configureXonoticGametypeList(entity me) -{ - float i; - me.configureXonoticListBox(me); - me.nItems = GameType_GetCount(); - - // we want the pics mipmapped - for(i = 0; i < GameType_GetCount(); ++i) - draw_PreloadPictureWithFlags(GameType_GetIcon(i), PRECACHE_PIC_MIPMAP); - - me.loadCvars(me); -} -void XonoticGametypeList_setSelected(entity me, float i) -{ - SUPER(XonoticGametypeList).setSelected(me, i); - me.saveCvars(me); -} - -void XonoticGametypeList_loadCvars(entity me) -{ - float t; - t = MapInfo_CurrentGametype(); - float i; - for(i = 0; i < GameType_GetCount(); ++i) - if(t == GameType_GetID(i)) - break; - if(i >= GameType_GetCount()) - { - for(i = 0; i < GameType_GetCount(); ++i) - if(t == MAPINFO_TYPE_DEATHMATCH) - break; - if(i >= GameType_GetCount()) - i = 0; - } - me.setSelected(me, i); - // do we need this: me.parent.gameTypeChangeNotify(me.parent); // to make sure -} -void XonoticGametypeList_saveCvars(entity me) -{ - float t; - t = GameType_GetID(me.selectedItem); - if(t == MapInfo_CurrentGametype()) - return; - MapInfo_SwitchGameType(t); - me.parent.gameTypeChangeNotify(me.parent); -} -void XonoticGametypeList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s1, s2; - - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - draw_Picture(me.columnIconOrigin * eX, GameType_GetIcon(i), me.columnIconSize * eX + eY, '1 1 1', SKINALPHA_LISTBOX_SELECTED); - s1 = GameType_GetName(i); - - if(_MapInfo_GetTeamPlayBool(GameType_GetID(i))) - s2 = _("teamplay"); - else - s2 = _("free for all"); - - vector save_fontscale = draw_fontscale; - float f = draw_CondensedFontFactor(strcat(s1, " ", s2), FALSE, me.realFontSize, 1); - draw_fontscale_x *= f; - vector fs = me.realFontSize; - fs_x *= f; - draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s1, fs, '1 1 1', SKINALPHA_TEXT, 0); - draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 1.0 * (me.columnNameSize - draw_TextWidth(s2, 0, fs))) * eX, s2, fs, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0); - draw_fontscale = save_fontscale; -} -void XonoticGametypeList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticServerList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - me.columnIconOrigin = 0; - me.columnIconSize = me.itemAbsSize_y / me.itemAbsSize_x; - me.columnNameOrigin = me.columnIconOrigin + me.columnIconSize + (0.5 * me.realFontSize_x); - me.columnNameSize = 1 - me.columnIconSize - (1.5 * me.realFontSize_x); -} - -float XonoticGametypeList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(scan == K_ENTER || scan == K_KP_ENTER) - { - me.parent.gameTypeSelectNotify(me.parent); - return 1; - } - - return SUPER(XonoticGametypeList).keyDown(me, scan, ascii, shift); -} -#endif diff --git a/qcsrc/menu/xonotic/gametypelist.qc b/qcsrc/menu/xonotic/gametypelist.qc new file mode 100644 index 000000000..e3df84467 --- /dev/null +++ b/qcsrc/menu/xonotic/gametypelist.qc @@ -0,0 +1,125 @@ +#ifdef INTERFACE +CLASS(XonoticGametypeList) EXTENDS(XonoticListBox) + METHOD(XonoticGametypeList, configureXonoticGametypeList, void(entity)) + ATTRIB(XonoticGametypeList, rowsPerItem, float, 2) + METHOD(XonoticGametypeList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticGametypeList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticGametypeList, setSelected, void(entity, float)) + METHOD(XonoticGametypeList, loadCvars, void(entity)) + METHOD(XonoticGametypeList, saveCvars, void(entity)) + METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float)) + + ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticGametypeList, realUpperMargin, float, 0) + ATTRIB(XonoticGametypeList, columnIconOrigin, float, 0) + ATTRIB(XonoticGametypeList, columnIconSize, float, 0) + ATTRIB(XonoticGametypeList, columnNameOrigin, float, 0) + ATTRIB(XonoticGametypeList, columnNameSize, float, 0) +ENDCLASS(XonoticGametypeList) +entity makeXonoticGametypeList(); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticGametypeList(void) +{ + entity me; + me = spawnXonoticGametypeList(); + me.configureXonoticGametypeList(me); + return me; +} +void XonoticGametypeList_configureXonoticGametypeList(entity me) +{ + float i; + me.configureXonoticListBox(me); + me.nItems = GameType_GetCount(); + + // we want the pics mipmapped + for(i = 0; i < GameType_GetCount(); ++i) + draw_PreloadPictureWithFlags(GameType_GetIcon(i), PRECACHE_PIC_MIPMAP); + + me.loadCvars(me); +} +void XonoticGametypeList_setSelected(entity me, float i) +{ + SUPER(XonoticGametypeList).setSelected(me, i); + me.saveCvars(me); +} + +void XonoticGametypeList_loadCvars(entity me) +{ + float t; + t = MapInfo_CurrentGametype(); + float i; + for(i = 0; i < GameType_GetCount(); ++i) + if(t == GameType_GetID(i)) + break; + if(i >= GameType_GetCount()) + { + for(i = 0; i < GameType_GetCount(); ++i) + if(t == MAPINFO_TYPE_DEATHMATCH) + break; + if(i >= GameType_GetCount()) + i = 0; + } + me.setSelected(me, i); + // do we need this: me.parent.gameTypeChangeNotify(me.parent); // to make sure +} +void XonoticGametypeList_saveCvars(entity me) +{ + float t; + t = GameType_GetID(me.selectedItem); + if(t == MapInfo_CurrentGametype()) + return; + MapInfo_SwitchGameType(t); + me.parent.gameTypeChangeNotify(me.parent); +} +void XonoticGametypeList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s1, s2; + + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + draw_Picture(me.columnIconOrigin * eX, GameType_GetIcon(i), me.columnIconSize * eX + eY, '1 1 1', SKINALPHA_LISTBOX_SELECTED); + s1 = GameType_GetName(i); + + if(_MapInfo_GetTeamPlayBool(GameType_GetID(i))) + s2 = _("teamplay"); + else + s2 = _("free for all"); + + vector save_fontscale = draw_fontscale; + float f = draw_CondensedFontFactor(strcat(s1, " ", s2), FALSE, me.realFontSize, 1); + draw_fontscale_x *= f; + vector fs = me.realFontSize; + fs_x *= f; + draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s1, fs, '1 1 1', SKINALPHA_TEXT, 0); + draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 1.0 * (me.columnNameSize - draw_TextWidth(s2, 0, fs))) * eX, s2, fs, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0); + draw_fontscale = save_fontscale; +} +void XonoticGametypeList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticServerList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + me.columnIconOrigin = 0; + me.columnIconSize = me.itemAbsSize_y / me.itemAbsSize_x; + me.columnNameOrigin = me.columnIconOrigin + me.columnIconSize + (0.5 * me.realFontSize_x); + me.columnNameSize = 1 - me.columnIconSize - (1.5 * me.realFontSize_x); +} + +float XonoticGametypeList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_KP_ENTER) + { + me.parent.gameTypeSelectNotify(me.parent); + return 1; + } + + return SUPER(XonoticGametypeList).keyDown(me, scan, ascii, shift); +} +#endif diff --git a/qcsrc/menu/xonotic/image.c b/qcsrc/menu/xonotic/image.c deleted file mode 100644 index 9f0de67b8..000000000 --- a/qcsrc/menu/xonotic/image.c +++ /dev/null @@ -1,21 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticImage) EXTENDS(Image) - METHOD(XonoticImage, configureXonoticImage, void(entity, string, float)) -ENDCLASS(XonoticImage) -entity makeXonoticImage(string theImage, float theAspect); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticImage(string theImage, float theAspect) -{ - entity me; - me = spawnXonoticImage(); - me.configureXonoticImage(me, theImage, theAspect); - return me; -} -void XonoticImage_configureXonoticImage(entity me, string theImage, float theAspect) -{ - me.configureImage(me, theImage); - me.forcedAspect = theAspect; -} -#endif diff --git a/qcsrc/menu/xonotic/image.qc b/qcsrc/menu/xonotic/image.qc new file mode 100644 index 000000000..9f0de67b8 --- /dev/null +++ b/qcsrc/menu/xonotic/image.qc @@ -0,0 +1,21 @@ +#ifdef INTERFACE +CLASS(XonoticImage) EXTENDS(Image) + METHOD(XonoticImage, configureXonoticImage, void(entity, string, float)) +ENDCLASS(XonoticImage) +entity makeXonoticImage(string theImage, float theAspect); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticImage(string theImage, float theAspect) +{ + entity me; + me = spawnXonoticImage(); + me.configureXonoticImage(me, theImage, theAspect); + return me; +} +void XonoticImage_configureXonoticImage(entity me, string theImage, float theAspect) +{ + me.configureImage(me, theImage); + me.forcedAspect = theAspect; +} +#endif diff --git a/qcsrc/menu/xonotic/inputbox.c b/qcsrc/menu/xonotic/inputbox.c deleted file mode 100644 index 5d7d17999..000000000 --- a/qcsrc/menu/xonotic/inputbox.c +++ /dev/null @@ -1,105 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticInputBox) EXTENDS(InputBox) - METHOD(XonoticInputBox, configureXonoticInputBox, void(entity, float, string)) - METHOD(XonoticInputBox, focusLeave, void(entity)) - METHOD(XonoticInputBox, setText, void(entity, string)) - ATTRIB(XonoticInputBox, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticInputBox, image, string, SKINGFX_INPUTBOX) - ATTRIB(XonoticInputBox, onChange, void(entity, entity), func_null) - ATTRIB(XonoticInputBox, onChangeEntity, entity, NULL) - ATTRIB(XonoticInputBox, onEnter, void(entity, entity), func_null) - ATTRIB(XonoticInputBox, onEnterEntity, entity, NULL) - ATTRIB(XonoticInputBox, marginLeft, float, SKINMARGIN_INPUTBOX_CHARS) - ATTRIB(XonoticInputBox, marginRight, float, SKINMARGIN_INPUTBOX_CHARS) - ATTRIB(XonoticInputBox, color, vector, SKINCOLOR_INPUTBOX_N) - ATTRIB(XonoticInputBox, colorF, vector, SKINCOLOR_INPUTBOX_F) - - ATTRIB(XonoticInputBox, alpha, float, SKINALPHA_TEXT) - - // Clear button attributes - ATTRIB(XonoticInputBox, cb_offset, float, SKINOFFSET_CLEARBUTTON) // bound to range -1, 0 - ATTRIB(XonoticInputBox, cb_src, string, SKINGFX_CLEARBUTTON) - ATTRIB(XonoticInputBox, cb_color, vector, SKINCOLOR_CLEARBUTTON_N) - ATTRIB(XonoticInputBox, cb_colorF, vector, SKINCOLOR_CLEARBUTTON_F) - ATTRIB(XonoticInputBox, cb_colorC, vector, SKINCOLOR_CLEARBUTTON_C) - - ATTRIB(XonoticInputBox, cvarName, string, string_null) - METHOD(XonoticInputBox, loadCvars, void(entity)) - METHOD(XonoticInputBox, saveCvars, void(entity)) - ATTRIB(XonoticInputBox, sendCvars, float, 0) - METHOD(XonoticInputBox, keyDown, float(entity, float, float, float)) - - ATTRIB(XonoticInputBox, saveImmediately, float, 0) -ENDCLASS(XonoticInputBox) -entity makeXonoticInputBox(float, string); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticInputBox(float doEditColorCodes, string theCvar) -{ - entity me; - me = spawnXonoticInputBox(); - me.configureXonoticInputBox(me, doEditColorCodes, theCvar); - return me; -} -void XonoticInputBox_configureXonoticInputBox(entity me, float doEditColorCodes, string theCvar) -{ - me.configureInputBox(me, "", 0, me.fontSize, me.image); - me.editColorCodes = doEditColorCodes; - if(theCvar) - { - me.cvarName = theCvar; - me.tooltip = getZonedTooltipForIdentifier(theCvar); - me.loadCvars(me); - } - me.cursorPos = strlen(me.text); -} -void XonoticInputBox_focusLeave(entity me) -{ - me.saveCvars(me); -} -void XonoticInputBox_setText(entity me, string new) -{ - if(me.text != new) - { - SUPER(XonoticInputBox).setText(me, new); - if(me.onChange) - me.onChange(me, me.onChangeEntity); - if(me.saveImmediately) - me.saveCvars(me); - } - else - SUPER(XonoticInputBox).setText(me, new); -} -void XonoticInputBox_loadCvars(entity me) -{ - if (!me.cvarName) - return; - SUPER(XonoticInputBox).setText(me, cvar_string(me.cvarName)); -} -void XonoticInputBox_saveCvars(entity me) -{ - if (!me.cvarName) - return; - cvar_set(me.cvarName, me.text); - CheckSendCvars(me, me.cvarName); -} -float XonoticInputBox_keyDown(entity me, float key, float ascii, float shift) -{ - float r; - r = 0; - if(key == K_ENTER || key == K_KP_ENTER) - { - if(me.cvarName) - { - me.saveCvars(me); - r = 1; - } - if(me.onEnter) - me.onEnter(me, me.onEnterEntity); - } - if(SUPER(XonoticInputBox).keyDown(me, key, ascii, shift)) - r = 1; - return r; -} -#endif diff --git a/qcsrc/menu/xonotic/inputbox.qc b/qcsrc/menu/xonotic/inputbox.qc new file mode 100644 index 000000000..5d7d17999 --- /dev/null +++ b/qcsrc/menu/xonotic/inputbox.qc @@ -0,0 +1,105 @@ +#ifdef INTERFACE +CLASS(XonoticInputBox) EXTENDS(InputBox) + METHOD(XonoticInputBox, configureXonoticInputBox, void(entity, float, string)) + METHOD(XonoticInputBox, focusLeave, void(entity)) + METHOD(XonoticInputBox, setText, void(entity, string)) + ATTRIB(XonoticInputBox, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticInputBox, image, string, SKINGFX_INPUTBOX) + ATTRIB(XonoticInputBox, onChange, void(entity, entity), func_null) + ATTRIB(XonoticInputBox, onChangeEntity, entity, NULL) + ATTRIB(XonoticInputBox, onEnter, void(entity, entity), func_null) + ATTRIB(XonoticInputBox, onEnterEntity, entity, NULL) + ATTRIB(XonoticInputBox, marginLeft, float, SKINMARGIN_INPUTBOX_CHARS) + ATTRIB(XonoticInputBox, marginRight, float, SKINMARGIN_INPUTBOX_CHARS) + ATTRIB(XonoticInputBox, color, vector, SKINCOLOR_INPUTBOX_N) + ATTRIB(XonoticInputBox, colorF, vector, SKINCOLOR_INPUTBOX_F) + + ATTRIB(XonoticInputBox, alpha, float, SKINALPHA_TEXT) + + // Clear button attributes + ATTRIB(XonoticInputBox, cb_offset, float, SKINOFFSET_CLEARBUTTON) // bound to range -1, 0 + ATTRIB(XonoticInputBox, cb_src, string, SKINGFX_CLEARBUTTON) + ATTRIB(XonoticInputBox, cb_color, vector, SKINCOLOR_CLEARBUTTON_N) + ATTRIB(XonoticInputBox, cb_colorF, vector, SKINCOLOR_CLEARBUTTON_F) + ATTRIB(XonoticInputBox, cb_colorC, vector, SKINCOLOR_CLEARBUTTON_C) + + ATTRIB(XonoticInputBox, cvarName, string, string_null) + METHOD(XonoticInputBox, loadCvars, void(entity)) + METHOD(XonoticInputBox, saveCvars, void(entity)) + ATTRIB(XonoticInputBox, sendCvars, float, 0) + METHOD(XonoticInputBox, keyDown, float(entity, float, float, float)) + + ATTRIB(XonoticInputBox, saveImmediately, float, 0) +ENDCLASS(XonoticInputBox) +entity makeXonoticInputBox(float, string); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticInputBox(float doEditColorCodes, string theCvar) +{ + entity me; + me = spawnXonoticInputBox(); + me.configureXonoticInputBox(me, doEditColorCodes, theCvar); + return me; +} +void XonoticInputBox_configureXonoticInputBox(entity me, float doEditColorCodes, string theCvar) +{ + me.configureInputBox(me, "", 0, me.fontSize, me.image); + me.editColorCodes = doEditColorCodes; + if(theCvar) + { + me.cvarName = theCvar; + me.tooltip = getZonedTooltipForIdentifier(theCvar); + me.loadCvars(me); + } + me.cursorPos = strlen(me.text); +} +void XonoticInputBox_focusLeave(entity me) +{ + me.saveCvars(me); +} +void XonoticInputBox_setText(entity me, string new) +{ + if(me.text != new) + { + SUPER(XonoticInputBox).setText(me, new); + if(me.onChange) + me.onChange(me, me.onChangeEntity); + if(me.saveImmediately) + me.saveCvars(me); + } + else + SUPER(XonoticInputBox).setText(me, new); +} +void XonoticInputBox_loadCvars(entity me) +{ + if (!me.cvarName) + return; + SUPER(XonoticInputBox).setText(me, cvar_string(me.cvarName)); +} +void XonoticInputBox_saveCvars(entity me) +{ + if (!me.cvarName) + return; + cvar_set(me.cvarName, me.text); + CheckSendCvars(me, me.cvarName); +} +float XonoticInputBox_keyDown(entity me, float key, float ascii, float shift) +{ + float r; + r = 0; + if(key == K_ENTER || key == K_KP_ENTER) + { + if(me.cvarName) + { + me.saveCvars(me); + r = 1; + } + if(me.onEnter) + me.onEnter(me, me.onEnterEntity); + } + if(SUPER(XonoticInputBox).keyDown(me, key, ascii, shift)) + r = 1; + return r; +} +#endif diff --git a/qcsrc/menu/xonotic/keybinder.c b/qcsrc/menu/xonotic/keybinder.c deleted file mode 100644 index 6f3e56f72..000000000 --- a/qcsrc/menu/xonotic/keybinder.c +++ /dev/null @@ -1,363 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticKeyBinder) EXTENDS(XonoticListBox) - METHOD(XonoticKeyBinder, configureXonoticKeyBinder, void(entity)) - ATTRIB(XonoticKeyBinder, rowsPerItem, float, 1) - METHOD(XonoticKeyBinder, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticKeyBinder, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticKeyBinder, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticKeyBinder, setSelected, void(entity, float)) - METHOD(XonoticKeyBinder, keyDown, float(entity, float, float, float)) - METHOD(XonoticKeyBinder, keyGrabbed, void(entity, float, float)) - - ATTRIB(XonoticKeyBinder, realFontSize, vector, '0 0 0') - ATTRIB(XonoticKeyBinder, realUpperMargin, float, 0) - ATTRIB(XonoticKeyBinder, columnFunctionOrigin, float, 0) - ATTRIB(XonoticKeyBinder, columnFunctionSize, float, 0) - ATTRIB(XonoticKeyBinder, columnKeysOrigin, float, 0) - ATTRIB(XonoticKeyBinder, columnKeysSize, float, 0) - - ATTRIB(XonoticKeyBinder, previouslySelected, float, -1) - ATTRIB(XonoticKeyBinder, inMouseHandler, float, 0) - ATTRIB(XonoticKeyBinder, userbindEditButton, entity, NULL) - ATTRIB(XonoticKeyBinder, keyGrabButton, entity, NULL) - ATTRIB(XonoticKeyBinder, clearButton, entity, NULL) - ATTRIB(XonoticKeyBinder, userbindEditDialog, entity, NULL) - METHOD(XonoticKeyBinder, editUserbind, void(entity, string, string, string)) -ENDCLASS(XonoticKeyBinder) -entity makeXonoticKeyBinder(); -void KeyBinder_Bind_Change(entity btn, entity me); -void KeyBinder_Bind_Clear(entity btn, entity me); -void KeyBinder_Bind_Edit(entity btn, entity me); -#endif - -#ifdef IMPLEMENTATION - -const string KEY_NOT_BOUND_CMD = "// not bound"; - -const float MAX_KEYS_PER_FUNCTION = 2; -const float MAX_KEYBINDS = 256; -string Xonotic_KeyBinds_Functions[MAX_KEYBINDS]; -string Xonotic_KeyBinds_Descriptions[MAX_KEYBINDS]; -var float Xonotic_KeyBinds_Count = -1; - -void Xonotic_KeyBinds_Read() -{ - float fh; - string s; - - Xonotic_KeyBinds_Count = 0; - fh = fopen(language_filename("keybinds.txt"), FILE_READ); - if(fh < 0) - return; - while((s = fgets(fh))) - { - if(tokenize_console(s) != 2) - continue; - Xonotic_KeyBinds_Functions[Xonotic_KeyBinds_Count] = strzone(argv(0)); - Xonotic_KeyBinds_Descriptions[Xonotic_KeyBinds_Count] = strzone(argv(1)); - ++Xonotic_KeyBinds_Count; - if(Xonotic_KeyBinds_Count >= MAX_KEYBINDS) - break; - } - fclose(fh); -} - -entity makeXonoticKeyBinder() -{ - entity me; - me = spawnXonoticKeyBinder(); - me.configureXonoticKeyBinder(me); - return me; -} -void replace_bind(string from, string to) -{ - float n, j, k; - n = tokenize(findkeysforcommand(from, 0)); // uses '...' strings - for(j = 0; j < n; ++j) - { - k = stof(argv(j)); - if(k != -1) - localcmd("\nbind \"", keynumtostring(k), "\" \"", to, "\"\n"); - } - if(n) - cvar_set("_hud_showbinds_reload", "1"); -} -void XonoticKeyBinder_configureXonoticKeyBinder(entity me) -{ - me.configureXonoticListBox(me); - if(Xonotic_KeyBinds_Count < 0) - Xonotic_KeyBinds_Read(); - me.nItems = Xonotic_KeyBinds_Count; - me.setSelected(me, 0); - - // TEMP: Xonotic 0.1 to later - replace_bind("impulse 1", "weapon_group_1"); - replace_bind("impulse 2", "weapon_group_2"); - replace_bind("impulse 3", "weapon_group_3"); - replace_bind("impulse 4", "weapon_group_4"); - replace_bind("impulse 5", "weapon_group_5"); - replace_bind("impulse 6", "weapon_group_6"); - replace_bind("impulse 7", "weapon_group_7"); - replace_bind("impulse 8", "weapon_group_8"); - replace_bind("impulse 9", "weapon_group_9"); - replace_bind("impulse 14", "weapon_group_0"); -} -void XonoticKeyBinder_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(XonoticKeyBinder).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); - me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - - me.columnFunctionOrigin = 0; - me.columnKeysSize = me.realFontSize_x * 12; - me.columnFunctionSize = 1 - me.columnKeysSize - 2 * me.realFontSize_x; - me.columnKeysOrigin = me.columnFunctionOrigin + me.columnFunctionSize + me.realFontSize_x; - - if(me.userbindEditButton) - me.userbindEditButton.disabled = (substring(Xonotic_KeyBinds_Descriptions[me.selectedItem], 0, 1) != "$"); -} -void KeyBinder_Bind_Change(entity btn, entity me) -{ - string func; - - func = Xonotic_KeyBinds_Functions[me.selectedItem]; - if(func == "") - return; - - me.keyGrabButton.forcePressed = 1; - me.clearButton.disabled = 1; - keyGrabber = me; -} -void XonoticKeyBinder_keyGrabbed(entity me, float key, float ascii) -{ - float n, j, k, nvalid; - string func; - - me.keyGrabButton.forcePressed = 0; - me.clearButton.disabled = 0; - - if(key == K_ESCAPE) - return; - - // forbid these keys from being bound in the menu - if(key == K_CAPSLOCK || key == K_NUMLOCK) - { - KeyBinder_Bind_Change(me, me); - return; - } - - func = Xonotic_KeyBinds_Functions[me.selectedItem]; - if(func == "") - return; - - n = tokenize(findkeysforcommand(func, 0)); // uses '...' strings - nvalid = 0; - for(j = 0; j < n; ++j) - { - k = stof(argv(j)); - if(k != -1) - ++nvalid; - } - if(nvalid >= MAX_KEYS_PER_FUNCTION) - { - for(j = 0; j < n; ++j) - { - k = stof(argv(j)); - if(k != -1) - //localcmd("\nunbind \"", keynumtostring(k), "\"\n"); - localcmd("\nbind \"", keynumtostring(k), "\" \"", KEY_NOT_BOUND_CMD, "\"\n"); - } - } - localcmd("\nbind \"", keynumtostring(key), "\" \"", func, "\"\n"); - localcmd("-zoom\n"); // to make sure we aren't in togglezoom'd state - cvar_set("_hud_showbinds_reload", "1"); -} -void XonoticKeyBinder_editUserbind(entity me, string theName, string theCommandPress, string theCommandRelease) -{ - string func, descr; - - if(!me.userbindEditDialog) - return; - - func = Xonotic_KeyBinds_Functions[me.selectedItem]; - if(func == "") - return; - - descr = Xonotic_KeyBinds_Descriptions[me.selectedItem]; - if(substring(descr, 0, 1) != "$") - return; - descr = substring(descr, 1, strlen(descr) - 1); - - // Hooray! It IS a user bind! - cvar_set(strcat(descr, "_description"), theName); - cvar_set(strcat(descr, "_press"), theCommandPress); - cvar_set(strcat(descr, "_release"), theCommandRelease); -} -void KeyBinder_Bind_Edit(entity btn, entity me) -{ - string func, descr; - - if(!me.userbindEditDialog) - return; - - func = Xonotic_KeyBinds_Functions[me.selectedItem]; - if(func == "") - return; - - descr = Xonotic_KeyBinds_Descriptions[me.selectedItem]; - if(substring(descr, 0, 1) != "$") - return; - descr = substring(descr, 1, strlen(descr) - 1); - - // Hooray! It IS a user bind! - me.userbindEditDialog.loadUserBind(me.userbindEditDialog, cvar_string(strcat(descr, "_description")), cvar_string(strcat(descr, "_press")), cvar_string(strcat(descr, "_release"))); - - DialogOpenButton_Click(btn, me.userbindEditDialog); -} -void KeyBinder_Bind_Clear(entity btn, entity me) -{ - float n, j, k; - string func; - - func = Xonotic_KeyBinds_Functions[me.selectedItem]; - if(func == "") - return; - - n = tokenize(findkeysforcommand(func, 0)); // uses '...' strings - for(j = 0; j < n; ++j) - { - k = stof(argv(j)); - if(k != -1) - //localcmd("\nunbind \"", keynumtostring(k), "\"\n"); - localcmd("\nbind \"", keynumtostring(k), "\" \"", KEY_NOT_BOUND_CMD, "\"\n"); - } - localcmd("-zoom\n"); // to make sure we aren't in togglezoom'd state - cvar_set("_hud_showbinds_reload", "1"); -} -void KeyBinder_Bind_Reset_All(entity btn, entity me) -{ - localcmd("unbindall\n"); - localcmd("exec binds-default.cfg\n"); - localcmd("-zoom\n"); // to make sure we aren't in togglezoom'd state - cvar_set("_hud_showbinds_reload", "1"); -} -void XonoticKeyBinder_doubleClickListBoxItem(entity me, float i, vector where) -{ - KeyBinder_Bind_Change(NULL, me); -} -void XonoticKeyBinder_setSelected(entity me, float i) -{ - // handling of "unselectable" items - i = floor(0.5 + bound(0, i, me.nItems - 1)); - if(me.pressed == 0 || me.pressed == 1) // keyboard or scrolling - skip unselectable items - { - if(i > me.previouslySelected) - { - while((i < me.nItems - 1) && (Xonotic_KeyBinds_Functions[i] == "")) - ++i; - } - while((i > 0) && (Xonotic_KeyBinds_Functions[i] == "")) - --i; - while((i < me.nItems - 1) && (Xonotic_KeyBinds_Functions[i] == "")) - ++i; - } - if(me.pressed == 3) // released the mouse - fall back to last valid item - { - if(Xonotic_KeyBinds_Functions[i] == "") - i = me.previouslySelected; - } - if(Xonotic_KeyBinds_Functions[i] != "") - me.previouslySelected = i; - if(me.userbindEditButton) - me.userbindEditButton.disabled = (substring(Xonotic_KeyBinds_Descriptions[i], 0, 1) != "$"); - SUPER(XonoticKeyBinder).setSelected(me, i); -} -float XonoticKeyBinder_keyDown(entity me, float key, float ascii, float shift) -{ - float r; - r = 1; - switch(key) - { - case K_ENTER: - case K_KP_ENTER: - case K_SPACE: - KeyBinder_Bind_Change(me, me); - break; - case K_DEL: - case K_KP_DEL: - case K_BACKSPACE: - KeyBinder_Bind_Clear(me, me); - break; - default: - r = SUPER(XonoticKeyBinder).keyDown(me, key, ascii, shift); - break; - } - return r; -} -void XonoticKeyBinder_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s; - float j, k, n; - vector theColor; - float theAlpha; - string func, descr; - float extraMargin; - - descr = Xonotic_KeyBinds_Descriptions[i]; - func = Xonotic_KeyBinds_Functions[i]; - - if(func == "") - { - theAlpha = 1; - theColor = SKINCOLOR_KEYGRABBER_TITLES; - theAlpha = SKINALPHA_KEYGRABBER_TITLES; - extraMargin = 0; - } - else - { - if(isSelected) - { - if(keyGrabber == me) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_WAITING, SKINALPHA_LISTBOX_WAITING); - else - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - } - theAlpha = SKINALPHA_KEYGRABBER_KEYS; - theColor = SKINCOLOR_KEYGRABBER_KEYS; - extraMargin = me.realFontSize_x * 0.5; - } - - if(substring(descr, 0, 1) == "$") - { - s = substring(descr, 1, strlen(descr) - 1); - descr = cvar_string(strcat(s, "_description")); - if(descr == "") - descr = s; - if(cvar_string(strcat(s, "_press")) == "") - if(cvar_string(strcat(s, "_release")) == "") - theAlpha *= SKINALPHA_DISABLED; - } - - s = draw_TextShortenToWidth(descr, me.columnFunctionSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + extraMargin * eX, s, me.realFontSize, theColor, theAlpha, 0); - if(func != "") - { - n = tokenize(findkeysforcommand(func, 0)); // uses '...' strings - s = ""; - for(j = 0; j < n; ++j) - { - k = stof(argv(j)); - if(k != -1) - { - if(s != "") - s = strcat(s, ", "); - s = strcat(s, keynumtostring(k)); - } - } - s = draw_TextShortenToWidth(s, me.columnKeysSize, 0, me.realFontSize); - draw_CenterText(me.realUpperMargin * eY + (me.columnKeysOrigin + 0.5 * me.columnKeysSize) * eX, s, me.realFontSize, theColor, theAlpha, 0); - } -} -#endif diff --git a/qcsrc/menu/xonotic/keybinder.qc b/qcsrc/menu/xonotic/keybinder.qc new file mode 100644 index 000000000..6f3e56f72 --- /dev/null +++ b/qcsrc/menu/xonotic/keybinder.qc @@ -0,0 +1,363 @@ +#ifdef INTERFACE +CLASS(XonoticKeyBinder) EXTENDS(XonoticListBox) + METHOD(XonoticKeyBinder, configureXonoticKeyBinder, void(entity)) + ATTRIB(XonoticKeyBinder, rowsPerItem, float, 1) + METHOD(XonoticKeyBinder, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticKeyBinder, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticKeyBinder, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticKeyBinder, setSelected, void(entity, float)) + METHOD(XonoticKeyBinder, keyDown, float(entity, float, float, float)) + METHOD(XonoticKeyBinder, keyGrabbed, void(entity, float, float)) + + ATTRIB(XonoticKeyBinder, realFontSize, vector, '0 0 0') + ATTRIB(XonoticKeyBinder, realUpperMargin, float, 0) + ATTRIB(XonoticKeyBinder, columnFunctionOrigin, float, 0) + ATTRIB(XonoticKeyBinder, columnFunctionSize, float, 0) + ATTRIB(XonoticKeyBinder, columnKeysOrigin, float, 0) + ATTRIB(XonoticKeyBinder, columnKeysSize, float, 0) + + ATTRIB(XonoticKeyBinder, previouslySelected, float, -1) + ATTRIB(XonoticKeyBinder, inMouseHandler, float, 0) + ATTRIB(XonoticKeyBinder, userbindEditButton, entity, NULL) + ATTRIB(XonoticKeyBinder, keyGrabButton, entity, NULL) + ATTRIB(XonoticKeyBinder, clearButton, entity, NULL) + ATTRIB(XonoticKeyBinder, userbindEditDialog, entity, NULL) + METHOD(XonoticKeyBinder, editUserbind, void(entity, string, string, string)) +ENDCLASS(XonoticKeyBinder) +entity makeXonoticKeyBinder(); +void KeyBinder_Bind_Change(entity btn, entity me); +void KeyBinder_Bind_Clear(entity btn, entity me); +void KeyBinder_Bind_Edit(entity btn, entity me); +#endif + +#ifdef IMPLEMENTATION + +const string KEY_NOT_BOUND_CMD = "// not bound"; + +const float MAX_KEYS_PER_FUNCTION = 2; +const float MAX_KEYBINDS = 256; +string Xonotic_KeyBinds_Functions[MAX_KEYBINDS]; +string Xonotic_KeyBinds_Descriptions[MAX_KEYBINDS]; +var float Xonotic_KeyBinds_Count = -1; + +void Xonotic_KeyBinds_Read() +{ + float fh; + string s; + + Xonotic_KeyBinds_Count = 0; + fh = fopen(language_filename("keybinds.txt"), FILE_READ); + if(fh < 0) + return; + while((s = fgets(fh))) + { + if(tokenize_console(s) != 2) + continue; + Xonotic_KeyBinds_Functions[Xonotic_KeyBinds_Count] = strzone(argv(0)); + Xonotic_KeyBinds_Descriptions[Xonotic_KeyBinds_Count] = strzone(argv(1)); + ++Xonotic_KeyBinds_Count; + if(Xonotic_KeyBinds_Count >= MAX_KEYBINDS) + break; + } + fclose(fh); +} + +entity makeXonoticKeyBinder() +{ + entity me; + me = spawnXonoticKeyBinder(); + me.configureXonoticKeyBinder(me); + return me; +} +void replace_bind(string from, string to) +{ + float n, j, k; + n = tokenize(findkeysforcommand(from, 0)); // uses '...' strings + for(j = 0; j < n; ++j) + { + k = stof(argv(j)); + if(k != -1) + localcmd("\nbind \"", keynumtostring(k), "\" \"", to, "\"\n"); + } + if(n) + cvar_set("_hud_showbinds_reload", "1"); +} +void XonoticKeyBinder_configureXonoticKeyBinder(entity me) +{ + me.configureXonoticListBox(me); + if(Xonotic_KeyBinds_Count < 0) + Xonotic_KeyBinds_Read(); + me.nItems = Xonotic_KeyBinds_Count; + me.setSelected(me, 0); + + // TEMP: Xonotic 0.1 to later + replace_bind("impulse 1", "weapon_group_1"); + replace_bind("impulse 2", "weapon_group_2"); + replace_bind("impulse 3", "weapon_group_3"); + replace_bind("impulse 4", "weapon_group_4"); + replace_bind("impulse 5", "weapon_group_5"); + replace_bind("impulse 6", "weapon_group_6"); + replace_bind("impulse 7", "weapon_group_7"); + replace_bind("impulse 8", "weapon_group_8"); + replace_bind("impulse 9", "weapon_group_9"); + replace_bind("impulse 14", "weapon_group_0"); +} +void XonoticKeyBinder_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(XonoticKeyBinder).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); + me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + + me.columnFunctionOrigin = 0; + me.columnKeysSize = me.realFontSize_x * 12; + me.columnFunctionSize = 1 - me.columnKeysSize - 2 * me.realFontSize_x; + me.columnKeysOrigin = me.columnFunctionOrigin + me.columnFunctionSize + me.realFontSize_x; + + if(me.userbindEditButton) + me.userbindEditButton.disabled = (substring(Xonotic_KeyBinds_Descriptions[me.selectedItem], 0, 1) != "$"); +} +void KeyBinder_Bind_Change(entity btn, entity me) +{ + string func; + + func = Xonotic_KeyBinds_Functions[me.selectedItem]; + if(func == "") + return; + + me.keyGrabButton.forcePressed = 1; + me.clearButton.disabled = 1; + keyGrabber = me; +} +void XonoticKeyBinder_keyGrabbed(entity me, float key, float ascii) +{ + float n, j, k, nvalid; + string func; + + me.keyGrabButton.forcePressed = 0; + me.clearButton.disabled = 0; + + if(key == K_ESCAPE) + return; + + // forbid these keys from being bound in the menu + if(key == K_CAPSLOCK || key == K_NUMLOCK) + { + KeyBinder_Bind_Change(me, me); + return; + } + + func = Xonotic_KeyBinds_Functions[me.selectedItem]; + if(func == "") + return; + + n = tokenize(findkeysforcommand(func, 0)); // uses '...' strings + nvalid = 0; + for(j = 0; j < n; ++j) + { + k = stof(argv(j)); + if(k != -1) + ++nvalid; + } + if(nvalid >= MAX_KEYS_PER_FUNCTION) + { + for(j = 0; j < n; ++j) + { + k = stof(argv(j)); + if(k != -1) + //localcmd("\nunbind \"", keynumtostring(k), "\"\n"); + localcmd("\nbind \"", keynumtostring(k), "\" \"", KEY_NOT_BOUND_CMD, "\"\n"); + } + } + localcmd("\nbind \"", keynumtostring(key), "\" \"", func, "\"\n"); + localcmd("-zoom\n"); // to make sure we aren't in togglezoom'd state + cvar_set("_hud_showbinds_reload", "1"); +} +void XonoticKeyBinder_editUserbind(entity me, string theName, string theCommandPress, string theCommandRelease) +{ + string func, descr; + + if(!me.userbindEditDialog) + return; + + func = Xonotic_KeyBinds_Functions[me.selectedItem]; + if(func == "") + return; + + descr = Xonotic_KeyBinds_Descriptions[me.selectedItem]; + if(substring(descr, 0, 1) != "$") + return; + descr = substring(descr, 1, strlen(descr) - 1); + + // Hooray! It IS a user bind! + cvar_set(strcat(descr, "_description"), theName); + cvar_set(strcat(descr, "_press"), theCommandPress); + cvar_set(strcat(descr, "_release"), theCommandRelease); +} +void KeyBinder_Bind_Edit(entity btn, entity me) +{ + string func, descr; + + if(!me.userbindEditDialog) + return; + + func = Xonotic_KeyBinds_Functions[me.selectedItem]; + if(func == "") + return; + + descr = Xonotic_KeyBinds_Descriptions[me.selectedItem]; + if(substring(descr, 0, 1) != "$") + return; + descr = substring(descr, 1, strlen(descr) - 1); + + // Hooray! It IS a user bind! + me.userbindEditDialog.loadUserBind(me.userbindEditDialog, cvar_string(strcat(descr, "_description")), cvar_string(strcat(descr, "_press")), cvar_string(strcat(descr, "_release"))); + + DialogOpenButton_Click(btn, me.userbindEditDialog); +} +void KeyBinder_Bind_Clear(entity btn, entity me) +{ + float n, j, k; + string func; + + func = Xonotic_KeyBinds_Functions[me.selectedItem]; + if(func == "") + return; + + n = tokenize(findkeysforcommand(func, 0)); // uses '...' strings + for(j = 0; j < n; ++j) + { + k = stof(argv(j)); + if(k != -1) + //localcmd("\nunbind \"", keynumtostring(k), "\"\n"); + localcmd("\nbind \"", keynumtostring(k), "\" \"", KEY_NOT_BOUND_CMD, "\"\n"); + } + localcmd("-zoom\n"); // to make sure we aren't in togglezoom'd state + cvar_set("_hud_showbinds_reload", "1"); +} +void KeyBinder_Bind_Reset_All(entity btn, entity me) +{ + localcmd("unbindall\n"); + localcmd("exec binds-default.cfg\n"); + localcmd("-zoom\n"); // to make sure we aren't in togglezoom'd state + cvar_set("_hud_showbinds_reload", "1"); +} +void XonoticKeyBinder_doubleClickListBoxItem(entity me, float i, vector where) +{ + KeyBinder_Bind_Change(NULL, me); +} +void XonoticKeyBinder_setSelected(entity me, float i) +{ + // handling of "unselectable" items + i = floor(0.5 + bound(0, i, me.nItems - 1)); + if(me.pressed == 0 || me.pressed == 1) // keyboard or scrolling - skip unselectable items + { + if(i > me.previouslySelected) + { + while((i < me.nItems - 1) && (Xonotic_KeyBinds_Functions[i] == "")) + ++i; + } + while((i > 0) && (Xonotic_KeyBinds_Functions[i] == "")) + --i; + while((i < me.nItems - 1) && (Xonotic_KeyBinds_Functions[i] == "")) + ++i; + } + if(me.pressed == 3) // released the mouse - fall back to last valid item + { + if(Xonotic_KeyBinds_Functions[i] == "") + i = me.previouslySelected; + } + if(Xonotic_KeyBinds_Functions[i] != "") + me.previouslySelected = i; + if(me.userbindEditButton) + me.userbindEditButton.disabled = (substring(Xonotic_KeyBinds_Descriptions[i], 0, 1) != "$"); + SUPER(XonoticKeyBinder).setSelected(me, i); +} +float XonoticKeyBinder_keyDown(entity me, float key, float ascii, float shift) +{ + float r; + r = 1; + switch(key) + { + case K_ENTER: + case K_KP_ENTER: + case K_SPACE: + KeyBinder_Bind_Change(me, me); + break; + case K_DEL: + case K_KP_DEL: + case K_BACKSPACE: + KeyBinder_Bind_Clear(me, me); + break; + default: + r = SUPER(XonoticKeyBinder).keyDown(me, key, ascii, shift); + break; + } + return r; +} +void XonoticKeyBinder_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s; + float j, k, n; + vector theColor; + float theAlpha; + string func, descr; + float extraMargin; + + descr = Xonotic_KeyBinds_Descriptions[i]; + func = Xonotic_KeyBinds_Functions[i]; + + if(func == "") + { + theAlpha = 1; + theColor = SKINCOLOR_KEYGRABBER_TITLES; + theAlpha = SKINALPHA_KEYGRABBER_TITLES; + extraMargin = 0; + } + else + { + if(isSelected) + { + if(keyGrabber == me) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_WAITING, SKINALPHA_LISTBOX_WAITING); + else + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + } + theAlpha = SKINALPHA_KEYGRABBER_KEYS; + theColor = SKINCOLOR_KEYGRABBER_KEYS; + extraMargin = me.realFontSize_x * 0.5; + } + + if(substring(descr, 0, 1) == "$") + { + s = substring(descr, 1, strlen(descr) - 1); + descr = cvar_string(strcat(s, "_description")); + if(descr == "") + descr = s; + if(cvar_string(strcat(s, "_press")) == "") + if(cvar_string(strcat(s, "_release")) == "") + theAlpha *= SKINALPHA_DISABLED; + } + + s = draw_TextShortenToWidth(descr, me.columnFunctionSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + extraMargin * eX, s, me.realFontSize, theColor, theAlpha, 0); + if(func != "") + { + n = tokenize(findkeysforcommand(func, 0)); // uses '...' strings + s = ""; + for(j = 0; j < n; ++j) + { + k = stof(argv(j)); + if(k != -1) + { + if(s != "") + s = strcat(s, ", "); + s = strcat(s, keynumtostring(k)); + } + } + s = draw_TextShortenToWidth(s, me.columnKeysSize, 0, me.realFontSize); + draw_CenterText(me.realUpperMargin * eY + (me.columnKeysOrigin + 0.5 * me.columnKeysSize) * eX, s, me.realFontSize, theColor, theAlpha, 0); + } +} +#endif diff --git a/qcsrc/menu/xonotic/languagelist.c b/qcsrc/menu/xonotic/languagelist.c deleted file mode 100644 index d34062d46..000000000 --- a/qcsrc/menu/xonotic/languagelist.c +++ /dev/null @@ -1,215 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticLanguageList) EXTENDS(XonoticListBox) - METHOD(XonoticLanguageList, configureXonoticLanguageList, void(entity)) - ATTRIB(XonoticLanguageList, rowsPerItem, float, 1) - METHOD(XonoticLanguageList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticLanguageList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticLanguageList, setSelected, void(entity, float)) - METHOD(XonoticLanguageList, loadCvars, void(entity)) - METHOD(XonoticLanguageList, saveCvars, void(entity)) - - ATTRIB(XonoticLanguageList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticLanguageList, realUpperMargin, float, 0) - ATTRIB(XonoticLanguageList, columnNameOrigin, float, 0) - ATTRIB(XonoticLanguageList, columnNameSize, float, 0) - ATTRIB(XonoticLanguageList, columnPercentageOrigin, float, 0) - ATTRIB(XonoticLanguageList, columnPercentageSize, float, 0) - - METHOD(XonoticLanguageList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticLanguageList, keyDown, float(entity, float, float, float)) // enter handling - - METHOD(XonoticLanguageList, destroy, void(entity)) - - ATTRIB(XonoticLanguageList, languagelist, float, -1) - METHOD(XonoticLanguageList, getLanguages, void(entity)) - METHOD(XonoticLanguageList, setLanguage, void(entity)) - METHOD(XonoticLanguageList, languageParameter, string(entity, float, float)) - - ATTRIB(XonoticLanguageList, name, string, "languageselector") // change this to make it noninteractive (for first run dialog) -ENDCLASS(XonoticLanguageList) - -entity makeXonoticLanguageList(); -void SetLanguage_Click(entity btn, entity me); -#endif - -#ifdef IMPLEMENTATION - -const float LANGPARM_ID = 0; -const float LANGPARM_NAME = 1; -const float LANGPARM_NAME_LOCALIZED = 2; -const float LANGPARM_PERCENTAGE = 3; -const float LANGPARM_COUNT = 4; - -entity makeXonoticLanguageList() -{ - entity me; - me = spawnXonoticLanguageList(); - me.configureXonoticLanguageList(me); - return me; -} - -void XonoticLanguageList_configureXonoticLanguageList(entity me) -{ - me.configureXonoticListBox(me); - me.getLanguages(me); - me.loadCvars(me); -} - -void XonoticLanguageList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s, p; - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - s = me.languageParameter(me, i, LANGPARM_NAME_LOCALIZED); - - vector save_fontscale = draw_fontscale; - float f = draw_CondensedFontFactor(s, FALSE, me.realFontSize, 1); - draw_fontscale_x *= f; - vector fs = me.realFontSize; - fs_x *= f; - draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, fs, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0); - draw_fontscale = save_fontscale; - - p = me.languageParameter(me, i, LANGPARM_PERCENTAGE); - if(p != "") - { - vector save_fontscale = draw_fontscale; - float f = draw_CondensedFontFactor(p, FALSE, me.realFontSize, 1); - draw_fontscale_x *= f; - vector fs = me.realFontSize; - fs_x *= f; - draw_Text(me.realUpperMargin * eY + (me.columnPercentageOrigin + (me.columnPercentageSize - draw_TextWidth(p, 0, fs))) * eX, p, fs, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0); - draw_fontscale = save_fontscale; - } -} - -void XonoticLanguageList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(XonoticLanguageList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); - me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - me.columnPercentageSize = me.realFontSize_x * 3; - me.columnPercentageOrigin = 1 - me.columnPercentageSize; - me.columnNameOrigin = 0; - me.columnNameSize = me.columnPercentageOrigin; -} - -void XonoticLanguageList_setSelected(entity me, float i) -{ - SUPER(XonoticLanguageList).setSelected(me, i); - me.saveCvars(me); -} - -void XonoticLanguageList_loadCvars(entity me) -{ - string s; - float i, n; - s = cvar_string("_menu_prvm_language"); - n = me.nItems; - - // default to English - for(i = 0; i < n; ++i) - { - if(me.languageParameter(me, i, LANGPARM_ID) == "en") - { - me.selectedItem = i; - break; - } - } - - // otherwise, find the language - for(i = 0; i < n; ++i) - { - if(me.languageParameter(me, i, LANGPARM_ID) == s) - { - me.selectedItem = i; - break; - } - } - - // save it off (turning anything unknown into "en") - me.saveCvars(me); -} - -void XonoticLanguageList_saveCvars(entity me) -{ - cvar_set("_menu_prvm_language", me.languageParameter(me, me.selectedItem, LANGPARM_ID)); -} - -void XonoticLanguageList_doubleClickListBoxItem(entity me, float i, vector where) -{ - me.setLanguage(me); -} - -float XonoticLanguageList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(scan == K_ENTER || scan == K_KP_ENTER) { - me.setLanguage(me); - return 1; - } - else - return SUPER(XonoticLanguageList).keyDown(me, scan, ascii, shift); -} - -void XonoticLanguageList_destroy(entity me) -{ - buf_del(me.languagelist); -} - -void XonoticLanguageList_getLanguages(entity me) -{ - float buf, i, n, fh; - string s; - - buf = buf_create(); - - fh = fopen("languages.txt", FILE_READ); - i = 0; - while((s = fgets(fh))) - { - n = tokenize_console(s); - if(n < 3) - continue; - bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_ID, argv(0)); - bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_NAME, argv(1)); - float k = strstrofs(argv(2), "(", 0); - if(k > 0) - if(substring(argv(2), strlen(argv(2)) - 1, 1) == ")") - { - string percent = substring(argv(2), k + 1, -2); - if(percent != "100%") - bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_PERCENTAGE, percent); - } - bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_NAME_LOCALIZED, (k < 0) ? argv(2) : substring(argv(2), 0, k - 1)); - ++i; - } - fclose(fh); - - me.languagelist = buf; - me.nItems = i; -} - -void XonoticLanguageList_setLanguage(entity me) -{ - if(prvm_language != cvar_string("_menu_prvm_language")) - { - if(!(gamestatus & GAME_CONNECTED)) - localcmd("\nprvm_language \"$_menu_prvm_language\"; menu_restart; menu_cmd languageselect\n"); - else - DialogOpenButton_Click(me, main.languageWarningDialog); - } -} - -string XonoticLanguageList_languageParameter(entity me, float i, float key) -{ - return bufstr_get(me.languagelist, i * LANGPARM_COUNT + key); -} - -void SetLanguage_Click(entity btn, entity me) -{ - me.setLanguage(me); -} - -#endif diff --git a/qcsrc/menu/xonotic/languagelist.qc b/qcsrc/menu/xonotic/languagelist.qc new file mode 100644 index 000000000..d34062d46 --- /dev/null +++ b/qcsrc/menu/xonotic/languagelist.qc @@ -0,0 +1,215 @@ +#ifdef INTERFACE +CLASS(XonoticLanguageList) EXTENDS(XonoticListBox) + METHOD(XonoticLanguageList, configureXonoticLanguageList, void(entity)) + ATTRIB(XonoticLanguageList, rowsPerItem, float, 1) + METHOD(XonoticLanguageList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticLanguageList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticLanguageList, setSelected, void(entity, float)) + METHOD(XonoticLanguageList, loadCvars, void(entity)) + METHOD(XonoticLanguageList, saveCvars, void(entity)) + + ATTRIB(XonoticLanguageList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticLanguageList, realUpperMargin, float, 0) + ATTRIB(XonoticLanguageList, columnNameOrigin, float, 0) + ATTRIB(XonoticLanguageList, columnNameSize, float, 0) + ATTRIB(XonoticLanguageList, columnPercentageOrigin, float, 0) + ATTRIB(XonoticLanguageList, columnPercentageSize, float, 0) + + METHOD(XonoticLanguageList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticLanguageList, keyDown, float(entity, float, float, float)) // enter handling + + METHOD(XonoticLanguageList, destroy, void(entity)) + + ATTRIB(XonoticLanguageList, languagelist, float, -1) + METHOD(XonoticLanguageList, getLanguages, void(entity)) + METHOD(XonoticLanguageList, setLanguage, void(entity)) + METHOD(XonoticLanguageList, languageParameter, string(entity, float, float)) + + ATTRIB(XonoticLanguageList, name, string, "languageselector") // change this to make it noninteractive (for first run dialog) +ENDCLASS(XonoticLanguageList) + +entity makeXonoticLanguageList(); +void SetLanguage_Click(entity btn, entity me); +#endif + +#ifdef IMPLEMENTATION + +const float LANGPARM_ID = 0; +const float LANGPARM_NAME = 1; +const float LANGPARM_NAME_LOCALIZED = 2; +const float LANGPARM_PERCENTAGE = 3; +const float LANGPARM_COUNT = 4; + +entity makeXonoticLanguageList() +{ + entity me; + me = spawnXonoticLanguageList(); + me.configureXonoticLanguageList(me); + return me; +} + +void XonoticLanguageList_configureXonoticLanguageList(entity me) +{ + me.configureXonoticListBox(me); + me.getLanguages(me); + me.loadCvars(me); +} + +void XonoticLanguageList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s, p; + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + s = me.languageParameter(me, i, LANGPARM_NAME_LOCALIZED); + + vector save_fontscale = draw_fontscale; + float f = draw_CondensedFontFactor(s, FALSE, me.realFontSize, 1); + draw_fontscale_x *= f; + vector fs = me.realFontSize; + fs_x *= f; + draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, fs, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0); + draw_fontscale = save_fontscale; + + p = me.languageParameter(me, i, LANGPARM_PERCENTAGE); + if(p != "") + { + vector save_fontscale = draw_fontscale; + float f = draw_CondensedFontFactor(p, FALSE, me.realFontSize, 1); + draw_fontscale_x *= f; + vector fs = me.realFontSize; + fs_x *= f; + draw_Text(me.realUpperMargin * eY + (me.columnPercentageOrigin + (me.columnPercentageSize - draw_TextWidth(p, 0, fs))) * eX, p, fs, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0); + draw_fontscale = save_fontscale; + } +} + +void XonoticLanguageList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(XonoticLanguageList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); + me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + me.columnPercentageSize = me.realFontSize_x * 3; + me.columnPercentageOrigin = 1 - me.columnPercentageSize; + me.columnNameOrigin = 0; + me.columnNameSize = me.columnPercentageOrigin; +} + +void XonoticLanguageList_setSelected(entity me, float i) +{ + SUPER(XonoticLanguageList).setSelected(me, i); + me.saveCvars(me); +} + +void XonoticLanguageList_loadCvars(entity me) +{ + string s; + float i, n; + s = cvar_string("_menu_prvm_language"); + n = me.nItems; + + // default to English + for(i = 0; i < n; ++i) + { + if(me.languageParameter(me, i, LANGPARM_ID) == "en") + { + me.selectedItem = i; + break; + } + } + + // otherwise, find the language + for(i = 0; i < n; ++i) + { + if(me.languageParameter(me, i, LANGPARM_ID) == s) + { + me.selectedItem = i; + break; + } + } + + // save it off (turning anything unknown into "en") + me.saveCvars(me); +} + +void XonoticLanguageList_saveCvars(entity me) +{ + cvar_set("_menu_prvm_language", me.languageParameter(me, me.selectedItem, LANGPARM_ID)); +} + +void XonoticLanguageList_doubleClickListBoxItem(entity me, float i, vector where) +{ + me.setLanguage(me); +} + +float XonoticLanguageList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_KP_ENTER) { + me.setLanguage(me); + return 1; + } + else + return SUPER(XonoticLanguageList).keyDown(me, scan, ascii, shift); +} + +void XonoticLanguageList_destroy(entity me) +{ + buf_del(me.languagelist); +} + +void XonoticLanguageList_getLanguages(entity me) +{ + float buf, i, n, fh; + string s; + + buf = buf_create(); + + fh = fopen("languages.txt", FILE_READ); + i = 0; + while((s = fgets(fh))) + { + n = tokenize_console(s); + if(n < 3) + continue; + bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_ID, argv(0)); + bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_NAME, argv(1)); + float k = strstrofs(argv(2), "(", 0); + if(k > 0) + if(substring(argv(2), strlen(argv(2)) - 1, 1) == ")") + { + string percent = substring(argv(2), k + 1, -2); + if(percent != "100%") + bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_PERCENTAGE, percent); + } + bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_NAME_LOCALIZED, (k < 0) ? argv(2) : substring(argv(2), 0, k - 1)); + ++i; + } + fclose(fh); + + me.languagelist = buf; + me.nItems = i; +} + +void XonoticLanguageList_setLanguage(entity me) +{ + if(prvm_language != cvar_string("_menu_prvm_language")) + { + if(!(gamestatus & GAME_CONNECTED)) + localcmd("\nprvm_language \"$_menu_prvm_language\"; menu_restart; menu_cmd languageselect\n"); + else + DialogOpenButton_Click(me, main.languageWarningDialog); + } +} + +string XonoticLanguageList_languageParameter(entity me, float i, float key) +{ + return bufstr_get(me.languagelist, i * LANGPARM_COUNT + key); +} + +void SetLanguage_Click(entity btn, entity me) +{ + me.setLanguage(me); +} + +#endif diff --git a/qcsrc/menu/xonotic/listbox.c b/qcsrc/menu/xonotic/listbox.c deleted file mode 100644 index 23fa58d83..000000000 --- a/qcsrc/menu/xonotic/listbox.c +++ /dev/null @@ -1,37 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticListBox) EXTENDS(ListBox) - METHOD(XonoticListBox, configureXonoticListBox, void(entity)) - ATTRIB(XonoticListBox, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticListBox, scrollbarWidth, float, SKINWIDTH_SCROLLBAR) - ATTRIB(XonoticListBox, src, string, SKINGFX_SCROLLBAR) - ATTRIB(XonoticListBox, tolerance, vector, SKINTOLERANCE_SLIDER) - ATTRIB(XonoticListBox, rowsPerItem, float, 1) - METHOD(XonoticListBox, resizeNotify, void(entity, vector, vector, vector, vector)) - ATTRIB(XonoticListBox, color, vector, SKINCOLOR_SCROLLBAR_N) - ATTRIB(XonoticListBox, colorF, vector, SKINCOLOR_SCROLLBAR_F) - ATTRIB(XonoticListBox, color2, vector, SKINCOLOR_SCROLLBAR_S) - ATTRIB(XonoticListBox, colorC, vector, SKINCOLOR_SCROLLBAR_C) - ATTRIB(XonoticListBox, colorBG, vector, SKINCOLOR_LISTBOX_BACKGROUND) - ATTRIB(XonoticListBox, alphaBG, float, SKINALPHA_LISTBOX_BACKGROUND) -ENDCLASS(XonoticListBox) -entity makeXonoticListBox(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticListBox() -{ - entity me; - me = spawnXonoticListBox(); - me.configureXonoticListBox(me); - return me; -} -void XonoticListBox_configureXonoticListBox(entity me) -{ - me.configureListBox(me, me.scrollbarWidth, 1); // item height gets set up later -} -void XonoticListBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemHeight = me.rowsPerItem * me.fontSize / absSize_y; - SUPER(XonoticListBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); -} -#endif diff --git a/qcsrc/menu/xonotic/listbox.qc b/qcsrc/menu/xonotic/listbox.qc new file mode 100644 index 000000000..23fa58d83 --- /dev/null +++ b/qcsrc/menu/xonotic/listbox.qc @@ -0,0 +1,37 @@ +#ifdef INTERFACE +CLASS(XonoticListBox) EXTENDS(ListBox) + METHOD(XonoticListBox, configureXonoticListBox, void(entity)) + ATTRIB(XonoticListBox, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticListBox, scrollbarWidth, float, SKINWIDTH_SCROLLBAR) + ATTRIB(XonoticListBox, src, string, SKINGFX_SCROLLBAR) + ATTRIB(XonoticListBox, tolerance, vector, SKINTOLERANCE_SLIDER) + ATTRIB(XonoticListBox, rowsPerItem, float, 1) + METHOD(XonoticListBox, resizeNotify, void(entity, vector, vector, vector, vector)) + ATTRIB(XonoticListBox, color, vector, SKINCOLOR_SCROLLBAR_N) + ATTRIB(XonoticListBox, colorF, vector, SKINCOLOR_SCROLLBAR_F) + ATTRIB(XonoticListBox, color2, vector, SKINCOLOR_SCROLLBAR_S) + ATTRIB(XonoticListBox, colorC, vector, SKINCOLOR_SCROLLBAR_C) + ATTRIB(XonoticListBox, colorBG, vector, SKINCOLOR_LISTBOX_BACKGROUND) + ATTRIB(XonoticListBox, alphaBG, float, SKINALPHA_LISTBOX_BACKGROUND) +ENDCLASS(XonoticListBox) +entity makeXonoticListBox(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticListBox() +{ + entity me; + me = spawnXonoticListBox(); + me.configureXonoticListBox(me); + return me; +} +void XonoticListBox_configureXonoticListBox(entity me) +{ + me.configureListBox(me, me.scrollbarWidth, 1); // item height gets set up later +} +void XonoticListBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemHeight = me.rowsPerItem * me.fontSize / absSize_y; + SUPER(XonoticListBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); +} +#endif diff --git a/qcsrc/menu/xonotic/mainwindow.c b/qcsrc/menu/xonotic/mainwindow.c deleted file mode 100644 index 6fa40bfac..000000000 --- a/qcsrc/menu/xonotic/mainwindow.c +++ /dev/null @@ -1,253 +0,0 @@ -#ifdef INTERFACE -CLASS(MainWindow) EXTENDS(ModalController) - METHOD(MainWindow, configureMainWindow, void(entity)) - METHOD(MainWindow, draw, void(entity)) - ATTRIB(MainWindow, firstRunDialog, entity, NULL) - ATTRIB(MainWindow, advancedDialog, entity, NULL) - ATTRIB(MainWindow, mutatorsDialog, entity, NULL) - ATTRIB(MainWindow, mapInfoDialog, entity, NULL) - ATTRIB(MainWindow, userbindEditDialog, entity, NULL) - ATTRIB(MainWindow, winnerDialog, entity, NULL) - ATTRIB(MainWindow, serverInfoDialog, entity, NULL) - ATTRIB(MainWindow, cvarsDialog, entity, NULL) - ATTRIB(MainWindow, screenshotViewerDialog, entity, NULL) - ATTRIB(MainWindow, viewDialog, entity, NULL) - ATTRIB(MainWindow, hudconfirmDialog, entity, NULL) - ATTRIB(MainWindow, languageWarningDialog, entity, NULL) - ATTRIB(MainWindow, mainNexposee, entity, NULL) - ATTRIB(MainWindow, fadedAlpha, float, SKINALPHA_BEHIND) - ATTRIB(MainWindow, dialogToShow, entity, NULL) - ATTRIB(MainWindow, demostartconfirmDialog, entity, NULL) - ATTRIB(MainWindow, demotimeconfirmDialog, entity, NULL) - ATTRIB(MainWindow, resetDialog, entity, NULL) -ENDCLASS(MainWindow) -#endif - -#ifdef IMPLEMENTATION -void MainWindow_draw(entity me) -{ - SUPER(MainWindow).draw(me); - - if(me.dialogToShow) - { - DialogOpenButton_Click_withCoords(world, me.dialogToShow, '0 0 0', eX * conwidth + eY * conheight); - me.dialogToShow = NULL; - } -} - -void DemoButton_Click(entity me, entity other) -{ - if(me.text == _("Do not press this button again!")) - DialogOpenButton_Click(me, other); - else - me.setText(me, _("Do not press this button again!")); -} - -void MainWindow_configureMainWindow(entity me) -{ - entity n, i; - - // dialog run upon startup - me.firstRunDialog = i = spawnXonoticFirstRunDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - - // hud_configure dialogs - i = spawnXonoticHUDExitDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDNotificationDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDAmmoDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDHealthArmorDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDChatDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDModIconsDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDPowerupsDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDPressedKeysDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDRaceTimerDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDRadarDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDScoreDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDTimerDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDVoteDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDWeaponsDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDEngineInfoDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDInfoMessagesDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDPhysicsDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - me.screenshotViewerDialog = i = spawnXonoticScreenshotViewerDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDCenterprintDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticHUDBuffsDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - - // dialogs used by settings - me.userbindEditDialog = i = spawnXonoticUserbindEditDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - me.cvarsDialog = i = spawnXonoticCvarsDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - me.resetDialog = i = spawnXonoticResetDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - me.languageWarningDialog = i = spawnXonoticLanguageWarningDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - me.hudconfirmDialog = i = spawnXonoticHUDConfirmDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - - // dialog used by singleplayer - me.winnerDialog = i = spawnXonoticWinnerDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - - // dialog used by multiplayer/join - me.serverInfoDialog = i = spawnXonoticServerInfoDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - me.demostartconfirmDialog = i = spawnXonoticDemoStartConfirmDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - me.demotimeconfirmDialog = i = spawnXonoticDemoTimeConfirmDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - - // dialogs used by multiplayer/create - me.mapInfoDialog = i = spawnXonoticMapInfoDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - me.mutatorsDialog = i = spawnXonoticMutatorsDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - // mutator dialogs - i = spawnXonoticSandboxToolsDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z * SKINALPHA_DIALOG_SANDBOXTOOLS); - - - // miscellaneous dialogs - i = spawnXonoticTeamSelectDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - - i = spawnXonoticMonsterToolsDialog(); - i.configureDialog(i); - me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z * SKINALPHA_DIALOG_SANDBOXTOOLS); - - - // main dialogs/windows - me.mainNexposee = n = spawnXonoticNexposee(); - /* - if(checkextension("DP_GECKO_SUPPORT")) - { - i = spawnXonoticNewsDialog(); - i.configureDialog(i); - n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - n.setNexposee(n, i, '0.1 0.1 0', SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); - } - */ - i = spawnXonoticSingleplayerDialog(); - i.configureDialog(i); - n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - n.setNexposee(n, i, SKINPOSITION_DIALOG_SINGLEPLAYER, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); - - i = spawnXonoticMultiplayerDialog(); - i.configureDialog(i); - n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - n.setNexposee(n, i, SKINPOSITION_DIALOG_MULTIPLAYER, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); - - i = spawnXonoticSettingsDialog(); - i.configureDialog(i); - n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - n.setNexposee(n, i, SKINPOSITION_DIALOG_SETTINGS, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); - - i = spawnXonoticCreditsDialog(); - i.configureDialog(i); - n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - n.setNexposee(n, i, SKINPOSITION_DIALOG_CREDITS, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); - n.pullNexposee(n, i, eY * (SKINHEIGHT_TITLE * SKINFONTSIZE_TITLE / conheight)); - - i = spawnXonoticQuitDialog(); - i.configureDialog(i); - n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); - n.setNexposee(n, i, SKINPOSITION_DIALOG_QUIT, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); - n.pullNexposee(n, i, eY * (SKINHEIGHT_TITLE * SKINFONTSIZE_TITLE / conheight)); - - me.addItem(me, n, '0 0 0', '1 1 0', SKINALPHAS_MAINMENU_z); - me.moveItemAfter(me, n, NULL); - - me.initializeDialog(me, n); - - if(cvar_string("_cl_name") == cvar_defstring("_cl_name")) - me.dialogToShow = me.firstRunDialog; -} -#endif - -/* Click. The c-word is here so you can grep for it :-) */ diff --git a/qcsrc/menu/xonotic/mainwindow.qc b/qcsrc/menu/xonotic/mainwindow.qc new file mode 100644 index 000000000..6fa40bfac --- /dev/null +++ b/qcsrc/menu/xonotic/mainwindow.qc @@ -0,0 +1,253 @@ +#ifdef INTERFACE +CLASS(MainWindow) EXTENDS(ModalController) + METHOD(MainWindow, configureMainWindow, void(entity)) + METHOD(MainWindow, draw, void(entity)) + ATTRIB(MainWindow, firstRunDialog, entity, NULL) + ATTRIB(MainWindow, advancedDialog, entity, NULL) + ATTRIB(MainWindow, mutatorsDialog, entity, NULL) + ATTRIB(MainWindow, mapInfoDialog, entity, NULL) + ATTRIB(MainWindow, userbindEditDialog, entity, NULL) + ATTRIB(MainWindow, winnerDialog, entity, NULL) + ATTRIB(MainWindow, serverInfoDialog, entity, NULL) + ATTRIB(MainWindow, cvarsDialog, entity, NULL) + ATTRIB(MainWindow, screenshotViewerDialog, entity, NULL) + ATTRIB(MainWindow, viewDialog, entity, NULL) + ATTRIB(MainWindow, hudconfirmDialog, entity, NULL) + ATTRIB(MainWindow, languageWarningDialog, entity, NULL) + ATTRIB(MainWindow, mainNexposee, entity, NULL) + ATTRIB(MainWindow, fadedAlpha, float, SKINALPHA_BEHIND) + ATTRIB(MainWindow, dialogToShow, entity, NULL) + ATTRIB(MainWindow, demostartconfirmDialog, entity, NULL) + ATTRIB(MainWindow, demotimeconfirmDialog, entity, NULL) + ATTRIB(MainWindow, resetDialog, entity, NULL) +ENDCLASS(MainWindow) +#endif + +#ifdef IMPLEMENTATION +void MainWindow_draw(entity me) +{ + SUPER(MainWindow).draw(me); + + if(me.dialogToShow) + { + DialogOpenButton_Click_withCoords(world, me.dialogToShow, '0 0 0', eX * conwidth + eY * conheight); + me.dialogToShow = NULL; + } +} + +void DemoButton_Click(entity me, entity other) +{ + if(me.text == _("Do not press this button again!")) + DialogOpenButton_Click(me, other); + else + me.setText(me, _("Do not press this button again!")); +} + +void MainWindow_configureMainWindow(entity me) +{ + entity n, i; + + // dialog run upon startup + me.firstRunDialog = i = spawnXonoticFirstRunDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + + // hud_configure dialogs + i = spawnXonoticHUDExitDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDNotificationDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDAmmoDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDHealthArmorDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDChatDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDModIconsDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDPowerupsDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDPressedKeysDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDRaceTimerDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDRadarDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDScoreDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDTimerDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDVoteDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDWeaponsDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDEngineInfoDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDInfoMessagesDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDPhysicsDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + me.screenshotViewerDialog = i = spawnXonoticScreenshotViewerDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDCenterprintDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticHUDBuffsDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + + // dialogs used by settings + me.userbindEditDialog = i = spawnXonoticUserbindEditDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + me.cvarsDialog = i = spawnXonoticCvarsDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + me.resetDialog = i = spawnXonoticResetDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + me.languageWarningDialog = i = spawnXonoticLanguageWarningDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + me.hudconfirmDialog = i = spawnXonoticHUDConfirmDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + + // dialog used by singleplayer + me.winnerDialog = i = spawnXonoticWinnerDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + + // dialog used by multiplayer/join + me.serverInfoDialog = i = spawnXonoticServerInfoDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + me.demostartconfirmDialog = i = spawnXonoticDemoStartConfirmDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + me.demotimeconfirmDialog = i = spawnXonoticDemoTimeConfirmDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + + // dialogs used by multiplayer/create + me.mapInfoDialog = i = spawnXonoticMapInfoDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + me.mutatorsDialog = i = spawnXonoticMutatorsDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + // mutator dialogs + i = spawnXonoticSandboxToolsDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z * SKINALPHA_DIALOG_SANDBOXTOOLS); + + + // miscellaneous dialogs + i = spawnXonoticTeamSelectDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + + i = spawnXonoticMonsterToolsDialog(); + i.configureDialog(i); + me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z * SKINALPHA_DIALOG_SANDBOXTOOLS); + + + // main dialogs/windows + me.mainNexposee = n = spawnXonoticNexposee(); + /* + if(checkextension("DP_GECKO_SUPPORT")) + { + i = spawnXonoticNewsDialog(); + i.configureDialog(i); + n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + n.setNexposee(n, i, '0.1 0.1 0', SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); + } + */ + i = spawnXonoticSingleplayerDialog(); + i.configureDialog(i); + n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + n.setNexposee(n, i, SKINPOSITION_DIALOG_SINGLEPLAYER, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); + + i = spawnXonoticMultiplayerDialog(); + i.configureDialog(i); + n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + n.setNexposee(n, i, SKINPOSITION_DIALOG_MULTIPLAYER, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); + + i = spawnXonoticSettingsDialog(); + i.configureDialog(i); + n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + n.setNexposee(n, i, SKINPOSITION_DIALOG_SETTINGS, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); + + i = spawnXonoticCreditsDialog(); + i.configureDialog(i); + n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + n.setNexposee(n, i, SKINPOSITION_DIALOG_CREDITS, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); + n.pullNexposee(n, i, eY * (SKINHEIGHT_TITLE * SKINFONTSIZE_TITLE / conheight)); + + i = spawnXonoticQuitDialog(); + i.configureDialog(i); + n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z); + n.setNexposee(n, i, SKINPOSITION_DIALOG_QUIT, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y); + n.pullNexposee(n, i, eY * (SKINHEIGHT_TITLE * SKINFONTSIZE_TITLE / conheight)); + + me.addItem(me, n, '0 0 0', '1 1 0', SKINALPHAS_MAINMENU_z); + me.moveItemAfter(me, n, NULL); + + me.initializeDialog(me, n); + + if(cvar_string("_cl_name") == cvar_defstring("_cl_name")) + me.dialogToShow = me.firstRunDialog; +} +#endif + +/* Click. The c-word is here so you can grep for it :-) */ diff --git a/qcsrc/menu/xonotic/maplist.c b/qcsrc/menu/xonotic/maplist.c deleted file mode 100644 index e05c7644f..000000000 --- a/qcsrc/menu/xonotic/maplist.c +++ /dev/null @@ -1,353 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticMapList) EXTENDS(XonoticListBox) - METHOD(XonoticMapList, configureXonoticMapList, void(entity)) - ATTRIB(XonoticMapList, rowsPerItem, float, 4) - METHOD(XonoticMapList, draw, void(entity)) - METHOD(XonoticMapList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticMapList, clickListBoxItem, void(entity, float, vector)) - METHOD(XonoticMapList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticMapList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticMapList, refilter, void(entity)) - METHOD(XonoticMapList, refilterCallback, void(entity, entity)) - METHOD(XonoticMapList, keyDown, float(entity, float, float, float)) - - ATTRIB(XonoticMapList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticMapList, columnPreviewOrigin, float, 0) - ATTRIB(XonoticMapList, columnPreviewSize, float, 0) - ATTRIB(XonoticMapList, columnNameOrigin, float, 0) - ATTRIB(XonoticMapList, columnNameSize, float, 0) - ATTRIB(XonoticMapList, checkMarkOrigin, vector, '0 0 0') - ATTRIB(XonoticMapList, checkMarkSize, vector, '0 0 0') - ATTRIB(XonoticMapList, realUpperMargin1, float, 0) - ATTRIB(XonoticMapList, realUpperMargin2, float, 0) - - ATTRIB(XonoticMapList, lastGametype, float, 0) - ATTRIB(XonoticMapList, lastFeatures, float, 0) - - ATTRIB(XonoticMapList, origin, vector, '0 0 0') - ATTRIB(XonoticMapList, itemAbsSize, vector, '0 0 0') - - ATTRIB(XonoticMapList, g_maplistCache, string, string_null) - METHOD(XonoticMapList, g_maplistCacheToggle, void(entity, float)) - METHOD(XonoticMapList, g_maplistCacheQuery, float(entity, float)) - - ATTRIB(XonoticMapList, startButton, entity, NULL) - - METHOD(XonoticMapList, loadCvars, void(entity)) - - ATTRIB(XonoticMapList, typeToSearchString, string, string_null) - ATTRIB(XonoticMapList, typeToSearchTime, float, 0) - - METHOD(XonoticMapList, destroy, void(entity)) - - ATTRIB(XonoticListBox, alphaBG, float, 0) -ENDCLASS(XonoticMapList) -entity makeXonoticMapList(); -void MapList_All(entity btn, entity me); -void MapList_None(entity btn, entity me); -void MapList_LoadMap(entity btn, entity me); -#endif - -#ifdef IMPLEMENTATION -void XonoticMapList_destroy(entity me) -{ - MapInfo_Shutdown(); -} - -entity makeXonoticMapList() -{ - entity me; - me = spawnXonoticMapList(); - me.configureXonoticMapList(me); - return me; -} - -void XonoticMapList_configureXonoticMapList(entity me) -{ - me.configureXonoticListBox(me); - me.refilter(me); -} - -void XonoticMapList_loadCvars(entity me) -{ - me.refilter(me); -} - -float XonoticMapList_g_maplistCacheQuery(entity me, float i) -{ - return stof(substring(me.g_maplistCache, i, 1)); -} -void XonoticMapList_g_maplistCacheToggle(entity me, float i) -{ - string a, b, c, s, bspname; - float n; - s = me.g_maplistCache; - if (!s) - return; - b = substring(s, i, 1); - if(b == "0") - b = "1"; - else if(b == "1") - b = "0"; - else - return; // nothing happens - a = substring(s, 0, i); - c = substring(s, i+1, strlen(s) - (i+1)); - strunzone(s); - me.g_maplistCache = strzone(strcat(a, b, c)); - // TODO also update the actual cvar - if (!((bspname = MapInfo_BSPName_ByID(i)))) - return; - if(b == "1") - cvar_set("g_maplist", strcat(bspname, " ", cvar_string("g_maplist"))); - else - { - s = ""; - n = tokenize_console(cvar_string("g_maplist")); - for(i = 0; i < n; ++i) - if(argv(i) != bspname) - s = strcat(s, " ", argv(i)); - cvar_set("g_maplist", substring(s, 1, strlen(s) - 1)); - } -} - -void XonoticMapList_draw(entity me) -{ - if(me.startButton) - me.startButton.disabled = ((me.selectedItem < 0) || (me.selectedItem >= me.nItems)); - SUPER(XonoticMapList).draw(me); -} - -void XonoticMapList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticMapList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin1 = 0.5 * (1 - 2.5 * me.realFontSize_y); - me.realUpperMargin2 = me.realUpperMargin1 + 1.5 * me.realFontSize_y; - - me.columnPreviewOrigin = 0; - me.columnPreviewSize = me.itemAbsSize_y / me.itemAbsSize_x * 4 / 3; - me.columnNameOrigin = me.columnPreviewOrigin + me.columnPreviewSize + me.realFontSize_x; - me.columnNameSize = 1 - me.columnPreviewSize - 2 * me.realFontSize_x; - - me.checkMarkSize = (eX * (me.itemAbsSize_y / me.itemAbsSize_x) + eY) * 0.5; - me.checkMarkOrigin = eY + eX * (me.columnPreviewOrigin + me.columnPreviewSize) - me.checkMarkSize; -} - -void XonoticMapList_clickListBoxItem(entity me, float i, vector where) -{ - if(where_x <= me.columnPreviewOrigin + me.columnPreviewSize) - if(where_x >= 0) - me.g_maplistCacheToggle(me, i); -} - -void XonoticMapList_doubleClickListBoxItem(entity me, float i, vector where) -{ - if(where_x >= me.columnNameOrigin) - if(where_x <= 1) - { - // pop up map info screen - main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, i, me); - DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * i - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize)); - } -} - -void XonoticMapList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - // layout: Ping, Map name, Map name, NP, TP, MP - string s; - float theAlpha; - float included; - - if(!MapInfo_Get_ByID(i)) - return; - - included = me.g_maplistCacheQuery(me, i); - if(included || isSelected) - theAlpha = SKINALPHA_MAPLIST_INCLUDEDFG; - else - theAlpha = SKINALPHA_MAPLIST_NOTINCLUDEDFG; - - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - else if(included) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_MAPLIST_INCLUDEDBG, SKINALPHA_MAPLIST_INCLUDEDBG); - - if(draw_PictureSize(strcat("/maps/", MapInfo_Map_bspname)) == '0 0 0') - draw_Picture(me.columnPreviewOrigin * eX, "nopreview_map", me.columnPreviewSize * eX + eY, '1 1 1', theAlpha); - else - draw_Picture(me.columnPreviewOrigin * eX, strcat("/maps/", MapInfo_Map_bspname), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha); - - if(included) - draw_Picture(me.checkMarkOrigin, "checkmark", me.checkMarkSize, '1 1 1', 1); - s = draw_TextShortenToWidth(strdecolorize(MapInfo_Map_titlestring), me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_TITLE, theAlpha, 0); - s = draw_TextShortenToWidth(strdecolorize(MapInfo_Map_author), me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_AUTHOR, theAlpha, 0); - - MapInfo_ClearTemps(); -} - -void XonoticMapList_refilter(entity me) -{ - float i, j, n; - string s; - float gt, f; - gt = MapInfo_CurrentGametype(); - f = MapInfo_CurrentFeatures(); - MapInfo_FilterGametype(gt, f, MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); - me.nItems = MapInfo_count; - for(i = 0; i < MapInfo_count; ++i) - draw_PreloadPicture(strcat("/maps/", MapInfo_BSPName_ByID(i))); - if(me.g_maplistCache) - strunzone(me.g_maplistCache); - s = "0"; - for(i = 1; i < MapInfo_count; i *= 2) - s = strcat(s, s); - n = tokenize_console(cvar_string("g_maplist")); - for(i = 0; i < n; ++i) - { - j = MapInfo_FindName(argv(i)); - if(j >= 0) - s = strcat( - substring(s, 0, j), - "1", - substring(s, j+1, MapInfo_count - (j+1)) - ); - } - me.g_maplistCache = strzone(s); - if(gt != me.lastGametype || f != me.lastFeatures) - { - me.lastGametype = gt; - me.lastFeatures = f; - me.setSelected(me, 0); - } -} - -void XonoticMapList_refilterCallback(entity me, entity cb) -{ - me.refilter(me); -} - -void MapList_All(entity btn, entity me) -{ - float i; - string s; - MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 0, MapInfo_ForbiddenFlags(), 0); // all - s = ""; - for(i = 0; i < MapInfo_count; ++i) - s = strcat(s, " ", MapInfo_BSPName_ByID(i)); - cvar_set("g_maplist", substring(s, 1, strlen(s) - 1)); - me.refilter(me); -} - -void MapList_None(entity btn, entity me) -{ - cvar_set("g_maplist", ""); - me.refilter(me); -} - -void MapList_LoadMap(entity btn, entity me) -{ - string m; - float i; - - i = me.selectedItem; - - if(btn.parent.instanceOfXonoticMapInfoDialog) - { - i = btn.parent.currentMapIndex; - Dialog_Close(btn, btn.parent); - } - - if(i >= me.nItems || i < 0) - return; - - m = MapInfo_BSPName_ByID(i); - if (!m) - { - print(_("Huh? Can't play this (m is NULL). Refiltering so this won't happen again.\n")); - me.refilter(me); - return; - } - if(MapInfo_CheckMap(m)) - { - localcmd("\nmenu_loadmap_prepare\n"); - if(cvar("menu_use_default_hostname")) - localcmd("hostname \"", sprintf(_("%s's Xonotic Server"), strdecolorize(cvar_string("_cl_name"))), "\"\n"); - MapInfo_LoadMap(m, 1); - } - else - { - print(_("Huh? Can't play this (invalid game type). Refiltering so this won't happen again.\n")); - me.refilter(me); - return; - } -} - -float XonoticMapList_keyDown(entity me, float scan, float ascii, float shift) -{ - string ch, save; - if(me.nItems <= 0) - return SUPER(XonoticMapList).keyDown(me, scan, ascii, shift); - if(scan == K_MOUSE2 || scan == K_SPACE || scan == K_ENTER || scan == K_KP_ENTER) - { - // pop up map info screen - main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, me.selectedItem, me); - DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * me.selectedItem - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize)); - } - else if(scan == K_MOUSE3 || scan == K_INS || scan == K_KP_INS) - { - me.g_maplistCacheToggle(me, me.selectedItem); - } - else if(ascii == 43) // + - { - if (!me.g_maplistCacheQuery(me, me.selectedItem)) - me.g_maplistCacheToggle(me, me.selectedItem); - } - else if(ascii == 45) // - - { - if(me.g_maplistCacheQuery(me, me.selectedItem)) - me.g_maplistCacheToggle(me, me.selectedItem); - } - else if(scan == K_BACKSPACE) - { - if(time < me.typeToSearchTime) - { - save = substring(me.typeToSearchString, 0, strlen(me.typeToSearchString) - 1); - if(me.typeToSearchString) - strunzone(me.typeToSearchString); - me.typeToSearchString = strzone(save); - me.typeToSearchTime = time + 0.5; - if(strlen(me.typeToSearchString)) - { - MapInfo_FindName(me.typeToSearchString); - if(MapInfo_FindName_firstResult >= 0) - me.setSelected(me, MapInfo_FindName_firstResult); - } - } - } - else if(ascii >= 32 && ascii != 127) - { - ch = chr(ascii); - if(time > me.typeToSearchTime) - save = ch; - else - save = strcat(me.typeToSearchString, ch); - if(me.typeToSearchString) - strunzone(me.typeToSearchString); - me.typeToSearchString = strzone(save); - me.typeToSearchTime = time + 0.5; - MapInfo_FindName(me.typeToSearchString); - if(MapInfo_FindName_firstResult >= 0) - me.setSelected(me, MapInfo_FindName_firstResult); - } - else - return SUPER(XonoticMapList).keyDown(me, scan, ascii, shift); - return 1; -} - -#endif diff --git a/qcsrc/menu/xonotic/maplist.qc b/qcsrc/menu/xonotic/maplist.qc new file mode 100644 index 000000000..e05c7644f --- /dev/null +++ b/qcsrc/menu/xonotic/maplist.qc @@ -0,0 +1,353 @@ +#ifdef INTERFACE +CLASS(XonoticMapList) EXTENDS(XonoticListBox) + METHOD(XonoticMapList, configureXonoticMapList, void(entity)) + ATTRIB(XonoticMapList, rowsPerItem, float, 4) + METHOD(XonoticMapList, draw, void(entity)) + METHOD(XonoticMapList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticMapList, clickListBoxItem, void(entity, float, vector)) + METHOD(XonoticMapList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticMapList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticMapList, refilter, void(entity)) + METHOD(XonoticMapList, refilterCallback, void(entity, entity)) + METHOD(XonoticMapList, keyDown, float(entity, float, float, float)) + + ATTRIB(XonoticMapList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticMapList, columnPreviewOrigin, float, 0) + ATTRIB(XonoticMapList, columnPreviewSize, float, 0) + ATTRIB(XonoticMapList, columnNameOrigin, float, 0) + ATTRIB(XonoticMapList, columnNameSize, float, 0) + ATTRIB(XonoticMapList, checkMarkOrigin, vector, '0 0 0') + ATTRIB(XonoticMapList, checkMarkSize, vector, '0 0 0') + ATTRIB(XonoticMapList, realUpperMargin1, float, 0) + ATTRIB(XonoticMapList, realUpperMargin2, float, 0) + + ATTRIB(XonoticMapList, lastGametype, float, 0) + ATTRIB(XonoticMapList, lastFeatures, float, 0) + + ATTRIB(XonoticMapList, origin, vector, '0 0 0') + ATTRIB(XonoticMapList, itemAbsSize, vector, '0 0 0') + + ATTRIB(XonoticMapList, g_maplistCache, string, string_null) + METHOD(XonoticMapList, g_maplistCacheToggle, void(entity, float)) + METHOD(XonoticMapList, g_maplistCacheQuery, float(entity, float)) + + ATTRIB(XonoticMapList, startButton, entity, NULL) + + METHOD(XonoticMapList, loadCvars, void(entity)) + + ATTRIB(XonoticMapList, typeToSearchString, string, string_null) + ATTRIB(XonoticMapList, typeToSearchTime, float, 0) + + METHOD(XonoticMapList, destroy, void(entity)) + + ATTRIB(XonoticListBox, alphaBG, float, 0) +ENDCLASS(XonoticMapList) +entity makeXonoticMapList(); +void MapList_All(entity btn, entity me); +void MapList_None(entity btn, entity me); +void MapList_LoadMap(entity btn, entity me); +#endif + +#ifdef IMPLEMENTATION +void XonoticMapList_destroy(entity me) +{ + MapInfo_Shutdown(); +} + +entity makeXonoticMapList() +{ + entity me; + me = spawnXonoticMapList(); + me.configureXonoticMapList(me); + return me; +} + +void XonoticMapList_configureXonoticMapList(entity me) +{ + me.configureXonoticListBox(me); + me.refilter(me); +} + +void XonoticMapList_loadCvars(entity me) +{ + me.refilter(me); +} + +float XonoticMapList_g_maplistCacheQuery(entity me, float i) +{ + return stof(substring(me.g_maplistCache, i, 1)); +} +void XonoticMapList_g_maplistCacheToggle(entity me, float i) +{ + string a, b, c, s, bspname; + float n; + s = me.g_maplistCache; + if (!s) + return; + b = substring(s, i, 1); + if(b == "0") + b = "1"; + else if(b == "1") + b = "0"; + else + return; // nothing happens + a = substring(s, 0, i); + c = substring(s, i+1, strlen(s) - (i+1)); + strunzone(s); + me.g_maplistCache = strzone(strcat(a, b, c)); + // TODO also update the actual cvar + if (!((bspname = MapInfo_BSPName_ByID(i)))) + return; + if(b == "1") + cvar_set("g_maplist", strcat(bspname, " ", cvar_string("g_maplist"))); + else + { + s = ""; + n = tokenize_console(cvar_string("g_maplist")); + for(i = 0; i < n; ++i) + if(argv(i) != bspname) + s = strcat(s, " ", argv(i)); + cvar_set("g_maplist", substring(s, 1, strlen(s) - 1)); + } +} + +void XonoticMapList_draw(entity me) +{ + if(me.startButton) + me.startButton.disabled = ((me.selectedItem < 0) || (me.selectedItem >= me.nItems)); + SUPER(XonoticMapList).draw(me); +} + +void XonoticMapList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticMapList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin1 = 0.5 * (1 - 2.5 * me.realFontSize_y); + me.realUpperMargin2 = me.realUpperMargin1 + 1.5 * me.realFontSize_y; + + me.columnPreviewOrigin = 0; + me.columnPreviewSize = me.itemAbsSize_y / me.itemAbsSize_x * 4 / 3; + me.columnNameOrigin = me.columnPreviewOrigin + me.columnPreviewSize + me.realFontSize_x; + me.columnNameSize = 1 - me.columnPreviewSize - 2 * me.realFontSize_x; + + me.checkMarkSize = (eX * (me.itemAbsSize_y / me.itemAbsSize_x) + eY) * 0.5; + me.checkMarkOrigin = eY + eX * (me.columnPreviewOrigin + me.columnPreviewSize) - me.checkMarkSize; +} + +void XonoticMapList_clickListBoxItem(entity me, float i, vector where) +{ + if(where_x <= me.columnPreviewOrigin + me.columnPreviewSize) + if(where_x >= 0) + me.g_maplistCacheToggle(me, i); +} + +void XonoticMapList_doubleClickListBoxItem(entity me, float i, vector where) +{ + if(where_x >= me.columnNameOrigin) + if(where_x <= 1) + { + // pop up map info screen + main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, i, me); + DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * i - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize)); + } +} + +void XonoticMapList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + // layout: Ping, Map name, Map name, NP, TP, MP + string s; + float theAlpha; + float included; + + if(!MapInfo_Get_ByID(i)) + return; + + included = me.g_maplistCacheQuery(me, i); + if(included || isSelected) + theAlpha = SKINALPHA_MAPLIST_INCLUDEDFG; + else + theAlpha = SKINALPHA_MAPLIST_NOTINCLUDEDFG; + + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + else if(included) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_MAPLIST_INCLUDEDBG, SKINALPHA_MAPLIST_INCLUDEDBG); + + if(draw_PictureSize(strcat("/maps/", MapInfo_Map_bspname)) == '0 0 0') + draw_Picture(me.columnPreviewOrigin * eX, "nopreview_map", me.columnPreviewSize * eX + eY, '1 1 1', theAlpha); + else + draw_Picture(me.columnPreviewOrigin * eX, strcat("/maps/", MapInfo_Map_bspname), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha); + + if(included) + draw_Picture(me.checkMarkOrigin, "checkmark", me.checkMarkSize, '1 1 1', 1); + s = draw_TextShortenToWidth(strdecolorize(MapInfo_Map_titlestring), me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_TITLE, theAlpha, 0); + s = draw_TextShortenToWidth(strdecolorize(MapInfo_Map_author), me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_AUTHOR, theAlpha, 0); + + MapInfo_ClearTemps(); +} + +void XonoticMapList_refilter(entity me) +{ + float i, j, n; + string s; + float gt, f; + gt = MapInfo_CurrentGametype(); + f = MapInfo_CurrentFeatures(); + MapInfo_FilterGametype(gt, f, MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); + me.nItems = MapInfo_count; + for(i = 0; i < MapInfo_count; ++i) + draw_PreloadPicture(strcat("/maps/", MapInfo_BSPName_ByID(i))); + if(me.g_maplistCache) + strunzone(me.g_maplistCache); + s = "0"; + for(i = 1; i < MapInfo_count; i *= 2) + s = strcat(s, s); + n = tokenize_console(cvar_string("g_maplist")); + for(i = 0; i < n; ++i) + { + j = MapInfo_FindName(argv(i)); + if(j >= 0) + s = strcat( + substring(s, 0, j), + "1", + substring(s, j+1, MapInfo_count - (j+1)) + ); + } + me.g_maplistCache = strzone(s); + if(gt != me.lastGametype || f != me.lastFeatures) + { + me.lastGametype = gt; + me.lastFeatures = f; + me.setSelected(me, 0); + } +} + +void XonoticMapList_refilterCallback(entity me, entity cb) +{ + me.refilter(me); +} + +void MapList_All(entity btn, entity me) +{ + float i; + string s; + MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 0, MapInfo_ForbiddenFlags(), 0); // all + s = ""; + for(i = 0; i < MapInfo_count; ++i) + s = strcat(s, " ", MapInfo_BSPName_ByID(i)); + cvar_set("g_maplist", substring(s, 1, strlen(s) - 1)); + me.refilter(me); +} + +void MapList_None(entity btn, entity me) +{ + cvar_set("g_maplist", ""); + me.refilter(me); +} + +void MapList_LoadMap(entity btn, entity me) +{ + string m; + float i; + + i = me.selectedItem; + + if(btn.parent.instanceOfXonoticMapInfoDialog) + { + i = btn.parent.currentMapIndex; + Dialog_Close(btn, btn.parent); + } + + if(i >= me.nItems || i < 0) + return; + + m = MapInfo_BSPName_ByID(i); + if (!m) + { + print(_("Huh? Can't play this (m is NULL). Refiltering so this won't happen again.\n")); + me.refilter(me); + return; + } + if(MapInfo_CheckMap(m)) + { + localcmd("\nmenu_loadmap_prepare\n"); + if(cvar("menu_use_default_hostname")) + localcmd("hostname \"", sprintf(_("%s's Xonotic Server"), strdecolorize(cvar_string("_cl_name"))), "\"\n"); + MapInfo_LoadMap(m, 1); + } + else + { + print(_("Huh? Can't play this (invalid game type). Refiltering so this won't happen again.\n")); + me.refilter(me); + return; + } +} + +float XonoticMapList_keyDown(entity me, float scan, float ascii, float shift) +{ + string ch, save; + if(me.nItems <= 0) + return SUPER(XonoticMapList).keyDown(me, scan, ascii, shift); + if(scan == K_MOUSE2 || scan == K_SPACE || scan == K_ENTER || scan == K_KP_ENTER) + { + // pop up map info screen + main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, me.selectedItem, me); + DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * me.selectedItem - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize)); + } + else if(scan == K_MOUSE3 || scan == K_INS || scan == K_KP_INS) + { + me.g_maplistCacheToggle(me, me.selectedItem); + } + else if(ascii == 43) // + + { + if (!me.g_maplistCacheQuery(me, me.selectedItem)) + me.g_maplistCacheToggle(me, me.selectedItem); + } + else if(ascii == 45) // - + { + if(me.g_maplistCacheQuery(me, me.selectedItem)) + me.g_maplistCacheToggle(me, me.selectedItem); + } + else if(scan == K_BACKSPACE) + { + if(time < me.typeToSearchTime) + { + save = substring(me.typeToSearchString, 0, strlen(me.typeToSearchString) - 1); + if(me.typeToSearchString) + strunzone(me.typeToSearchString); + me.typeToSearchString = strzone(save); + me.typeToSearchTime = time + 0.5; + if(strlen(me.typeToSearchString)) + { + MapInfo_FindName(me.typeToSearchString); + if(MapInfo_FindName_firstResult >= 0) + me.setSelected(me, MapInfo_FindName_firstResult); + } + } + } + else if(ascii >= 32 && ascii != 127) + { + ch = chr(ascii); + if(time > me.typeToSearchTime) + save = ch; + else + save = strcat(me.typeToSearchString, ch); + if(me.typeToSearchString) + strunzone(me.typeToSearchString); + me.typeToSearchString = strzone(save); + me.typeToSearchTime = time + 0.5; + MapInfo_FindName(me.typeToSearchString); + if(MapInfo_FindName_firstResult >= 0) + me.setSelected(me, MapInfo_FindName_firstResult); + } + else + return SUPER(XonoticMapList).keyDown(me, scan, ascii, shift); + return 1; +} + +#endif diff --git a/qcsrc/menu/xonotic/nexposee.c b/qcsrc/menu/xonotic/nexposee.c deleted file mode 100644 index b375393c0..000000000 --- a/qcsrc/menu/xonotic/nexposee.c +++ /dev/null @@ -1,26 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticNexposee) EXTENDS(Nexposee) - METHOD(XonoticNexposee, configureXonoticNexposee, void(entity)) - METHOD(XonoticNexposee, close, void(entity)) -ENDCLASS(XonoticNexposee) -entity makeXonoticNexposee(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticNexposee() -{ - entity me; - me = spawnXonoticNexposee(); - me.configureXonoticNexposee(me); - return me; -} - -void XonoticNexposee_configureXonoticNexposee(entity me) -{ -} - -void XonoticNexposee_close(entity me) -{ - m_goto(string_null); // hide -} -#endif diff --git a/qcsrc/menu/xonotic/nexposee.qc b/qcsrc/menu/xonotic/nexposee.qc new file mode 100644 index 000000000..b375393c0 --- /dev/null +++ b/qcsrc/menu/xonotic/nexposee.qc @@ -0,0 +1,26 @@ +#ifdef INTERFACE +CLASS(XonoticNexposee) EXTENDS(Nexposee) + METHOD(XonoticNexposee, configureXonoticNexposee, void(entity)) + METHOD(XonoticNexposee, close, void(entity)) +ENDCLASS(XonoticNexposee) +entity makeXonoticNexposee(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticNexposee() +{ + entity me; + me = spawnXonoticNexposee(); + me.configureXonoticNexposee(me); + return me; +} + +void XonoticNexposee_configureXonoticNexposee(entity me) +{ +} + +void XonoticNexposee_close(entity me) +{ + m_goto(string_null); // hide +} +#endif diff --git a/qcsrc/menu/xonotic/playerlist.c b/qcsrc/menu/xonotic/playerlist.c deleted file mode 100644 index c60b34e38..000000000 --- a/qcsrc/menu/xonotic/playerlist.c +++ /dev/null @@ -1,138 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticPlayerList) EXTENDS(XonoticListBox) - ATTRIB(XonoticPlayerList, rowsPerItem, float, 1) - METHOD(XonoticPlayerList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticPlayerList, drawListBoxItem, void(entity, float, vector, float)) - ATTRIB(XonoticPlayerList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticPlayerList, columnNameOrigin, float, 0) - ATTRIB(XonoticPlayerList, columnNameSize, float, 0) - ATTRIB(XonoticPlayerList, columnScoreOrigin, float, 0) - ATTRIB(XonoticPlayerList, columnScoreSize, float, 0) - ATTRIB(XonoticPlayerList, realUpperMargin, float, 0) - ATTRIB(XonoticPlayerList, origin, vector, '0 0 0') - ATTRIB(XonoticPlayerList, itemAbsSize, vector, '0 0 0') - METHOD(XonoticPlayerList, setPlayerList, void(entity, string)) - METHOD(XonoticPlayerList, getPlayerList, string(entity, float, float)) - ATTRIB(XonoticPlayerList, playerList, float, -1) -ENDCLASS(XonoticPlayerList) -entity makeXonoticPlayerList(); -#endif - -#ifdef IMPLEMENTATION - -const float PLAYERPARM_SCORE = 0; -const float PLAYERPARM_PING = 1; -const float PLAYERPARM_TEAM = 2; -const float PLAYERPARM_NAME = 3; -const float PLAYERPARM_COUNT = 4; - -entity makeXonoticPlayerList() -{ - entity me; - me = spawnXonoticPlayerList(); - me.configureXonoticListBox(me); - return me; -} - -void XonoticPlayerList_setPlayerList(entity me, string plist) -{ - float buf,i,n; - string s; - - buf = buf_create(); - me.nItems = tokenizebyseparator(plist, "\n"); - for(i = 0; i < me.nItems; ++i) - { - bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_NAME, argv(i)); // -666 100 "^4Nex ^2Player" - } - - for(i = 0; i < me.nItems; ++i) - { - s = bufstr_get(buf, i * PLAYERPARM_COUNT + PLAYERPARM_NAME); - n = tokenize_console(s); - - if(n == 4) - { - bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_SCORE, argv(0)); // -666 - bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_PING, argv(1)); // 100 - bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_TEAM, argv(2)); // 0 for spec, else 1, 2, 3, 4 - bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_NAME, argv(3)); // ^4Nex ^2Player - } - else - { - bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_SCORE, argv(0)); // -666 - bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_PING, argv(1)); // 100 - bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_TEAM, "-1"); - bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_NAME, argv(2)); // ^4Nex ^2Player - } - } - me.playerList = buf; -} - -string XonoticPlayerList_getPlayerList(entity me, float i, float key) -{ - return bufstr_get(me.playerList, i * PLAYERPARM_COUNT + key); -} - -void XonoticPlayerList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticPlayerList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - - // this list does 1 char left and right margin - me.columnScoreSize = 5 * me.realFontSize_x; - me.columnNameSize = 1 - 3 * me.realFontSize_x - me.columnScoreSize; - - me.columnNameOrigin = me.realFontSize_x; - me.columnScoreOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x; -} - -void XonoticPlayerList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s; - string score; - float t; - vector rgb; - - t = stof(me.getPlayerList(me, i, PLAYERPARM_TEAM)); - if(t == 1) - rgb = colormapPaletteColor(4, 0); - else if(t == 2) - rgb = colormapPaletteColor(13, 0); - else if(t == 3) - rgb = colormapPaletteColor(12, 0); - else if(t == 4) - rgb = colormapPaletteColor(9, 0); - else - rgb = SKINCOLOR_TEXT; - - s = me.getPlayerList(me, i, PLAYERPARM_NAME); - score = me.getPlayerList(me, i, PLAYERPARM_SCORE); - - if(substring(score, strlen(score) - 10, 10) == ":spectator") - { - score = _("spectator"); - } - else - { - if((t = strstrofs(score, ":", 0)) >= 0) - score = substring(score, 0, t); - if((t = strstrofs(score, ",", 0)) >= 0) - score = substring(score, 0, t); - - if(stof(score) == -666) - score = _("spectator"); - } - - s = draw_TextShortenToWidth(s, me.columnNameSize, 1, me.realFontSize); - draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 1, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', 1, 1); - - score = draw_TextShortenToWidth(score, me.columnScoreSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin2 * eY + (me.columnScoreOrigin + 1.00 * (me.columnScoreSize - draw_TextWidth(score, 1, me.realFontSize))) * eX, score, me.realFontSize, rgb, 1, 0); -} - -#endif diff --git a/qcsrc/menu/xonotic/playerlist.qc b/qcsrc/menu/xonotic/playerlist.qc new file mode 100644 index 000000000..c60b34e38 --- /dev/null +++ b/qcsrc/menu/xonotic/playerlist.qc @@ -0,0 +1,138 @@ +#ifdef INTERFACE +CLASS(XonoticPlayerList) EXTENDS(XonoticListBox) + ATTRIB(XonoticPlayerList, rowsPerItem, float, 1) + METHOD(XonoticPlayerList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticPlayerList, drawListBoxItem, void(entity, float, vector, float)) + ATTRIB(XonoticPlayerList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticPlayerList, columnNameOrigin, float, 0) + ATTRIB(XonoticPlayerList, columnNameSize, float, 0) + ATTRIB(XonoticPlayerList, columnScoreOrigin, float, 0) + ATTRIB(XonoticPlayerList, columnScoreSize, float, 0) + ATTRIB(XonoticPlayerList, realUpperMargin, float, 0) + ATTRIB(XonoticPlayerList, origin, vector, '0 0 0') + ATTRIB(XonoticPlayerList, itemAbsSize, vector, '0 0 0') + METHOD(XonoticPlayerList, setPlayerList, void(entity, string)) + METHOD(XonoticPlayerList, getPlayerList, string(entity, float, float)) + ATTRIB(XonoticPlayerList, playerList, float, -1) +ENDCLASS(XonoticPlayerList) +entity makeXonoticPlayerList(); +#endif + +#ifdef IMPLEMENTATION + +const float PLAYERPARM_SCORE = 0; +const float PLAYERPARM_PING = 1; +const float PLAYERPARM_TEAM = 2; +const float PLAYERPARM_NAME = 3; +const float PLAYERPARM_COUNT = 4; + +entity makeXonoticPlayerList() +{ + entity me; + me = spawnXonoticPlayerList(); + me.configureXonoticListBox(me); + return me; +} + +void XonoticPlayerList_setPlayerList(entity me, string plist) +{ + float buf,i,n; + string s; + + buf = buf_create(); + me.nItems = tokenizebyseparator(plist, "\n"); + for(i = 0; i < me.nItems; ++i) + { + bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_NAME, argv(i)); // -666 100 "^4Nex ^2Player" + } + + for(i = 0; i < me.nItems; ++i) + { + s = bufstr_get(buf, i * PLAYERPARM_COUNT + PLAYERPARM_NAME); + n = tokenize_console(s); + + if(n == 4) + { + bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_SCORE, argv(0)); // -666 + bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_PING, argv(1)); // 100 + bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_TEAM, argv(2)); // 0 for spec, else 1, 2, 3, 4 + bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_NAME, argv(3)); // ^4Nex ^2Player + } + else + { + bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_SCORE, argv(0)); // -666 + bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_PING, argv(1)); // 100 + bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_TEAM, "-1"); + bufstr_set(buf, i * PLAYERPARM_COUNT + PLAYERPARM_NAME, argv(2)); // ^4Nex ^2Player + } + } + me.playerList = buf; +} + +string XonoticPlayerList_getPlayerList(entity me, float i, float key) +{ + return bufstr_get(me.playerList, i * PLAYERPARM_COUNT + key); +} + +void XonoticPlayerList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticPlayerList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + + // this list does 1 char left and right margin + me.columnScoreSize = 5 * me.realFontSize_x; + me.columnNameSize = 1 - 3 * me.realFontSize_x - me.columnScoreSize; + + me.columnNameOrigin = me.realFontSize_x; + me.columnScoreOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x; +} + +void XonoticPlayerList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s; + string score; + float t; + vector rgb; + + t = stof(me.getPlayerList(me, i, PLAYERPARM_TEAM)); + if(t == 1) + rgb = colormapPaletteColor(4, 0); + else if(t == 2) + rgb = colormapPaletteColor(13, 0); + else if(t == 3) + rgb = colormapPaletteColor(12, 0); + else if(t == 4) + rgb = colormapPaletteColor(9, 0); + else + rgb = SKINCOLOR_TEXT; + + s = me.getPlayerList(me, i, PLAYERPARM_NAME); + score = me.getPlayerList(me, i, PLAYERPARM_SCORE); + + if(substring(score, strlen(score) - 10, 10) == ":spectator") + { + score = _("spectator"); + } + else + { + if((t = strstrofs(score, ":", 0)) >= 0) + score = substring(score, 0, t); + if((t = strstrofs(score, ",", 0)) >= 0) + score = substring(score, 0, t); + + if(stof(score) == -666) + score = _("spectator"); + } + + s = draw_TextShortenToWidth(s, me.columnNameSize, 1, me.realFontSize); + draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 1, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', 1, 1); + + score = draw_TextShortenToWidth(score, me.columnScoreSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin2 * eY + (me.columnScoreOrigin + 1.00 * (me.columnScoreSize - draw_TextWidth(score, 1, me.realFontSize))) * eX, score, me.realFontSize, rgb, 1, 0); +} + +#endif diff --git a/qcsrc/menu/xonotic/playermodel.c b/qcsrc/menu/xonotic/playermodel.c deleted file mode 100644 index 0a0d6f940..000000000 --- a/qcsrc/menu/xonotic/playermodel.c +++ /dev/null @@ -1,223 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticPlayerModelSelector) EXTENDS(XonoticImage) - METHOD(XonoticPlayerModelSelector, configureXonoticPlayerModelSelector, void(entity)) - METHOD(XonoticPlayerModelSelector, loadCvars, void(entity)) - METHOD(XonoticPlayerModelSelector, saveCvars, void(entity)) - METHOD(XonoticPlayerModelSelector, draw, void(entity)) - METHOD(XonoticPlayerModelSelector, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticPlayerModelSelector, showNotify, void(entity)) - ATTRIB(XonoticPlayerModelSelector, currentModel, string, string_null) - ATTRIB(XonoticPlayerModelSelector, currentSkin, float, 0) - ATTRIB(XonoticPlayerModelSelector, currentModelImage, string, string_null) - ATTRIB(XonoticPlayerModelSelector, currentModelTitle, string, string_null) - ATTRIB(XonoticPlayerModelSelector, currentModelDescription, string, string_null) - METHOD(XonoticPlayerModelSelector, go, void(entity, float)) - METHOD(XonoticPlayerModelSelector, destroy, void(entity)) - ATTRIB(XonoticPlayerModelSelector, origin, vector, '0 0 0') - ATTRIB(XonoticPlayerModelSelector, size, vector, '0 0 0') - ATTRIB(XonoticPlayerModelSelector, realFontSize, vector, '0 0 0') - ATTRIB(XonoticPlayerModelSelector, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticPlayerModelSelector, titleFontSize, float, SKINFONTSIZE_TITLE) - ATTRIB(XonoticPlayerModelSelector, bufModels, float, -1) - ATTRIB(XonoticPlayerModelSelector, numModels, float, -1) - ATTRIB(XonoticPlayerModelSelector, idxModels, float, -1) -ENDCLASS(XonoticPlayerModelSelector) -entity makeXonoticPlayerModelSelector(); -void PlayerModelSelector_Next_Click(entity btn, entity me); -void PlayerModelSelector_Prev_Click(entity btn, entity me); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticPlayerModelSelector() -{ - entity me; - me = spawnXonoticPlayerModelSelector(); - me.configureXonoticPlayerModelSelector(me); - return me; -} - -const float BUFMODELS_TITLE = 0; -const float BUFMODELS_IMAGE = 1; -const float BUFMODELS_MODEL = 2; -const float BUFMODELS_SKIN = 3; -const float BUFMODELS_DESC = 4; -const float BUFMODELS_COUNT = 5; - -#define XONVOTE186 1 // (nyov) removal of model text description - -void XonoticPlayerModelSelector_configureXonoticPlayerModelSelector(entity me) -{ - float sortbuf, glob, i; - string fn; - - glob = search_begin(language_filename(get_model_datafilename(string_null, -1, "txt")), TRUE, TRUE); - if (glob < 0) - return; - - me.configureXonoticImage(me, string_null, -1); - - sortbuf = buf_create(); - for(i = 0; i < search_getsize(glob); ++i) - { - // select model #i! - fn = search_getfilename(glob, i); - if(!get_model_parameters(fn, -1)) - continue; - bufstr_add(sortbuf, sprintf("%-128s%s", get_model_parameters_name, fn), 1); - } - search_end(glob); - buf_sort(sortbuf, 128, 0); - me.numModels = buf_getsize(sortbuf); - me.bufModels = buf_create(); - for(i = 0; i < me.numModels; ++i) - { - fn = substring(bufstr_get(sortbuf, i), 128, -1); - if(!get_model_parameters(fn, -1)) - error("But it JUST worked!"); - bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_TITLE, get_model_parameters_name); - bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_IMAGE, strcat("/", substring(get_model_datafilename(get_model_parameters_modelname, get_model_parameters_modelskin, "tga"), 0, -5))); - bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL, get_model_parameters_modelname); - bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_SKIN, ftos(get_model_parameters_modelskin)); - get_model_parameters_desc = strcat(get_model_parameters_desc, "\n"); -#if XONVOTE186 - if(get_model_parameters_sex) - get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s", get_model_parameters_sex)); -#else - if(get_model_parameters_description) - get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s\n", get_model_parameters_description)); - if(get_model_parameters_sex) - get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nSex: %s", get_model_parameters_sex)); - if(get_model_parameters_weight) - get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nWeight: %g kg", get_model_parameters_weight)); - if(get_model_parameters_age) - get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nAge: %g", get_model_parameters_age)); -#endif - while(substring(get_model_parameters_desc, -1, 1) == "\n") - get_model_parameters_desc = substring(get_model_parameters_desc, 0, -2); - bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_DESC, get_model_parameters_desc); - } - buf_del(sortbuf); - get_model_parameters(string_null, 0); - me.loadCvars(me); // this will select the initial model, depending on the current cvars - me.go(me, 0); // this will set the vars for the selected model -} -void XonoticPlayerModelSelector_destroy(entity me) -{ - buf_del(me.bufModels); - me.bufModels = -1; -} - -void XonoticPlayerModelSelector_loadCvars(entity me) -{ - string skin, modelname; - float i; - - skin = cvar_string("_cl_playerskin"); - modelname = cvar_string("_cl_playermodel"); - - for(i = 0; i < me.numModels; ++i) - { - if(bufstr_get(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL) == modelname) - if(bufstr_get(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_SKIN) == skin) - break; - } - if(i >= me.numModels) // fail - i = 0; - me.idxModels = i; -} - -void XonoticPlayerModelSelector_go(entity me, float d) -{ - me.idxModels = mod(me.idxModels + d + me.numModels, me.numModels); - - if(me.currentModel) - strunzone(me.currentModel); - if(me.currentModelTitle) - strunzone(me.currentModelTitle); - if(me.currentModelImage) - strunzone(me.currentModelImage); - if(me.currentModelDescription) - strunzone(me.currentModelDescription); - - // select model #i! - me.currentModelTitle = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_TITLE)); - me.currentModelImage = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_IMAGE)); - me.currentSkin = stof(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_SKIN)); - me.currentModel = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_MODEL)); - me.currentModelDescription = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_DESC)); - - // fix the image - if(draw_PictureSize(me.currentModelImage) == '0 0 0') - me.src = "nopreview_player"; - else - me.src = me.currentModelImage; - me.updateAspect(me); -} - -void PlayerModelSelector_Next_Click(entity btn, entity me) -{ - if (me.numModels <= 0) - return; - me.go(me, +1); - me.saveCvars(me); -} - -void PlayerModelSelector_Prev_Click(entity btn, entity me) -{ - if (me.numModels <= 0) - return; - me.go(me, -1); - me.saveCvars(me); -} - -void XonoticPlayerModelSelector_saveCvars(entity me) -{ - // we can't immediately apply here because of flood control - cvar_set("_cl_playermodel", me.currentModel); - cvar_set("_cl_playerskin", ftos(me.currentSkin)); -} - -void XonoticPlayerModelSelector_draw(entity me) -{ - float i, n; - vector o; - - if (me.numModels <= 0) - { - draw_CenterText('0.5 0.5 0', _(""), me.realFontSize, SKINCOLOR_TEXT, 0.6, FALSE); - return; - } - - SUPER(XonoticPlayerModelSelector).draw(me); - // draw text on the image, handle \n in the description - - draw_beginBoldFont(); - -#if XONVOTE186 // (nyov) lower name display looks better when there is no description text - draw_CenterText('0.5 0.8 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, FALSE); -#else - draw_CenterText('0.5 0 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, FALSE); -#endif - - draw_endBoldFont(); - - o = '0.5 1 0' - eY * me.realFontSize_y * ((n = tokenizebyseparator(me.currentModelDescription, "\n")) + 0.5); - for(i = 0; i < n; ++i) - { - draw_CenterText(o, argv(i), me.realFontSize, SKINCOLOR_TEXT, 1, FALSE); - o += eY * me.realFontSize_y; - } -} - -void XonoticPlayerModelSelector_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(XonoticPlayerModelSelector).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - me.realFontSize_y = me.fontSize / absSize_y; - me.realFontSize_x = me.fontSize / absSize_x; -} - -void XonoticPlayerModelSelector_showNotify(entity me) -{ - me.configureXonoticPlayerModelSelector(me); -} -#endif diff --git a/qcsrc/menu/xonotic/playermodel.qc b/qcsrc/menu/xonotic/playermodel.qc new file mode 100644 index 000000000..0a0d6f940 --- /dev/null +++ b/qcsrc/menu/xonotic/playermodel.qc @@ -0,0 +1,223 @@ +#ifdef INTERFACE +CLASS(XonoticPlayerModelSelector) EXTENDS(XonoticImage) + METHOD(XonoticPlayerModelSelector, configureXonoticPlayerModelSelector, void(entity)) + METHOD(XonoticPlayerModelSelector, loadCvars, void(entity)) + METHOD(XonoticPlayerModelSelector, saveCvars, void(entity)) + METHOD(XonoticPlayerModelSelector, draw, void(entity)) + METHOD(XonoticPlayerModelSelector, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticPlayerModelSelector, showNotify, void(entity)) + ATTRIB(XonoticPlayerModelSelector, currentModel, string, string_null) + ATTRIB(XonoticPlayerModelSelector, currentSkin, float, 0) + ATTRIB(XonoticPlayerModelSelector, currentModelImage, string, string_null) + ATTRIB(XonoticPlayerModelSelector, currentModelTitle, string, string_null) + ATTRIB(XonoticPlayerModelSelector, currentModelDescription, string, string_null) + METHOD(XonoticPlayerModelSelector, go, void(entity, float)) + METHOD(XonoticPlayerModelSelector, destroy, void(entity)) + ATTRIB(XonoticPlayerModelSelector, origin, vector, '0 0 0') + ATTRIB(XonoticPlayerModelSelector, size, vector, '0 0 0') + ATTRIB(XonoticPlayerModelSelector, realFontSize, vector, '0 0 0') + ATTRIB(XonoticPlayerModelSelector, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticPlayerModelSelector, titleFontSize, float, SKINFONTSIZE_TITLE) + ATTRIB(XonoticPlayerModelSelector, bufModels, float, -1) + ATTRIB(XonoticPlayerModelSelector, numModels, float, -1) + ATTRIB(XonoticPlayerModelSelector, idxModels, float, -1) +ENDCLASS(XonoticPlayerModelSelector) +entity makeXonoticPlayerModelSelector(); +void PlayerModelSelector_Next_Click(entity btn, entity me); +void PlayerModelSelector_Prev_Click(entity btn, entity me); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticPlayerModelSelector() +{ + entity me; + me = spawnXonoticPlayerModelSelector(); + me.configureXonoticPlayerModelSelector(me); + return me; +} + +const float BUFMODELS_TITLE = 0; +const float BUFMODELS_IMAGE = 1; +const float BUFMODELS_MODEL = 2; +const float BUFMODELS_SKIN = 3; +const float BUFMODELS_DESC = 4; +const float BUFMODELS_COUNT = 5; + +#define XONVOTE186 1 // (nyov) removal of model text description + +void XonoticPlayerModelSelector_configureXonoticPlayerModelSelector(entity me) +{ + float sortbuf, glob, i; + string fn; + + glob = search_begin(language_filename(get_model_datafilename(string_null, -1, "txt")), TRUE, TRUE); + if (glob < 0) + return; + + me.configureXonoticImage(me, string_null, -1); + + sortbuf = buf_create(); + for(i = 0; i < search_getsize(glob); ++i) + { + // select model #i! + fn = search_getfilename(glob, i); + if(!get_model_parameters(fn, -1)) + continue; + bufstr_add(sortbuf, sprintf("%-128s%s", get_model_parameters_name, fn), 1); + } + search_end(glob); + buf_sort(sortbuf, 128, 0); + me.numModels = buf_getsize(sortbuf); + me.bufModels = buf_create(); + for(i = 0; i < me.numModels; ++i) + { + fn = substring(bufstr_get(sortbuf, i), 128, -1); + if(!get_model_parameters(fn, -1)) + error("But it JUST worked!"); + bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_TITLE, get_model_parameters_name); + bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_IMAGE, strcat("/", substring(get_model_datafilename(get_model_parameters_modelname, get_model_parameters_modelskin, "tga"), 0, -5))); + bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL, get_model_parameters_modelname); + bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_SKIN, ftos(get_model_parameters_modelskin)); + get_model_parameters_desc = strcat(get_model_parameters_desc, "\n"); +#if XONVOTE186 + if(get_model_parameters_sex) + get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s", get_model_parameters_sex)); +#else + if(get_model_parameters_description) + get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s\n", get_model_parameters_description)); + if(get_model_parameters_sex) + get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nSex: %s", get_model_parameters_sex)); + if(get_model_parameters_weight) + get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nWeight: %g kg", get_model_parameters_weight)); + if(get_model_parameters_age) + get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nAge: %g", get_model_parameters_age)); +#endif + while(substring(get_model_parameters_desc, -1, 1) == "\n") + get_model_parameters_desc = substring(get_model_parameters_desc, 0, -2); + bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_DESC, get_model_parameters_desc); + } + buf_del(sortbuf); + get_model_parameters(string_null, 0); + me.loadCvars(me); // this will select the initial model, depending on the current cvars + me.go(me, 0); // this will set the vars for the selected model +} +void XonoticPlayerModelSelector_destroy(entity me) +{ + buf_del(me.bufModels); + me.bufModels = -1; +} + +void XonoticPlayerModelSelector_loadCvars(entity me) +{ + string skin, modelname; + float i; + + skin = cvar_string("_cl_playerskin"); + modelname = cvar_string("_cl_playermodel"); + + for(i = 0; i < me.numModels; ++i) + { + if(bufstr_get(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL) == modelname) + if(bufstr_get(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_SKIN) == skin) + break; + } + if(i >= me.numModels) // fail + i = 0; + me.idxModels = i; +} + +void XonoticPlayerModelSelector_go(entity me, float d) +{ + me.idxModels = mod(me.idxModels + d + me.numModels, me.numModels); + + if(me.currentModel) + strunzone(me.currentModel); + if(me.currentModelTitle) + strunzone(me.currentModelTitle); + if(me.currentModelImage) + strunzone(me.currentModelImage); + if(me.currentModelDescription) + strunzone(me.currentModelDescription); + + // select model #i! + me.currentModelTitle = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_TITLE)); + me.currentModelImage = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_IMAGE)); + me.currentSkin = stof(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_SKIN)); + me.currentModel = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_MODEL)); + me.currentModelDescription = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_DESC)); + + // fix the image + if(draw_PictureSize(me.currentModelImage) == '0 0 0') + me.src = "nopreview_player"; + else + me.src = me.currentModelImage; + me.updateAspect(me); +} + +void PlayerModelSelector_Next_Click(entity btn, entity me) +{ + if (me.numModels <= 0) + return; + me.go(me, +1); + me.saveCvars(me); +} + +void PlayerModelSelector_Prev_Click(entity btn, entity me) +{ + if (me.numModels <= 0) + return; + me.go(me, -1); + me.saveCvars(me); +} + +void XonoticPlayerModelSelector_saveCvars(entity me) +{ + // we can't immediately apply here because of flood control + cvar_set("_cl_playermodel", me.currentModel); + cvar_set("_cl_playerskin", ftos(me.currentSkin)); +} + +void XonoticPlayerModelSelector_draw(entity me) +{ + float i, n; + vector o; + + if (me.numModels <= 0) + { + draw_CenterText('0.5 0.5 0', _(""), me.realFontSize, SKINCOLOR_TEXT, 0.6, FALSE); + return; + } + + SUPER(XonoticPlayerModelSelector).draw(me); + // draw text on the image, handle \n in the description + + draw_beginBoldFont(); + +#if XONVOTE186 // (nyov) lower name display looks better when there is no description text + draw_CenterText('0.5 0.8 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, FALSE); +#else + draw_CenterText('0.5 0 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, FALSE); +#endif + + draw_endBoldFont(); + + o = '0.5 1 0' - eY * me.realFontSize_y * ((n = tokenizebyseparator(me.currentModelDescription, "\n")) + 0.5); + for(i = 0; i < n; ++i) + { + draw_CenterText(o, argv(i), me.realFontSize, SKINCOLOR_TEXT, 1, FALSE); + o += eY * me.realFontSize_y; + } +} + +void XonoticPlayerModelSelector_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(XonoticPlayerModelSelector).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + me.realFontSize_y = me.fontSize / absSize_y; + me.realFontSize_x = me.fontSize / absSize_x; +} + +void XonoticPlayerModelSelector_showNotify(entity me) +{ + me.configureXonoticPlayerModelSelector(me); +} +#endif diff --git a/qcsrc/menu/xonotic/playlist.c b/qcsrc/menu/xonotic/playlist.c deleted file mode 100644 index e918adacd..000000000 --- a/qcsrc/menu/xonotic/playlist.c +++ /dev/null @@ -1,302 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticPlayList) EXTENDS(XonoticListBox) - METHOD(XonoticPlayList, configureXonoticPlayList, void(entity)) - ATTRIB(XonoticPlayList, rowsPerItem, float, 1) - METHOD(XonoticPlayList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticPlayList, draw, void(entity)) - METHOD(XonoticPlayList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticPlayList, stopSound, void(entity)) - METHOD(XonoticPlayList, startSound, void(entity, float)) - METHOD(XonoticPlayList, resumeSound, void(entity)) - METHOD(XonoticPlayList, pauseSound, void(entity)) - METHOD(XonoticPlayList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticPlayList, keyDown, float(entity, float, float, float)) - METHOD(XonoticPlayList, mouseDrag, float(entity, vector)) - - METHOD(XonoticPlayList, addToPlayList, void(entity, string)) - METHOD(XonoticPlayList, removeSelectedFromPlayList, void(entity)) - ATTRIB(XonoticPlayList, playingTrack, float, -1) - - ATTRIB(XonoticPlayList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticPlayList, columnNameOrigin, float, 0) - ATTRIB(XonoticPlayList, columnNameSize, float, 0) - ATTRIB(XonoticPlayList, columnNumberOrigin, float, 0) - ATTRIB(XonoticPlayList, columnNumberSize, float, 0) - ATTRIB(XonoticPlayList, realUpperMargin, float, 0) - ATTRIB(XonoticPlayList, origin, vector, '0 0 0') - ATTRIB(XonoticPlayList, itemAbsSize, vector, '0 0 0') -ENDCLASS(XonoticPlayList) - -entity makeXonoticPlayList(); -void PlayList_Remove(entity btn, entity me); -void PlayList_Remove_All(entity btn, entity me); -void StopSound_Click(entity btn, entity me); -void StartSound_Click(entity btn, entity me); -void PauseSound_Click(entity btn, entity me); -void PrevSound_Click(entity btn, entity me); -void NextSound_Click(entity btn, entity me); -#endif - -#ifdef IMPLEMENTATION - -entity makeXonoticPlayList() -{ - entity me; - me = spawnXonoticPlayList(); - me.configureXonoticPlayList(me); - return me; -} - -void XonoticPlayList_configureXonoticPlayList(entity me) -{ - me.nItems = tokenize_console(cvar_string("music_playlist_list0")); - me.configureXonoticListBox(me); -} - -void XonoticPlayList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticPlayList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - - me.columnNumberOrigin = 0; - me.columnNumberSize = 3 * me.realFontSize_x; - - me.columnNameOrigin = me.columnNumberSize + me.realFontSize_x; - me.columnNameSize = 1 - me.columnNameOrigin - me.realFontSize_x; -} - -void XonoticPlayList_addToPlayList(entity me, string track) -{ - me.nItems = tokenize_console(cvar_string("music_playlist_list0")); - if(me.nItems == 0) - { - cvar_set("music_playlist_list0", track); - return; - } - float i; - for(i = 0; i < me.nItems; ++i) - { - if(argv(i) == track) - return; // track is already in playlist - } - cvar_set("music_playlist_list0", strcat(cvar_string("music_playlist_list0"), " ", track)); -} - -void XonoticPlayList_removeSelectedFromPlayList(entity me) -{ - float i, cpt = FALSE; - string s = ""; - me.nItems = tokenize_console(cvar_string("music_playlist_list0")); - if(me.nItems == 0) - return; - for(i = 0; i < me.nItems; ++i) - { - if(i == me.selectedItem) - { - if(i == me.nItems - 1) - me.setSelected(me, me.selectedItem - 1); - if(cvar("music_playlist_index") == 0 || cvar("music_playlist_index") == 999) - { - if(cvar("music_playlist_current0") == i) - cpt = TRUE; // current playing track (we can't start next track here because startSound calls tokenize_console) - else if(cvar("music_playlist_current0") > i) - cvar_set("music_playlist_current0", ftos(cvar("music_playlist_current0") - 1)); - } - continue; - } - s = strcat(s, " ", argv(i)); - } - // we must stop the current playing track if it has been removed - // otherwise pause/play button will resume from another track - if(s == "") - { - cvar_set("music_playlist_list0", ""); - if(cpt) - me.stopSound(me); - } - else - { - cvar_set("music_playlist_list0", substring(s, 1, strlen(s))); // remove initial space - if(cpt) - me.startSound(me, 0); - } -} - -void PlayList_Remove(entity btn, entity me) -{ - me.removeSelectedFromPlayList(me); -} - -void PlayList_Remove_All(entity btn, entity me) -{ - cvar_set("music_playlist_list0", ""); - me.stopSound(me); - me.selectedItem = 0; -} - -float XonoticPlayList_mouseDrag(entity me, vector pos) -{ - float f, i; - i = me.selectedItem; - f = SUPER(XonoticPlayList).mouseDrag(me, pos); - - if(me.pressed != 1) // don't change priority if the person is just scrolling - { - if(me.selectedItem != i) - { - cvar_set("music_playlist_list0", swapInPriorityList(cvar_string("music_playlist_list0"), me.selectedItem, i)); - float c = cvar("music_playlist_current0"); - if(c == i) - cvar_set("music_playlist_current0", ftos(me.selectedItem)); - else if(c == me.selectedItem) - cvar_set("music_playlist_current0", ftos(i)); - } - } - - return f; -} - -void XonoticPlayList_draw(entity me) -{ - me.nItems = tokenize_console(cvar_string("music_playlist_list0")); - if(cvar("music_playlist_index") == 0 || cvar("music_playlist_index") == 999) - me.playingTrack = cvar("music_playlist_current0"); - else - me.playingTrack = -1; - SUPER(XonoticPlayList).draw(me); -} - -void XonoticPlayList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s; - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - if(i == me.playingTrack) - { - float f = cvar("music_playlist_sampleposition0"); - if(f <= 0 || (((time * 2) & 1) && f > 0)) - draw_Text(me.realUpperMargin * eY + (me.columnNumberOrigin + me.columnNumberSize) * eX, "\xE2\x96\xB6", me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); - } - - s = ftos(i+1); - draw_CenterText(me.realUpperMargin * eY + (me.columnNumberOrigin + 0.5 * me.columnNumberSize) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); - - s = draw_TextShortenToWidth(argv(i), me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); -} - -void XonoticPlayList_stopSound(entity me) -{ - // STOP: list 0 is disabled by setting the index to -1 - // we set sampleposition0 to 0 to forget the position that the engine saves in this frame (for this reason we need to wait a frame) - if(cvar("music_playlist_index") == 0 || cvar("music_playlist_index") == 999) - { - cvar_set("music_playlist_index", "-1"); - localcmd("\nwait; music_playlist_sampleposition0 0\n"); - localcmd("\ndefer 3 \"cd play $menu_cdtrack\"\n"); - } -} - -void StopSound_Click(entity btn, entity me) -{ - me.stopSound(me); -} - -void XonoticPlayList_startSound(entity me, float offset) -{ - float f; - me.nItems = tokenize_console(cvar_string("music_playlist_list0")); - if(offset) - { - if(cvar("music_playlist_index") == -1) - return; - f = bound(0, cvar("music_playlist_current0") + offset, me.nItems - 1); - if(f == cvar("music_playlist_current0")) - return; - } - else - { - f = me.selectedItem; - // if it was paused then resume - if(f == cvar("music_playlist_current0")) - if(cvar("music_playlist_index") == 999) - { - me.resumeSound(me); - return; - } - // if it was not paused then proceed with restart - } - - // START: list 0 is disabled by setting the index to 999 - // we set current0 to the selected track and sampleposition0 to 0 to forget the position that the engine saves in this frame (for this reason we need to wait a frame) - // then we switch back to list 0 - cvar_set("music_playlist_index", "999"); - cvar_set("music_playlist_current0", ftos(f)); - localcmd("\nwait; music_playlist_sampleposition0 0; wait; music_playlist_index 0\n"); -} - -void StartSound_Click(entity btn, entity me) -{ - me.startSound(me, 0); -} - -void PrevSound_Click(entity btn, entity me) -{ - me.startSound(me, -1); -} - -void NextSound_Click(entity btn, entity me) -{ - me.startSound(me, +1); -} - -void XonoticPlayList_resumeSound(entity me) -{ - // RESUME: list 0 is enabled by setting the index to 0 - // (we reset sampleposition0 to 0 to mark the track as in playing back state) - if(cvar("music_playlist_index") == 999) - localcmd("\nmusic_playlist_index 0; wait; music_playlist_sampleposition0 0\n"); -} -void XonoticPlayList_pauseSound(entity me) -{ - // PAUSE: list 0 is disabled by setting the index to 999 - // (we know the track is paused because the engine sets sampleposition0 to remember current position) - if(cvar("music_playlist_index") == 0) - localcmd("\nmusic_playlist_index 999\n"); - else me.resumeSound(me); -} - -void PauseSound_Click(entity btn, entity me) -{ - me.pauseSound(me); -} - -void XonoticPlayList_doubleClickListBoxItem(entity me, float i, vector where) -{ - me.startSound(me, 0); -} - -float XonoticPlayList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(scan == K_ENTER || scan == K_KP_ENTER) { - me.startSound(me, 0); - return 1; - } - else if(scan == K_SPACE) { - me.pauseSound(me); - return 1; - } - else if(scan == K_DEL || scan == K_KP_DEL || scan == K_BACKSPACE || scan == K_MOUSE3) { - me.removeSelectedFromPlayList(me); - return 1; - } - else - return SUPER(XonoticPlayList).keyDown(me, scan, ascii, shift); -} -#endif - diff --git a/qcsrc/menu/xonotic/playlist.qc b/qcsrc/menu/xonotic/playlist.qc new file mode 100644 index 000000000..e918adacd --- /dev/null +++ b/qcsrc/menu/xonotic/playlist.qc @@ -0,0 +1,302 @@ +#ifdef INTERFACE +CLASS(XonoticPlayList) EXTENDS(XonoticListBox) + METHOD(XonoticPlayList, configureXonoticPlayList, void(entity)) + ATTRIB(XonoticPlayList, rowsPerItem, float, 1) + METHOD(XonoticPlayList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticPlayList, draw, void(entity)) + METHOD(XonoticPlayList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticPlayList, stopSound, void(entity)) + METHOD(XonoticPlayList, startSound, void(entity, float)) + METHOD(XonoticPlayList, resumeSound, void(entity)) + METHOD(XonoticPlayList, pauseSound, void(entity)) + METHOD(XonoticPlayList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticPlayList, keyDown, float(entity, float, float, float)) + METHOD(XonoticPlayList, mouseDrag, float(entity, vector)) + + METHOD(XonoticPlayList, addToPlayList, void(entity, string)) + METHOD(XonoticPlayList, removeSelectedFromPlayList, void(entity)) + ATTRIB(XonoticPlayList, playingTrack, float, -1) + + ATTRIB(XonoticPlayList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticPlayList, columnNameOrigin, float, 0) + ATTRIB(XonoticPlayList, columnNameSize, float, 0) + ATTRIB(XonoticPlayList, columnNumberOrigin, float, 0) + ATTRIB(XonoticPlayList, columnNumberSize, float, 0) + ATTRIB(XonoticPlayList, realUpperMargin, float, 0) + ATTRIB(XonoticPlayList, origin, vector, '0 0 0') + ATTRIB(XonoticPlayList, itemAbsSize, vector, '0 0 0') +ENDCLASS(XonoticPlayList) + +entity makeXonoticPlayList(); +void PlayList_Remove(entity btn, entity me); +void PlayList_Remove_All(entity btn, entity me); +void StopSound_Click(entity btn, entity me); +void StartSound_Click(entity btn, entity me); +void PauseSound_Click(entity btn, entity me); +void PrevSound_Click(entity btn, entity me); +void NextSound_Click(entity btn, entity me); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticPlayList() +{ + entity me; + me = spawnXonoticPlayList(); + me.configureXonoticPlayList(me); + return me; +} + +void XonoticPlayList_configureXonoticPlayList(entity me) +{ + me.nItems = tokenize_console(cvar_string("music_playlist_list0")); + me.configureXonoticListBox(me); +} + +void XonoticPlayList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticPlayList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + + me.columnNumberOrigin = 0; + me.columnNumberSize = 3 * me.realFontSize_x; + + me.columnNameOrigin = me.columnNumberSize + me.realFontSize_x; + me.columnNameSize = 1 - me.columnNameOrigin - me.realFontSize_x; +} + +void XonoticPlayList_addToPlayList(entity me, string track) +{ + me.nItems = tokenize_console(cvar_string("music_playlist_list0")); + if(me.nItems == 0) + { + cvar_set("music_playlist_list0", track); + return; + } + float i; + for(i = 0; i < me.nItems; ++i) + { + if(argv(i) == track) + return; // track is already in playlist + } + cvar_set("music_playlist_list0", strcat(cvar_string("music_playlist_list0"), " ", track)); +} + +void XonoticPlayList_removeSelectedFromPlayList(entity me) +{ + float i, cpt = FALSE; + string s = ""; + me.nItems = tokenize_console(cvar_string("music_playlist_list0")); + if(me.nItems == 0) + return; + for(i = 0; i < me.nItems; ++i) + { + if(i == me.selectedItem) + { + if(i == me.nItems - 1) + me.setSelected(me, me.selectedItem - 1); + if(cvar("music_playlist_index") == 0 || cvar("music_playlist_index") == 999) + { + if(cvar("music_playlist_current0") == i) + cpt = TRUE; // current playing track (we can't start next track here because startSound calls tokenize_console) + else if(cvar("music_playlist_current0") > i) + cvar_set("music_playlist_current0", ftos(cvar("music_playlist_current0") - 1)); + } + continue; + } + s = strcat(s, " ", argv(i)); + } + // we must stop the current playing track if it has been removed + // otherwise pause/play button will resume from another track + if(s == "") + { + cvar_set("music_playlist_list0", ""); + if(cpt) + me.stopSound(me); + } + else + { + cvar_set("music_playlist_list0", substring(s, 1, strlen(s))); // remove initial space + if(cpt) + me.startSound(me, 0); + } +} + +void PlayList_Remove(entity btn, entity me) +{ + me.removeSelectedFromPlayList(me); +} + +void PlayList_Remove_All(entity btn, entity me) +{ + cvar_set("music_playlist_list0", ""); + me.stopSound(me); + me.selectedItem = 0; +} + +float XonoticPlayList_mouseDrag(entity me, vector pos) +{ + float f, i; + i = me.selectedItem; + f = SUPER(XonoticPlayList).mouseDrag(me, pos); + + if(me.pressed != 1) // don't change priority if the person is just scrolling + { + if(me.selectedItem != i) + { + cvar_set("music_playlist_list0", swapInPriorityList(cvar_string("music_playlist_list0"), me.selectedItem, i)); + float c = cvar("music_playlist_current0"); + if(c == i) + cvar_set("music_playlist_current0", ftos(me.selectedItem)); + else if(c == me.selectedItem) + cvar_set("music_playlist_current0", ftos(i)); + } + } + + return f; +} + +void XonoticPlayList_draw(entity me) +{ + me.nItems = tokenize_console(cvar_string("music_playlist_list0")); + if(cvar("music_playlist_index") == 0 || cvar("music_playlist_index") == 999) + me.playingTrack = cvar("music_playlist_current0"); + else + me.playingTrack = -1; + SUPER(XonoticPlayList).draw(me); +} + +void XonoticPlayList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s; + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + if(i == me.playingTrack) + { + float f = cvar("music_playlist_sampleposition0"); + if(f <= 0 || (((time * 2) & 1) && f > 0)) + draw_Text(me.realUpperMargin * eY + (me.columnNumberOrigin + me.columnNumberSize) * eX, "\xE2\x96\xB6", me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); + } + + s = ftos(i+1); + draw_CenterText(me.realUpperMargin * eY + (me.columnNumberOrigin + 0.5 * me.columnNumberSize) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); + + s = draw_TextShortenToWidth(argv(i), me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); +} + +void XonoticPlayList_stopSound(entity me) +{ + // STOP: list 0 is disabled by setting the index to -1 + // we set sampleposition0 to 0 to forget the position that the engine saves in this frame (for this reason we need to wait a frame) + if(cvar("music_playlist_index") == 0 || cvar("music_playlist_index") == 999) + { + cvar_set("music_playlist_index", "-1"); + localcmd("\nwait; music_playlist_sampleposition0 0\n"); + localcmd("\ndefer 3 \"cd play $menu_cdtrack\"\n"); + } +} + +void StopSound_Click(entity btn, entity me) +{ + me.stopSound(me); +} + +void XonoticPlayList_startSound(entity me, float offset) +{ + float f; + me.nItems = tokenize_console(cvar_string("music_playlist_list0")); + if(offset) + { + if(cvar("music_playlist_index") == -1) + return; + f = bound(0, cvar("music_playlist_current0") + offset, me.nItems - 1); + if(f == cvar("music_playlist_current0")) + return; + } + else + { + f = me.selectedItem; + // if it was paused then resume + if(f == cvar("music_playlist_current0")) + if(cvar("music_playlist_index") == 999) + { + me.resumeSound(me); + return; + } + // if it was not paused then proceed with restart + } + + // START: list 0 is disabled by setting the index to 999 + // we set current0 to the selected track and sampleposition0 to 0 to forget the position that the engine saves in this frame (for this reason we need to wait a frame) + // then we switch back to list 0 + cvar_set("music_playlist_index", "999"); + cvar_set("music_playlist_current0", ftos(f)); + localcmd("\nwait; music_playlist_sampleposition0 0; wait; music_playlist_index 0\n"); +} + +void StartSound_Click(entity btn, entity me) +{ + me.startSound(me, 0); +} + +void PrevSound_Click(entity btn, entity me) +{ + me.startSound(me, -1); +} + +void NextSound_Click(entity btn, entity me) +{ + me.startSound(me, +1); +} + +void XonoticPlayList_resumeSound(entity me) +{ + // RESUME: list 0 is enabled by setting the index to 0 + // (we reset sampleposition0 to 0 to mark the track as in playing back state) + if(cvar("music_playlist_index") == 999) + localcmd("\nmusic_playlist_index 0; wait; music_playlist_sampleposition0 0\n"); +} +void XonoticPlayList_pauseSound(entity me) +{ + // PAUSE: list 0 is disabled by setting the index to 999 + // (we know the track is paused because the engine sets sampleposition0 to remember current position) + if(cvar("music_playlist_index") == 0) + localcmd("\nmusic_playlist_index 999\n"); + else me.resumeSound(me); +} + +void PauseSound_Click(entity btn, entity me) +{ + me.pauseSound(me); +} + +void XonoticPlayList_doubleClickListBoxItem(entity me, float i, vector where) +{ + me.startSound(me, 0); +} + +float XonoticPlayList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_KP_ENTER) { + me.startSound(me, 0); + return 1; + } + else if(scan == K_SPACE) { + me.pauseSound(me); + return 1; + } + else if(scan == K_DEL || scan == K_KP_DEL || scan == K_BACKSPACE || scan == K_MOUSE3) { + me.removeSelectedFromPlayList(me); + return 1; + } + else + return SUPER(XonoticPlayList).keyDown(me, scan, ascii, shift); +} +#endif + diff --git a/qcsrc/menu/xonotic/radiobutton.c b/qcsrc/menu/xonotic/radiobutton.c deleted file mode 100644 index 85cc4fc5c..000000000 --- a/qcsrc/menu/xonotic/radiobutton.c +++ /dev/null @@ -1,120 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticRadioButton) EXTENDS(RadioButton) - METHOD(XonoticRadioButton, configureXonoticRadioButton, void(entity, float, string, string, string)) - METHOD(XonoticRadioButton, draw, void(entity)) - METHOD(XonoticRadioButton, setChecked, void(entity, float)) - ATTRIB(XonoticRadioButton, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticRadioButton, image, string, SKINGFX_RADIOBUTTON) - ATTRIB(XonoticRadioButton, color, vector, SKINCOLOR_RADIOBUTTON_N) - ATTRIB(XonoticRadioButton, colorC, vector, SKINCOLOR_RADIOBUTTON_C) - ATTRIB(XonoticRadioButton, colorF, vector, SKINCOLOR_RADIOBUTTON_F) - ATTRIB(XonoticRadioButton, colorD, vector, SKINCOLOR_RADIOBUTTON_D) - - ATTRIB(XonoticRadioButton, cvarName, string, string_null) - ATTRIB(XonoticRadioButton, cvarValue, string, string_null) - ATTRIB(XonoticRadioButton, cvarOffValue, string, string_null) - ATTRIB(XonoticRadioButton, getCvarValueFromCvar, float, 0) - METHOD(XonoticRadioButton, loadCvars, void(entity)) - METHOD(XonoticRadioButton, saveCvars, void(entity)) - - ATTRIB(XonoticRadioButton, alpha, float, SKINALPHA_TEXT) - ATTRIB(XonoticRadioButton, disabledAlpha, float, SKINALPHA_DISABLED) -ENDCLASS(XonoticRadioButton) -entity makeXonoticRadioButton(float, string, string, string); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticRadioButton(float theGroup, string theCvar, string theValue, string theText) -{ - entity me; - me = spawnXonoticRadioButton(); - me.configureXonoticRadioButton(me, theGroup, theCvar, theValue, theText); - return me; -} -void XonoticRadioButton_configureXonoticRadioButton(entity me, float theGroup, string theCvar, string theValue, string theText) -{ - if(theCvar) - { - me.cvarName = theCvar; - me.cvarValue = theValue; - me.tooltip = getZonedTooltipForIdentifier(theCvar); - me.loadCvars(me); - } - me.configureRadioButton(me, theText, me.fontSize, me.image, theGroup, 0); -} -void XonoticRadioButton_setChecked(entity me, float val) -{ - if(val != me.checked) - { - me.checked = val; - me.saveCvars(me); - } -} -void XonoticRadioButton_loadCvars(entity me) -{ - if(me.cvarValue) - { - if(me.cvarName) - me.checked = (cvar_string(me.cvarName) == me.cvarValue); - } - else - { - if(me.cvarName) - { - me.checked = !!cvar(me.cvarName); - } - else - { - // this is difficult - // this is the "generic" selection... but at this time, not - // everything is constructed yet. - // we need to set this later in draw() - me.checked = 0; - } - } -} -void XonoticRadioButton_draw(entity me) -{ - if (!me.cvarValue) - if (!me.cvarName) - { - // this is the "other" option - // always select this if none other is - entity e; - float found; - found = 0; - for(e = me.parent.firstChild; e; e = e.nextSibling) - if(e.group == me.group) - if(e.checked) - found = 1; - if(!found) - me.setChecked(me, 1); - } - SUPER(XonoticRadioButton).draw(me); -} -void XonoticRadioButton_saveCvars(entity me) -{ - if(me.cvarValue) - { - if(me.cvarName) - { - if(me.checked) - { - if(me.getCvarValueFromCvar) - cvar_set(me.cvarName, cvar_string(me.cvarValue)); - else - cvar_set(me.cvarName, me.cvarValue); - } - else if(me.cvarOffValue) - cvar_set(me.cvarName, me.cvarOffValue); - } - } - else - { - if(me.cvarName) - { - cvar_set(me.cvarName, ftos(me.checked)); - } - } -} -#endif diff --git a/qcsrc/menu/xonotic/radiobutton.qc b/qcsrc/menu/xonotic/radiobutton.qc new file mode 100644 index 000000000..85cc4fc5c --- /dev/null +++ b/qcsrc/menu/xonotic/radiobutton.qc @@ -0,0 +1,120 @@ +#ifdef INTERFACE +CLASS(XonoticRadioButton) EXTENDS(RadioButton) + METHOD(XonoticRadioButton, configureXonoticRadioButton, void(entity, float, string, string, string)) + METHOD(XonoticRadioButton, draw, void(entity)) + METHOD(XonoticRadioButton, setChecked, void(entity, float)) + ATTRIB(XonoticRadioButton, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticRadioButton, image, string, SKINGFX_RADIOBUTTON) + ATTRIB(XonoticRadioButton, color, vector, SKINCOLOR_RADIOBUTTON_N) + ATTRIB(XonoticRadioButton, colorC, vector, SKINCOLOR_RADIOBUTTON_C) + ATTRIB(XonoticRadioButton, colorF, vector, SKINCOLOR_RADIOBUTTON_F) + ATTRIB(XonoticRadioButton, colorD, vector, SKINCOLOR_RADIOBUTTON_D) + + ATTRIB(XonoticRadioButton, cvarName, string, string_null) + ATTRIB(XonoticRadioButton, cvarValue, string, string_null) + ATTRIB(XonoticRadioButton, cvarOffValue, string, string_null) + ATTRIB(XonoticRadioButton, getCvarValueFromCvar, float, 0) + METHOD(XonoticRadioButton, loadCvars, void(entity)) + METHOD(XonoticRadioButton, saveCvars, void(entity)) + + ATTRIB(XonoticRadioButton, alpha, float, SKINALPHA_TEXT) + ATTRIB(XonoticRadioButton, disabledAlpha, float, SKINALPHA_DISABLED) +ENDCLASS(XonoticRadioButton) +entity makeXonoticRadioButton(float, string, string, string); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticRadioButton(float theGroup, string theCvar, string theValue, string theText) +{ + entity me; + me = spawnXonoticRadioButton(); + me.configureXonoticRadioButton(me, theGroup, theCvar, theValue, theText); + return me; +} +void XonoticRadioButton_configureXonoticRadioButton(entity me, float theGroup, string theCvar, string theValue, string theText) +{ + if(theCvar) + { + me.cvarName = theCvar; + me.cvarValue = theValue; + me.tooltip = getZonedTooltipForIdentifier(theCvar); + me.loadCvars(me); + } + me.configureRadioButton(me, theText, me.fontSize, me.image, theGroup, 0); +} +void XonoticRadioButton_setChecked(entity me, float val) +{ + if(val != me.checked) + { + me.checked = val; + me.saveCvars(me); + } +} +void XonoticRadioButton_loadCvars(entity me) +{ + if(me.cvarValue) + { + if(me.cvarName) + me.checked = (cvar_string(me.cvarName) == me.cvarValue); + } + else + { + if(me.cvarName) + { + me.checked = !!cvar(me.cvarName); + } + else + { + // this is difficult + // this is the "generic" selection... but at this time, not + // everything is constructed yet. + // we need to set this later in draw() + me.checked = 0; + } + } +} +void XonoticRadioButton_draw(entity me) +{ + if (!me.cvarValue) + if (!me.cvarName) + { + // this is the "other" option + // always select this if none other is + entity e; + float found; + found = 0; + for(e = me.parent.firstChild; e; e = e.nextSibling) + if(e.group == me.group) + if(e.checked) + found = 1; + if(!found) + me.setChecked(me, 1); + } + SUPER(XonoticRadioButton).draw(me); +} +void XonoticRadioButton_saveCvars(entity me) +{ + if(me.cvarValue) + { + if(me.cvarName) + { + if(me.checked) + { + if(me.getCvarValueFromCvar) + cvar_set(me.cvarName, cvar_string(me.cvarValue)); + else + cvar_set(me.cvarName, me.cvarValue); + } + else if(me.cvarOffValue) + cvar_set(me.cvarName, me.cvarOffValue); + } + } + else + { + if(me.cvarName) + { + cvar_set(me.cvarName, ftos(me.checked)); + } + } +} +#endif diff --git a/qcsrc/menu/xonotic/rootdialog.c b/qcsrc/menu/xonotic/rootdialog.c deleted file mode 100644 index e8c9db364..000000000 --- a/qcsrc/menu/xonotic/rootdialog.c +++ /dev/null @@ -1,21 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticRootDialog) EXTENDS(XonoticDialog) - // still to be customized by user - /* - ATTRIB(XonoticDialog, closable, float, 1) - ATTRIB(XonoticDialog, title, string, _("Form1")) // ;) - ATTRIB(XonoticDialog, color, vector, '1 0.5 1') - ATTRIB(XonoticDialog, intendedWidth, float, 0) - ATTRIB(XonoticDialog, rows, float, 3) - ATTRIB(XonoticDialog, columns, float, 2) - */ - METHOD(XonoticRootDialog, close, void(entity)) -ENDCLASS(XonoticRootDialog) -#endif - -#ifdef IMPLEMENTATION -void XonoticRootDialog_close(entity me) -{ - m_goto(string_null); -} -#endif diff --git a/qcsrc/menu/xonotic/rootdialog.qc b/qcsrc/menu/xonotic/rootdialog.qc new file mode 100644 index 000000000..e8c9db364 --- /dev/null +++ b/qcsrc/menu/xonotic/rootdialog.qc @@ -0,0 +1,21 @@ +#ifdef INTERFACE +CLASS(XonoticRootDialog) EXTENDS(XonoticDialog) + // still to be customized by user + /* + ATTRIB(XonoticDialog, closable, float, 1) + ATTRIB(XonoticDialog, title, string, _("Form1")) // ;) + ATTRIB(XonoticDialog, color, vector, '1 0.5 1') + ATTRIB(XonoticDialog, intendedWidth, float, 0) + ATTRIB(XonoticDialog, rows, float, 3) + ATTRIB(XonoticDialog, columns, float, 2) + */ + METHOD(XonoticRootDialog, close, void(entity)) +ENDCLASS(XonoticRootDialog) +#endif + +#ifdef IMPLEMENTATION +void XonoticRootDialog_close(entity me) +{ + m_goto(string_null); +} +#endif diff --git a/qcsrc/menu/xonotic/screenshotimage.c b/qcsrc/menu/xonotic/screenshotimage.c deleted file mode 100644 index 469f177fc..000000000 --- a/qcsrc/menu/xonotic/screenshotimage.c +++ /dev/null @@ -1,95 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticScreenshotImage) EXTENDS(XonoticImage) - METHOD(XonoticScreenshotImage, configureXonoticScreenshotImage, void(entity)) - METHOD(XonoticScreenshotImage, load, void(entity, string)) - METHOD(XonoticScreenshotImage, draw, void(entity)) - ATTRIB(XonoticScreenshotImage, focusable, float, 1) // mousePress and mouseDrag work only if focusable is set - METHOD(XonoticScreenshotImage, mousePress, float(entity, vector)) - METHOD(XonoticScreenshotImage, mouseDrag, float(entity, vector)) - METHOD(XonoticScreenshotImage, mouseMove, float(entity, vector)) - METHOD(XonoticScreenshotImage, resizeNotify, void(entity, vector, vector, vector, vector)) - ATTRIB(XonoticScreenshotImage, realFontSize, vector, '0 0 0') - ATTRIB(XonoticScreenshotImage, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticScreenshotImage, showTitle, float, 1) - ATTRIB(XonoticScreenshotImage, screenshotTime, float, 0) - ATTRIB(XonoticScreenshotImage, screenshotTitle, string, string_null) -ENDCLASS(XonoticScreenshotImage) -entity makeXonoticScreenshotImage(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticScreenshotImage() -{ - entity me; - me = spawnXonoticScreenshotImage(); - me.configureXonoticScreenshotImage(me); - return me; -} - -void XonoticScreenshotImage_configureXonoticScreenshotImage(entity me) -{ - me.configureXonoticImage(me, string_null, -2); - me.zoomLimitedByTheBox = FALSE; // enable this to forbid enlarging the image more than the containing box (if making use of draw_SetClip is a too bad thing) - me.zoomSnapToTheBox = FALSE; // disabled: it's cooler -} - -void XonoticScreenshotImage_load(entity me, string theImage) -{ - me.screenshotTime = time; - me.src = theImage; - if (me.screenshotTitle) - strunzone(me.screenshotTitle); - me.screenshotTitle = strzone(substring(me.src, 13, strlen(theImage) - 13)); //strip "/screenshots/" - - me.initZoom(me); // this image may have a different size - me.setZoom(me, 0, 0); -} - -float XonoticScreenshotImage_mousePress(entity me, vector coords) -{ - return me.drag_setStartPos(me, coords); -} - -float XonoticScreenshotImage_mouseDrag(entity me, vector coords) -{ - return me.drag(me, coords); -} - -float XonoticScreenshotImage_mouseMove(entity me, vector coords) -{ - return me.drag_setStartPos(me, coords); -} - -void XonoticScreenshotImage_draw(entity me) -{ - if (me.src != "") - { - float theAlpha; - SUPER(XonoticScreenshotImage).draw(me); - if (me.showTitle && time < me.screenshotTime + 4) // 3 seconds at full alpha, 1 second fading out - { - theAlpha = (4 - (time - me.screenshotTime)); - draw_CenterText('0.5 0 0', me.screenshotTitle, me.realFontSize, '1 1 1', theAlpha, FALSE); - } - if (time < me.zoomTime + 2) // 1 seconds at full alpha, 1 second fading out - { - string zoomString; - float z; - z = me.zoomFactor * 100; - if (z - floor(z) == 0) - zoomString = sprintf("%d%%", z); - else - zoomString = sprintf("%.2f%%", z); - theAlpha = (2 - (time - me.zoomTime)); - draw_Text('0.05 0.95 0', zoomString, me.realFontSize, '1 1 1', theAlpha, FALSE); - } - } -} - -void XonoticScreenshotImage_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(XonoticScreenshotImage).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - me.realFontSize_y = me.fontSize / absSize_y; - me.realFontSize_x = me.fontSize / absSize_x; -} -#endif diff --git a/qcsrc/menu/xonotic/screenshotimage.qc b/qcsrc/menu/xonotic/screenshotimage.qc new file mode 100644 index 000000000..469f177fc --- /dev/null +++ b/qcsrc/menu/xonotic/screenshotimage.qc @@ -0,0 +1,95 @@ +#ifdef INTERFACE +CLASS(XonoticScreenshotImage) EXTENDS(XonoticImage) + METHOD(XonoticScreenshotImage, configureXonoticScreenshotImage, void(entity)) + METHOD(XonoticScreenshotImage, load, void(entity, string)) + METHOD(XonoticScreenshotImage, draw, void(entity)) + ATTRIB(XonoticScreenshotImage, focusable, float, 1) // mousePress and mouseDrag work only if focusable is set + METHOD(XonoticScreenshotImage, mousePress, float(entity, vector)) + METHOD(XonoticScreenshotImage, mouseDrag, float(entity, vector)) + METHOD(XonoticScreenshotImage, mouseMove, float(entity, vector)) + METHOD(XonoticScreenshotImage, resizeNotify, void(entity, vector, vector, vector, vector)) + ATTRIB(XonoticScreenshotImage, realFontSize, vector, '0 0 0') + ATTRIB(XonoticScreenshotImage, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticScreenshotImage, showTitle, float, 1) + ATTRIB(XonoticScreenshotImage, screenshotTime, float, 0) + ATTRIB(XonoticScreenshotImage, screenshotTitle, string, string_null) +ENDCLASS(XonoticScreenshotImage) +entity makeXonoticScreenshotImage(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticScreenshotImage() +{ + entity me; + me = spawnXonoticScreenshotImage(); + me.configureXonoticScreenshotImage(me); + return me; +} + +void XonoticScreenshotImage_configureXonoticScreenshotImage(entity me) +{ + me.configureXonoticImage(me, string_null, -2); + me.zoomLimitedByTheBox = FALSE; // enable this to forbid enlarging the image more than the containing box (if making use of draw_SetClip is a too bad thing) + me.zoomSnapToTheBox = FALSE; // disabled: it's cooler +} + +void XonoticScreenshotImage_load(entity me, string theImage) +{ + me.screenshotTime = time; + me.src = theImage; + if (me.screenshotTitle) + strunzone(me.screenshotTitle); + me.screenshotTitle = strzone(substring(me.src, 13, strlen(theImage) - 13)); //strip "/screenshots/" + + me.initZoom(me); // this image may have a different size + me.setZoom(me, 0, 0); +} + +float XonoticScreenshotImage_mousePress(entity me, vector coords) +{ + return me.drag_setStartPos(me, coords); +} + +float XonoticScreenshotImage_mouseDrag(entity me, vector coords) +{ + return me.drag(me, coords); +} + +float XonoticScreenshotImage_mouseMove(entity me, vector coords) +{ + return me.drag_setStartPos(me, coords); +} + +void XonoticScreenshotImage_draw(entity me) +{ + if (me.src != "") + { + float theAlpha; + SUPER(XonoticScreenshotImage).draw(me); + if (me.showTitle && time < me.screenshotTime + 4) // 3 seconds at full alpha, 1 second fading out + { + theAlpha = (4 - (time - me.screenshotTime)); + draw_CenterText('0.5 0 0', me.screenshotTitle, me.realFontSize, '1 1 1', theAlpha, FALSE); + } + if (time < me.zoomTime + 2) // 1 seconds at full alpha, 1 second fading out + { + string zoomString; + float z; + z = me.zoomFactor * 100; + if (z - floor(z) == 0) + zoomString = sprintf("%d%%", z); + else + zoomString = sprintf("%.2f%%", z); + theAlpha = (2 - (time - me.zoomTime)); + draw_Text('0.05 0.95 0', zoomString, me.realFontSize, '1 1 1', theAlpha, FALSE); + } + } +} + +void XonoticScreenshotImage_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(XonoticScreenshotImage).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + me.realFontSize_y = me.fontSize / absSize_y; + me.realFontSize_x = me.fontSize / absSize_x; +} +#endif diff --git a/qcsrc/menu/xonotic/screenshotlist.c b/qcsrc/menu/xonotic/screenshotlist.c deleted file mode 100644 index c8f3becfa..000000000 --- a/qcsrc/menu/xonotic/screenshotlist.c +++ /dev/null @@ -1,296 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticScreenshotList) EXTENDS(XonoticListBox) - METHOD(XonoticScreenshotList, configureXonoticScreenshotList, void(entity)) - ATTRIB(XonoticScreenshotList, rowsPerItem, float, 1) - METHOD(XonoticScreenshotList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticScreenshotList, setSelected, void(entity, float)) - METHOD(XonoticScreenshotList, draw, void(entity)) - METHOD(XonoticScreenshotList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticScreenshotList, getScreenshots, void(entity)) - METHOD(XonoticScreenshotList, previewScreenshot, void(entity)) - METHOD(XonoticScreenshotList, startScreenshot, void(entity)) - METHOD(XonoticScreenshotList, screenshotName, string(entity, float)) - METHOD(XonoticScreenshotList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticScreenshotList, keyDown, float(entity, float, float, float)) - METHOD(XonoticScreenshotList, destroy, void(entity)) - METHOD(XonoticScreenshotList, showNotify, void(entity)) - ATTRIB(XonoticScreenshotList, listScreenshot, float, -1) - ATTRIB(XonoticScreenshotList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticScreenshotList, columnNameOrigin, float, 0) - ATTRIB(XonoticScreenshotList, columnNameSize, float, 0) - ATTRIB(XonoticScreenshotList, realUpperMargin, float, 0) - ATTRIB(XonoticScreenshotList, origin, vector, '0 0 0') - ATTRIB(XonoticScreenshotList, itemAbsSize, vector, '0 0 0') - ATTRIB(XonoticScreenshotList, filterString, string, string_null) - ATTRIB(XonoticScreenshotList, filterBox, entity, NULL) - ATTRIB(XonoticScreenshotList, filterTime, float, 0) - - ATTRIB(XonoticScreenshotList, newScreenshotTime, float, 0) - ATTRIB(XonoticScreenshotList, newSlideShowScreenshotTime, float, 0) - ATTRIB(XonoticScreenshotList, prevSelectedItem, float, 0) - - ATTRIB(XonoticScreenshotList, screenshotBrowserDialog, entity, NULL) - ATTRIB(XonoticScreenshotList, screenshotPreview, entity, NULL) - ATTRIB(XonoticScreenshotList, screenshotViewerDialog, entity, NULL) - METHOD(XonoticScreenshotList, goScreenshot, void(entity, float)) - METHOD(XonoticScreenshotList, startSlideShow, void(entity)) - METHOD(XonoticScreenshotList, stopSlideShow, void(entity)) -ENDCLASS(XonoticScreenshotList) - -entity makeXonoticScreenshotList(); -void StartScreenshot_Click(entity btn, entity me); -void ScreenshotList_Refresh_Click(entity btn, entity me); -void ScreenshotList_Filter_Would_Change(entity box, entity me); -void ScreenshotList_Filter_Change(entity box, entity me); -#endif - -#ifdef IMPLEMENTATION - -entity makeXonoticScreenshotList() -{ - entity me; - me = spawnXonoticScreenshotList(); - me.configureXonoticScreenshotList(me); - return me; -} - -void XonoticScreenshotList_configureXonoticScreenshotList(entity me) -{ - me.configureXonoticListBox(me); - me.getScreenshots(me); -} - -string XonoticScreenshotList_screenshotName(entity me, float i) -{ - string s; - s = bufstr_get(me.listScreenshot, i); - - if(substring(s, 0, 1) == "/") - s = substring(s, 1, strlen(s) - 1); // remove the first forward slash - - return s; -} - -// if subdir is TRUE look in subdirectories too (1 level) -void getScreenshots_for_ext(entity me, string ext, float subdir) -{ - string s; - if (subdir) - s="screenshots/*/"; - else - s="screenshots/"; - if(me.filterString) - s=strcat(s, me.filterString, ext); - else - s=strcat(s, "*", ext); - - float list, i, n; - list = search_begin(s, FALSE, TRUE); - if(list >= 0) - { - n = search_getsize(list); - for(i = 0; i < n; ++i) - { - s = search_getfilename(list, i); // get initial full file name - s = substring(s, 12, (strlen(s) - 12 - 4)); // remove "screenshots/" prefix and "." suffix - s = strdecolorize(s); // remove any pre-existing colors - if(subdir) - { - s = strreplace("/", "^7/", s); // clear colors at the forward slash - s = strcat("/", rgb_to_hexcolor(SKINCOLOR_SCREENSHOTLIST_SUBDIR), s); // add a forward slash for sorting, then color - bufstr_add(me.listScreenshot, s, TRUE); - } - else { bufstr_add(me.listScreenshot, s, TRUE); } - } - search_end(list); - } - - if (subdir) - getScreenshots_for_ext(me, ext, FALSE); -} - -void XonoticScreenshotList_getScreenshots(entity me) -{ - if (me.listScreenshot >= 0) - buf_del(me.listScreenshot); - me.listScreenshot = buf_create(); - if (me.listScreenshot < 0) - { - me.nItems = 0; - return; - } - getScreenshots_for_ext(me, ".jpg", TRUE); - getScreenshots_for_ext(me, ".tga", TRUE); - getScreenshots_for_ext(me, ".png", TRUE); - me.nItems = buf_getsize(me.listScreenshot); - if(me.nItems > 0) - buf_sort(me.listScreenshot, 128, FALSE); -} - -void XonoticScreenshotList_destroy(entity me) -{ - if(me.nItems > 0) - buf_del(me.listScreenshot); -} - -void XonoticScreenshotList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticScreenshotList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - - me.columnNameOrigin = me.realFontSize_x; - me.columnNameSize = 1 - 2 * me.realFontSize_x; -} - -void XonoticScreenshotList_setSelected(entity me, float i) -{ - if (me.newSlideShowScreenshotTime) - me.startSlideShow(me); - me.prevSelectedItem = me.selectedItem; - SUPER(XonoticScreenshotList).setSelected(me, i); - if (me.pressed && me.selectedItem != me.prevSelectedItem) - { - // while dragging the scrollbar (or an item) - // for a smooth mouse movement do not load immediately the new selected images - me.newScreenshotTime = time + 0.22; // dragging an item we need a delay > 0.2 (from listbox: me.dragScrollTimer = time + 0.2;) - } - else if (time > me.newScreenshotTime) - { - me.newScreenshotTime = 0; - me.previewScreenshot(me); // load the preview on selection change - } -} - -void XonoticScreenshotList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s; - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - s = me.screenshotName(me,i); - s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 1); -} - -void XonoticScreenshotList_showNotify(entity me) -{ - me.getScreenshots(me); - me.previewScreenshot(me); -} - -void ScreenshotList_Refresh_Click(entity btn, entity me) -{ - me.getScreenshots(me); - me.setSelected(me, 0); //always select the first element after a list update -} - -void ScreenshotList_Filter_Change(entity box, entity me) -{ - if(me.filterString) - strunzone(me.filterString); - - if(box.text != "") - { - if (strstrofs(box.text, "*", 0) >= 0 || strstrofs(box.text, "?", 0) >= 0) - me.filterString = strzone(box.text); - else - me.filterString = strzone(strcat("*", box.text, "*")); - } - else - me.filterString = string_null; - - ScreenshotList_Refresh_Click(world, me); -} - -void ScreenshotList_Filter_Would_Change(entity box, entity me) -{ - me.filterBox = box; - me.filterTime = time + 0.5; -} - -void XonoticScreenshotList_draw(entity me) -{ - if (me.filterTime && time > me.filterTime) - { - ScreenshotList_Filter_Change(me.filterBox, me); - me.filterTime = 0; - } - if (me.newScreenshotTime && time > me.newScreenshotTime) - { - me.previewScreenshot(me); - me.newScreenshotTime = 0; - } - else if (me.newSlideShowScreenshotTime && time > me.newSlideShowScreenshotTime) - { - if (me.selectedItem == me.nItems - 1) //last screenshot? - { - // restart from the first screenshot - me.setSelected(me, 0); - me.goScreenshot(me, +0); - } - else - me.goScreenshot(me, +1); - } - SUPER(XonoticScreenshotList).draw(me); -} - -void XonoticScreenshotList_startSlideShow(entity me) -{ - me.newSlideShowScreenshotTime = time + 3; -} - -void XonoticScreenshotList_stopSlideShow(entity me) -{ - me.newSlideShowScreenshotTime = 0; -} - -void XonoticScreenshotList_goScreenshot(entity me, float d) -{ - if(!me.screenshotViewerDialog) - return; - me.setSelected(me, me.selectedItem + d); - me.screenshotViewerDialog.loadScreenshot(me.screenshotViewerDialog, strcat("/screenshots/", strdecolorize(me.screenshotName(me,me.selectedItem)))); -} - -void XonoticScreenshotList_startScreenshot(entity me) -{ - me.screenshotViewerDialog.loadScreenshot(me.screenshotViewerDialog, strcat("/screenshots/", strdecolorize(me.screenshotName(me,me.selectedItem)))); - // pop up screenshot - DialogOpenButton_Click_withCoords(NULL, me.screenshotViewerDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * me.selectedItem - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize)); -} - -void XonoticScreenshotList_previewScreenshot(entity me) -{ - if(!me.screenshotBrowserDialog) - return; - if (me.nItems <= 0) - me.screenshotBrowserDialog.loadPreviewScreenshot(me.screenshotBrowserDialog, ""); - else - me.screenshotBrowserDialog.loadPreviewScreenshot(me.screenshotBrowserDialog, strcat("/screenshots/", strdecolorize(me.screenshotName(me,me.selectedItem)))); -} - -void StartScreenshot_Click(entity btn, entity me) -{ - me.startScreenshot(me); -} - -void XonoticScreenshotList_doubleClickListBoxItem(entity me, float i, vector where) -{ - me.startScreenshot(me); -} - -float XonoticScreenshotList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(scan == K_ENTER || scan == K_KP_ENTER || scan == K_MOUSE2 || scan == K_SPACE) { - me.startScreenshot(me); - return 1; - } - if(scan == K_MWHEELUP || scan == K_MWHEELDOWN) - me.newScreenshotTime = time + 0.2; - return SUPER(XonoticScreenshotList).keyDown(me, scan, ascii, shift); -} -#endif diff --git a/qcsrc/menu/xonotic/screenshotlist.qc b/qcsrc/menu/xonotic/screenshotlist.qc new file mode 100644 index 000000000..c8f3becfa --- /dev/null +++ b/qcsrc/menu/xonotic/screenshotlist.qc @@ -0,0 +1,296 @@ +#ifdef INTERFACE +CLASS(XonoticScreenshotList) EXTENDS(XonoticListBox) + METHOD(XonoticScreenshotList, configureXonoticScreenshotList, void(entity)) + ATTRIB(XonoticScreenshotList, rowsPerItem, float, 1) + METHOD(XonoticScreenshotList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticScreenshotList, setSelected, void(entity, float)) + METHOD(XonoticScreenshotList, draw, void(entity)) + METHOD(XonoticScreenshotList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticScreenshotList, getScreenshots, void(entity)) + METHOD(XonoticScreenshotList, previewScreenshot, void(entity)) + METHOD(XonoticScreenshotList, startScreenshot, void(entity)) + METHOD(XonoticScreenshotList, screenshotName, string(entity, float)) + METHOD(XonoticScreenshotList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticScreenshotList, keyDown, float(entity, float, float, float)) + METHOD(XonoticScreenshotList, destroy, void(entity)) + METHOD(XonoticScreenshotList, showNotify, void(entity)) + ATTRIB(XonoticScreenshotList, listScreenshot, float, -1) + ATTRIB(XonoticScreenshotList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticScreenshotList, columnNameOrigin, float, 0) + ATTRIB(XonoticScreenshotList, columnNameSize, float, 0) + ATTRIB(XonoticScreenshotList, realUpperMargin, float, 0) + ATTRIB(XonoticScreenshotList, origin, vector, '0 0 0') + ATTRIB(XonoticScreenshotList, itemAbsSize, vector, '0 0 0') + ATTRIB(XonoticScreenshotList, filterString, string, string_null) + ATTRIB(XonoticScreenshotList, filterBox, entity, NULL) + ATTRIB(XonoticScreenshotList, filterTime, float, 0) + + ATTRIB(XonoticScreenshotList, newScreenshotTime, float, 0) + ATTRIB(XonoticScreenshotList, newSlideShowScreenshotTime, float, 0) + ATTRIB(XonoticScreenshotList, prevSelectedItem, float, 0) + + ATTRIB(XonoticScreenshotList, screenshotBrowserDialog, entity, NULL) + ATTRIB(XonoticScreenshotList, screenshotPreview, entity, NULL) + ATTRIB(XonoticScreenshotList, screenshotViewerDialog, entity, NULL) + METHOD(XonoticScreenshotList, goScreenshot, void(entity, float)) + METHOD(XonoticScreenshotList, startSlideShow, void(entity)) + METHOD(XonoticScreenshotList, stopSlideShow, void(entity)) +ENDCLASS(XonoticScreenshotList) + +entity makeXonoticScreenshotList(); +void StartScreenshot_Click(entity btn, entity me); +void ScreenshotList_Refresh_Click(entity btn, entity me); +void ScreenshotList_Filter_Would_Change(entity box, entity me); +void ScreenshotList_Filter_Change(entity box, entity me); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticScreenshotList() +{ + entity me; + me = spawnXonoticScreenshotList(); + me.configureXonoticScreenshotList(me); + return me; +} + +void XonoticScreenshotList_configureXonoticScreenshotList(entity me) +{ + me.configureXonoticListBox(me); + me.getScreenshots(me); +} + +string XonoticScreenshotList_screenshotName(entity me, float i) +{ + string s; + s = bufstr_get(me.listScreenshot, i); + + if(substring(s, 0, 1) == "/") + s = substring(s, 1, strlen(s) - 1); // remove the first forward slash + + return s; +} + +// if subdir is TRUE look in subdirectories too (1 level) +void getScreenshots_for_ext(entity me, string ext, float subdir) +{ + string s; + if (subdir) + s="screenshots/*/"; + else + s="screenshots/"; + if(me.filterString) + s=strcat(s, me.filterString, ext); + else + s=strcat(s, "*", ext); + + float list, i, n; + list = search_begin(s, FALSE, TRUE); + if(list >= 0) + { + n = search_getsize(list); + for(i = 0; i < n; ++i) + { + s = search_getfilename(list, i); // get initial full file name + s = substring(s, 12, (strlen(s) - 12 - 4)); // remove "screenshots/" prefix and "." suffix + s = strdecolorize(s); // remove any pre-existing colors + if(subdir) + { + s = strreplace("/", "^7/", s); // clear colors at the forward slash + s = strcat("/", rgb_to_hexcolor(SKINCOLOR_SCREENSHOTLIST_SUBDIR), s); // add a forward slash for sorting, then color + bufstr_add(me.listScreenshot, s, TRUE); + } + else { bufstr_add(me.listScreenshot, s, TRUE); } + } + search_end(list); + } + + if (subdir) + getScreenshots_for_ext(me, ext, FALSE); +} + +void XonoticScreenshotList_getScreenshots(entity me) +{ + if (me.listScreenshot >= 0) + buf_del(me.listScreenshot); + me.listScreenshot = buf_create(); + if (me.listScreenshot < 0) + { + me.nItems = 0; + return; + } + getScreenshots_for_ext(me, ".jpg", TRUE); + getScreenshots_for_ext(me, ".tga", TRUE); + getScreenshots_for_ext(me, ".png", TRUE); + me.nItems = buf_getsize(me.listScreenshot); + if(me.nItems > 0) + buf_sort(me.listScreenshot, 128, FALSE); +} + +void XonoticScreenshotList_destroy(entity me) +{ + if(me.nItems > 0) + buf_del(me.listScreenshot); +} + +void XonoticScreenshotList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticScreenshotList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + + me.columnNameOrigin = me.realFontSize_x; + me.columnNameSize = 1 - 2 * me.realFontSize_x; +} + +void XonoticScreenshotList_setSelected(entity me, float i) +{ + if (me.newSlideShowScreenshotTime) + me.startSlideShow(me); + me.prevSelectedItem = me.selectedItem; + SUPER(XonoticScreenshotList).setSelected(me, i); + if (me.pressed && me.selectedItem != me.prevSelectedItem) + { + // while dragging the scrollbar (or an item) + // for a smooth mouse movement do not load immediately the new selected images + me.newScreenshotTime = time + 0.22; // dragging an item we need a delay > 0.2 (from listbox: me.dragScrollTimer = time + 0.2;) + } + else if (time > me.newScreenshotTime) + { + me.newScreenshotTime = 0; + me.previewScreenshot(me); // load the preview on selection change + } +} + +void XonoticScreenshotList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s; + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + s = me.screenshotName(me,i); + s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 1); +} + +void XonoticScreenshotList_showNotify(entity me) +{ + me.getScreenshots(me); + me.previewScreenshot(me); +} + +void ScreenshotList_Refresh_Click(entity btn, entity me) +{ + me.getScreenshots(me); + me.setSelected(me, 0); //always select the first element after a list update +} + +void ScreenshotList_Filter_Change(entity box, entity me) +{ + if(me.filterString) + strunzone(me.filterString); + + if(box.text != "") + { + if (strstrofs(box.text, "*", 0) >= 0 || strstrofs(box.text, "?", 0) >= 0) + me.filterString = strzone(box.text); + else + me.filterString = strzone(strcat("*", box.text, "*")); + } + else + me.filterString = string_null; + + ScreenshotList_Refresh_Click(world, me); +} + +void ScreenshotList_Filter_Would_Change(entity box, entity me) +{ + me.filterBox = box; + me.filterTime = time + 0.5; +} + +void XonoticScreenshotList_draw(entity me) +{ + if (me.filterTime && time > me.filterTime) + { + ScreenshotList_Filter_Change(me.filterBox, me); + me.filterTime = 0; + } + if (me.newScreenshotTime && time > me.newScreenshotTime) + { + me.previewScreenshot(me); + me.newScreenshotTime = 0; + } + else if (me.newSlideShowScreenshotTime && time > me.newSlideShowScreenshotTime) + { + if (me.selectedItem == me.nItems - 1) //last screenshot? + { + // restart from the first screenshot + me.setSelected(me, 0); + me.goScreenshot(me, +0); + } + else + me.goScreenshot(me, +1); + } + SUPER(XonoticScreenshotList).draw(me); +} + +void XonoticScreenshotList_startSlideShow(entity me) +{ + me.newSlideShowScreenshotTime = time + 3; +} + +void XonoticScreenshotList_stopSlideShow(entity me) +{ + me.newSlideShowScreenshotTime = 0; +} + +void XonoticScreenshotList_goScreenshot(entity me, float d) +{ + if(!me.screenshotViewerDialog) + return; + me.setSelected(me, me.selectedItem + d); + me.screenshotViewerDialog.loadScreenshot(me.screenshotViewerDialog, strcat("/screenshots/", strdecolorize(me.screenshotName(me,me.selectedItem)))); +} + +void XonoticScreenshotList_startScreenshot(entity me) +{ + me.screenshotViewerDialog.loadScreenshot(me.screenshotViewerDialog, strcat("/screenshots/", strdecolorize(me.screenshotName(me,me.selectedItem)))); + // pop up screenshot + DialogOpenButton_Click_withCoords(NULL, me.screenshotViewerDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * me.selectedItem - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize)); +} + +void XonoticScreenshotList_previewScreenshot(entity me) +{ + if(!me.screenshotBrowserDialog) + return; + if (me.nItems <= 0) + me.screenshotBrowserDialog.loadPreviewScreenshot(me.screenshotBrowserDialog, ""); + else + me.screenshotBrowserDialog.loadPreviewScreenshot(me.screenshotBrowserDialog, strcat("/screenshots/", strdecolorize(me.screenshotName(me,me.selectedItem)))); +} + +void StartScreenshot_Click(entity btn, entity me) +{ + me.startScreenshot(me); +} + +void XonoticScreenshotList_doubleClickListBoxItem(entity me, float i, vector where) +{ + me.startScreenshot(me); +} + +float XonoticScreenshotList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_KP_ENTER || scan == K_MOUSE2 || scan == K_SPACE) { + me.startScreenshot(me); + return 1; + } + if(scan == K_MWHEELUP || scan == K_MWHEELDOWN) + me.newScreenshotTime = time + 0.2; + return SUPER(XonoticScreenshotList).keyDown(me, scan, ascii, shift); +} +#endif diff --git a/qcsrc/menu/xonotic/serverlist.c b/qcsrc/menu/xonotic/serverlist.c deleted file mode 100644 index 50ce594e8..000000000 --- a/qcsrc/menu/xonotic/serverlist.c +++ /dev/null @@ -1,1314 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticServerList) EXTENDS(XonoticListBox) - METHOD(XonoticServerList, configureXonoticServerList, void(entity)) - ATTRIB(XonoticServerList, rowsPerItem, float, 1) - METHOD(XonoticServerList, draw, void(entity)) - METHOD(XonoticServerList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticServerList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticServerList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticServerList, keyDown, float(entity, float, float, float)) - METHOD(XonoticServerList, toggleFavorite, void(entity, string)) - - ATTRIB(XonoticServerList, iconsSizeFactor, float, 0.85) - - ATTRIB(XonoticServerList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticServerList, realUpperMargin, float, 0) - ATTRIB(XonoticServerList, columnIconsOrigin, float, 0) - ATTRIB(XonoticServerList, columnIconsSize, float, 0) - ATTRIB(XonoticServerList, columnPingOrigin, float, 0) - ATTRIB(XonoticServerList, columnPingSize, float, 0) - ATTRIB(XonoticServerList, columnNameOrigin, float, 0) - ATTRIB(XonoticServerList, columnNameSize, float, 0) - ATTRIB(XonoticServerList, columnMapOrigin, float, 0) - ATTRIB(XonoticServerList, columnMapSize, float, 0) - ATTRIB(XonoticServerList, columnTypeOrigin, float, 0) - ATTRIB(XonoticServerList, columnTypeSize, float, 0) - ATTRIB(XonoticServerList, columnPlayersOrigin, float, 0) - ATTRIB(XonoticServerList, columnPlayersSize, float, 0) - - ATTRIB(XonoticServerList, selectedServer, string, string_null) // to restore selected server when needed - METHOD(XonoticServerList, setSelected, void(entity, float)) - METHOD(XonoticServerList, setSortOrder, void(entity, float, float)) - ATTRIB(XonoticServerList, filterShowEmpty, float, 1) - ATTRIB(XonoticServerList, filterShowFull, float, 1) - ATTRIB(XonoticServerList, filterString, string, string_null) - ATTRIB(XonoticServerList, controlledTextbox, entity, NULL) - ATTRIB(XonoticServerList, ipAddressBox, entity, NULL) - ATTRIB(XonoticServerList, favoriteButton, entity, NULL) - ATTRIB(XonoticServerList, nextRefreshTime, float, 0) - METHOD(XonoticServerList, refreshServerList, void(entity, float)) // refresh mode: REFRESHSERVERLIST_* - ATTRIB(XonoticServerList, needsRefresh, float, 1) - METHOD(XonoticServerList, focusEnter, void(entity)) - METHOD(XonoticServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity))) - ATTRIB(XonoticServerList, sortButton1, entity, NULL) - ATTRIB(XonoticServerList, sortButton2, entity, NULL) - ATTRIB(XonoticServerList, sortButton3, entity, NULL) - ATTRIB(XonoticServerList, sortButton4, entity, NULL) - ATTRIB(XonoticServerList, sortButton5, entity, NULL) - ATTRIB(XonoticServerList, connectButton, entity, NULL) - ATTRIB(XonoticServerList, infoButton, entity, NULL) - ATTRIB(XonoticServerList, currentSortOrder, float, 0) - ATTRIB(XonoticServerList, currentSortField, float, -1) - - ATTRIB(XonoticServerList, ipAddressBoxFocused, float, -1) - - ATTRIB(XonoticServerList, seenIPv4, float, 0) - ATTRIB(XonoticServerList, seenIPv6, float, 0) - ATTRIB(XonoticServerList, categoriesHeight, float, 1.25) - - METHOD(XonoticServerList, getTotalHeight, float(entity)) - METHOD(XonoticServerList, getItemAtPos, float(entity, float)) - METHOD(XonoticServerList, getItemStart, float(entity, float)) - METHOD(XonoticServerList, getItemHeight, float(entity, float)) -ENDCLASS(XonoticServerList) -entity makeXonoticServerList(); - -#ifndef IMPLEMENTATION -float autocvar_menu_slist_categories; -float autocvar_menu_slist_categories_onlyifmultiple; -float autocvar_menu_slist_purethreshold; -float autocvar_menu_slist_modimpurity; -float autocvar_menu_slist_recommendations; -float autocvar_menu_slist_recommendations_maxping; -float autocvar_menu_slist_recommendations_minfreeslots; -float autocvar_menu_slist_recommendations_minhumans; -float autocvar_menu_slist_recommendations_purethreshold; - -// server cache fields -#define SLIST_FIELDS \ - SLIST_FIELD(CNAME, "cname") \ - SLIST_FIELD(PING, "ping") \ - SLIST_FIELD(GAME, "game") \ - SLIST_FIELD(MOD, "mod") \ - SLIST_FIELD(MAP, "map") \ - SLIST_FIELD(NAME, "name") \ - SLIST_FIELD(MAXPLAYERS, "maxplayers") \ - SLIST_FIELD(NUMPLAYERS, "numplayers") \ - SLIST_FIELD(NUMHUMANS, "numhumans") \ - SLIST_FIELD(NUMBOTS, "numbots") \ - SLIST_FIELD(PROTOCOL, "protocol") \ - SLIST_FIELD(FREESLOTS, "freeslots") \ - SLIST_FIELD(PLAYERS, "players") \ - SLIST_FIELD(QCSTATUS, "qcstatus") \ - SLIST_FIELD(CATEGORY, "category") \ - SLIST_FIELD(ISFAVORITE, "isfavorite") - -#define SLIST_FIELD(suffix,name) float SLIST_FIELD_##suffix; -SLIST_FIELDS -#undef SLIST_FIELD - -const float REFRESHSERVERLIST_RESORT = 0; // sort the server list again to update for changes to e.g. favorite status, categories -const float REFRESHSERVERLIST_REFILTER = 1; // ..., also update filter and sort criteria -const float REFRESHSERVERLIST_ASK = 2; // ..., also suggest querying servers now -const float REFRESHSERVERLIST_RESET = 3; // ..., also clear the list first - -// function declarations -float IsServerInList(string list, string srv); -#define IsFavorite(srv) IsServerInList(cvar_string("net_slist_favorites"), srv) -#define IsPromoted(srv) IsServerInList(_Nex_ExtResponseSystem_PromotedServers, srv) -#define IsRecommended(srv) IsServerInList(_Nex_ExtResponseSystem_RecommendedServers, srv) - -entity RetrieveCategoryEnt(float catnum); - -float CheckCategoryOverride(float cat); -float CheckCategoryForEntry(float entry); -float m_gethostcachecategory(float entry) { return CheckCategoryOverride(CheckCategoryForEntry(entry)); } - -void RegisterSLCategories(); - -void ServerList_Connect_Click(entity btn, entity me); -void ServerList_Categories_Click(entity box, entity me); -void ServerList_ShowEmpty_Click(entity box, entity me); -void ServerList_ShowFull_Click(entity box, entity me); -void ServerList_Filter_Change(entity box, entity me); -void ServerList_Favorite_Click(entity btn, entity me); -void ServerList_Info_Click(entity btn, entity me); -void ServerList_Update_favoriteButton(entity btn, entity me); - -// fields for category entities -const float MAX_CATEGORIES = 9; -const float CATEGORY_FIRST = 1; -entity categories[MAX_CATEGORIES]; -float category_ent_count; -.string cat_name; -.string cat_string; -.string cat_enoverride_string; -.string cat_dioverride_string; -.float cat_enoverride; -.float cat_dioverride; - -// fields for drawing categories -float category_name[MAX_CATEGORIES]; -float category_item[MAX_CATEGORIES]; -float category_draw_count; - -#define SLIST_CATEGORIES \ - SLIST_CATEGORY(CAT_FAVORITED, "", "", ZCTX(_("SLCAT^Favorites"))) \ - SLIST_CATEGORY(CAT_RECOMMENDED, "", "", ZCTX(_("SLCAT^Recommended"))) \ - SLIST_CATEGORY(CAT_NORMAL, "", "CAT_SERVERS", ZCTX(_("SLCAT^Normal Servers"))) \ - SLIST_CATEGORY(CAT_SERVERS, "CAT_NORMAL", "CAT_SERVERS", ZCTX(_("SLCAT^Servers"))) \ - SLIST_CATEGORY(CAT_XPM, "CAT_NORMAL", "CAT_SERVERS", ZCTX(_("SLCAT^Competitive Mode"))) \ - SLIST_CATEGORY(CAT_MODIFIED, "", "CAT_SERVERS", ZCTX(_("SLCAT^Modified Servers"))) \ - SLIST_CATEGORY(CAT_OVERKILL, "", "CAT_SERVERS", ZCTX(_("SLCAT^Overkill Mode"))) \ - SLIST_CATEGORY(CAT_INSTAGIB, "", "CAT_SERVERS", ZCTX(_("SLCAT^InstaGib Mode"))) \ - SLIST_CATEGORY(CAT_DEFRAG, "", "CAT_SERVERS", ZCTX(_("SLCAT^Defrag Mode"))) - -#define SLIST_CATEGORY_AUTOCVAR(name) autocvar_menu_slist_categories_##name##_override -#define SLIST_CATEGORY(name,enoverride,dioverride,str) \ - float name; \ - var string SLIST_CATEGORY_AUTOCVAR(name) = enoverride; -SLIST_CATEGORIES -#undef SLIST_CATEGORY - -#endif -#endif -#ifdef IMPLEMENTATION - -void RegisterSLCategories() -{ - entity cat; - #define SLIST_CATEGORY(name,enoverride,dioverride,str) \ - SET_FIELD_COUNT(name, CATEGORY_FIRST, category_ent_count) \ - CHECK_MAX_COUNT(name, MAX_CATEGORIES, category_ent_count, "SLIST_CATEGORY") \ - cat = spawn(); \ - categories[name - 1] = cat; \ - cat.classname = "slist_category"; \ - cat.cat_name = strzone(#name); \ - cat.cat_enoverride_string = strzone(SLIST_CATEGORY_AUTOCVAR(name)); \ - cat.cat_dioverride_string = strzone(dioverride); \ - cat.cat_string = strzone(str); - SLIST_CATEGORIES - #undef SLIST_CATEGORY - - float i, x, catnum; - string s; - - #define PROCESS_OVERRIDE(override_string,override_field) \ - for(i = 0; i < category_ent_count; ++i) \ - { \ - s = categories[i].override_string; \ - if((s != "") && (s != categories[i].cat_name)) \ - { \ - catnum = 0; \ - for(x = 0; x < category_ent_count; ++x) \ - { if(categories[x].cat_name == s) { \ - catnum = (x+1); \ - break; \ - } } \ - if(catnum) \ - { \ - strunzone(categories[i].override_string); \ - categories[i].override_field = catnum; \ - continue; \ - } \ - else \ - { \ - printf( \ - "RegisterSLCategories(): Improper override '%s' for category '%s'!\n", \ - s, \ - categories[i].cat_name \ - ); \ - } \ - } \ - strunzone(categories[i].override_string); \ - categories[i].override_field = 0; \ - } - PROCESS_OVERRIDE(cat_enoverride_string, cat_enoverride) - PROCESS_OVERRIDE(cat_dioverride_string, cat_dioverride) - #undef PROCESS_OVERRIDE -} - -// Supporting Functions -entity RetrieveCategoryEnt(float catnum) -{ - if((catnum > 0) && (catnum <= category_ent_count)) - { - return categories[catnum - 1]; - } - else - { - error(sprintf("RetrieveCategoryEnt(%d): Improper category number!\n", catnum)); - return world; - } -} - -float IsServerInList(string list, string srv) -{ - string p; - float i, n; - if(srv == "") - return FALSE; - srv = netaddress_resolve(srv, 26000); - if(srv == "") - return FALSE; - p = crypto_getidfp(srv); - n = tokenize_console(list); - for(i = 0; i < n; ++i) - { - if(substring(argv(i), 0, 1) != "[" && strlen(argv(i)) == 44 && strstrofs(argv(i), ".", 0) < 0) - { - if(p) - if(argv(i) == p) - return TRUE; - } - else - { - if(srv == netaddress_resolve(argv(i), 26000)) - return TRUE; - } - } - return FALSE; -} - -float CheckCategoryOverride(float cat) -{ - entity catent = RetrieveCategoryEnt(cat); - if(catent) - { - float override = (autocvar_menu_slist_categories ? catent.cat_enoverride : catent.cat_dioverride); - if(override) { return override; } - else { return cat; } - } - else - { - error(sprintf("CheckCategoryOverride(%d): Improper category number!\n", cat)); - return cat; - } -} - -float CheckCategoryForEntry(float entry) -{ - string s, k, v, modtype = ""; - float j, m, impure = 0, freeslots = 0, sflags = 0; - s = gethostcachestring(SLIST_FIELD_QCSTATUS, entry); - m = tokenizebyseparator(s, ":"); - - for(j = 2; j < m; ++j) - { - if(argv(j) == "") { break; } - k = substring(argv(j), 0, 1); - v = substring(argv(j), 1, -1); - switch(k) - { - case "P": { impure = stof(v); break; } - case "S": { freeslots = stof(v); break; } - case "F": { sflags = stof(v); break; } - case "M": { modtype = strtolower(v); break; } - } - } - - if(modtype != "xonotic") { impure += autocvar_menu_slist_modimpurity; } - - // check if this server is favorited - if(gethostcachenumber(SLIST_FIELD_ISFAVORITE, entry)) { return CAT_FAVORITED; } - - // now check if it's recommended - if(autocvar_menu_slist_recommendations) - { - string cname = gethostcachestring(SLIST_FIELD_CNAME, entry); - - if(IsPromoted(cname)) { return CAT_RECOMMENDED; } - else - { - float recommended = 0; - if(autocvar_menu_slist_recommendations & 1) - { - if(IsRecommended(cname)) { ++recommended; } - else { --recommended; } - } - if(autocvar_menu_slist_recommendations & 2) - { - if( - ///// check for minimum free slots - (freeslots >= autocvar_menu_slist_recommendations_minfreeslots) - - && // check for purity requirement - ( - (autocvar_menu_slist_recommendations_purethreshold < 0) - || - (impure <= autocvar_menu_slist_recommendations_purethreshold) - ) - - && // check for minimum amount of humans - ( - gethostcachenumber(SLIST_FIELD_NUMHUMANS, entry) - >= - autocvar_menu_slist_recommendations_minhumans - ) - - && // check for maximum latency - ( - gethostcachenumber(SLIST_FIELD_PING, entry) - <= - autocvar_menu_slist_recommendations_maxping - ) - ) - { ++recommended; } - else - { --recommended; } - } - if(recommended > 0) { return CAT_RECOMMENDED; } - } - } - - // if not favorited or recommended, check modname - if(modtype != "xonotic") - { - switch(modtype) - { - // old servers which don't report their mod name are considered modified now - case "": { return CAT_MODIFIED; } - - case "xpm": { return CAT_XPM; } - case "minstagib": - case "instagib": { return CAT_INSTAGIB; } - case "overkill": { return CAT_OVERKILL; } - //case "nix": { return CAT_NIX; } - //case "newtoys": { return CAT_NEWTOYS; } - - // "cts" is allowed as compat, xdf is replacement - case "cts": - case "xdf": { return CAT_DEFRAG; } - - default: { dprintf("Found strange mod type: %s\n", modtype); return CAT_MODIFIED; } - } - } - - // must be normal or impure server - return ((impure > autocvar_menu_slist_purethreshold) ? CAT_MODIFIED : CAT_NORMAL); -} - -void XonoticServerList_toggleFavorite(entity me, string srv) -{ - string s, s0, s1, s2, srv_resolved, p; - float i, n, f; - srv_resolved = netaddress_resolve(srv, 26000); - p = crypto_getidfp(srv_resolved); - s = cvar_string("net_slist_favorites"); - n = tokenize_console(s); - f = 0; - for(i = 0; i < n; ++i) - { - if(substring(argv(i), 0, 1) != "[" && strlen(argv(i)) == 44 && strstrofs(argv(i), ".", 0) < 0) - { - if(p) - if(argv(i) != p) - continue; - } - else - { - if(srv_resolved != netaddress_resolve(argv(i), 26000)) - continue; - } - s0 = s1 = s2 = ""; - if(i > 0) - s0 = substring(s, 0, argv_end_index(i - 1)); - if(i < n-1) - s2 = substring(s, argv_start_index(i + 1), -1); - if(s0 != "" && s2 != "") - s1 = " "; - cvar_set("net_slist_favorites", strcat(s0, s1, s2)); - s = cvar_string("net_slist_favorites"); - n = tokenize_console(s); - f = 1; - --i; - } - - if(!f) - { - s1 = ""; - if(s != "") - s1 = " "; - if(p) - cvar_set("net_slist_favorites", strcat(s, s1, p)); - else - cvar_set("net_slist_favorites", strcat(s, s1, srv)); - } - - me.refreshServerList(me, REFRESHSERVERLIST_RESORT); -} - -void ServerList_Update_favoriteButton(entity btn, entity me) -{ - me.favoriteButton.setText(me.favoriteButton, - (IsFavorite(me.ipAddressBox.text) ? - _("Remove") : _("Favorite") - ) - ); -} - -entity makeXonoticServerList() -{ - entity me; - me = spawnXonoticServerList(); - me.configureXonoticServerList(me); - return me; -} -void XonoticServerList_configureXonoticServerList(entity me) -{ - me.configureXonoticListBox(me); - - // update field ID's - #define SLIST_FIELD(suffix,name) SLIST_FIELD_##suffix = gethostcacheindexforkey(name); - SLIST_FIELDS - #undef SLIST_FIELD - - // clear list - me.nItems = 0; -} -void XonoticServerList_setSelected(entity me, float i) -{ - float save; - save = me.selectedItem; - SUPER(XonoticServerList).setSelected(me, i); - /* - if(me.selectedItem == save) - return; - */ - if(me.nItems == 0) - return; - if(gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT) != me.nItems) - return; // sorry, it would be wrong - - if(me.selectedServer) - strunzone(me.selectedServer); - me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem)); - - me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer); - me.ipAddressBox.cursorPos = strlen(me.selectedServer); - me.ipAddressBoxFocused = -1; -} -void XonoticServerList_refreshServerList(entity me, float mode) -{ - //print("refresh of type ", ftos(mode), "\n"); - - if(mode >= REFRESHSERVERLIST_REFILTER) - { - float m, i, n; - float listflags = 0; - string s, typestr, modstr; - - s = me.filterString; - - m = strstrofs(s, ":", 0); - if(m >= 0) - { - typestr = substring(s, 0, m); - s = substring(s, m + 1, strlen(s) - m - 1); - while(substring(s, 0, 1) == " ") - s = substring(s, 1, strlen(s) - 1); - } - else - typestr = ""; - - modstr = cvar_string("menu_slist_modfilter"); - - m = SLIST_MASK_AND - 1; - resethostcachemasks(); - - // ping: reject negative ping (no idea why this happens in the first place, engine bug) - sethostcachemasknumber(++m, SLIST_FIELD_PING, 0, SLIST_TEST_GREATEREQUAL); - - // show full button - if(!me.filterShowFull) - { - sethostcachemasknumber(++m, SLIST_FIELD_FREESLOTS, 1, SLIST_TEST_GREATEREQUAL); // legacy - sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, ":S0:", SLIST_TEST_NOTCONTAIN); // g_maxplayers support - } - - // show empty button - if(!me.filterShowEmpty) - sethostcachemasknumber(++m, SLIST_FIELD_NUMHUMANS, 1, SLIST_TEST_GREATEREQUAL); - - // gametype filtering - if(typestr != "") - sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(typestr, ":"), SLIST_TEST_STARTSWITH); - - // mod filtering - if(modstr != "") - { - if(substring(modstr, 0, 1) == "!") - sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(substring(modstr, 1, strlen(modstr) - 1)), SLIST_TEST_NOTEQUAL); - else - sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(modstr), SLIST_TEST_EQUAL); - } - - // server banning - n = tokenizebyseparator(_Nex_ExtResponseSystem_BannedServers, " "); - for(i = 0; i < n; ++i) - if(argv(i) != "") - sethostcachemaskstring(++m, SLIST_FIELD_CNAME, argv(i), SLIST_TEST_NOTSTARTSWITH); - - m = SLIST_MASK_OR - 1; - if(s != "") - { - sethostcachemaskstring(++m, SLIST_FIELD_NAME, s, SLIST_TEST_CONTAINS); - sethostcachemaskstring(++m, SLIST_FIELD_MAP, s, SLIST_TEST_CONTAINS); - sethostcachemaskstring(++m, SLIST_FIELD_PLAYERS, s, SLIST_TEST_CONTAINS); - sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(s, ":"), SLIST_TEST_STARTSWITH); - } - - // sorting flags - //listflags |= SLSF_FAVORITES; - listflags |= SLSF_CATEGORIES; - if(me.currentSortOrder < 0) { listflags |= SLSF_DESCENDING; } - sethostcachesort(me.currentSortField, listflags); - } - - resorthostcache(); - if(mode >= REFRESHSERVERLIST_ASK) - refreshhostcache(mode >= REFRESHSERVERLIST_RESET); -} -void XonoticServerList_focusEnter(entity me) -{ - if(time < me.nextRefreshTime) - { - //print("sorry, no refresh yet\n"); - return; - } - me.nextRefreshTime = time + 10; - me.refreshServerList(me, REFRESHSERVERLIST_ASK); -} - -void XonoticServerList_draw(entity me) -{ - float i, found, owned; - - if(_Nex_ExtResponseSystem_BannedServersNeedsRefresh) - { - if(!me.needsRefresh) - me.needsRefresh = 2; - _Nex_ExtResponseSystem_BannedServersNeedsRefresh = 0; - } - - if(_Nex_ExtResponseSystem_PromotedServersNeedsRefresh) - { - if(!me.needsRefresh) - me.needsRefresh = 3; - _Nex_ExtResponseSystem_PromotedServersNeedsRefresh = 0; - } - - if(_Nex_ExtResponseSystem_RecommendedServersNeedsRefresh) - { - if(!me.needsRefresh) - me.needsRefresh = 3; - _Nex_ExtResponseSystem_RecommendedServersNeedsRefresh = 0; - } - - if(me.currentSortField == -1) - { - me.setSortOrder(me, SLIST_FIELD_PING, +1); - me.refreshServerList(me, REFRESHSERVERLIST_RESET); - } - else if(me.needsRefresh == 1) - { - me.needsRefresh = 2; // delay by one frame to make sure "slist" has been executed - } - else if(me.needsRefresh == 2) - { - me.needsRefresh = 0; - me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); - } - else if(me.needsRefresh == 3) - { - me.needsRefresh = 0; - me.refreshServerList(me, REFRESHSERVERLIST_RESORT); - } - - owned = ((me.selectedServer == me.ipAddressBox.text) && (me.ipAddressBox.text != "")); - - for(i = 0; i < category_draw_count; ++i) { category_name[i] = -1; category_item[i] = -1; } - category_draw_count = 0; - - if(autocvar_menu_slist_categories >= 0) // if less than 0, don't even draw a category heading for favorites - { - float itemcount = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); - me.nItems = itemcount; - - //float visible = floor(me.scrollPos / me.itemHeight); - // ^ unfortunately no such optimization can be made-- we must process through the - // entire list, otherwise there is no way to know which item is first in its category. - - // binary search method suggested by div - float x; - float begin = 0; - for(x = 1; x <= category_ent_count; ++x) { - float first = begin; - float last = (itemcount - 1); - if (first > last) { - // List is empty. - break; - } - float catf = gethostcachenumber(SLIST_FIELD_CATEGORY, first); - float catl = gethostcachenumber(SLIST_FIELD_CATEGORY, last); - if (catf > x) { - // The first one is already > x. - // Therefore, category x does not exist. - // Higher numbered categories do exist though. - } else if (catl < x) { - // The last one is < x. - // Thus this category - and any following - - // don't exist. - break; - } else if (catf == x) { - // Starts at first. This breaks the loop - // invariant in the binary search and thus has - // to be handled separately. - if(gethostcachenumber(SLIST_FIELD_CATEGORY, first) != x) - error("Category mismatch I"); - if(first > 0) - if(gethostcachenumber(SLIST_FIELD_CATEGORY, first - 1) == x) - error("Category mismatch II"); - category_name[category_draw_count] = x; - category_item[category_draw_count] = first; - ++category_draw_count; - begin = first + 1; - } else { - // At this point, catf <= x < catl, thus - // catf < catl, thus first < last. - // INVARIANTS: - // last - first >= 1 - // catf == gethostcachenumber(SLIST_FIELD_CATEGORY(first) - // catl == gethostcachenumber(SLIST_FIELD_CATEGORY(last) - // catf < x - // catl >= x - while (last - first > 1) { - float middle = floor((first + last) / 2); - // By loop condition, middle != first && middle != last. - float cat = gethostcachenumber(SLIST_FIELD_CATEGORY, middle); - if (cat >= x) { - last = middle; - catl = cat; - } else { - first = middle; - catf = cat; - } - } - if (catl == x) { - if(gethostcachenumber(SLIST_FIELD_CATEGORY, last) != x) - error("Category mismatch III"); - if(last > 0) - if(gethostcachenumber(SLIST_FIELD_CATEGORY, last - 1) == x) - error("Category mismatch IV"); - category_name[category_draw_count] = x; - category_item[category_draw_count] = last; - ++category_draw_count; - begin = last + 1; // already scanned through these, skip 'em - } - else - begin = last; // already scanned through these, skip 'em - } - } - if(autocvar_menu_slist_categories_onlyifmultiple && (category_draw_count == 1)) - { - category_name[0] = -1; - category_item[0] = -1; - category_draw_count = 0; - me.nItems = itemcount; - } - } - else { me.nItems = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); } - - me.connectButton.disabled = ((me.nItems == 0) && (me.ipAddressBox.text == "")); - me.infoButton.disabled = ((me.nItems == 0) || !owned); - me.favoriteButton.disabled = ((me.nItems == 0) && (me.ipAddressBox.text == "")); - - found = 0; - if(me.selectedServer) - { - for(i = 0; i < me.nItems; ++i) - { - if(gethostcachestring(SLIST_FIELD_CNAME, i) == me.selectedServer) - { - me.selectedItem = i; - found = 1; - break; - } - } - } - if(!found) - { - if(me.nItems > 0) - { - if(me.selectedItem >= me.nItems) - me.selectedItem = me.nItems - 1; - if(me.selectedServer) - strunzone(me.selectedServer); - me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem)); - } - } - - if(owned) - { - if(me.selectedServer != me.ipAddressBox.text) - { - me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer); - me.ipAddressBox.cursorPos = strlen(me.selectedServer); - me.ipAddressBoxFocused = -1; - } - } - - if(me.ipAddressBoxFocused != me.ipAddressBox.focused) - { - if(me.ipAddressBox.focused || me.ipAddressBoxFocused < 0) - ServerList_Update_favoriteButton(NULL, me); - me.ipAddressBoxFocused = me.ipAddressBox.focused; - } - - SUPER(XonoticServerList).draw(me); -} -void ServerList_PingSort_Click(entity btn, entity me) -{ - me.setSortOrder(me, SLIST_FIELD_PING, +1); -} -void ServerList_NameSort_Click(entity btn, entity me) -{ - me.setSortOrder(me, SLIST_FIELD_NAME, -1); // why? -} -void ServerList_MapSort_Click(entity btn, entity me) -{ - me.setSortOrder(me, SLIST_FIELD_MAP, -1); // why? -} -void ServerList_PlayerSort_Click(entity btn, entity me) -{ - me.setSortOrder(me, SLIST_FIELD_NUMHUMANS, -1); -} -void ServerList_TypeSort_Click(entity btn, entity me) -{ - string s, t; - float i, m; - s = me.filterString; - m = strstrofs(s, ":", 0); - if(m >= 0) - { - s = substring(s, 0, m); - while(substring(s, m+1, 1) == " ") // skip spaces - ++m; - } - else - s = ""; - - for(i = 1; ; i *= 2) // 20 modes ought to be enough for anyone - { - t = MapInfo_Type_ToString(i); - if(i > 1) - if(t == "") // it repeats (default case) - { - // no type was found - // choose the first one - s = MapInfo_Type_ToString(1); - break; - } - if(s == t) - { - // the type was found - // choose the next one - s = MapInfo_Type_ToString(i * 2); - if(s == "") - s = MapInfo_Type_ToString(1); - break; - } - } - - if(s != "") - s = strcat(s, ":"); - s = strcat(s, substring(me.filterString, m+1, strlen(me.filterString) - m - 1)); - - me.controlledTextbox.setText(me.controlledTextbox, s); - me.controlledTextbox.keyDown(me.controlledTextbox, K_END, 0, 0); - me.controlledTextbox.keyUp(me.controlledTextbox, K_END, 0, 0); - //ServerList_Filter_Change(me.controlledTextbox, me); -} -void ServerList_Filter_Change(entity box, entity me) -{ - if(me.filterString) - strunzone(me.filterString); - if(box.text != "") - me.filterString = strzone(box.text); - else - me.filterString = string_null; - me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); - - me.ipAddressBox.setText(me.ipAddressBox, ""); - me.ipAddressBox.cursorPos = 0; - me.ipAddressBoxFocused = -1; -} -void ServerList_Categories_Click(entity box, entity me) -{ - box.setChecked(box, autocvar_menu_slist_categories = !autocvar_menu_slist_categories); - me.refreshServerList(me, REFRESHSERVERLIST_RESORT); - - me.ipAddressBox.setText(me.ipAddressBox, ""); - me.ipAddressBox.cursorPos = 0; - me.ipAddressBoxFocused = -1; -} -void ServerList_ShowEmpty_Click(entity box, entity me) -{ - box.setChecked(box, me.filterShowEmpty = !me.filterShowEmpty); - me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); - - me.ipAddressBox.setText(me.ipAddressBox, ""); - me.ipAddressBox.cursorPos = 0; - me.ipAddressBoxFocused = -1; -} -void ServerList_ShowFull_Click(entity box, entity me) -{ - box.setChecked(box, me.filterShowFull = !me.filterShowFull); - me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); - - me.ipAddressBox.setText(me.ipAddressBox, ""); - me.ipAddressBox.cursorPos = 0; - me.ipAddressBoxFocused = -1; -} -void XonoticServerList_setSortOrder(entity me, float fld, float direction) -{ - if(me.currentSortField == fld) - direction = -me.currentSortOrder; - me.currentSortOrder = direction; - me.currentSortField = fld; - me.sortButton1.forcePressed = (fld == SLIST_FIELD_PING); - me.sortButton2.forcePressed = (fld == SLIST_FIELD_NAME); - me.sortButton3.forcePressed = (fld == SLIST_FIELD_MAP); - me.sortButton4.forcePressed = 0; - me.sortButton5.forcePressed = (fld == SLIST_FIELD_NUMHUMANS); - me.selectedItem = 0; - if(me.selectedServer) - strunzone(me.selectedServer); - me.selectedServer = string_null; - me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); -} -void XonoticServerList_positionSortButton(entity me, entity btn, float theOrigin, float theSize, string theTitle, void(entity, entity) theFunc) -{ - vector originInLBSpace, sizeInLBSpace; - originInLBSpace = eY * (-me.itemHeight); - sizeInLBSpace = eY * me.itemHeight + eX * (1 - me.controlWidth); - - vector originInDialogSpace, sizeInDialogSpace; - originInDialogSpace = boxToGlobal(originInLBSpace, me.Container_origin, me.Container_size); - sizeInDialogSpace = boxToGlobalSize(sizeInLBSpace, me.Container_size); - - btn.Container_origin_x = originInDialogSpace_x + sizeInDialogSpace_x * theOrigin; - btn.Container_size_x = sizeInDialogSpace_x * theSize; - btn.setText(btn, theTitle); - btn.onClick = theFunc; - btn.onClickEntity = me; - btn.resized = 1; -} -void XonoticServerList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(XonoticServerList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); - me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - - me.columnIconsOrigin = 0; - me.columnIconsSize = me.realFontSize_x * 4 * me.iconsSizeFactor; - me.columnPingSize = me.realFontSize_x * 3; - me.columnMapSize = me.realFontSize_x * 10; - me.columnTypeSize = me.realFontSize_x * 4; - me.columnPlayersSize = me.realFontSize_x * 5; - me.columnNameSize = 1 - me.columnPlayersSize - me.columnMapSize - me.columnPingSize - me.columnIconsSize - me.columnTypeSize - 5 * me.realFontSize_x; - me.columnPingOrigin = me.columnIconsOrigin + me.columnIconsSize + me.realFontSize_x; - me.columnNameOrigin = me.columnPingOrigin + me.columnPingSize + me.realFontSize_x; - me.columnMapOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x; - me.columnTypeOrigin = me.columnMapOrigin + me.columnMapSize + me.realFontSize_x; - me.columnPlayersOrigin = me.columnTypeOrigin + me.columnTypeSize + me.realFontSize_x; - - me.positionSortButton(me, me.sortButton1, me.columnPingOrigin, me.columnPingSize, _("Ping"), ServerList_PingSort_Click); - me.positionSortButton(me, me.sortButton2, me.columnNameOrigin, me.columnNameSize, _("Host name"), ServerList_NameSort_Click); - me.positionSortButton(me, me.sortButton3, me.columnMapOrigin, me.columnMapSize, _("Map"), ServerList_MapSort_Click); - me.positionSortButton(me, me.sortButton4, me.columnTypeOrigin, me.columnTypeSize, _("Type"), ServerList_TypeSort_Click); - me.positionSortButton(me, me.sortButton5, me.columnPlayersOrigin, me.columnPlayersSize, _("Players"), ServerList_PlayerSort_Click); - - float f; - f = me.currentSortField; - if(f >= 0) - { - me.currentSortField = -1; - me.setSortOrder(me, f, me.currentSortOrder); // force resetting the sort order - } -} -void ServerList_Connect_Click(entity btn, entity me) -{ - localcmd(sprintf("connect %s\n", - ((me.ipAddressBox.text != "") ? - me.ipAddressBox.text : me.selectedServer - ) - )); -} -void ServerList_Favorite_Click(entity btn, entity me) -{ - string ipstr; - ipstr = netaddress_resolve(me.ipAddressBox.text, 26000); - if(ipstr != "") - { - me.toggleFavorite(me, me.ipAddressBox.text); - me.ipAddressBoxFocused = -1; - } -} -void ServerList_Info_Click(entity btn, entity me) -{ - if (me.nItems != 0) - main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, me.selectedItem); - - vector org = boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size); - vector sz = boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size); - DialogOpenButton_Click_withCoords(me, main.serverInfoDialog, org, sz); -} -void XonoticServerList_doubleClickListBoxItem(entity me, float i, vector where) -{ - ServerList_Connect_Click(NULL, me); -} -void XonoticServerList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - // layout: Ping, Server name, Map name, NP, TP, MP - float p, q; - float isv4, isv6; - vector theColor; - float theAlpha; - float m, pure, freeslots, j, sflags; - string s, typestr, versionstr, k, v, modname; - - //printf("time: %f, i: %d, item: %d, nitems: %d\n", time, i, item, me.nItems); - - vector oldscale = draw_scale; - vector oldshift = draw_shift; -#define SET_YRANGE(start,end) \ - draw_scale = boxToGlobalSize(eX * 1 + eY * (end - start), oldscale); \ - draw_shift = boxToGlobal(eY * start, oldshift, oldscale); - - for (j = 0; j < category_draw_count; ++j) { - // Matches exactly the headings with increased height. - if (i == category_item[j]) - break; - } - - if (j < category_draw_count) - { - entity catent = RetrieveCategoryEnt(category_name[j]); - if(catent) - { - SET_YRANGE( - (me.categoriesHeight - 1) / (me.categoriesHeight + 1), - me.categoriesHeight / (me.categoriesHeight + 1) - ); - draw_Text( - eY * me.realUpperMargin - + -#if 0 - eX * (me.columnNameOrigin + (me.columnNameSize - draw_TextWidth(catent.cat_string, 0, me.realFontSize)) * 0.5), - catent.cat_string, -#else - eX * (me.columnNameOrigin), - strcat(catent.cat_string, ":"), -#endif - me.realFontSize, - SKINCOLOR_SERVERLIST_CATEGORY, - SKINALPHA_SERVERLIST_CATEGORY, - 0 - ); - SET_YRANGE(me.categoriesHeight / (me.categoriesHeight + 1), 1); - } - } - - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - s = gethostcachestring(SLIST_FIELD_QCSTATUS, i); - m = tokenizebyseparator(s, ":"); - typestr = ""; - if(m >= 2) - { - typestr = argv(0); - versionstr = argv(1); - } - freeslots = -1; - sflags = -1; - modname = ""; - pure = 0; - for(j = 2; j < m; ++j) - { - if(argv(j) == "") - break; - k = substring(argv(j), 0, 1); - v = substring(argv(j), 1, -1); - if(k == "P") - pure = stof(v); - else if(k == "S") - freeslots = stof(v); - else if(k == "F") - sflags = stof(v); - else if(k == "M") - modname = v; - } - -#ifdef COMPAT_NO_MOD_IS_XONOTIC - if(modname == "") - modname = "Xonotic"; -#endif - - /* - SLIST_FIELD_MOD = gethostcacheindexforkey("mod"); - s = gethostcachestring(SLIST_FIELD_MOD, i); - if(s != "data") - if(modname == "Xonotic") - modname = s; - */ - - // list the mods here on which the pure server check actually works - if(modname != "Xonotic") - if(modname != "InstaGib" || modname != "MinstaGib") - if(modname != "CTS") - if(modname != "NIX") - if(modname != "NewToys") - pure = 0; - - if(gethostcachenumber(SLIST_FIELD_FREESLOTS, i) <= 0) - theAlpha = SKINALPHA_SERVERLIST_FULL; - else if(freeslots == 0) - theAlpha = SKINALPHA_SERVERLIST_FULL; // g_maxplayers support - else if (!gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)) - theAlpha = SKINALPHA_SERVERLIST_EMPTY; - else - theAlpha = 1; - - p = gethostcachenumber(SLIST_FIELD_PING, i); - const float PING_LOW = 75; - const float PING_MED = 200; - const float PING_HIGH = 500; - if(p < PING_LOW) - theColor = SKINCOLOR_SERVERLIST_LOWPING + (SKINCOLOR_SERVERLIST_MEDPING - SKINCOLOR_SERVERLIST_LOWPING) * (p / PING_LOW); - else if(p < PING_MED) - theColor = SKINCOLOR_SERVERLIST_MEDPING + (SKINCOLOR_SERVERLIST_HIGHPING - SKINCOLOR_SERVERLIST_MEDPING) * ((p - PING_LOW) / (PING_MED - PING_LOW)); - else if(p < PING_HIGH) - { - theColor = SKINCOLOR_SERVERLIST_HIGHPING; - theAlpha *= 1 + (SKINALPHA_SERVERLIST_HIGHPING - 1) * ((p - PING_MED) / (PING_HIGH - PING_MED)); - } - else - { - theColor = eX; - theAlpha *= SKINALPHA_SERVERLIST_HIGHPING; - } - - if(gethostcachenumber(SLIST_FIELD_ISFAVORITE, i)) - { - theColor = theColor * (1 - SKINALPHA_SERVERLIST_FAVORITE) + SKINCOLOR_SERVERLIST_FAVORITE * SKINALPHA_SERVERLIST_FAVORITE; - theAlpha = theAlpha * (1 - SKINALPHA_SERVERLIST_FAVORITE) + SKINALPHA_SERVERLIST_FAVORITE; - } - - s = gethostcachestring(SLIST_FIELD_CNAME, i); - - isv4 = isv6 = 0; - if(substring(s, 0, 1) == "[") - { - isv6 = 1; - me.seenIPv6 += 1; - } - else if(strstrofs("0123456789", substring(s, 0, 1), 0) >= 0) - { - isv4 = 1; - me.seenIPv4 += 1; - } - - q = stof(substring(crypto_getencryptlevel(s), 0, 1)); - if((q <= 0 && cvar("crypto_aeslevel") >= 3) || (q >= 3 && cvar("crypto_aeslevel") <= 0)) - { - theColor = SKINCOLOR_SERVERLIST_IMPOSSIBLE; - theAlpha = SKINALPHA_SERVERLIST_IMPOSSIBLE; - } - - if(q == 1) - { - if(cvar("crypto_aeslevel") >= 2) - q |= 4; - } - if(q == 2) - { - if(cvar("crypto_aeslevel") >= 1) - q |= 4; - } - if(q == 3) - q = 5; - else if(q >= 3) - q -= 2; - // possible status: - // 0: crypto off - // 1: AES possible - // 2: AES recommended but not available - // 3: AES possible and will be used - // 4: AES recommended and will be used - // 5: AES required - - // -------------- - // RENDER ICONS - // -------------- - vector iconSize = '0 0 0'; - iconSize_y = me.realFontSize_y * me.iconsSizeFactor; - iconSize_x = me.realFontSize_x * me.iconsSizeFactor; - - vector iconPos = '0 0 0'; - iconPos_x = (me.columnIconsSize - 3 * iconSize_x) * 0.5; - iconPos_y = (1 - iconSize_y) * 0.5; - - string n; - - if (!(me.seenIPv4 && me.seenIPv6)) - { - iconPos_x += iconSize_x * 0.5; - } - else if(me.seenIPv4 && me.seenIPv6) - { - n = string_null; - if(isv6) - draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_ipv6"), 0); // PRECACHE_PIC_MIPMAP - else if(isv4) - draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_ipv4"), 0); // PRECACHE_PIC_MIPMAP - if(n) - draw_Picture(iconPos, n, iconSize, '1 1 1', 1); - iconPos_x += iconSize_x; - } - - if(q > 0) - { - draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_aeslevel", ftos(q)), 0); // PRECACHE_PIC_MIPMAP - draw_Picture(iconPos, n, iconSize, '1 1 1', 1); - } - iconPos_x += iconSize_x; - - if(modname == "Xonotic") - { - if(pure == 0) - { - draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_pure1"), PRECACHE_PIC_MIPMAP); - draw_Picture(iconPos, n, iconSize, '1 1 1', 1); - } - } - else - { - draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_mod_", modname), PRECACHE_PIC_MIPMAP); - if(draw_PictureSize(n) == '0 0 0') - draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_mod_"), PRECACHE_PIC_MIPMAP); - if(pure == 0) - draw_Picture(iconPos, n, iconSize, '1 1 1', 1); - else - draw_Picture(iconPos, n, iconSize, '1 1 1', SKINALPHA_SERVERLIST_ICON_NONPURE); - } - iconPos_x += iconSize_x; - - if(sflags >= 0 && (sflags & SERVERFLAG_PLAYERSTATS)) - { - draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_stats1"), 0); // PRECACHE_PIC_MIPMAP - draw_Picture(iconPos, n, iconSize, '1 1 1', 1); - } - iconPos_x += iconSize_x; - - // -------------- - // RENDER TEXT - // -------------- - - // ping - s = ftos(p); - draw_Text(me.realUpperMargin * eY + (me.columnPingOrigin + me.columnPingSize - draw_TextWidth(s, 0, me.realFontSize)) * eX, s, me.realFontSize, theColor, theAlpha, 0); - - // server name - s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_NAME, i), me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0); - - // server map - s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_MAP, i), me.columnMapSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + (me.columnMapOrigin + (me.columnMapSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0); - - // server gametype - s = draw_TextShortenToWidth(typestr, me.columnTypeSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + (me.columnTypeOrigin + (me.columnTypeSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0); - - // server playercount - s = strcat(ftos(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)), "/", ftos(gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i))); - draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0); -} - -float XonoticServerList_keyDown(entity me, float scan, float ascii, float shift) -{ - vector org, sz; - - org = boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size); - sz = boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size); - - if(scan == K_ENTER || scan == K_KP_ENTER) - { - ServerList_Connect_Click(NULL, me); - return 1; - } - else if(scan == K_MOUSE2 || scan == K_SPACE) - { - if(me.nItems != 0) - { - main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, me.selectedItem); - DialogOpenButton_Click_withCoords(me, main.serverInfoDialog, org, sz); - return 1; - } - return 0; - } - else if(scan == K_INS || scan == K_MOUSE3 || scan == K_KP_INS) - { - if(me.nItems != 0) - { - me.toggleFavorite(me, me.selectedServer); - me.ipAddressBoxFocused = -1; - return 1; - } - return 0; - } - else if(SUPER(XonoticServerList).keyDown(me, scan, ascii, shift)) - return 1; - else if(!me.controlledTextbox) - return 0; - else - return me.controlledTextbox.keyDown(me.controlledTextbox, scan, ascii, shift); -} - -float XonoticServerList_getTotalHeight(entity me) { - float num_normal_rows = me.nItems; - float num_headers = category_draw_count; - return me.itemHeight * (num_normal_rows + me.categoriesHeight * num_headers); -} -float XonoticServerList_getItemAtPos(entity me, float pos) { - pos = pos / me.itemHeight; - float i; - for (i = category_draw_count - 1; i >= 0; --i) { - float itemidx = category_item[i]; - float itempos = i * me.categoriesHeight + category_item[i]; - if (pos >= itempos + me.categoriesHeight + 1) - return itemidx + 1 + floor(pos - (itempos + me.categoriesHeight + 1)); - if (pos >= itempos) - return itemidx; - } - // No category matches? Note that category 0 is... 0. Therefore no headings exist at all. - return floor(pos); -} -float XonoticServerList_getItemStart(entity me, float item) { - float i; - for (i = category_draw_count - 1; i >= 0; --i) { - float itemidx = category_item[i]; - float itempos = i * me.categoriesHeight + category_item[i]; - if (item >= itemidx + 1) - return (itempos + me.categoriesHeight + 1 + item - (itemidx + 1)) * me.itemHeight; - if (item >= itemidx) - return itempos * me.itemHeight; - } - // No category matches? Note that category 0 is... 0. Therefore no headings exist at all. - return item * me.itemHeight; -} -float XonoticServerList_getItemHeight(entity me, float item) { - float i; - for (i = 0; i < category_draw_count; ++i) { - // Matches exactly the headings with increased height. - if (item == category_item[i]) - return me.itemHeight * (me.categoriesHeight + 1); - } - return me.itemHeight; -} - -#endif diff --git a/qcsrc/menu/xonotic/serverlist.qc b/qcsrc/menu/xonotic/serverlist.qc new file mode 100644 index 000000000..50ce594e8 --- /dev/null +++ b/qcsrc/menu/xonotic/serverlist.qc @@ -0,0 +1,1314 @@ +#ifdef INTERFACE +CLASS(XonoticServerList) EXTENDS(XonoticListBox) + METHOD(XonoticServerList, configureXonoticServerList, void(entity)) + ATTRIB(XonoticServerList, rowsPerItem, float, 1) + METHOD(XonoticServerList, draw, void(entity)) + METHOD(XonoticServerList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticServerList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticServerList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticServerList, keyDown, float(entity, float, float, float)) + METHOD(XonoticServerList, toggleFavorite, void(entity, string)) + + ATTRIB(XonoticServerList, iconsSizeFactor, float, 0.85) + + ATTRIB(XonoticServerList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticServerList, realUpperMargin, float, 0) + ATTRIB(XonoticServerList, columnIconsOrigin, float, 0) + ATTRIB(XonoticServerList, columnIconsSize, float, 0) + ATTRIB(XonoticServerList, columnPingOrigin, float, 0) + ATTRIB(XonoticServerList, columnPingSize, float, 0) + ATTRIB(XonoticServerList, columnNameOrigin, float, 0) + ATTRIB(XonoticServerList, columnNameSize, float, 0) + ATTRIB(XonoticServerList, columnMapOrigin, float, 0) + ATTRIB(XonoticServerList, columnMapSize, float, 0) + ATTRIB(XonoticServerList, columnTypeOrigin, float, 0) + ATTRIB(XonoticServerList, columnTypeSize, float, 0) + ATTRIB(XonoticServerList, columnPlayersOrigin, float, 0) + ATTRIB(XonoticServerList, columnPlayersSize, float, 0) + + ATTRIB(XonoticServerList, selectedServer, string, string_null) // to restore selected server when needed + METHOD(XonoticServerList, setSelected, void(entity, float)) + METHOD(XonoticServerList, setSortOrder, void(entity, float, float)) + ATTRIB(XonoticServerList, filterShowEmpty, float, 1) + ATTRIB(XonoticServerList, filterShowFull, float, 1) + ATTRIB(XonoticServerList, filterString, string, string_null) + ATTRIB(XonoticServerList, controlledTextbox, entity, NULL) + ATTRIB(XonoticServerList, ipAddressBox, entity, NULL) + ATTRIB(XonoticServerList, favoriteButton, entity, NULL) + ATTRIB(XonoticServerList, nextRefreshTime, float, 0) + METHOD(XonoticServerList, refreshServerList, void(entity, float)) // refresh mode: REFRESHSERVERLIST_* + ATTRIB(XonoticServerList, needsRefresh, float, 1) + METHOD(XonoticServerList, focusEnter, void(entity)) + METHOD(XonoticServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity))) + ATTRIB(XonoticServerList, sortButton1, entity, NULL) + ATTRIB(XonoticServerList, sortButton2, entity, NULL) + ATTRIB(XonoticServerList, sortButton3, entity, NULL) + ATTRIB(XonoticServerList, sortButton4, entity, NULL) + ATTRIB(XonoticServerList, sortButton5, entity, NULL) + ATTRIB(XonoticServerList, connectButton, entity, NULL) + ATTRIB(XonoticServerList, infoButton, entity, NULL) + ATTRIB(XonoticServerList, currentSortOrder, float, 0) + ATTRIB(XonoticServerList, currentSortField, float, -1) + + ATTRIB(XonoticServerList, ipAddressBoxFocused, float, -1) + + ATTRIB(XonoticServerList, seenIPv4, float, 0) + ATTRIB(XonoticServerList, seenIPv6, float, 0) + ATTRIB(XonoticServerList, categoriesHeight, float, 1.25) + + METHOD(XonoticServerList, getTotalHeight, float(entity)) + METHOD(XonoticServerList, getItemAtPos, float(entity, float)) + METHOD(XonoticServerList, getItemStart, float(entity, float)) + METHOD(XonoticServerList, getItemHeight, float(entity, float)) +ENDCLASS(XonoticServerList) +entity makeXonoticServerList(); + +#ifndef IMPLEMENTATION +float autocvar_menu_slist_categories; +float autocvar_menu_slist_categories_onlyifmultiple; +float autocvar_menu_slist_purethreshold; +float autocvar_menu_slist_modimpurity; +float autocvar_menu_slist_recommendations; +float autocvar_menu_slist_recommendations_maxping; +float autocvar_menu_slist_recommendations_minfreeslots; +float autocvar_menu_slist_recommendations_minhumans; +float autocvar_menu_slist_recommendations_purethreshold; + +// server cache fields +#define SLIST_FIELDS \ + SLIST_FIELD(CNAME, "cname") \ + SLIST_FIELD(PING, "ping") \ + SLIST_FIELD(GAME, "game") \ + SLIST_FIELD(MOD, "mod") \ + SLIST_FIELD(MAP, "map") \ + SLIST_FIELD(NAME, "name") \ + SLIST_FIELD(MAXPLAYERS, "maxplayers") \ + SLIST_FIELD(NUMPLAYERS, "numplayers") \ + SLIST_FIELD(NUMHUMANS, "numhumans") \ + SLIST_FIELD(NUMBOTS, "numbots") \ + SLIST_FIELD(PROTOCOL, "protocol") \ + SLIST_FIELD(FREESLOTS, "freeslots") \ + SLIST_FIELD(PLAYERS, "players") \ + SLIST_FIELD(QCSTATUS, "qcstatus") \ + SLIST_FIELD(CATEGORY, "category") \ + SLIST_FIELD(ISFAVORITE, "isfavorite") + +#define SLIST_FIELD(suffix,name) float SLIST_FIELD_##suffix; +SLIST_FIELDS +#undef SLIST_FIELD + +const float REFRESHSERVERLIST_RESORT = 0; // sort the server list again to update for changes to e.g. favorite status, categories +const float REFRESHSERVERLIST_REFILTER = 1; // ..., also update filter and sort criteria +const float REFRESHSERVERLIST_ASK = 2; // ..., also suggest querying servers now +const float REFRESHSERVERLIST_RESET = 3; // ..., also clear the list first + +// function declarations +float IsServerInList(string list, string srv); +#define IsFavorite(srv) IsServerInList(cvar_string("net_slist_favorites"), srv) +#define IsPromoted(srv) IsServerInList(_Nex_ExtResponseSystem_PromotedServers, srv) +#define IsRecommended(srv) IsServerInList(_Nex_ExtResponseSystem_RecommendedServers, srv) + +entity RetrieveCategoryEnt(float catnum); + +float CheckCategoryOverride(float cat); +float CheckCategoryForEntry(float entry); +float m_gethostcachecategory(float entry) { return CheckCategoryOverride(CheckCategoryForEntry(entry)); } + +void RegisterSLCategories(); + +void ServerList_Connect_Click(entity btn, entity me); +void ServerList_Categories_Click(entity box, entity me); +void ServerList_ShowEmpty_Click(entity box, entity me); +void ServerList_ShowFull_Click(entity box, entity me); +void ServerList_Filter_Change(entity box, entity me); +void ServerList_Favorite_Click(entity btn, entity me); +void ServerList_Info_Click(entity btn, entity me); +void ServerList_Update_favoriteButton(entity btn, entity me); + +// fields for category entities +const float MAX_CATEGORIES = 9; +const float CATEGORY_FIRST = 1; +entity categories[MAX_CATEGORIES]; +float category_ent_count; +.string cat_name; +.string cat_string; +.string cat_enoverride_string; +.string cat_dioverride_string; +.float cat_enoverride; +.float cat_dioverride; + +// fields for drawing categories +float category_name[MAX_CATEGORIES]; +float category_item[MAX_CATEGORIES]; +float category_draw_count; + +#define SLIST_CATEGORIES \ + SLIST_CATEGORY(CAT_FAVORITED, "", "", ZCTX(_("SLCAT^Favorites"))) \ + SLIST_CATEGORY(CAT_RECOMMENDED, "", "", ZCTX(_("SLCAT^Recommended"))) \ + SLIST_CATEGORY(CAT_NORMAL, "", "CAT_SERVERS", ZCTX(_("SLCAT^Normal Servers"))) \ + SLIST_CATEGORY(CAT_SERVERS, "CAT_NORMAL", "CAT_SERVERS", ZCTX(_("SLCAT^Servers"))) \ + SLIST_CATEGORY(CAT_XPM, "CAT_NORMAL", "CAT_SERVERS", ZCTX(_("SLCAT^Competitive Mode"))) \ + SLIST_CATEGORY(CAT_MODIFIED, "", "CAT_SERVERS", ZCTX(_("SLCAT^Modified Servers"))) \ + SLIST_CATEGORY(CAT_OVERKILL, "", "CAT_SERVERS", ZCTX(_("SLCAT^Overkill Mode"))) \ + SLIST_CATEGORY(CAT_INSTAGIB, "", "CAT_SERVERS", ZCTX(_("SLCAT^InstaGib Mode"))) \ + SLIST_CATEGORY(CAT_DEFRAG, "", "CAT_SERVERS", ZCTX(_("SLCAT^Defrag Mode"))) + +#define SLIST_CATEGORY_AUTOCVAR(name) autocvar_menu_slist_categories_##name##_override +#define SLIST_CATEGORY(name,enoverride,dioverride,str) \ + float name; \ + var string SLIST_CATEGORY_AUTOCVAR(name) = enoverride; +SLIST_CATEGORIES +#undef SLIST_CATEGORY + +#endif +#endif +#ifdef IMPLEMENTATION + +void RegisterSLCategories() +{ + entity cat; + #define SLIST_CATEGORY(name,enoverride,dioverride,str) \ + SET_FIELD_COUNT(name, CATEGORY_FIRST, category_ent_count) \ + CHECK_MAX_COUNT(name, MAX_CATEGORIES, category_ent_count, "SLIST_CATEGORY") \ + cat = spawn(); \ + categories[name - 1] = cat; \ + cat.classname = "slist_category"; \ + cat.cat_name = strzone(#name); \ + cat.cat_enoverride_string = strzone(SLIST_CATEGORY_AUTOCVAR(name)); \ + cat.cat_dioverride_string = strzone(dioverride); \ + cat.cat_string = strzone(str); + SLIST_CATEGORIES + #undef SLIST_CATEGORY + + float i, x, catnum; + string s; + + #define PROCESS_OVERRIDE(override_string,override_field) \ + for(i = 0; i < category_ent_count; ++i) \ + { \ + s = categories[i].override_string; \ + if((s != "") && (s != categories[i].cat_name)) \ + { \ + catnum = 0; \ + for(x = 0; x < category_ent_count; ++x) \ + { if(categories[x].cat_name == s) { \ + catnum = (x+1); \ + break; \ + } } \ + if(catnum) \ + { \ + strunzone(categories[i].override_string); \ + categories[i].override_field = catnum; \ + continue; \ + } \ + else \ + { \ + printf( \ + "RegisterSLCategories(): Improper override '%s' for category '%s'!\n", \ + s, \ + categories[i].cat_name \ + ); \ + } \ + } \ + strunzone(categories[i].override_string); \ + categories[i].override_field = 0; \ + } + PROCESS_OVERRIDE(cat_enoverride_string, cat_enoverride) + PROCESS_OVERRIDE(cat_dioverride_string, cat_dioverride) + #undef PROCESS_OVERRIDE +} + +// Supporting Functions +entity RetrieveCategoryEnt(float catnum) +{ + if((catnum > 0) && (catnum <= category_ent_count)) + { + return categories[catnum - 1]; + } + else + { + error(sprintf("RetrieveCategoryEnt(%d): Improper category number!\n", catnum)); + return world; + } +} + +float IsServerInList(string list, string srv) +{ + string p; + float i, n; + if(srv == "") + return FALSE; + srv = netaddress_resolve(srv, 26000); + if(srv == "") + return FALSE; + p = crypto_getidfp(srv); + n = tokenize_console(list); + for(i = 0; i < n; ++i) + { + if(substring(argv(i), 0, 1) != "[" && strlen(argv(i)) == 44 && strstrofs(argv(i), ".", 0) < 0) + { + if(p) + if(argv(i) == p) + return TRUE; + } + else + { + if(srv == netaddress_resolve(argv(i), 26000)) + return TRUE; + } + } + return FALSE; +} + +float CheckCategoryOverride(float cat) +{ + entity catent = RetrieveCategoryEnt(cat); + if(catent) + { + float override = (autocvar_menu_slist_categories ? catent.cat_enoverride : catent.cat_dioverride); + if(override) { return override; } + else { return cat; } + } + else + { + error(sprintf("CheckCategoryOverride(%d): Improper category number!\n", cat)); + return cat; + } +} + +float CheckCategoryForEntry(float entry) +{ + string s, k, v, modtype = ""; + float j, m, impure = 0, freeslots = 0, sflags = 0; + s = gethostcachestring(SLIST_FIELD_QCSTATUS, entry); + m = tokenizebyseparator(s, ":"); + + for(j = 2; j < m; ++j) + { + if(argv(j) == "") { break; } + k = substring(argv(j), 0, 1); + v = substring(argv(j), 1, -1); + switch(k) + { + case "P": { impure = stof(v); break; } + case "S": { freeslots = stof(v); break; } + case "F": { sflags = stof(v); break; } + case "M": { modtype = strtolower(v); break; } + } + } + + if(modtype != "xonotic") { impure += autocvar_menu_slist_modimpurity; } + + // check if this server is favorited + if(gethostcachenumber(SLIST_FIELD_ISFAVORITE, entry)) { return CAT_FAVORITED; } + + // now check if it's recommended + if(autocvar_menu_slist_recommendations) + { + string cname = gethostcachestring(SLIST_FIELD_CNAME, entry); + + if(IsPromoted(cname)) { return CAT_RECOMMENDED; } + else + { + float recommended = 0; + if(autocvar_menu_slist_recommendations & 1) + { + if(IsRecommended(cname)) { ++recommended; } + else { --recommended; } + } + if(autocvar_menu_slist_recommendations & 2) + { + if( + ///// check for minimum free slots + (freeslots >= autocvar_menu_slist_recommendations_minfreeslots) + + && // check for purity requirement + ( + (autocvar_menu_slist_recommendations_purethreshold < 0) + || + (impure <= autocvar_menu_slist_recommendations_purethreshold) + ) + + && // check for minimum amount of humans + ( + gethostcachenumber(SLIST_FIELD_NUMHUMANS, entry) + >= + autocvar_menu_slist_recommendations_minhumans + ) + + && // check for maximum latency + ( + gethostcachenumber(SLIST_FIELD_PING, entry) + <= + autocvar_menu_slist_recommendations_maxping + ) + ) + { ++recommended; } + else + { --recommended; } + } + if(recommended > 0) { return CAT_RECOMMENDED; } + } + } + + // if not favorited or recommended, check modname + if(modtype != "xonotic") + { + switch(modtype) + { + // old servers which don't report their mod name are considered modified now + case "": { return CAT_MODIFIED; } + + case "xpm": { return CAT_XPM; } + case "minstagib": + case "instagib": { return CAT_INSTAGIB; } + case "overkill": { return CAT_OVERKILL; } + //case "nix": { return CAT_NIX; } + //case "newtoys": { return CAT_NEWTOYS; } + + // "cts" is allowed as compat, xdf is replacement + case "cts": + case "xdf": { return CAT_DEFRAG; } + + default: { dprintf("Found strange mod type: %s\n", modtype); return CAT_MODIFIED; } + } + } + + // must be normal or impure server + return ((impure > autocvar_menu_slist_purethreshold) ? CAT_MODIFIED : CAT_NORMAL); +} + +void XonoticServerList_toggleFavorite(entity me, string srv) +{ + string s, s0, s1, s2, srv_resolved, p; + float i, n, f; + srv_resolved = netaddress_resolve(srv, 26000); + p = crypto_getidfp(srv_resolved); + s = cvar_string("net_slist_favorites"); + n = tokenize_console(s); + f = 0; + for(i = 0; i < n; ++i) + { + if(substring(argv(i), 0, 1) != "[" && strlen(argv(i)) == 44 && strstrofs(argv(i), ".", 0) < 0) + { + if(p) + if(argv(i) != p) + continue; + } + else + { + if(srv_resolved != netaddress_resolve(argv(i), 26000)) + continue; + } + s0 = s1 = s2 = ""; + if(i > 0) + s0 = substring(s, 0, argv_end_index(i - 1)); + if(i < n-1) + s2 = substring(s, argv_start_index(i + 1), -1); + if(s0 != "" && s2 != "") + s1 = " "; + cvar_set("net_slist_favorites", strcat(s0, s1, s2)); + s = cvar_string("net_slist_favorites"); + n = tokenize_console(s); + f = 1; + --i; + } + + if(!f) + { + s1 = ""; + if(s != "") + s1 = " "; + if(p) + cvar_set("net_slist_favorites", strcat(s, s1, p)); + else + cvar_set("net_slist_favorites", strcat(s, s1, srv)); + } + + me.refreshServerList(me, REFRESHSERVERLIST_RESORT); +} + +void ServerList_Update_favoriteButton(entity btn, entity me) +{ + me.favoriteButton.setText(me.favoriteButton, + (IsFavorite(me.ipAddressBox.text) ? + _("Remove") : _("Favorite") + ) + ); +} + +entity makeXonoticServerList() +{ + entity me; + me = spawnXonoticServerList(); + me.configureXonoticServerList(me); + return me; +} +void XonoticServerList_configureXonoticServerList(entity me) +{ + me.configureXonoticListBox(me); + + // update field ID's + #define SLIST_FIELD(suffix,name) SLIST_FIELD_##suffix = gethostcacheindexforkey(name); + SLIST_FIELDS + #undef SLIST_FIELD + + // clear list + me.nItems = 0; +} +void XonoticServerList_setSelected(entity me, float i) +{ + float save; + save = me.selectedItem; + SUPER(XonoticServerList).setSelected(me, i); + /* + if(me.selectedItem == save) + return; + */ + if(me.nItems == 0) + return; + if(gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT) != me.nItems) + return; // sorry, it would be wrong + + if(me.selectedServer) + strunzone(me.selectedServer); + me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem)); + + me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer); + me.ipAddressBox.cursorPos = strlen(me.selectedServer); + me.ipAddressBoxFocused = -1; +} +void XonoticServerList_refreshServerList(entity me, float mode) +{ + //print("refresh of type ", ftos(mode), "\n"); + + if(mode >= REFRESHSERVERLIST_REFILTER) + { + float m, i, n; + float listflags = 0; + string s, typestr, modstr; + + s = me.filterString; + + m = strstrofs(s, ":", 0); + if(m >= 0) + { + typestr = substring(s, 0, m); + s = substring(s, m + 1, strlen(s) - m - 1); + while(substring(s, 0, 1) == " ") + s = substring(s, 1, strlen(s) - 1); + } + else + typestr = ""; + + modstr = cvar_string("menu_slist_modfilter"); + + m = SLIST_MASK_AND - 1; + resethostcachemasks(); + + // ping: reject negative ping (no idea why this happens in the first place, engine bug) + sethostcachemasknumber(++m, SLIST_FIELD_PING, 0, SLIST_TEST_GREATEREQUAL); + + // show full button + if(!me.filterShowFull) + { + sethostcachemasknumber(++m, SLIST_FIELD_FREESLOTS, 1, SLIST_TEST_GREATEREQUAL); // legacy + sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, ":S0:", SLIST_TEST_NOTCONTAIN); // g_maxplayers support + } + + // show empty button + if(!me.filterShowEmpty) + sethostcachemasknumber(++m, SLIST_FIELD_NUMHUMANS, 1, SLIST_TEST_GREATEREQUAL); + + // gametype filtering + if(typestr != "") + sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(typestr, ":"), SLIST_TEST_STARTSWITH); + + // mod filtering + if(modstr != "") + { + if(substring(modstr, 0, 1) == "!") + sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(substring(modstr, 1, strlen(modstr) - 1)), SLIST_TEST_NOTEQUAL); + else + sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(modstr), SLIST_TEST_EQUAL); + } + + // server banning + n = tokenizebyseparator(_Nex_ExtResponseSystem_BannedServers, " "); + for(i = 0; i < n; ++i) + if(argv(i) != "") + sethostcachemaskstring(++m, SLIST_FIELD_CNAME, argv(i), SLIST_TEST_NOTSTARTSWITH); + + m = SLIST_MASK_OR - 1; + if(s != "") + { + sethostcachemaskstring(++m, SLIST_FIELD_NAME, s, SLIST_TEST_CONTAINS); + sethostcachemaskstring(++m, SLIST_FIELD_MAP, s, SLIST_TEST_CONTAINS); + sethostcachemaskstring(++m, SLIST_FIELD_PLAYERS, s, SLIST_TEST_CONTAINS); + sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(s, ":"), SLIST_TEST_STARTSWITH); + } + + // sorting flags + //listflags |= SLSF_FAVORITES; + listflags |= SLSF_CATEGORIES; + if(me.currentSortOrder < 0) { listflags |= SLSF_DESCENDING; } + sethostcachesort(me.currentSortField, listflags); + } + + resorthostcache(); + if(mode >= REFRESHSERVERLIST_ASK) + refreshhostcache(mode >= REFRESHSERVERLIST_RESET); +} +void XonoticServerList_focusEnter(entity me) +{ + if(time < me.nextRefreshTime) + { + //print("sorry, no refresh yet\n"); + return; + } + me.nextRefreshTime = time + 10; + me.refreshServerList(me, REFRESHSERVERLIST_ASK); +} + +void XonoticServerList_draw(entity me) +{ + float i, found, owned; + + if(_Nex_ExtResponseSystem_BannedServersNeedsRefresh) + { + if(!me.needsRefresh) + me.needsRefresh = 2; + _Nex_ExtResponseSystem_BannedServersNeedsRefresh = 0; + } + + if(_Nex_ExtResponseSystem_PromotedServersNeedsRefresh) + { + if(!me.needsRefresh) + me.needsRefresh = 3; + _Nex_ExtResponseSystem_PromotedServersNeedsRefresh = 0; + } + + if(_Nex_ExtResponseSystem_RecommendedServersNeedsRefresh) + { + if(!me.needsRefresh) + me.needsRefresh = 3; + _Nex_ExtResponseSystem_RecommendedServersNeedsRefresh = 0; + } + + if(me.currentSortField == -1) + { + me.setSortOrder(me, SLIST_FIELD_PING, +1); + me.refreshServerList(me, REFRESHSERVERLIST_RESET); + } + else if(me.needsRefresh == 1) + { + me.needsRefresh = 2; // delay by one frame to make sure "slist" has been executed + } + else if(me.needsRefresh == 2) + { + me.needsRefresh = 0; + me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); + } + else if(me.needsRefresh == 3) + { + me.needsRefresh = 0; + me.refreshServerList(me, REFRESHSERVERLIST_RESORT); + } + + owned = ((me.selectedServer == me.ipAddressBox.text) && (me.ipAddressBox.text != "")); + + for(i = 0; i < category_draw_count; ++i) { category_name[i] = -1; category_item[i] = -1; } + category_draw_count = 0; + + if(autocvar_menu_slist_categories >= 0) // if less than 0, don't even draw a category heading for favorites + { + float itemcount = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); + me.nItems = itemcount; + + //float visible = floor(me.scrollPos / me.itemHeight); + // ^ unfortunately no such optimization can be made-- we must process through the + // entire list, otherwise there is no way to know which item is first in its category. + + // binary search method suggested by div + float x; + float begin = 0; + for(x = 1; x <= category_ent_count; ++x) { + float first = begin; + float last = (itemcount - 1); + if (first > last) { + // List is empty. + break; + } + float catf = gethostcachenumber(SLIST_FIELD_CATEGORY, first); + float catl = gethostcachenumber(SLIST_FIELD_CATEGORY, last); + if (catf > x) { + // The first one is already > x. + // Therefore, category x does not exist. + // Higher numbered categories do exist though. + } else if (catl < x) { + // The last one is < x. + // Thus this category - and any following - + // don't exist. + break; + } else if (catf == x) { + // Starts at first. This breaks the loop + // invariant in the binary search and thus has + // to be handled separately. + if(gethostcachenumber(SLIST_FIELD_CATEGORY, first) != x) + error("Category mismatch I"); + if(first > 0) + if(gethostcachenumber(SLIST_FIELD_CATEGORY, first - 1) == x) + error("Category mismatch II"); + category_name[category_draw_count] = x; + category_item[category_draw_count] = first; + ++category_draw_count; + begin = first + 1; + } else { + // At this point, catf <= x < catl, thus + // catf < catl, thus first < last. + // INVARIANTS: + // last - first >= 1 + // catf == gethostcachenumber(SLIST_FIELD_CATEGORY(first) + // catl == gethostcachenumber(SLIST_FIELD_CATEGORY(last) + // catf < x + // catl >= x + while (last - first > 1) { + float middle = floor((first + last) / 2); + // By loop condition, middle != first && middle != last. + float cat = gethostcachenumber(SLIST_FIELD_CATEGORY, middle); + if (cat >= x) { + last = middle; + catl = cat; + } else { + first = middle; + catf = cat; + } + } + if (catl == x) { + if(gethostcachenumber(SLIST_FIELD_CATEGORY, last) != x) + error("Category mismatch III"); + if(last > 0) + if(gethostcachenumber(SLIST_FIELD_CATEGORY, last - 1) == x) + error("Category mismatch IV"); + category_name[category_draw_count] = x; + category_item[category_draw_count] = last; + ++category_draw_count; + begin = last + 1; // already scanned through these, skip 'em + } + else + begin = last; // already scanned through these, skip 'em + } + } + if(autocvar_menu_slist_categories_onlyifmultiple && (category_draw_count == 1)) + { + category_name[0] = -1; + category_item[0] = -1; + category_draw_count = 0; + me.nItems = itemcount; + } + } + else { me.nItems = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); } + + me.connectButton.disabled = ((me.nItems == 0) && (me.ipAddressBox.text == "")); + me.infoButton.disabled = ((me.nItems == 0) || !owned); + me.favoriteButton.disabled = ((me.nItems == 0) && (me.ipAddressBox.text == "")); + + found = 0; + if(me.selectedServer) + { + for(i = 0; i < me.nItems; ++i) + { + if(gethostcachestring(SLIST_FIELD_CNAME, i) == me.selectedServer) + { + me.selectedItem = i; + found = 1; + break; + } + } + } + if(!found) + { + if(me.nItems > 0) + { + if(me.selectedItem >= me.nItems) + me.selectedItem = me.nItems - 1; + if(me.selectedServer) + strunzone(me.selectedServer); + me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem)); + } + } + + if(owned) + { + if(me.selectedServer != me.ipAddressBox.text) + { + me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer); + me.ipAddressBox.cursorPos = strlen(me.selectedServer); + me.ipAddressBoxFocused = -1; + } + } + + if(me.ipAddressBoxFocused != me.ipAddressBox.focused) + { + if(me.ipAddressBox.focused || me.ipAddressBoxFocused < 0) + ServerList_Update_favoriteButton(NULL, me); + me.ipAddressBoxFocused = me.ipAddressBox.focused; + } + + SUPER(XonoticServerList).draw(me); +} +void ServerList_PingSort_Click(entity btn, entity me) +{ + me.setSortOrder(me, SLIST_FIELD_PING, +1); +} +void ServerList_NameSort_Click(entity btn, entity me) +{ + me.setSortOrder(me, SLIST_FIELD_NAME, -1); // why? +} +void ServerList_MapSort_Click(entity btn, entity me) +{ + me.setSortOrder(me, SLIST_FIELD_MAP, -1); // why? +} +void ServerList_PlayerSort_Click(entity btn, entity me) +{ + me.setSortOrder(me, SLIST_FIELD_NUMHUMANS, -1); +} +void ServerList_TypeSort_Click(entity btn, entity me) +{ + string s, t; + float i, m; + s = me.filterString; + m = strstrofs(s, ":", 0); + if(m >= 0) + { + s = substring(s, 0, m); + while(substring(s, m+1, 1) == " ") // skip spaces + ++m; + } + else + s = ""; + + for(i = 1; ; i *= 2) // 20 modes ought to be enough for anyone + { + t = MapInfo_Type_ToString(i); + if(i > 1) + if(t == "") // it repeats (default case) + { + // no type was found + // choose the first one + s = MapInfo_Type_ToString(1); + break; + } + if(s == t) + { + // the type was found + // choose the next one + s = MapInfo_Type_ToString(i * 2); + if(s == "") + s = MapInfo_Type_ToString(1); + break; + } + } + + if(s != "") + s = strcat(s, ":"); + s = strcat(s, substring(me.filterString, m+1, strlen(me.filterString) - m - 1)); + + me.controlledTextbox.setText(me.controlledTextbox, s); + me.controlledTextbox.keyDown(me.controlledTextbox, K_END, 0, 0); + me.controlledTextbox.keyUp(me.controlledTextbox, K_END, 0, 0); + //ServerList_Filter_Change(me.controlledTextbox, me); +} +void ServerList_Filter_Change(entity box, entity me) +{ + if(me.filterString) + strunzone(me.filterString); + if(box.text != "") + me.filterString = strzone(box.text); + else + me.filterString = string_null; + me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); + + me.ipAddressBox.setText(me.ipAddressBox, ""); + me.ipAddressBox.cursorPos = 0; + me.ipAddressBoxFocused = -1; +} +void ServerList_Categories_Click(entity box, entity me) +{ + box.setChecked(box, autocvar_menu_slist_categories = !autocvar_menu_slist_categories); + me.refreshServerList(me, REFRESHSERVERLIST_RESORT); + + me.ipAddressBox.setText(me.ipAddressBox, ""); + me.ipAddressBox.cursorPos = 0; + me.ipAddressBoxFocused = -1; +} +void ServerList_ShowEmpty_Click(entity box, entity me) +{ + box.setChecked(box, me.filterShowEmpty = !me.filterShowEmpty); + me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); + + me.ipAddressBox.setText(me.ipAddressBox, ""); + me.ipAddressBox.cursorPos = 0; + me.ipAddressBoxFocused = -1; +} +void ServerList_ShowFull_Click(entity box, entity me) +{ + box.setChecked(box, me.filterShowFull = !me.filterShowFull); + me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); + + me.ipAddressBox.setText(me.ipAddressBox, ""); + me.ipAddressBox.cursorPos = 0; + me.ipAddressBoxFocused = -1; +} +void XonoticServerList_setSortOrder(entity me, float fld, float direction) +{ + if(me.currentSortField == fld) + direction = -me.currentSortOrder; + me.currentSortOrder = direction; + me.currentSortField = fld; + me.sortButton1.forcePressed = (fld == SLIST_FIELD_PING); + me.sortButton2.forcePressed = (fld == SLIST_FIELD_NAME); + me.sortButton3.forcePressed = (fld == SLIST_FIELD_MAP); + me.sortButton4.forcePressed = 0; + me.sortButton5.forcePressed = (fld == SLIST_FIELD_NUMHUMANS); + me.selectedItem = 0; + if(me.selectedServer) + strunzone(me.selectedServer); + me.selectedServer = string_null; + me.refreshServerList(me, REFRESHSERVERLIST_REFILTER); +} +void XonoticServerList_positionSortButton(entity me, entity btn, float theOrigin, float theSize, string theTitle, void(entity, entity) theFunc) +{ + vector originInLBSpace, sizeInLBSpace; + originInLBSpace = eY * (-me.itemHeight); + sizeInLBSpace = eY * me.itemHeight + eX * (1 - me.controlWidth); + + vector originInDialogSpace, sizeInDialogSpace; + originInDialogSpace = boxToGlobal(originInLBSpace, me.Container_origin, me.Container_size); + sizeInDialogSpace = boxToGlobalSize(sizeInLBSpace, me.Container_size); + + btn.Container_origin_x = originInDialogSpace_x + sizeInDialogSpace_x * theOrigin; + btn.Container_size_x = sizeInDialogSpace_x * theSize; + btn.setText(btn, theTitle); + btn.onClick = theFunc; + btn.onClickEntity = me; + btn.resized = 1; +} +void XonoticServerList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(XonoticServerList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); + me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + + me.columnIconsOrigin = 0; + me.columnIconsSize = me.realFontSize_x * 4 * me.iconsSizeFactor; + me.columnPingSize = me.realFontSize_x * 3; + me.columnMapSize = me.realFontSize_x * 10; + me.columnTypeSize = me.realFontSize_x * 4; + me.columnPlayersSize = me.realFontSize_x * 5; + me.columnNameSize = 1 - me.columnPlayersSize - me.columnMapSize - me.columnPingSize - me.columnIconsSize - me.columnTypeSize - 5 * me.realFontSize_x; + me.columnPingOrigin = me.columnIconsOrigin + me.columnIconsSize + me.realFontSize_x; + me.columnNameOrigin = me.columnPingOrigin + me.columnPingSize + me.realFontSize_x; + me.columnMapOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x; + me.columnTypeOrigin = me.columnMapOrigin + me.columnMapSize + me.realFontSize_x; + me.columnPlayersOrigin = me.columnTypeOrigin + me.columnTypeSize + me.realFontSize_x; + + me.positionSortButton(me, me.sortButton1, me.columnPingOrigin, me.columnPingSize, _("Ping"), ServerList_PingSort_Click); + me.positionSortButton(me, me.sortButton2, me.columnNameOrigin, me.columnNameSize, _("Host name"), ServerList_NameSort_Click); + me.positionSortButton(me, me.sortButton3, me.columnMapOrigin, me.columnMapSize, _("Map"), ServerList_MapSort_Click); + me.positionSortButton(me, me.sortButton4, me.columnTypeOrigin, me.columnTypeSize, _("Type"), ServerList_TypeSort_Click); + me.positionSortButton(me, me.sortButton5, me.columnPlayersOrigin, me.columnPlayersSize, _("Players"), ServerList_PlayerSort_Click); + + float f; + f = me.currentSortField; + if(f >= 0) + { + me.currentSortField = -1; + me.setSortOrder(me, f, me.currentSortOrder); // force resetting the sort order + } +} +void ServerList_Connect_Click(entity btn, entity me) +{ + localcmd(sprintf("connect %s\n", + ((me.ipAddressBox.text != "") ? + me.ipAddressBox.text : me.selectedServer + ) + )); +} +void ServerList_Favorite_Click(entity btn, entity me) +{ + string ipstr; + ipstr = netaddress_resolve(me.ipAddressBox.text, 26000); + if(ipstr != "") + { + me.toggleFavorite(me, me.ipAddressBox.text); + me.ipAddressBoxFocused = -1; + } +} +void ServerList_Info_Click(entity btn, entity me) +{ + if (me.nItems != 0) + main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, me.selectedItem); + + vector org = boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size); + vector sz = boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size); + DialogOpenButton_Click_withCoords(me, main.serverInfoDialog, org, sz); +} +void XonoticServerList_doubleClickListBoxItem(entity me, float i, vector where) +{ + ServerList_Connect_Click(NULL, me); +} +void XonoticServerList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + // layout: Ping, Server name, Map name, NP, TP, MP + float p, q; + float isv4, isv6; + vector theColor; + float theAlpha; + float m, pure, freeslots, j, sflags; + string s, typestr, versionstr, k, v, modname; + + //printf("time: %f, i: %d, item: %d, nitems: %d\n", time, i, item, me.nItems); + + vector oldscale = draw_scale; + vector oldshift = draw_shift; +#define SET_YRANGE(start,end) \ + draw_scale = boxToGlobalSize(eX * 1 + eY * (end - start), oldscale); \ + draw_shift = boxToGlobal(eY * start, oldshift, oldscale); + + for (j = 0; j < category_draw_count; ++j) { + // Matches exactly the headings with increased height. + if (i == category_item[j]) + break; + } + + if (j < category_draw_count) + { + entity catent = RetrieveCategoryEnt(category_name[j]); + if(catent) + { + SET_YRANGE( + (me.categoriesHeight - 1) / (me.categoriesHeight + 1), + me.categoriesHeight / (me.categoriesHeight + 1) + ); + draw_Text( + eY * me.realUpperMargin + + +#if 0 + eX * (me.columnNameOrigin + (me.columnNameSize - draw_TextWidth(catent.cat_string, 0, me.realFontSize)) * 0.5), + catent.cat_string, +#else + eX * (me.columnNameOrigin), + strcat(catent.cat_string, ":"), +#endif + me.realFontSize, + SKINCOLOR_SERVERLIST_CATEGORY, + SKINALPHA_SERVERLIST_CATEGORY, + 0 + ); + SET_YRANGE(me.categoriesHeight / (me.categoriesHeight + 1), 1); + } + } + + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + s = gethostcachestring(SLIST_FIELD_QCSTATUS, i); + m = tokenizebyseparator(s, ":"); + typestr = ""; + if(m >= 2) + { + typestr = argv(0); + versionstr = argv(1); + } + freeslots = -1; + sflags = -1; + modname = ""; + pure = 0; + for(j = 2; j < m; ++j) + { + if(argv(j) == "") + break; + k = substring(argv(j), 0, 1); + v = substring(argv(j), 1, -1); + if(k == "P") + pure = stof(v); + else if(k == "S") + freeslots = stof(v); + else if(k == "F") + sflags = stof(v); + else if(k == "M") + modname = v; + } + +#ifdef COMPAT_NO_MOD_IS_XONOTIC + if(modname == "") + modname = "Xonotic"; +#endif + + /* + SLIST_FIELD_MOD = gethostcacheindexforkey("mod"); + s = gethostcachestring(SLIST_FIELD_MOD, i); + if(s != "data") + if(modname == "Xonotic") + modname = s; + */ + + // list the mods here on which the pure server check actually works + if(modname != "Xonotic") + if(modname != "InstaGib" || modname != "MinstaGib") + if(modname != "CTS") + if(modname != "NIX") + if(modname != "NewToys") + pure = 0; + + if(gethostcachenumber(SLIST_FIELD_FREESLOTS, i) <= 0) + theAlpha = SKINALPHA_SERVERLIST_FULL; + else if(freeslots == 0) + theAlpha = SKINALPHA_SERVERLIST_FULL; // g_maxplayers support + else if (!gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)) + theAlpha = SKINALPHA_SERVERLIST_EMPTY; + else + theAlpha = 1; + + p = gethostcachenumber(SLIST_FIELD_PING, i); + const float PING_LOW = 75; + const float PING_MED = 200; + const float PING_HIGH = 500; + if(p < PING_LOW) + theColor = SKINCOLOR_SERVERLIST_LOWPING + (SKINCOLOR_SERVERLIST_MEDPING - SKINCOLOR_SERVERLIST_LOWPING) * (p / PING_LOW); + else if(p < PING_MED) + theColor = SKINCOLOR_SERVERLIST_MEDPING + (SKINCOLOR_SERVERLIST_HIGHPING - SKINCOLOR_SERVERLIST_MEDPING) * ((p - PING_LOW) / (PING_MED - PING_LOW)); + else if(p < PING_HIGH) + { + theColor = SKINCOLOR_SERVERLIST_HIGHPING; + theAlpha *= 1 + (SKINALPHA_SERVERLIST_HIGHPING - 1) * ((p - PING_MED) / (PING_HIGH - PING_MED)); + } + else + { + theColor = eX; + theAlpha *= SKINALPHA_SERVERLIST_HIGHPING; + } + + if(gethostcachenumber(SLIST_FIELD_ISFAVORITE, i)) + { + theColor = theColor * (1 - SKINALPHA_SERVERLIST_FAVORITE) + SKINCOLOR_SERVERLIST_FAVORITE * SKINALPHA_SERVERLIST_FAVORITE; + theAlpha = theAlpha * (1 - SKINALPHA_SERVERLIST_FAVORITE) + SKINALPHA_SERVERLIST_FAVORITE; + } + + s = gethostcachestring(SLIST_FIELD_CNAME, i); + + isv4 = isv6 = 0; + if(substring(s, 0, 1) == "[") + { + isv6 = 1; + me.seenIPv6 += 1; + } + else if(strstrofs("0123456789", substring(s, 0, 1), 0) >= 0) + { + isv4 = 1; + me.seenIPv4 += 1; + } + + q = stof(substring(crypto_getencryptlevel(s), 0, 1)); + if((q <= 0 && cvar("crypto_aeslevel") >= 3) || (q >= 3 && cvar("crypto_aeslevel") <= 0)) + { + theColor = SKINCOLOR_SERVERLIST_IMPOSSIBLE; + theAlpha = SKINALPHA_SERVERLIST_IMPOSSIBLE; + } + + if(q == 1) + { + if(cvar("crypto_aeslevel") >= 2) + q |= 4; + } + if(q == 2) + { + if(cvar("crypto_aeslevel") >= 1) + q |= 4; + } + if(q == 3) + q = 5; + else if(q >= 3) + q -= 2; + // possible status: + // 0: crypto off + // 1: AES possible + // 2: AES recommended but not available + // 3: AES possible and will be used + // 4: AES recommended and will be used + // 5: AES required + + // -------------- + // RENDER ICONS + // -------------- + vector iconSize = '0 0 0'; + iconSize_y = me.realFontSize_y * me.iconsSizeFactor; + iconSize_x = me.realFontSize_x * me.iconsSizeFactor; + + vector iconPos = '0 0 0'; + iconPos_x = (me.columnIconsSize - 3 * iconSize_x) * 0.5; + iconPos_y = (1 - iconSize_y) * 0.5; + + string n; + + if (!(me.seenIPv4 && me.seenIPv6)) + { + iconPos_x += iconSize_x * 0.5; + } + else if(me.seenIPv4 && me.seenIPv6) + { + n = string_null; + if(isv6) + draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_ipv6"), 0); // PRECACHE_PIC_MIPMAP + else if(isv4) + draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_ipv4"), 0); // PRECACHE_PIC_MIPMAP + if(n) + draw_Picture(iconPos, n, iconSize, '1 1 1', 1); + iconPos_x += iconSize_x; + } + + if(q > 0) + { + draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_aeslevel", ftos(q)), 0); // PRECACHE_PIC_MIPMAP + draw_Picture(iconPos, n, iconSize, '1 1 1', 1); + } + iconPos_x += iconSize_x; + + if(modname == "Xonotic") + { + if(pure == 0) + { + draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_pure1"), PRECACHE_PIC_MIPMAP); + draw_Picture(iconPos, n, iconSize, '1 1 1', 1); + } + } + else + { + draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_mod_", modname), PRECACHE_PIC_MIPMAP); + if(draw_PictureSize(n) == '0 0 0') + draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_mod_"), PRECACHE_PIC_MIPMAP); + if(pure == 0) + draw_Picture(iconPos, n, iconSize, '1 1 1', 1); + else + draw_Picture(iconPos, n, iconSize, '1 1 1', SKINALPHA_SERVERLIST_ICON_NONPURE); + } + iconPos_x += iconSize_x; + + if(sflags >= 0 && (sflags & SERVERFLAG_PLAYERSTATS)) + { + draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_stats1"), 0); // PRECACHE_PIC_MIPMAP + draw_Picture(iconPos, n, iconSize, '1 1 1', 1); + } + iconPos_x += iconSize_x; + + // -------------- + // RENDER TEXT + // -------------- + + // ping + s = ftos(p); + draw_Text(me.realUpperMargin * eY + (me.columnPingOrigin + me.columnPingSize - draw_TextWidth(s, 0, me.realFontSize)) * eX, s, me.realFontSize, theColor, theAlpha, 0); + + // server name + s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_NAME, i), me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0); + + // server map + s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_MAP, i), me.columnMapSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + (me.columnMapOrigin + (me.columnMapSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0); + + // server gametype + s = draw_TextShortenToWidth(typestr, me.columnTypeSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + (me.columnTypeOrigin + (me.columnTypeSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0); + + // server playercount + s = strcat(ftos(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)), "/", ftos(gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i))); + draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0); +} + +float XonoticServerList_keyDown(entity me, float scan, float ascii, float shift) +{ + vector org, sz; + + org = boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size); + sz = boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size); + + if(scan == K_ENTER || scan == K_KP_ENTER) + { + ServerList_Connect_Click(NULL, me); + return 1; + } + else if(scan == K_MOUSE2 || scan == K_SPACE) + { + if(me.nItems != 0) + { + main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, me.selectedItem); + DialogOpenButton_Click_withCoords(me, main.serverInfoDialog, org, sz); + return 1; + } + return 0; + } + else if(scan == K_INS || scan == K_MOUSE3 || scan == K_KP_INS) + { + if(me.nItems != 0) + { + me.toggleFavorite(me, me.selectedServer); + me.ipAddressBoxFocused = -1; + return 1; + } + return 0; + } + else if(SUPER(XonoticServerList).keyDown(me, scan, ascii, shift)) + return 1; + else if(!me.controlledTextbox) + return 0; + else + return me.controlledTextbox.keyDown(me.controlledTextbox, scan, ascii, shift); +} + +float XonoticServerList_getTotalHeight(entity me) { + float num_normal_rows = me.nItems; + float num_headers = category_draw_count; + return me.itemHeight * (num_normal_rows + me.categoriesHeight * num_headers); +} +float XonoticServerList_getItemAtPos(entity me, float pos) { + pos = pos / me.itemHeight; + float i; + for (i = category_draw_count - 1; i >= 0; --i) { + float itemidx = category_item[i]; + float itempos = i * me.categoriesHeight + category_item[i]; + if (pos >= itempos + me.categoriesHeight + 1) + return itemidx + 1 + floor(pos - (itempos + me.categoriesHeight + 1)); + if (pos >= itempos) + return itemidx; + } + // No category matches? Note that category 0 is... 0. Therefore no headings exist at all. + return floor(pos); +} +float XonoticServerList_getItemStart(entity me, float item) { + float i; + for (i = category_draw_count - 1; i >= 0; --i) { + float itemidx = category_item[i]; + float itempos = i * me.categoriesHeight + category_item[i]; + if (item >= itemidx + 1) + return (itempos + me.categoriesHeight + 1 + item - (itemidx + 1)) * me.itemHeight; + if (item >= itemidx) + return itempos * me.itemHeight; + } + // No category matches? Note that category 0 is... 0. Therefore no headings exist at all. + return item * me.itemHeight; +} +float XonoticServerList_getItemHeight(entity me, float item) { + float i; + for (i = 0; i < category_draw_count; ++i) { + // Matches exactly the headings with increased height. + if (item == category_item[i]) + return me.itemHeight * (me.categoriesHeight + 1); + } + return me.itemHeight; +} + +#endif diff --git a/qcsrc/menu/xonotic/skinlist.c b/qcsrc/menu/xonotic/skinlist.c deleted file mode 100644 index 6d11fe9c6..000000000 --- a/qcsrc/menu/xonotic/skinlist.c +++ /dev/null @@ -1,196 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticSkinList) EXTENDS(XonoticListBox) - METHOD(XonoticSkinList, configureXonoticSkinList, void(entity)) - ATTRIB(XonoticSkinList, rowsPerItem, float, 4) - METHOD(XonoticSkinList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticSkinList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticSkinList, getSkins, void(entity)) - METHOD(XonoticSkinList, setSkin, void(entity)) - METHOD(XonoticSkinList, loadCvars, void(entity)) - METHOD(XonoticSkinList, saveCvars, void(entity)) - METHOD(XonoticSkinList, skinParameter, string(entity, float, float)) - METHOD(XonoticSkinList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticSkinList, keyDown, float(entity, float, float, float)) - METHOD(XonoticSkinList, destroy, void(entity)) - - ATTRIB(XonoticSkinList, skinlist, float, -1) - ATTRIB(XonoticSkinList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticSkinList, columnPreviewOrigin, float, 0) - ATTRIB(XonoticSkinList, columnPreviewSize, float, 0) - ATTRIB(XonoticSkinList, columnNameOrigin, float, 0) - ATTRIB(XonoticSkinList, columnNameSize, float, 0) - ATTRIB(XonoticSkinList, realUpperMargin1, float, 0) - ATTRIB(XonoticSkinList, realUpperMargin2, float, 0) - ATTRIB(XonoticSkinList, origin, vector, '0 0 0') - ATTRIB(XonoticSkinList, itemAbsSize, vector, '0 0 0') - - ATTRIB(XonoticSkinList, name, string, "skinselector") -ENDCLASS(XonoticSkinList) - -entity makeXonoticSkinList(); -void SetSkin_Click(entity btn, entity me); -#endif - -#ifdef IMPLEMENTATION - -const float SKINPARM_NAME = 0; -const float SKINPARM_TITLE = 1; -const float SKINPARM_AUTHOR = 2; -const float SKINPARM_PREVIEW = 3; -const float SKINPARM_COUNT = 4; - -entity makeXonoticSkinList() -{ - entity me; - me = spawnXonoticSkinList(); - me.configureXonoticSkinList(me); - return me; -} - -void XonoticSkinList_configureXonoticSkinList(entity me) -{ - me.configureXonoticListBox(me); - me.getSkins(me); - me.loadCvars(me); -} - -void XonoticSkinList_loadCvars(entity me) -{ - string s; - float i, n; - s = cvar_string("menu_skin"); - n = me.nItems; - for(i = 0; i < n; ++i) - { - if(me.skinParameter(me, i, SKINPARM_NAME) == s) - { - me.selectedItem = i; - break; - } - } -} - -void XonoticSkinList_saveCvars(entity me) -{ - cvar_set("menu_skin", me.skinParameter(me, me.selectedItem, SKINPARM_NAME)); -} - -string XonoticSkinList_skinParameter(entity me, float i, float key) -{ - return bufstr_get(me.skinlist, i * SKINPARM_COUNT + key); -} - -void XonoticSkinList_getSkins(entity me) -{ - float glob, buf, i, n, fh; - string s; - - buf = buf_create(); - glob = search_begin("gfx/menu/*/skinvalues.txt", TRUE, TRUE); - if(glob < 0) - { - me.skinlist = buf; - me.nItems = 0; - return; - } - - n = search_getsize(glob); - for(i = 0; i < n; ++i) - { - s = search_getfilename(glob, i); - bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_NAME, substring(s, 9, strlen(s) - 24)); // the * part - bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_TITLE, _("")); - bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_AUTHOR, _("<AUTHOR>")); - if(draw_PictureSize(strcat("/gfx/menu/", substring(s, 9, strlen(s) - 24), "/skinpreview")) == '0 0 0') - bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_PREVIEW, "nopreview_menuskin"); - else - bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_PREVIEW, strcat("/gfx/menu/", substring(s, 9, strlen(s) - 24), "/skinpreview")); - fh = fopen(language_filename(s), FILE_READ); - if(fh < 0) - { - print("Warning: can't open skinvalues.txt file\n"); - continue; - } - while((s = fgets(fh))) - { - // these two are handled by skinlist.qc - if(substring(s, 0, 6) == "title ") - bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_TITLE, substring(s, 6, strlen(s) - 6)); - else if(substring(s, 0, 7) == "author ") - bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_AUTHOR, substring(s, 7, strlen(s) - 7)); - } - fclose(fh); - } - - search_end(glob); - - me.skinlist = buf; - me.nItems = n; -} - -void XonoticSkinList_destroy(entity me) -{ - buf_del(me.skinlist); -} - -void XonoticSkinList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticSkinList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin1 = 0.5 * (1 - 2.5 * me.realFontSize_y); - me.realUpperMargin2 = me.realUpperMargin1 + 1.5 * me.realFontSize_y; - - me.columnPreviewOrigin = 0; - me.columnPreviewSize = me.itemAbsSize_y / me.itemAbsSize_x * 4 / 3; - me.columnNameOrigin = me.columnPreviewOrigin + me.columnPreviewSize + me.realFontSize_x; - me.columnNameSize = 1 - me.columnPreviewSize - 2 * me.realFontSize_x; -} - -void XonoticSkinList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s; - - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - s = me.skinParameter(me, i, SKINPARM_PREVIEW); - draw_Picture(me.columnPreviewOrigin * eX, s, me.columnPreviewSize * eX + eY, '1 1 1', 1); - - s = me.skinParameter(me, i, SKINPARM_TITLE); - s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_TITLE, SKINALPHA_TEXT, 0); - - s = me.skinParameter(me, i, SKINPARM_AUTHOR); - s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_AUTHOR, SKINALPHA_TEXT, 0); -} - -void XonoticSkinList_setSkin(entity me) -{ - me.saveCvars(me); - localcmd("\nmenu_restart\nmenu_cmd skinselect\n"); -} - -void SetSkin_Click(entity btn, entity me) -{ - me.setSkin(me); -} - -void XonoticSkinList_doubleClickListBoxItem(entity me, float i, vector where) -{ - me.setSkin(me); -} - -float XonoticSkinList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(scan == K_ENTER || scan == K_KP_ENTER) { - me.setSkin(me); - return 1; - } - else - return SUPER(XonoticSkinList).keyDown(me, scan, ascii, shift); -} -#endif diff --git a/qcsrc/menu/xonotic/skinlist.qc b/qcsrc/menu/xonotic/skinlist.qc new file mode 100644 index 000000000..6d11fe9c6 --- /dev/null +++ b/qcsrc/menu/xonotic/skinlist.qc @@ -0,0 +1,196 @@ +#ifdef INTERFACE +CLASS(XonoticSkinList) EXTENDS(XonoticListBox) + METHOD(XonoticSkinList, configureXonoticSkinList, void(entity)) + ATTRIB(XonoticSkinList, rowsPerItem, float, 4) + METHOD(XonoticSkinList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticSkinList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticSkinList, getSkins, void(entity)) + METHOD(XonoticSkinList, setSkin, void(entity)) + METHOD(XonoticSkinList, loadCvars, void(entity)) + METHOD(XonoticSkinList, saveCvars, void(entity)) + METHOD(XonoticSkinList, skinParameter, string(entity, float, float)) + METHOD(XonoticSkinList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticSkinList, keyDown, float(entity, float, float, float)) + METHOD(XonoticSkinList, destroy, void(entity)) + + ATTRIB(XonoticSkinList, skinlist, float, -1) + ATTRIB(XonoticSkinList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticSkinList, columnPreviewOrigin, float, 0) + ATTRIB(XonoticSkinList, columnPreviewSize, float, 0) + ATTRIB(XonoticSkinList, columnNameOrigin, float, 0) + ATTRIB(XonoticSkinList, columnNameSize, float, 0) + ATTRIB(XonoticSkinList, realUpperMargin1, float, 0) + ATTRIB(XonoticSkinList, realUpperMargin2, float, 0) + ATTRIB(XonoticSkinList, origin, vector, '0 0 0') + ATTRIB(XonoticSkinList, itemAbsSize, vector, '0 0 0') + + ATTRIB(XonoticSkinList, name, string, "skinselector") +ENDCLASS(XonoticSkinList) + +entity makeXonoticSkinList(); +void SetSkin_Click(entity btn, entity me); +#endif + +#ifdef IMPLEMENTATION + +const float SKINPARM_NAME = 0; +const float SKINPARM_TITLE = 1; +const float SKINPARM_AUTHOR = 2; +const float SKINPARM_PREVIEW = 3; +const float SKINPARM_COUNT = 4; + +entity makeXonoticSkinList() +{ + entity me; + me = spawnXonoticSkinList(); + me.configureXonoticSkinList(me); + return me; +} + +void XonoticSkinList_configureXonoticSkinList(entity me) +{ + me.configureXonoticListBox(me); + me.getSkins(me); + me.loadCvars(me); +} + +void XonoticSkinList_loadCvars(entity me) +{ + string s; + float i, n; + s = cvar_string("menu_skin"); + n = me.nItems; + for(i = 0; i < n; ++i) + { + if(me.skinParameter(me, i, SKINPARM_NAME) == s) + { + me.selectedItem = i; + break; + } + } +} + +void XonoticSkinList_saveCvars(entity me) +{ + cvar_set("menu_skin", me.skinParameter(me, me.selectedItem, SKINPARM_NAME)); +} + +string XonoticSkinList_skinParameter(entity me, float i, float key) +{ + return bufstr_get(me.skinlist, i * SKINPARM_COUNT + key); +} + +void XonoticSkinList_getSkins(entity me) +{ + float glob, buf, i, n, fh; + string s; + + buf = buf_create(); + glob = search_begin("gfx/menu/*/skinvalues.txt", TRUE, TRUE); + if(glob < 0) + { + me.skinlist = buf; + me.nItems = 0; + return; + } + + n = search_getsize(glob); + for(i = 0; i < n; ++i) + { + s = search_getfilename(glob, i); + bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_NAME, substring(s, 9, strlen(s) - 24)); // the * part + bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_TITLE, _("<TITLE>")); + bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_AUTHOR, _("<AUTHOR>")); + if(draw_PictureSize(strcat("/gfx/menu/", substring(s, 9, strlen(s) - 24), "/skinpreview")) == '0 0 0') + bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_PREVIEW, "nopreview_menuskin"); + else + bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_PREVIEW, strcat("/gfx/menu/", substring(s, 9, strlen(s) - 24), "/skinpreview")); + fh = fopen(language_filename(s), FILE_READ); + if(fh < 0) + { + print("Warning: can't open skinvalues.txt file\n"); + continue; + } + while((s = fgets(fh))) + { + // these two are handled by skinlist.qc + if(substring(s, 0, 6) == "title ") + bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_TITLE, substring(s, 6, strlen(s) - 6)); + else if(substring(s, 0, 7) == "author ") + bufstr_set(buf, i * SKINPARM_COUNT + SKINPARM_AUTHOR, substring(s, 7, strlen(s) - 7)); + } + fclose(fh); + } + + search_end(glob); + + me.skinlist = buf; + me.nItems = n; +} + +void XonoticSkinList_destroy(entity me) +{ + buf_del(me.skinlist); +} + +void XonoticSkinList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticSkinList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin1 = 0.5 * (1 - 2.5 * me.realFontSize_y); + me.realUpperMargin2 = me.realUpperMargin1 + 1.5 * me.realFontSize_y; + + me.columnPreviewOrigin = 0; + me.columnPreviewSize = me.itemAbsSize_y / me.itemAbsSize_x * 4 / 3; + me.columnNameOrigin = me.columnPreviewOrigin + me.columnPreviewSize + me.realFontSize_x; + me.columnNameSize = 1 - me.columnPreviewSize - 2 * me.realFontSize_x; +} + +void XonoticSkinList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s; + + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + s = me.skinParameter(me, i, SKINPARM_PREVIEW); + draw_Picture(me.columnPreviewOrigin * eX, s, me.columnPreviewSize * eX + eY, '1 1 1', 1); + + s = me.skinParameter(me, i, SKINPARM_TITLE); + s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_TITLE, SKINALPHA_TEXT, 0); + + s = me.skinParameter(me, i, SKINPARM_AUTHOR); + s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_AUTHOR, SKINALPHA_TEXT, 0); +} + +void XonoticSkinList_setSkin(entity me) +{ + me.saveCvars(me); + localcmd("\nmenu_restart\nmenu_cmd skinselect\n"); +} + +void SetSkin_Click(entity btn, entity me) +{ + me.setSkin(me); +} + +void XonoticSkinList_doubleClickListBoxItem(entity me, float i, vector where) +{ + me.setSkin(me); +} + +float XonoticSkinList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_KP_ENTER) { + me.setSkin(me); + return 1; + } + else + return SUPER(XonoticSkinList).keyDown(me, scan, ascii, shift); +} +#endif diff --git a/qcsrc/menu/xonotic/slider.c b/qcsrc/menu/xonotic/slider.c deleted file mode 100644 index d63fe1c33..000000000 --- a/qcsrc/menu/xonotic/slider.c +++ /dev/null @@ -1,80 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticSlider) EXTENDS(Slider) - METHOD(XonoticSlider, configureXonoticSlider, void(entity, float, float, float, string)) - METHOD(XonoticSlider, setValue, void(entity, float)) - ATTRIB(XonoticSlider, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT) - ATTRIB(XonoticSlider, image, string, SKINGFX_SLIDER) - ATTRIB(XonoticSlider, tolerance, vector, SKINTOLERANCE_SLIDER) - ATTRIB(XonoticSlider, align, float, 0.5) - ATTRIB(XonoticSlider, color, vector, SKINCOLOR_SLIDER_N) - ATTRIB(XonoticSlider, colorC, vector, SKINCOLOR_SLIDER_C) - ATTRIB(XonoticSlider, colorF, vector, SKINCOLOR_SLIDER_F) - ATTRIB(XonoticSlider, colorD, vector, SKINCOLOR_SLIDER_D) - ATTRIB(XonoticSlider, color2, vector, SKINCOLOR_SLIDER_S) - - ATTRIB(XonoticSlider, cvarName, string, string_null) - METHOD(XonoticSlider, loadCvars, void(entity)) - METHOD(XonoticSlider, saveCvars, void(entity)) - ATTRIB(XonoticSlider, sendCvars, float, 0) - - ATTRIB(XonoticSlider, alpha, float, SKINALPHA_TEXT) - ATTRIB(XonoticSlider, disabledAlpha, float, SKINALPHA_DISABLED) -ENDCLASS(XonoticSlider) -entity makeXonoticSlider(float, float, float, string); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticSlider(float theValueMin, float theValueMax, float theValueStep, string theCvar) -{ - entity me; - me = spawnXonoticSlider(); - me.configureXonoticSlider(me, theValueMin, theValueMax, theValueStep, theCvar); - return me; -} -void XonoticSlider_configureXonoticSlider(entity me, float theValueMin, float theValueMax, float theValueStep, string theCvar) -{ - float vp; - vp = theValueStep * 10; - while(fabs(vp) < fabs(theValueMax - theValueMin) / 40) - vp *= 10; - - me.configureSliderVisuals(me, me.fontSize, me.align, me.valueSpace, me.image); - - if(theCvar) - { - // Prevent flickering of the slider button by initialising the - // slider out of bounds to hide the button before loading the cvar - me.configureSliderValues(me, theValueMin, theValueMin-theValueStep, theValueMax, theValueStep, theValueStep, vp); - me.cvarName = theCvar; - me.loadCvars(me); - me.tooltip = getZonedTooltipForIdentifier(theCvar); - } - else - me.configureSliderValues(me, theValueMin, theValueMin, theValueMax, theValueStep, theValueStep, vp); -} -void XonoticSlider_setValue(entity me, float val) -{ - if(val != me.value) - { - SUPER(XonoticSlider).setValue( me, val ); - me.saveCvars(me); - } -} -void XonoticSlider_loadCvars(entity me) -{ - if (!me.cvarName) - return; - - me.setValue( me, cvar(me.cvarName) ); -} -void XonoticSlider_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - cvar_set(me.cvarName, ftos(me.value)); - - CheckSendCvars(me, me.cvarName); -} -#endif diff --git a/qcsrc/menu/xonotic/slider.qc b/qcsrc/menu/xonotic/slider.qc new file mode 100644 index 000000000..d63fe1c33 --- /dev/null +++ b/qcsrc/menu/xonotic/slider.qc @@ -0,0 +1,80 @@ +#ifdef INTERFACE +CLASS(XonoticSlider) EXTENDS(Slider) + METHOD(XonoticSlider, configureXonoticSlider, void(entity, float, float, float, string)) + METHOD(XonoticSlider, setValue, void(entity, float)) + ATTRIB(XonoticSlider, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT) + ATTRIB(XonoticSlider, image, string, SKINGFX_SLIDER) + ATTRIB(XonoticSlider, tolerance, vector, SKINTOLERANCE_SLIDER) + ATTRIB(XonoticSlider, align, float, 0.5) + ATTRIB(XonoticSlider, color, vector, SKINCOLOR_SLIDER_N) + ATTRIB(XonoticSlider, colorC, vector, SKINCOLOR_SLIDER_C) + ATTRIB(XonoticSlider, colorF, vector, SKINCOLOR_SLIDER_F) + ATTRIB(XonoticSlider, colorD, vector, SKINCOLOR_SLIDER_D) + ATTRIB(XonoticSlider, color2, vector, SKINCOLOR_SLIDER_S) + + ATTRIB(XonoticSlider, cvarName, string, string_null) + METHOD(XonoticSlider, loadCvars, void(entity)) + METHOD(XonoticSlider, saveCvars, void(entity)) + ATTRIB(XonoticSlider, sendCvars, float, 0) + + ATTRIB(XonoticSlider, alpha, float, SKINALPHA_TEXT) + ATTRIB(XonoticSlider, disabledAlpha, float, SKINALPHA_DISABLED) +ENDCLASS(XonoticSlider) +entity makeXonoticSlider(float, float, float, string); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticSlider(float theValueMin, float theValueMax, float theValueStep, string theCvar) +{ + entity me; + me = spawnXonoticSlider(); + me.configureXonoticSlider(me, theValueMin, theValueMax, theValueStep, theCvar); + return me; +} +void XonoticSlider_configureXonoticSlider(entity me, float theValueMin, float theValueMax, float theValueStep, string theCvar) +{ + float vp; + vp = theValueStep * 10; + while(fabs(vp) < fabs(theValueMax - theValueMin) / 40) + vp *= 10; + + me.configureSliderVisuals(me, me.fontSize, me.align, me.valueSpace, me.image); + + if(theCvar) + { + // Prevent flickering of the slider button by initialising the + // slider out of bounds to hide the button before loading the cvar + me.configureSliderValues(me, theValueMin, theValueMin-theValueStep, theValueMax, theValueStep, theValueStep, vp); + me.cvarName = theCvar; + me.loadCvars(me); + me.tooltip = getZonedTooltipForIdentifier(theCvar); + } + else + me.configureSliderValues(me, theValueMin, theValueMin, theValueMax, theValueStep, theValueStep, vp); +} +void XonoticSlider_setValue(entity me, float val) +{ + if(val != me.value) + { + SUPER(XonoticSlider).setValue( me, val ); + me.saveCvars(me); + } +} +void XonoticSlider_loadCvars(entity me) +{ + if (!me.cvarName) + return; + + me.setValue( me, cvar(me.cvarName) ); +} +void XonoticSlider_saveCvars(entity me) +{ + if (!me.cvarName) + return; + + cvar_set(me.cvarName, ftos(me.value)); + + CheckSendCvars(me, me.cvarName); +} +#endif diff --git a/qcsrc/menu/xonotic/slider_decibels.c b/qcsrc/menu/xonotic/slider_decibels.c deleted file mode 100644 index bf847e312..000000000 --- a/qcsrc/menu/xonotic/slider_decibels.c +++ /dev/null @@ -1,105 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticDecibelsSlider) EXTENDS(XonoticSlider) - METHOD(XonoticDecibelsSlider, loadCvars, void(entity)) - METHOD(XonoticDecibelsSlider, saveCvars, void(entity)) - METHOD(XonoticDecibelsSlider, valueToText, string(entity, float)) -ENDCLASS(XonoticDecibelsSlider) -entity makeXonoticDecibelsSlider(float, float, float, string); -#endif - -#ifdef IMPLEMENTATION - -float toDecibelOfSquare(float f, float mi) -{ - float A = log(10) / 20; // note: about 0.115; inverse: about 8.686 - if(mi != 0) - { - // linear scale part - float t = 1 / A + mi; - float y = exp(1 + A * mi); - if(f <= y) - return mi + (t - mi) * (f / y); - } - return log(f) / A; -} - -float fromDecibelOfSquare(float f, float mi) -{ - float A = log(10) / 20; // note: about 0.115; inverse: about 8.686 - if(mi != 0) - { - // linear scale part - float t = 1 / A + mi; - float y = exp(1 + A * mi); - if(f <= t) - return y * ((f - mi) / (t - mi)); - } - return exp(A * f); -} - -entity makeXonoticDecibelsSlider(float theValueMin, float theValueMax, float theValueStep, string theCvar) -{ - entity me; - me = spawnXonoticDecibelsSlider(); - me.configureXonoticSlider(me, theValueMin, theValueMax, theValueStep, theCvar); - return me; -} -void XonoticDecibelsSlider_loadCvars(entity me) -{ - float v; - - if (!me.cvarName) - return; - - v = cvar(me.cvarName); - - // snapping - if(v > fromDecibelOfSquare(me.valueMax - 0.5 * me.valueStep, me.valueMin)) - Slider_setValue(me, me.valueMax); - else - Slider_setValue(me, me.valueStep * floor(0.5 + toDecibelOfSquare(v, me.valueMin) / me.valueStep) ); -} -void XonoticDecibelsSlider_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - if(me.value > me.valueMax - 0.5 * me.valueStep) - cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.valueMax, me.valueMin))); - else - cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.value, me.valueMin))); -} - -float autocvar_menu_snd_sliderscale; -string XonoticDecibelsSlider_valueToText(entity me, float v) -{ - if(v > me.valueMax - 0.5 * me.valueStep) - return CTX(_("VOL^MAX")); - else if(v <= me.valueMin) - return CTX(_("VOL^OFF")); - else if(autocvar_menu_snd_sliderscale == 3) // fake percent scale - return sprintf("%d %%", (v - me.valueMin) / (me.valueMax - me.valueMin) * 100); - else if(autocvar_menu_snd_sliderscale == 2) // 0..10 scale - return sprintf("%.1f", (v - me.valueMin) / (me.valueMax - me.valueMin) * 10); - else if(autocvar_menu_snd_sliderscale == 1) // real percent scale - return sprintf("%.2f %%", fromDecibelOfSquare(v, me.valueMin) * 100); - else // decibel scale - return sprintf(_("%s dB"), ftos_decimals(toDecibelOfSquare(fromDecibelOfSquare(v, me.valueMin), 0), me.valueDigits)); -} - -void _TEST_XonoticDecibelsSlider() -{ - float i; - for(i = -400; i < 0; ++i) - { - float db = i * 0.1; - float v = fromDecibelOfSquare(db, -40); - float dbv = toDecibelOfSquare(v, -40); - float d = dbv - db; - printf("%f -> %f -> %f (diff: %f)\n", db, v, dbv, d); - TEST_Check(fabs(d) > 0.02); - } - TEST_OK(); -} - -#endif diff --git a/qcsrc/menu/xonotic/slider_decibels.qc b/qcsrc/menu/xonotic/slider_decibels.qc new file mode 100644 index 000000000..bf847e312 --- /dev/null +++ b/qcsrc/menu/xonotic/slider_decibels.qc @@ -0,0 +1,105 @@ +#ifdef INTERFACE +CLASS(XonoticDecibelsSlider) EXTENDS(XonoticSlider) + METHOD(XonoticDecibelsSlider, loadCvars, void(entity)) + METHOD(XonoticDecibelsSlider, saveCvars, void(entity)) + METHOD(XonoticDecibelsSlider, valueToText, string(entity, float)) +ENDCLASS(XonoticDecibelsSlider) +entity makeXonoticDecibelsSlider(float, float, float, string); +#endif + +#ifdef IMPLEMENTATION + +float toDecibelOfSquare(float f, float mi) +{ + float A = log(10) / 20; // note: about 0.115; inverse: about 8.686 + if(mi != 0) + { + // linear scale part + float t = 1 / A + mi; + float y = exp(1 + A * mi); + if(f <= y) + return mi + (t - mi) * (f / y); + } + return log(f) / A; +} + +float fromDecibelOfSquare(float f, float mi) +{ + float A = log(10) / 20; // note: about 0.115; inverse: about 8.686 + if(mi != 0) + { + // linear scale part + float t = 1 / A + mi; + float y = exp(1 + A * mi); + if(f <= t) + return y * ((f - mi) / (t - mi)); + } + return exp(A * f); +} + +entity makeXonoticDecibelsSlider(float theValueMin, float theValueMax, float theValueStep, string theCvar) +{ + entity me; + me = spawnXonoticDecibelsSlider(); + me.configureXonoticSlider(me, theValueMin, theValueMax, theValueStep, theCvar); + return me; +} +void XonoticDecibelsSlider_loadCvars(entity me) +{ + float v; + + if (!me.cvarName) + return; + + v = cvar(me.cvarName); + + // snapping + if(v > fromDecibelOfSquare(me.valueMax - 0.5 * me.valueStep, me.valueMin)) + Slider_setValue(me, me.valueMax); + else + Slider_setValue(me, me.valueStep * floor(0.5 + toDecibelOfSquare(v, me.valueMin) / me.valueStep) ); +} +void XonoticDecibelsSlider_saveCvars(entity me) +{ + if (!me.cvarName) + return; + + if(me.value > me.valueMax - 0.5 * me.valueStep) + cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.valueMax, me.valueMin))); + else + cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.value, me.valueMin))); +} + +float autocvar_menu_snd_sliderscale; +string XonoticDecibelsSlider_valueToText(entity me, float v) +{ + if(v > me.valueMax - 0.5 * me.valueStep) + return CTX(_("VOL^MAX")); + else if(v <= me.valueMin) + return CTX(_("VOL^OFF")); + else if(autocvar_menu_snd_sliderscale == 3) // fake percent scale + return sprintf("%d %%", (v - me.valueMin) / (me.valueMax - me.valueMin) * 100); + else if(autocvar_menu_snd_sliderscale == 2) // 0..10 scale + return sprintf("%.1f", (v - me.valueMin) / (me.valueMax - me.valueMin) * 10); + else if(autocvar_menu_snd_sliderscale == 1) // real percent scale + return sprintf("%.2f %%", fromDecibelOfSquare(v, me.valueMin) * 100); + else // decibel scale + return sprintf(_("%s dB"), ftos_decimals(toDecibelOfSquare(fromDecibelOfSquare(v, me.valueMin), 0), me.valueDigits)); +} + +void _TEST_XonoticDecibelsSlider() +{ + float i; + for(i = -400; i < 0; ++i) + { + float db = i * 0.1; + float v = fromDecibelOfSquare(db, -40); + float dbv = toDecibelOfSquare(v, -40); + float d = dbv - db; + printf("%f -> %f -> %f (diff: %f)\n", db, v, dbv, d); + TEST_Check(fabs(d) > 0.02); + } + TEST_OK(); +} + +#endif diff --git a/qcsrc/menu/xonotic/slider_particles.c b/qcsrc/menu/xonotic/slider_particles.c deleted file mode 100644 index db29f556d..000000000 --- a/qcsrc/menu/xonotic/slider_particles.c +++ /dev/null @@ -1,48 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticParticlesSlider) EXTENDS(XonoticTextSlider) - METHOD(XonoticParticlesSlider, configureXonoticParticlesSlider, void(entity)) - METHOD(XonoticParticlesSlider, loadCvars, void(entity)) - METHOD(XonoticParticlesSlider, saveCvars, void(entity)) -ENDCLASS(XonoticParticlesSlider) -entity makeXonoticParticlesSlider(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticParticlesSlider() -{ - entity me; - me = spawnXonoticParticlesSlider(); - me.configureXonoticParticlesSlider(me); - return me; -} -void XonoticParticlesSlider_configureXonoticParticlesSlider(entity me) -{ - me.configureXonoticTextSlider(me, "cl_particles_quality"); - if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^OMG")), "0.4 250 0"); } - me.addValue(me, ZCTX(_("PART^Low")), "0.4 500 0"); - me.addValue(me, ZCTX(_("PART^Medium")), "0.8 750 0"); - me.addValue(me, ZCTX(_("PART^Normal")), "1.0 1000 1"); - me.addValue(me, ZCTX(_("PART^High")), "1.0 1500 1"); - me.addValue(me, ZCTX(_("PART^Ultra")), "1.0 2000 2"); - if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^Ultimate")), "1.0 3000 2"); } - me.configureXonoticTextSliderValues(me); -} -void XonoticParticlesSlider_loadCvars(entity me) -{ - me.setValueFromIdentifier(me, sprintf("%s %s %s", - cvar_string("cl_particles_quality"), - cvar_string("r_drawparticles_drawdistance"), - cvar_string("cl_damageeffect") - )); -} -void XonoticParticlesSlider_saveCvars(entity me) -{ - if(me.value >= 0 || me.value < me.nValues) - { - tokenize_console(me.getIdentifier(me)); - cvar_set("cl_particles_quality", argv(0)); - cvar_set("r_drawparticles_drawdistance", argv(1)); - cvar_set("cl_damageeffect", argv(2)); - } -} -#endif diff --git a/qcsrc/menu/xonotic/slider_particles.qc b/qcsrc/menu/xonotic/slider_particles.qc new file mode 100644 index 000000000..db29f556d --- /dev/null +++ b/qcsrc/menu/xonotic/slider_particles.qc @@ -0,0 +1,48 @@ +#ifdef INTERFACE +CLASS(XonoticParticlesSlider) EXTENDS(XonoticTextSlider) + METHOD(XonoticParticlesSlider, configureXonoticParticlesSlider, void(entity)) + METHOD(XonoticParticlesSlider, loadCvars, void(entity)) + METHOD(XonoticParticlesSlider, saveCvars, void(entity)) +ENDCLASS(XonoticParticlesSlider) +entity makeXonoticParticlesSlider(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticParticlesSlider() +{ + entity me; + me = spawnXonoticParticlesSlider(); + me.configureXonoticParticlesSlider(me); + return me; +} +void XonoticParticlesSlider_configureXonoticParticlesSlider(entity me) +{ + me.configureXonoticTextSlider(me, "cl_particles_quality"); + if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^OMG")), "0.4 250 0"); } + me.addValue(me, ZCTX(_("PART^Low")), "0.4 500 0"); + me.addValue(me, ZCTX(_("PART^Medium")), "0.8 750 0"); + me.addValue(me, ZCTX(_("PART^Normal")), "1.0 1000 1"); + me.addValue(me, ZCTX(_("PART^High")), "1.0 1500 1"); + me.addValue(me, ZCTX(_("PART^Ultra")), "1.0 2000 2"); + if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^Ultimate")), "1.0 3000 2"); } + me.configureXonoticTextSliderValues(me); +} +void XonoticParticlesSlider_loadCvars(entity me) +{ + me.setValueFromIdentifier(me, sprintf("%s %s %s", + cvar_string("cl_particles_quality"), + cvar_string("r_drawparticles_drawdistance"), + cvar_string("cl_damageeffect") + )); +} +void XonoticParticlesSlider_saveCvars(entity me) +{ + if(me.value >= 0 || me.value < me.nValues) + { + tokenize_console(me.getIdentifier(me)); + cvar_set("cl_particles_quality", argv(0)); + cvar_set("r_drawparticles_drawdistance", argv(1)); + cvar_set("cl_damageeffect", argv(2)); + } +} +#endif diff --git a/qcsrc/menu/xonotic/slider_picmip.c b/qcsrc/menu/xonotic/slider_picmip.c deleted file mode 100644 index ddedc4bab..000000000 --- a/qcsrc/menu/xonotic/slider_picmip.c +++ /dev/null @@ -1,53 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticPicmipSlider) EXTENDS(XonoticTextSlider) - METHOD(XonoticPicmipSlider, configureXonoticPicmipSlider, void(entity)) - METHOD(XonoticPicmipSlider, draw, void(entity)) - METHOD(XonoticPicmipSlider, autofix, void(entity)) - ATTRIB(XonoticPicmipSlider, have_s3tc, float, 0) -ENDCLASS(XonoticPicmipSlider) -entity makeXonoticPicmipSlider(); // note: you still need to call addValue and configureXonoticTextSliderValues! -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticPicmipSlider() -{ - entity me; - me = spawnXonoticPicmipSlider(); - me.configureXonoticPicmipSlider(me); - return me; -} -void XonoticPicmipSlider_configureXonoticPicmipSlider(entity me) -{ - me.configureXonoticTextSlider(me, "gl_picmip"); - me.autofix(me); - me.have_s3tc = GL_Have_TextureCompression(); -} -float texmemsize(float s3tc) -{ - return - ( - 2500 * pow(0.25, max(0, cvar("gl_picmip") + cvar("gl_picmip_other"))) - + 1500 * pow(0.25, max(0, cvar("gl_picmip") + cvar("gl_picmip_world"))) - ) * ((s3tc && (cvar("r_texture_dds_load") || cvar("gl_texturecompression"))) ? 0.2 : 1.0); // TC: normalmaps 50%, other 25%, few incompressible, guessing 40% as conservative average -} -void XonoticPicmipSlider_autofix(entity me) -{ - float max_hard, max_soft; - if(cvar("menu_picmip_bypass")) - return; - max_hard = cvar("sys_memsize_virtual"); - max_soft = cvar("sys_memsize_physical"); - if(max_hard > 0) - { - while(me.value > 0 && texmemsize(me.have_s3tc) > max_hard) - me.setValue(me, me.value - 1); - } - // TODO also check the soft limit! - // TODO better handling than clamping the slider! -} -void XonoticPicmipSlider_draw(entity me) -{ - me.autofix(me); - SUPER(XonoticPicmipSlider).draw(me); -} -#endif diff --git a/qcsrc/menu/xonotic/slider_picmip.qc b/qcsrc/menu/xonotic/slider_picmip.qc new file mode 100644 index 000000000..ddedc4bab --- /dev/null +++ b/qcsrc/menu/xonotic/slider_picmip.qc @@ -0,0 +1,53 @@ +#ifdef INTERFACE +CLASS(XonoticPicmipSlider) EXTENDS(XonoticTextSlider) + METHOD(XonoticPicmipSlider, configureXonoticPicmipSlider, void(entity)) + METHOD(XonoticPicmipSlider, draw, void(entity)) + METHOD(XonoticPicmipSlider, autofix, void(entity)) + ATTRIB(XonoticPicmipSlider, have_s3tc, float, 0) +ENDCLASS(XonoticPicmipSlider) +entity makeXonoticPicmipSlider(); // note: you still need to call addValue and configureXonoticTextSliderValues! +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticPicmipSlider() +{ + entity me; + me = spawnXonoticPicmipSlider(); + me.configureXonoticPicmipSlider(me); + return me; +} +void XonoticPicmipSlider_configureXonoticPicmipSlider(entity me) +{ + me.configureXonoticTextSlider(me, "gl_picmip"); + me.autofix(me); + me.have_s3tc = GL_Have_TextureCompression(); +} +float texmemsize(float s3tc) +{ + return + ( + 2500 * pow(0.25, max(0, cvar("gl_picmip") + cvar("gl_picmip_other"))) + + 1500 * pow(0.25, max(0, cvar("gl_picmip") + cvar("gl_picmip_world"))) + ) * ((s3tc && (cvar("r_texture_dds_load") || cvar("gl_texturecompression"))) ? 0.2 : 1.0); // TC: normalmaps 50%, other 25%, few incompressible, guessing 40% as conservative average +} +void XonoticPicmipSlider_autofix(entity me) +{ + float max_hard, max_soft; + if(cvar("menu_picmip_bypass")) + return; + max_hard = cvar("sys_memsize_virtual"); + max_soft = cvar("sys_memsize_physical"); + if(max_hard > 0) + { + while(me.value > 0 && texmemsize(me.have_s3tc) > max_hard) + me.setValue(me, me.value - 1); + } + // TODO also check the soft limit! + // TODO better handling than clamping the slider! +} +void XonoticPicmipSlider_draw(entity me) +{ + me.autofix(me); + SUPER(XonoticPicmipSlider).draw(me); +} +#endif diff --git a/qcsrc/menu/xonotic/slider_resolution.c b/qcsrc/menu/xonotic/slider_resolution.c deleted file mode 100644 index 66f48f9e5..000000000 --- a/qcsrc/menu/xonotic/slider_resolution.c +++ /dev/null @@ -1,220 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticResolutionSlider) EXTENDS(XonoticTextSlider) - METHOD(XonoticResolutionSlider, configureXonoticResolutionSlider, void(entity)) - METHOD(XonoticResolutionSlider, loadResolutions, void(entity, float)) - METHOD(XonoticResolutionSlider, addResolution, void(entity, float, float, float)) - METHOD(XonoticResolutionSlider, loadCvars, void(entity)) - METHOD(XonoticResolutionSlider, saveCvars, void(entity)) - METHOD(XonoticResolutionSlider, draw, void(entity)) - ATTRIB(XonoticResolutionSlider, vid_fullscreen, float, -1) -ENDCLASS(XonoticResolutionSlider) -entity makeXonoticResolutionSlider(); -float updateConwidths(float width, float height, float pixelheight); -#endif - -#ifdef IMPLEMENTATION - -/* private static */ float XonoticResolutionSlider_DataHasChanged; - -// Updates cvars (to be called by menu.qc at startup or on detected res change) -float updateConwidths(float width, float height, float pixelheight) -{ - vector r, c; - float minfactor, maxfactor; - float sz, f; - - sz = cvar("menu_vid_scale"); - if (sz < -1) - return 0; // No recalculation. - - // Save off current settings. - cvar_set("_menu_vid_width", ftos(width)); - cvar_set("_menu_vid_height", ftos(height)); - cvar_set("_menu_vid_pixelheight", ftos(pixelheight)); - cvar_set("_menu_vid_desktopfullscreen", cvar_string("vid_desktopfullscreen")); - - r_x = width; - r_y = height; - r_z = pixelheight; - - // calculate the base resolution - c_z = 0; - c_x = 800; - c_y = c_x * r_y * r_z / r_x; - if(c_y < 600) - { - c_y = 600; - c_x = c_y * r_x / (r_y * r_z); - } - - f = min(r_x / c_x, r_y / c_y); - if(f < 1) - c = c * f; // ensures that c_x <= r_x and c_y <= r_y - - minfactor = min(1, 640 / c_x); // can be > 1 only if c_x is <640 - maxfactor = max(1, r_x / c_x, r_y / c_y); // can be < 1 only if r_x < c_x and r_y < c_y - dprint("min factor: ", ftos(minfactor), "\n"); - dprint("max factor: ", ftos(maxfactor), "\n"); - - if(sz < 0) - f = 1 - (maxfactor - 1) * sz; - else if(sz > 0) - f = 1 + (minfactor - 1) * sz; - else - f = 1; - c = c * f; // fteqcc fail - - c_x = rint(c_x); - c_y = rint(c_y); - - // Please reload resolutions list and such stuff. - XonoticResolutionSlider_DataHasChanged = TRUE; - - if (c_x != cvar("vid_conwidth") || c_y != cvar("vid_conheight")) - { - cvar_set("vid_conwidth", ftos(c_x)); - cvar_set("vid_conheight", ftos(c_y)); - return 1; - } - return 0; -} -entity makeXonoticResolutionSlider() -{ - entity me; - me = spawnXonoticResolutionSlider(); - me.configureXonoticResolutionSlider(me); - return me; -} -void XonoticResolutionSlider_addResolution(entity me, float w, float h, float pixelheight) -{ - float i; - for (i = 0; i < me.nValues; ++i) - { - tokenize_console(me.valueToIdentifier(me, i)); - if (w > stof(argv(0))) continue; - if (w < stof(argv(0))) break; - if (h > stof(argv(1))) continue; - if (h < stof(argv(1))) break; - if (pixelheight > stof(argv(2)) + 0.01) continue; - if (pixelheight < stof(argv(2)) - 0.01) break; - return; // already there - } - if (pixelheight != 1) - { - float aspect = w / (h * pixelheight); - float bestdenom = rint(aspect); - float bestnum = 1; - float denom; - for (denom = 2; denom < 10; ++denom) { - float num = rint(aspect * denom); - if (fabs(num / denom - aspect) < fabs(bestnum / bestdenom - aspect)) - { - bestnum = num; - bestdenom = denom; - } - } - me.insertValue(me, i, strzone(sprintf(_("%dx%d (%d:%d)"), w, h, bestnum, bestdenom)), strzone(strcat(ftos(w), " ", ftos(h), " ", ftos(pixelheight)))); - } - else - me.insertValue(me, i, strzone(sprintf(_("%dx%d"), w, h)), strzone(strcat(ftos(w), " ", ftos(h), " ", ftos(pixelheight)))); -} -float autocvar_menu_vid_allowdualscreenresolution; -void XonoticResolutionSlider_configureXonoticResolutionSlider(entity me) -{ - me.configureXonoticTextSlider(me, "_menu_vid_width"); - me.loadResolutions(me, cvar("vid_fullscreen")); -} -void XonoticResolutionSlider_loadResolutions(entity me, float fullscreen) -{ - float i; - vector r; - - // HACK: text slider assumes the strings are constants, so clearValues - // will not unzone them - for(i = 0; i < me.nValues; ++i) - { - strunzone(me.valueToIdentifier(me, i)); - strunzone(me.valueToText(me, i)); - } - // NOW we can safely clear. - me.clearValues(me); - - if (fullscreen) - { - for(i = 0;; ++i) - { - r = getresolution(i); - if(r_x == 0 && r_y == 0) - break; - if(r_x < 640 || r_y < 480) - continue; - if(r_x > 2 * r_y) // likely dualscreen resolution, skip this one - if(autocvar_menu_vid_allowdualscreenresolution <= 0) - continue; - me.addResolution(me, r_x, r_y, r_z); - } - r = getresolution(-1); - if(r_x != 0 || r_y != 0) - me.addResolution(me, r_x, r_y, r_z); - dprint("Added system resolutions.\n"); - } - - if(me.nValues == 0) - { - me.addResolution(me, 640, 480, 1); // pc res -#if 0 - me.addResolution(me, 720, 480, 1.125); // DVD NTSC 4:3 - me.addResolution(me, 720, 576, 0.9375); // DVD PAL 4:3 - me.addResolution(me, 720, 480, 0.84375); // DVD NTSC 16:9 - me.addResolution(me, 720, 576, 0.703125); // DVD PAL 16:9 -#endif - me.addResolution(me, 800, 480, 1); // 480p at 1:1 pixel aspect - me.addResolution(me, 800, 600, 1); // pc res - me.addResolution(me, 1024, 600, 1); // notebook res - me.addResolution(me, 1024, 768, 1); // pc res - me.addResolution(me, 1280, 720, 1); // 720p - me.addResolution(me, 1280, 960, 1); // pc res - me.addResolution(me, 1280, 1024, 1); // pc res - me.addResolution(me, 1920, 1080, 1); // 1080p - dprint("Added default resolutions.\n"); - } - dprint("Total number of resolutions detected: ", ftos(me.nValues), "\n"); - - me.vid_fullscreen = fullscreen; - - me.configureXonoticTextSliderValues(me); -} -void XonoticResolutionSlider_loadCvars(entity me) -{ - me.setValueFromIdentifier(me, strcat(cvar_string("_menu_vid_width"), " ", cvar_string("_menu_vid_height"), " ", cvar_string("_menu_vid_pixelheight"))); -} -void XonoticResolutionSlider_saveCvars(entity me) -{ - if(me.value >= 0 || me.value < me.nValues) - { - tokenize_console(me.getIdentifier(me)); - cvar_set("_menu_vid_width", argv(0)); - cvar_set("_menu_vid_height", argv(1)); - cvar_set("_menu_vid_pixelheight", argv(2)); - vector r = getresolution(-1); - if (stof(argv(0)) == r_x && stof(argv(1)) == r_y && fabs(stof(argv(2)) - r_z) < 0.01) - cvar_set("_menu_vid_desktopfullscreen", "1"); - else - cvar_set("_menu_vid_desktopfullscreen", "0"); - } -} -void XonoticResolutionSlider_draw(entity me) -{ - if (cvar("vid_fullscreen") != me.vid_fullscreen) - { - me.loadResolutions(me, cvar("vid_fullscreen")); - XonoticResolutionSlider_DataHasChanged = TRUE; - } - if (XonoticResolutionSlider_DataHasChanged) - { - XonoticResolutionSlider_DataHasChanged = FALSE; - me.loadCvars(me); - } - SUPER(XonoticResolutionSlider).draw(me); -} -#endif diff --git a/qcsrc/menu/xonotic/slider_resolution.qc b/qcsrc/menu/xonotic/slider_resolution.qc new file mode 100644 index 000000000..66f48f9e5 --- /dev/null +++ b/qcsrc/menu/xonotic/slider_resolution.qc @@ -0,0 +1,220 @@ +#ifdef INTERFACE +CLASS(XonoticResolutionSlider) EXTENDS(XonoticTextSlider) + METHOD(XonoticResolutionSlider, configureXonoticResolutionSlider, void(entity)) + METHOD(XonoticResolutionSlider, loadResolutions, void(entity, float)) + METHOD(XonoticResolutionSlider, addResolution, void(entity, float, float, float)) + METHOD(XonoticResolutionSlider, loadCvars, void(entity)) + METHOD(XonoticResolutionSlider, saveCvars, void(entity)) + METHOD(XonoticResolutionSlider, draw, void(entity)) + ATTRIB(XonoticResolutionSlider, vid_fullscreen, float, -1) +ENDCLASS(XonoticResolutionSlider) +entity makeXonoticResolutionSlider(); +float updateConwidths(float width, float height, float pixelheight); +#endif + +#ifdef IMPLEMENTATION + +/* private static */ float XonoticResolutionSlider_DataHasChanged; + +// Updates cvars (to be called by menu.qc at startup or on detected res change) +float updateConwidths(float width, float height, float pixelheight) +{ + vector r, c; + float minfactor, maxfactor; + float sz, f; + + sz = cvar("menu_vid_scale"); + if (sz < -1) + return 0; // No recalculation. + + // Save off current settings. + cvar_set("_menu_vid_width", ftos(width)); + cvar_set("_menu_vid_height", ftos(height)); + cvar_set("_menu_vid_pixelheight", ftos(pixelheight)); + cvar_set("_menu_vid_desktopfullscreen", cvar_string("vid_desktopfullscreen")); + + r_x = width; + r_y = height; + r_z = pixelheight; + + // calculate the base resolution + c_z = 0; + c_x = 800; + c_y = c_x * r_y * r_z / r_x; + if(c_y < 600) + { + c_y = 600; + c_x = c_y * r_x / (r_y * r_z); + } + + f = min(r_x / c_x, r_y / c_y); + if(f < 1) + c = c * f; // ensures that c_x <= r_x and c_y <= r_y + + minfactor = min(1, 640 / c_x); // can be > 1 only if c_x is <640 + maxfactor = max(1, r_x / c_x, r_y / c_y); // can be < 1 only if r_x < c_x and r_y < c_y + dprint("min factor: ", ftos(minfactor), "\n"); + dprint("max factor: ", ftos(maxfactor), "\n"); + + if(sz < 0) + f = 1 - (maxfactor - 1) * sz; + else if(sz > 0) + f = 1 + (minfactor - 1) * sz; + else + f = 1; + c = c * f; // fteqcc fail + + c_x = rint(c_x); + c_y = rint(c_y); + + // Please reload resolutions list and such stuff. + XonoticResolutionSlider_DataHasChanged = TRUE; + + if (c_x != cvar("vid_conwidth") || c_y != cvar("vid_conheight")) + { + cvar_set("vid_conwidth", ftos(c_x)); + cvar_set("vid_conheight", ftos(c_y)); + return 1; + } + return 0; +} +entity makeXonoticResolutionSlider() +{ + entity me; + me = spawnXonoticResolutionSlider(); + me.configureXonoticResolutionSlider(me); + return me; +} +void XonoticResolutionSlider_addResolution(entity me, float w, float h, float pixelheight) +{ + float i; + for (i = 0; i < me.nValues; ++i) + { + tokenize_console(me.valueToIdentifier(me, i)); + if (w > stof(argv(0))) continue; + if (w < stof(argv(0))) break; + if (h > stof(argv(1))) continue; + if (h < stof(argv(1))) break; + if (pixelheight > stof(argv(2)) + 0.01) continue; + if (pixelheight < stof(argv(2)) - 0.01) break; + return; // already there + } + if (pixelheight != 1) + { + float aspect = w / (h * pixelheight); + float bestdenom = rint(aspect); + float bestnum = 1; + float denom; + for (denom = 2; denom < 10; ++denom) { + float num = rint(aspect * denom); + if (fabs(num / denom - aspect) < fabs(bestnum / bestdenom - aspect)) + { + bestnum = num; + bestdenom = denom; + } + } + me.insertValue(me, i, strzone(sprintf(_("%dx%d (%d:%d)"), w, h, bestnum, bestdenom)), strzone(strcat(ftos(w), " ", ftos(h), " ", ftos(pixelheight)))); + } + else + me.insertValue(me, i, strzone(sprintf(_("%dx%d"), w, h)), strzone(strcat(ftos(w), " ", ftos(h), " ", ftos(pixelheight)))); +} +float autocvar_menu_vid_allowdualscreenresolution; +void XonoticResolutionSlider_configureXonoticResolutionSlider(entity me) +{ + me.configureXonoticTextSlider(me, "_menu_vid_width"); + me.loadResolutions(me, cvar("vid_fullscreen")); +} +void XonoticResolutionSlider_loadResolutions(entity me, float fullscreen) +{ + float i; + vector r; + + // HACK: text slider assumes the strings are constants, so clearValues + // will not unzone them + for(i = 0; i < me.nValues; ++i) + { + strunzone(me.valueToIdentifier(me, i)); + strunzone(me.valueToText(me, i)); + } + // NOW we can safely clear. + me.clearValues(me); + + if (fullscreen) + { + for(i = 0;; ++i) + { + r = getresolution(i); + if(r_x == 0 && r_y == 0) + break; + if(r_x < 640 || r_y < 480) + continue; + if(r_x > 2 * r_y) // likely dualscreen resolution, skip this one + if(autocvar_menu_vid_allowdualscreenresolution <= 0) + continue; + me.addResolution(me, r_x, r_y, r_z); + } + r = getresolution(-1); + if(r_x != 0 || r_y != 0) + me.addResolution(me, r_x, r_y, r_z); + dprint("Added system resolutions.\n"); + } + + if(me.nValues == 0) + { + me.addResolution(me, 640, 480, 1); // pc res +#if 0 + me.addResolution(me, 720, 480, 1.125); // DVD NTSC 4:3 + me.addResolution(me, 720, 576, 0.9375); // DVD PAL 4:3 + me.addResolution(me, 720, 480, 0.84375); // DVD NTSC 16:9 + me.addResolution(me, 720, 576, 0.703125); // DVD PAL 16:9 +#endif + me.addResolution(me, 800, 480, 1); // 480p at 1:1 pixel aspect + me.addResolution(me, 800, 600, 1); // pc res + me.addResolution(me, 1024, 600, 1); // notebook res + me.addResolution(me, 1024, 768, 1); // pc res + me.addResolution(me, 1280, 720, 1); // 720p + me.addResolution(me, 1280, 960, 1); // pc res + me.addResolution(me, 1280, 1024, 1); // pc res + me.addResolution(me, 1920, 1080, 1); // 1080p + dprint("Added default resolutions.\n"); + } + dprint("Total number of resolutions detected: ", ftos(me.nValues), "\n"); + + me.vid_fullscreen = fullscreen; + + me.configureXonoticTextSliderValues(me); +} +void XonoticResolutionSlider_loadCvars(entity me) +{ + me.setValueFromIdentifier(me, strcat(cvar_string("_menu_vid_width"), " ", cvar_string("_menu_vid_height"), " ", cvar_string("_menu_vid_pixelheight"))); +} +void XonoticResolutionSlider_saveCvars(entity me) +{ + if(me.value >= 0 || me.value < me.nValues) + { + tokenize_console(me.getIdentifier(me)); + cvar_set("_menu_vid_width", argv(0)); + cvar_set("_menu_vid_height", argv(1)); + cvar_set("_menu_vid_pixelheight", argv(2)); + vector r = getresolution(-1); + if (stof(argv(0)) == r_x && stof(argv(1)) == r_y && fabs(stof(argv(2)) - r_z) < 0.01) + cvar_set("_menu_vid_desktopfullscreen", "1"); + else + cvar_set("_menu_vid_desktopfullscreen", "0"); + } +} +void XonoticResolutionSlider_draw(entity me) +{ + if (cvar("vid_fullscreen") != me.vid_fullscreen) + { + me.loadResolutions(me, cvar("vid_fullscreen")); + XonoticResolutionSlider_DataHasChanged = TRUE; + } + if (XonoticResolutionSlider_DataHasChanged) + { + XonoticResolutionSlider_DataHasChanged = FALSE; + me.loadCvars(me); + } + SUPER(XonoticResolutionSlider).draw(me); +} +#endif diff --git a/qcsrc/menu/xonotic/slider_sbfadetime.c b/qcsrc/menu/xonotic/slider_sbfadetime.c deleted file mode 100644 index 39f91f933..000000000 --- a/qcsrc/menu/xonotic/slider_sbfadetime.c +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticScoreboardFadeTimeSlider) EXTENDS(XonoticTextSlider) - METHOD(XonoticScoreboardFadeTimeSlider, configureXonoticScoreboardFadeTimeSlider, void(entity)) - METHOD(XonoticScoreboardFadeTimeSlider, loadCvars, void(entity)) - METHOD(XonoticScoreboardFadeTimeSlider, saveCvars, void(entity)) -ENDCLASS(XonoticScoreboardFadeTimeSlider) -entity makeXonoticScoreboardFadeTimeSlider(); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticScoreboardFadeTimeSlider() -{ - entity me; - me = spawnXonoticScoreboardFadeTimeSlider(); - me.configureXonoticScoreboardFadeTimeSlider(me); - return me; -} -void XonoticScoreboardFadeTimeSlider_configureXonoticScoreboardFadeTimeSlider(entity me) -{ - me.configureXonoticTextSlider(me, "scoreboard_fadeinspeed"); - me.addValue(me, ZCTX(_("PART^Slow")), "5 2.5"); - me.addValue(me, ZCTX(_("PART^Normal")), "10 5"); - me.addValue(me, ZCTX(_("PART^Fast")), "15 7.5"); - me.addValue(me, ZCTX(_("PART^Instant")), "0 0"); - me.configureXonoticTextSliderValues(me); -} -void XonoticScoreboardFadeTimeSlider_loadCvars(entity me) -{ - me.setValueFromIdentifier(me, sprintf("%s %s", - cvar_string("scoreboard_fadeinspeed"), - cvar_string("scoreboard_fadeoutspeed") - )); -} -void XonoticScoreboardFadeTimeSlider_saveCvars(entity me) -{ - if(me.value >= 0 || me.value < me.nValues) - { - tokenize_console(me.getIdentifier(me)); - cvar_set("scoreboard_fadeinspeed", argv(0)); - cvar_set("scoreboard_fadeoutspeed", argv(1)); - } -} -#endif diff --git a/qcsrc/menu/xonotic/slider_sbfadetime.qc b/qcsrc/menu/xonotic/slider_sbfadetime.qc new file mode 100644 index 000000000..39f91f933 --- /dev/null +++ b/qcsrc/menu/xonotic/slider_sbfadetime.qc @@ -0,0 +1,43 @@ +#ifdef INTERFACE +CLASS(XonoticScoreboardFadeTimeSlider) EXTENDS(XonoticTextSlider) + METHOD(XonoticScoreboardFadeTimeSlider, configureXonoticScoreboardFadeTimeSlider, void(entity)) + METHOD(XonoticScoreboardFadeTimeSlider, loadCvars, void(entity)) + METHOD(XonoticScoreboardFadeTimeSlider, saveCvars, void(entity)) +ENDCLASS(XonoticScoreboardFadeTimeSlider) +entity makeXonoticScoreboardFadeTimeSlider(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticScoreboardFadeTimeSlider() +{ + entity me; + me = spawnXonoticScoreboardFadeTimeSlider(); + me.configureXonoticScoreboardFadeTimeSlider(me); + return me; +} +void XonoticScoreboardFadeTimeSlider_configureXonoticScoreboardFadeTimeSlider(entity me) +{ + me.configureXonoticTextSlider(me, "scoreboard_fadeinspeed"); + me.addValue(me, ZCTX(_("PART^Slow")), "5 2.5"); + me.addValue(me, ZCTX(_("PART^Normal")), "10 5"); + me.addValue(me, ZCTX(_("PART^Fast")), "15 7.5"); + me.addValue(me, ZCTX(_("PART^Instant")), "0 0"); + me.configureXonoticTextSliderValues(me); +} +void XonoticScoreboardFadeTimeSlider_loadCvars(entity me) +{ + me.setValueFromIdentifier(me, sprintf("%s %s", + cvar_string("scoreboard_fadeinspeed"), + cvar_string("scoreboard_fadeoutspeed") + )); +} +void XonoticScoreboardFadeTimeSlider_saveCvars(entity me) +{ + if(me.value >= 0 || me.value < me.nValues) + { + tokenize_console(me.getIdentifier(me)); + cvar_set("scoreboard_fadeinspeed", argv(0)); + cvar_set("scoreboard_fadeoutspeed", argv(1)); + } +} +#endif diff --git a/qcsrc/menu/xonotic/soundlist.c b/qcsrc/menu/xonotic/soundlist.c deleted file mode 100644 index 7d1515062..000000000 --- a/qcsrc/menu/xonotic/soundlist.c +++ /dev/null @@ -1,175 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticSoundList) EXTENDS(XonoticListBox) - METHOD(XonoticSoundList, configureXonoticSoundList, void(entity)) - ATTRIB(XonoticSoundList, rowsPerItem, float, 1) - METHOD(XonoticSoundList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticSoundList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticSoundList, getSounds, void(entity)) - METHOD(XonoticSoundList, soundName, string(entity, float)) - METHOD(XonoticSoundList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticSoundList, keyDown, float(entity, float, float, float)) - METHOD(XonoticSoundList, destroy, void(entity)) - METHOD(XonoticSoundList, showNotify, void(entity)) - - ATTRIB(XonoticSoundList, listSound, float, -1) - ATTRIB(XonoticSoundList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticSoundList, columnNameOrigin, float, 0) - ATTRIB(XonoticSoundList, columnNameSize, float, 0) - ATTRIB(XonoticSoundList, columnNumberOrigin, float, 0) - ATTRIB(XonoticSoundList, columnNumberSize, float, 0) - ATTRIB(XonoticSoundList, realUpperMargin, float, 0) - ATTRIB(XonoticSoundList, origin, vector, '0 0 0') - ATTRIB(XonoticSoundList, itemAbsSize, vector, '0 0 0') - - ATTRIB(XonoticSoundList, filterString, string, string_null) - ATTRIB(XonoticSoundList, playlist, entity, world) -ENDCLASS(XonoticSoundList) - -entity makeXonoticSoundList(); -void SoundList_Filter_Change(entity box, entity me); -void SoundList_Add(entity box, entity me); -void SoundList_Add_All(entity box, entity me); -void SoundList_Menu_Track_Change(entity box, entity me); -void SoundList_Menu_Track_Reset(entity box, entity me); -#endif - -#ifdef IMPLEMENTATION - -entity makeXonoticSoundList() -{ - entity me; - me = spawnXonoticSoundList(); - me.configureXonoticSoundList(me); - return me; -} - -void XonoticSoundList_configureXonoticSoundList(entity me) -{ - me.configureXonoticListBox(me); - me.getSounds(me); -} - -string XonoticSoundList_soundName(entity me, float i ) -{ - string s; - s = search_getfilename(me.listSound, i); - s = substring(s, 15, strlen(s) - 15 - 4); // sound/cdtracks/, .ogg - return s; -} - - -void XonoticSoundList_getSounds(entity me) -{ - string s; - - if(me.filterString) - //subdirectory in filterString allowed - s = strcat("sound/cdtracks/*", me.filterString, "*.ogg"); - else - s = "sound/cdtracks/*.ogg"; - - if(me.listSound >= 0) - search_end(me.listSound); - - me.listSound = search_begin(s, FALSE, TRUE); - - if(me.listSound < 0) - me.nItems=0; - else - me.nItems=search_getsize(me.listSound); -} - -void XonoticSoundList_destroy(entity me) -{ - if(me.listSound >= 0) - search_end(me.listSound); -} - -void XonoticSoundList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticSoundList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - - me.columnNumberOrigin = 0; - me.columnNumberSize = me.realFontSize_x * 3; - - me.columnNameOrigin = me.columnNumberSize; - me.columnNameSize = 1 - me.columnNameOrigin - me.realFontSize_x; -} - -void XonoticSoundList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - string s; - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - s = me.soundName(me,i); - if(s == cvar_string("menu_cdtrack")) // current menu track - draw_CenterText((me.columnNumberOrigin + 0.5 * me.columnNumberSize) * eX + me.realUpperMargin * eY, "[C]", me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); - else if(s == cvar_defstring("menu_cdtrack")) // default menu track - draw_CenterText((me.columnNumberOrigin + 0.5 * me.columnNumberSize) * eX + me.realUpperMargin * eY, "[D]", me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); - - s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); -} - -void XonoticSoundList_showNotify(entity me) -{ - me.getSounds(me); -} - -void SoundList_Menu_Track_Change(entity box, entity me) -{ - cvar_set("menu_cdtrack", me.soundName(me,me.selectedItem)); -} - -void SoundList_Menu_Track_Reset(entity box, entity me) -{ - cvar_set("menu_cdtrack", cvar_defstring("menu_cdtrack")); -} - -void SoundList_Filter_Change(entity box, entity me) -{ - if(me.filterString) - strunzone(me.filterString); - - if(box.text != "") - me.filterString = strzone(box.text); - else - me.filterString = string_null; - - me.getSounds(me); -} - -void SoundList_Add(entity box, entity me) -{ - me.playlist.addToPlayList(me.playlist, me.soundName(me, me.selectedItem)); -} - -void SoundList_Add_All(entity box, entity me) -{ - float i; - for(i = 0; i < me.nItems; ++i) - me.playlist.addToPlayList(me.playlist, me.soundName(me, i)); -} - -void XonoticSoundList_doubleClickListBoxItem(entity me, float i, vector where) -{ - me.playlist.addToPlayList(me.playlist, me.soundName(me, i)); -} - -float XonoticSoundList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(scan == K_ENTER || scan == K_KP_ENTER || scan == K_SPACE) { - me.playlist.addToPlayList(me.playlist, me.soundName(me, me.selectedItem)); - return 1; - } - else - return SUPER(XonoticSoundList).keyDown(me, scan, ascii, shift); -} -#endif - diff --git a/qcsrc/menu/xonotic/soundlist.qc b/qcsrc/menu/xonotic/soundlist.qc new file mode 100644 index 000000000..7d1515062 --- /dev/null +++ b/qcsrc/menu/xonotic/soundlist.qc @@ -0,0 +1,175 @@ +#ifdef INTERFACE +CLASS(XonoticSoundList) EXTENDS(XonoticListBox) + METHOD(XonoticSoundList, configureXonoticSoundList, void(entity)) + ATTRIB(XonoticSoundList, rowsPerItem, float, 1) + METHOD(XonoticSoundList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticSoundList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticSoundList, getSounds, void(entity)) + METHOD(XonoticSoundList, soundName, string(entity, float)) + METHOD(XonoticSoundList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticSoundList, keyDown, float(entity, float, float, float)) + METHOD(XonoticSoundList, destroy, void(entity)) + METHOD(XonoticSoundList, showNotify, void(entity)) + + ATTRIB(XonoticSoundList, listSound, float, -1) + ATTRIB(XonoticSoundList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticSoundList, columnNameOrigin, float, 0) + ATTRIB(XonoticSoundList, columnNameSize, float, 0) + ATTRIB(XonoticSoundList, columnNumberOrigin, float, 0) + ATTRIB(XonoticSoundList, columnNumberSize, float, 0) + ATTRIB(XonoticSoundList, realUpperMargin, float, 0) + ATTRIB(XonoticSoundList, origin, vector, '0 0 0') + ATTRIB(XonoticSoundList, itemAbsSize, vector, '0 0 0') + + ATTRIB(XonoticSoundList, filterString, string, string_null) + ATTRIB(XonoticSoundList, playlist, entity, world) +ENDCLASS(XonoticSoundList) + +entity makeXonoticSoundList(); +void SoundList_Filter_Change(entity box, entity me); +void SoundList_Add(entity box, entity me); +void SoundList_Add_All(entity box, entity me); +void SoundList_Menu_Track_Change(entity box, entity me); +void SoundList_Menu_Track_Reset(entity box, entity me); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticSoundList() +{ + entity me; + me = spawnXonoticSoundList(); + me.configureXonoticSoundList(me); + return me; +} + +void XonoticSoundList_configureXonoticSoundList(entity me) +{ + me.configureXonoticListBox(me); + me.getSounds(me); +} + +string XonoticSoundList_soundName(entity me, float i ) +{ + string s; + s = search_getfilename(me.listSound, i); + s = substring(s, 15, strlen(s) - 15 - 4); // sound/cdtracks/, .ogg + return s; +} + + +void XonoticSoundList_getSounds(entity me) +{ + string s; + + if(me.filterString) + //subdirectory in filterString allowed + s = strcat("sound/cdtracks/*", me.filterString, "*.ogg"); + else + s = "sound/cdtracks/*.ogg"; + + if(me.listSound >= 0) + search_end(me.listSound); + + me.listSound = search_begin(s, FALSE, TRUE); + + if(me.listSound < 0) + me.nItems=0; + else + me.nItems=search_getsize(me.listSound); +} + +void XonoticSoundList_destroy(entity me) +{ + if(me.listSound >= 0) + search_end(me.listSound); +} + +void XonoticSoundList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticSoundList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + + me.columnNumberOrigin = 0; + me.columnNumberSize = me.realFontSize_x * 3; + + me.columnNameOrigin = me.columnNumberSize; + me.columnNameSize = 1 - me.columnNameOrigin - me.realFontSize_x; +} + +void XonoticSoundList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + string s; + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + s = me.soundName(me,i); + if(s == cvar_string("menu_cdtrack")) // current menu track + draw_CenterText((me.columnNumberOrigin + 0.5 * me.columnNumberSize) * eX + me.realUpperMargin * eY, "[C]", me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); + else if(s == cvar_defstring("menu_cdtrack")) // default menu track + draw_CenterText((me.columnNumberOrigin + 0.5 * me.columnNumberSize) * eX + me.realUpperMargin * eY, "[D]", me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); + + s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); +} + +void XonoticSoundList_showNotify(entity me) +{ + me.getSounds(me); +} + +void SoundList_Menu_Track_Change(entity box, entity me) +{ + cvar_set("menu_cdtrack", me.soundName(me,me.selectedItem)); +} + +void SoundList_Menu_Track_Reset(entity box, entity me) +{ + cvar_set("menu_cdtrack", cvar_defstring("menu_cdtrack")); +} + +void SoundList_Filter_Change(entity box, entity me) +{ + if(me.filterString) + strunzone(me.filterString); + + if(box.text != "") + me.filterString = strzone(box.text); + else + me.filterString = string_null; + + me.getSounds(me); +} + +void SoundList_Add(entity box, entity me) +{ + me.playlist.addToPlayList(me.playlist, me.soundName(me, me.selectedItem)); +} + +void SoundList_Add_All(entity box, entity me) +{ + float i; + for(i = 0; i < me.nItems; ++i) + me.playlist.addToPlayList(me.playlist, me.soundName(me, i)); +} + +void XonoticSoundList_doubleClickListBoxItem(entity me, float i, vector where) +{ + me.playlist.addToPlayList(me.playlist, me.soundName(me, i)); +} + +float XonoticSoundList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_KP_ENTER || scan == K_SPACE) { + me.playlist.addToPlayList(me.playlist, me.soundName(me, me.selectedItem)); + return 1; + } + else + return SUPER(XonoticSoundList).keyDown(me, scan, ascii, shift); +} +#endif + diff --git a/qcsrc/menu/xonotic/statslist.c b/qcsrc/menu/xonotic/statslist.c deleted file mode 100644 index c7b744a66..000000000 --- a/qcsrc/menu/xonotic/statslist.c +++ /dev/null @@ -1,351 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticStatsList) EXTENDS(XonoticListBox) - METHOD(XonoticStatsList, configureXonoticStatsList, void(entity)) - ATTRIB(XonoticStatsList, rowsPerItem, float, 1.4) - METHOD(XonoticStatsList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticStatsList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticStatsList, getStats, void(entity)) - METHOD(XonoticStatsList, doubleClickListBoxItem, void(entity, float, vector)) - METHOD(XonoticStatsList, keyDown, float(entity, float, float, float)) - METHOD(XonoticStatsList, destroy, void(entity)) - METHOD(XonoticStatsList, showNotify, void(entity)) - - ATTRIB(XonoticStatsList, listStats, float, -1) - ATTRIB(XonoticStatsList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticStatsList, realUpperMargin, float, 0) - ATTRIB(XonoticStatsList, columnNameOrigin, float, 0) - ATTRIB(XonoticStatsList, columnNameSize, float, 0) -ENDCLASS(XonoticStatsList) - -entity statslist; // for reference elsewhere -entity makeXonoticStatsList(); -#endif - -#ifdef IMPLEMENTATION - -entity makeXonoticStatsList() -{ - entity me; - me = spawnXonoticStatsList(); - me.configureXonoticStatsList(me); - return me; -} - -void XonoticStatsList_configureXonoticStatsList(entity me) -{ - me.configureXonoticListBox(me); - me.getStats(me); -} - -string XonoticStatsList_convertDate(string input) -{ - // 2013-12-21 - // 0123456789 - if(strlen(input) != 10) - return input; - - string monthname = ""; - - switch(stof(substring(input, 5, 2))) - { - case 1: monthname = _("January"); break; - case 2: monthname = _("February"); break; - case 3: monthname = _("March"); break; - case 4: monthname = _("April"); break; - case 5: monthname = _("May"); break; - case 6: monthname = _("June"); break; - case 7: monthname = _("July"); break; - case 8: monthname = _("August"); break; - case 9: monthname = _("September"); break; - case 10: monthname = _("October"); break; - case 11: monthname = _("November"); break; - case 12: monthname = _("December"); break; - default: return input; // failed, why? - } - - return sprintf( - "%s %s, %d", - monthname, - count_ordinal(stof(substring(input, 8, 2))), - stof(substring(input, 0, 4)) - ); -} - -void XonoticStatsList_getStats(entity me) -{ - dprint("XonoticStatsList_getStats() at time: ", ftos(time), "\n"); - // delete the old buffer if it exists - if(me.listStats >= 0) - buf_del(me.listStats); - - // create the new buffer if we have a stats buffer - if(PS_D_IN_DB >= 0) - me.listStats = buf_create(); - - // now confirmation, if we didn't create a buffer then just return now - if(me.listStats < 0) - { - me.nItems = 0; - return; - } - - float order = 0; - string e = "", en = "", data = ""; - - string outstr = ""; // NOTE: out string MUST use underscores for spaces here, we'll replace them later - string orderstr = ""; - - float out_total_matches = -1; - float out_total_wins = -1; - float out_total_losses = -1; - - float out_total_kills = -1; - float out_total_deaths = -1; - - for(e = PS_D_IN_EVL; (en = db_get(PS_D_IN_DB, e)) != ""; e = en) - { - order = 0; - outstr = ""; - orderstr = ""; - data = db_get(PS_D_IN_DB, sprintf("#%s", e)); - - // non-gamemode specific stuff - switch(e) - { - case "overall/joined_dt": - { - order = 1; - outstr = _("Joined:"); - data = XonoticStatsList_convertDate(car(data)); - break; - } - case "overall/last_seen_dt": - { - order = 1; - outstr = _("Last_Seen:"); - data = XonoticStatsList_convertDate(car(data)); - break; - } - case "overall/alivetime": - { - order = 1; - outstr = _("Time_Played:"); - data = process_time(3, stof(data)); - break; - } - case "overall/favorite-map": - { - order = 2; - outstr = _("Favorite_Map:"); - data = car(data); - break; - } - case "overall/matches": - { - order = -1; - out_total_matches = stof(data); - break; - } - case "overall/wins": - { - order = -1; - out_total_wins = stof(data); - break; - } - case "overall/total-kills": - { - order = -1; - out_total_kills = stof(data); - break; - } - case "overall/total-deaths": - { - order = -1; - out_total_deaths = stof(data); - break; - } - } - - if((order == -1) && (out_total_matches >= 0) && (out_total_wins >= 0)) - { - bufstr_add(me.listStats, sprintf("003Matches: %d", out_total_matches), TRUE); - - if(out_total_matches > 0) // don't show extra info if there are no matches played - { - out_total_losses = max(0, (out_total_matches - out_total_wins)); - bufstr_add(me.listStats, sprintf("003Wins/Losses: %d/%d", out_total_wins, out_total_losses), TRUE); - bufstr_add(me.listStats, sprintf("004Win_Percentage: %d%%", ((out_total_wins / out_total_matches) * 100)), TRUE); - } - - out_total_matches = -1; - out_total_wins = -1; - out_total_losses = -1; - continue; - } - - if((order == -1) && (out_total_kills >= 0) && (out_total_deaths >= 0)) - { - bufstr_add(me.listStats, sprintf("005Kills/Deaths: %d/%d", out_total_kills, out_total_deaths), TRUE); - - // if there are no deaths, just show kill count - if(out_total_deaths > 0) - bufstr_add(me.listStats, sprintf("006Kill_Ratio: %.2f", (out_total_kills / out_total_deaths)), TRUE); - else - bufstr_add(me.listStats, sprintf("006Kill_Ratio: %.2f", out_total_kills), TRUE); - - out_total_kills = -1; - out_total_deaths = -1; - continue; - } - - // game mode specific stuff - if(order > 0) - { - orderstr = sprintf("%03d", order); - } - else - { - float dividerpos = strstrofs(e, "/", 0); - - string gametype = substring(e, 0, dividerpos); - if(gametype == "overall") { continue; } - - string event = substring(e, (dividerpos + 1), strlen(e) - (dividerpos + 1)); - - // if we are ranked, read these sets of possible options - if(stof(db_get(PS_D_IN_DB, sprintf("#%s/rank", gametype)))) - { - switch(event) - { - case "matches": - { - order = 1; - outstr = sprintf(_("%s_Matches:"), strtoupper(gametype)); - //data = sprintf(_("%d (unranked)"), data); - break; - } - case "elo": - { - order = 2; - outstr = sprintf(_("%s_ELO:"), strtoupper(gametype)); - data = sprintf("%d", stof(data)); - break; - } - case "rank": - { - order = 3; - outstr = sprintf(_("%s_Rank:"), strtoupper(gametype)); - data = sprintf("%d", stof(data)); - break; - } - case "percentile": - { - order = 4; - outstr = sprintf(_("%s_Percentile:"), strtoupper(gametype)); - data = sprintf("%d%%", stof(data)); - break; - } - - #if 0 - case "favorite-map": - { - order = 5; - outstr = sprintf(_("%s_Favorite_Map:"), strtoupper(gametype)); - //data = sprintf(_("%d (unranked)"), data); - break; - } - #endif - - default: continue; // nothing to see here - } - - // now set up order for sorting later - orderstr = sprintf("%2.2s%d", gametype, order); - } - else if(event == "matches") - { - outstr = sprintf(_("%s_Matches:"), strtoupper(gametype)); - data = sprintf(_("%d (unranked)"), stof(data)); - - // unranked game modes ALWAYS get put last - orderstr = "zzz"; - } - else { continue; } - } - - bufstr_add(me.listStats, sprintf("%s%s %s", orderstr, outstr, data), TRUE); - } - - me.nItems = buf_getsize(me.listStats); - if(me.nItems > 0) - buf_sort(me.listStats, 128, FALSE); -} - -void XonoticStatsList_destroy(entity me) -{ - if(me.nItems > 0) - buf_del(me.listStats); -} - -void XonoticStatsList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - me.itemAbsSize = '0 0 0'; - SUPER(XonoticStatsList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); - me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); - -#if 0 - me.columnNameOrigin = me.realFontSize_x; - me.columnNameSize = 0.5 - me.realFontSize_x; // end halfway at maximum length - me.columnDataOrigin = me.columnNameOrigin + me.columnNameSize; - me.columnDataSize = 1 - me.columnNameSize - me.realFontSize_x; // fill the rest of the control -#else - me.columnNameOrigin = me.realFontSize_x; - me.columnNameSize = 1 - 2 * me.realFontSize_x; -#endif -} - -void XonoticStatsList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - - string data = bufstr_get(me.listStats, i); - string s = car(data); - string d = cdr(data); - - s = substring(s, 3, strlen(s) - 3); - s = strreplace("_", " ", s); - s = draw_TextShortenToWidth(s, 0.5 * me.columnNameSize, 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 1); - - d = draw_TextShortenToWidth(d, me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize), 0, me.realFontSize); - draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 1 * (me.columnNameSize - draw_TextWidth(d, 0, me.realFontSize))) * eX, d, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 1); -} - -void XonoticStatsList_showNotify(entity me) -{ - PlayerStats_PlayerDetail_CheckUpdate(); -} - -void XonoticStatsList_doubleClickListBoxItem(entity me, float i, vector where) -{ - //DemoConfirm_ListClick_Check_Gamestatus(me); -} - -float XonoticStatsList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(scan == K_ENTER || scan == K_KP_ENTER) - { - //DemoConfirm_ListClick_Check_Gamestatus(me); - return 1; - } - else - { - return SUPER(XonoticStatsList).keyDown(me, scan, ascii, shift); - } -} -#endif - diff --git a/qcsrc/menu/xonotic/statslist.qc b/qcsrc/menu/xonotic/statslist.qc new file mode 100644 index 000000000..c7b744a66 --- /dev/null +++ b/qcsrc/menu/xonotic/statslist.qc @@ -0,0 +1,351 @@ +#ifdef INTERFACE +CLASS(XonoticStatsList) EXTENDS(XonoticListBox) + METHOD(XonoticStatsList, configureXonoticStatsList, void(entity)) + ATTRIB(XonoticStatsList, rowsPerItem, float, 1.4) + METHOD(XonoticStatsList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticStatsList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticStatsList, getStats, void(entity)) + METHOD(XonoticStatsList, doubleClickListBoxItem, void(entity, float, vector)) + METHOD(XonoticStatsList, keyDown, float(entity, float, float, float)) + METHOD(XonoticStatsList, destroy, void(entity)) + METHOD(XonoticStatsList, showNotify, void(entity)) + + ATTRIB(XonoticStatsList, listStats, float, -1) + ATTRIB(XonoticStatsList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticStatsList, realUpperMargin, float, 0) + ATTRIB(XonoticStatsList, columnNameOrigin, float, 0) + ATTRIB(XonoticStatsList, columnNameSize, float, 0) +ENDCLASS(XonoticStatsList) + +entity statslist; // for reference elsewhere +entity makeXonoticStatsList(); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticStatsList() +{ + entity me; + me = spawnXonoticStatsList(); + me.configureXonoticStatsList(me); + return me; +} + +void XonoticStatsList_configureXonoticStatsList(entity me) +{ + me.configureXonoticListBox(me); + me.getStats(me); +} + +string XonoticStatsList_convertDate(string input) +{ + // 2013-12-21 + // 0123456789 + if(strlen(input) != 10) + return input; + + string monthname = ""; + + switch(stof(substring(input, 5, 2))) + { + case 1: monthname = _("January"); break; + case 2: monthname = _("February"); break; + case 3: monthname = _("March"); break; + case 4: monthname = _("April"); break; + case 5: monthname = _("May"); break; + case 6: monthname = _("June"); break; + case 7: monthname = _("July"); break; + case 8: monthname = _("August"); break; + case 9: monthname = _("September"); break; + case 10: monthname = _("October"); break; + case 11: monthname = _("November"); break; + case 12: monthname = _("December"); break; + default: return input; // failed, why? + } + + return sprintf( + "%s %s, %d", + monthname, + count_ordinal(stof(substring(input, 8, 2))), + stof(substring(input, 0, 4)) + ); +} + +void XonoticStatsList_getStats(entity me) +{ + dprint("XonoticStatsList_getStats() at time: ", ftos(time), "\n"); + // delete the old buffer if it exists + if(me.listStats >= 0) + buf_del(me.listStats); + + // create the new buffer if we have a stats buffer + if(PS_D_IN_DB >= 0) + me.listStats = buf_create(); + + // now confirmation, if we didn't create a buffer then just return now + if(me.listStats < 0) + { + me.nItems = 0; + return; + } + + float order = 0; + string e = "", en = "", data = ""; + + string outstr = ""; // NOTE: out string MUST use underscores for spaces here, we'll replace them later + string orderstr = ""; + + float out_total_matches = -1; + float out_total_wins = -1; + float out_total_losses = -1; + + float out_total_kills = -1; + float out_total_deaths = -1; + + for(e = PS_D_IN_EVL; (en = db_get(PS_D_IN_DB, e)) != ""; e = en) + { + order = 0; + outstr = ""; + orderstr = ""; + data = db_get(PS_D_IN_DB, sprintf("#%s", e)); + + // non-gamemode specific stuff + switch(e) + { + case "overall/joined_dt": + { + order = 1; + outstr = _("Joined:"); + data = XonoticStatsList_convertDate(car(data)); + break; + } + case "overall/last_seen_dt": + { + order = 1; + outstr = _("Last_Seen:"); + data = XonoticStatsList_convertDate(car(data)); + break; + } + case "overall/alivetime": + { + order = 1; + outstr = _("Time_Played:"); + data = process_time(3, stof(data)); + break; + } + case "overall/favorite-map": + { + order = 2; + outstr = _("Favorite_Map:"); + data = car(data); + break; + } + case "overall/matches": + { + order = -1; + out_total_matches = stof(data); + break; + } + case "overall/wins": + { + order = -1; + out_total_wins = stof(data); + break; + } + case "overall/total-kills": + { + order = -1; + out_total_kills = stof(data); + break; + } + case "overall/total-deaths": + { + order = -1; + out_total_deaths = stof(data); + break; + } + } + + if((order == -1) && (out_total_matches >= 0) && (out_total_wins >= 0)) + { + bufstr_add(me.listStats, sprintf("003Matches: %d", out_total_matches), TRUE); + + if(out_total_matches > 0) // don't show extra info if there are no matches played + { + out_total_losses = max(0, (out_total_matches - out_total_wins)); + bufstr_add(me.listStats, sprintf("003Wins/Losses: %d/%d", out_total_wins, out_total_losses), TRUE); + bufstr_add(me.listStats, sprintf("004Win_Percentage: %d%%", ((out_total_wins / out_total_matches) * 100)), TRUE); + } + + out_total_matches = -1; + out_total_wins = -1; + out_total_losses = -1; + continue; + } + + if((order == -1) && (out_total_kills >= 0) && (out_total_deaths >= 0)) + { + bufstr_add(me.listStats, sprintf("005Kills/Deaths: %d/%d", out_total_kills, out_total_deaths), TRUE); + + // if there are no deaths, just show kill count + if(out_total_deaths > 0) + bufstr_add(me.listStats, sprintf("006Kill_Ratio: %.2f", (out_total_kills / out_total_deaths)), TRUE); + else + bufstr_add(me.listStats, sprintf("006Kill_Ratio: %.2f", out_total_kills), TRUE); + + out_total_kills = -1; + out_total_deaths = -1; + continue; + } + + // game mode specific stuff + if(order > 0) + { + orderstr = sprintf("%03d", order); + } + else + { + float dividerpos = strstrofs(e, "/", 0); + + string gametype = substring(e, 0, dividerpos); + if(gametype == "overall") { continue; } + + string event = substring(e, (dividerpos + 1), strlen(e) - (dividerpos + 1)); + + // if we are ranked, read these sets of possible options + if(stof(db_get(PS_D_IN_DB, sprintf("#%s/rank", gametype)))) + { + switch(event) + { + case "matches": + { + order = 1; + outstr = sprintf(_("%s_Matches:"), strtoupper(gametype)); + //data = sprintf(_("%d (unranked)"), data); + break; + } + case "elo": + { + order = 2; + outstr = sprintf(_("%s_ELO:"), strtoupper(gametype)); + data = sprintf("%d", stof(data)); + break; + } + case "rank": + { + order = 3; + outstr = sprintf(_("%s_Rank:"), strtoupper(gametype)); + data = sprintf("%d", stof(data)); + break; + } + case "percentile": + { + order = 4; + outstr = sprintf(_("%s_Percentile:"), strtoupper(gametype)); + data = sprintf("%d%%", stof(data)); + break; + } + + #if 0 + case "favorite-map": + { + order = 5; + outstr = sprintf(_("%s_Favorite_Map:"), strtoupper(gametype)); + //data = sprintf(_("%d (unranked)"), data); + break; + } + #endif + + default: continue; // nothing to see here + } + + // now set up order for sorting later + orderstr = sprintf("%2.2s%d", gametype, order); + } + else if(event == "matches") + { + outstr = sprintf(_("%s_Matches:"), strtoupper(gametype)); + data = sprintf(_("%d (unranked)"), stof(data)); + + // unranked game modes ALWAYS get put last + orderstr = "zzz"; + } + else { continue; } + } + + bufstr_add(me.listStats, sprintf("%s%s %s", orderstr, outstr, data), TRUE); + } + + me.nItems = buf_getsize(me.listStats); + if(me.nItems > 0) + buf_sort(me.listStats, 128, FALSE); +} + +void XonoticStatsList_destroy(entity me) +{ + if(me.nItems > 0) + buf_del(me.listStats); +} + +void XonoticStatsList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.itemAbsSize = '0 0 0'; + SUPER(XonoticStatsList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight)); + me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth))); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); + +#if 0 + me.columnNameOrigin = me.realFontSize_x; + me.columnNameSize = 0.5 - me.realFontSize_x; // end halfway at maximum length + me.columnDataOrigin = me.columnNameOrigin + me.columnNameSize; + me.columnDataSize = 1 - me.columnNameSize - me.realFontSize_x; // fill the rest of the control +#else + me.columnNameOrigin = me.realFontSize_x; + me.columnNameSize = 1 - 2 * me.realFontSize_x; +#endif +} + +void XonoticStatsList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + + string data = bufstr_get(me.listStats, i); + string s = car(data); + string d = cdr(data); + + s = substring(s, 3, strlen(s) - 3); + s = strreplace("_", " ", s); + s = draw_TextShortenToWidth(s, 0.5 * me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 1); + + d = draw_TextShortenToWidth(d, me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize), 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 1 * (me.columnNameSize - draw_TextWidth(d, 0, me.realFontSize))) * eX, d, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 1); +} + +void XonoticStatsList_showNotify(entity me) +{ + PlayerStats_PlayerDetail_CheckUpdate(); +} + +void XonoticStatsList_doubleClickListBoxItem(entity me, float i, vector where) +{ + //DemoConfirm_ListClick_Check_Gamestatus(me); +} + +float XonoticStatsList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_KP_ENTER) + { + //DemoConfirm_ListClick_Check_Gamestatus(me); + return 1; + } + else + { + return SUPER(XonoticStatsList).keyDown(me, scan, ascii, shift); + } +} +#endif + diff --git a/qcsrc/menu/xonotic/tab.c b/qcsrc/menu/xonotic/tab.c deleted file mode 100644 index d1a867a2f..000000000 --- a/qcsrc/menu/xonotic/tab.c +++ /dev/null @@ -1,30 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticTab) EXTENDS(Tab) - // still to be customized by user - /* - ATTRIB(XonoticTab, intendedWidth, float, 0) - ATTRIB(XonoticTab, rows, float, 3) - ATTRIB(XonoticTab, columns, float, 2) - */ - METHOD(XonoticTab, showNotify, void(entity)) - - ATTRIB(XonoticTab, marginTop, float, 0) // pixels - ATTRIB(XonoticTab, marginBottom, float, 0) // pixels - ATTRIB(XonoticTab, marginLeft, float, 0) // pixels - ATTRIB(XonoticTab, marginRight, float, 0) // pixels - ATTRIB(XonoticTab, columnSpacing, float, SKINMARGIN_COLUMNS) // pixels - ATTRIB(XonoticTab, rowSpacing, float, SKINMARGIN_ROWS) // pixels - ATTRIB(XonoticTab, rowHeight, float, SKINFONTSIZE_NORMAL * SKINHEIGHT_NORMAL) // pixels - ATTRIB(XonoticTab, titleHeight, float, SKINFONTSIZE_TITLE * SKINHEIGHT_TITLE) // pixels - - ATTRIB(XonoticTab, backgroundImage, string, string_null) -ENDCLASS(XonoticTab) -#endif - -#ifdef IMPLEMENTATION -void XonoticTab_showNotify(entity me) -{ - loadAllCvars(me); - SUPER(XonoticTab).showNotify(me); -} -#endif diff --git a/qcsrc/menu/xonotic/tab.qc b/qcsrc/menu/xonotic/tab.qc new file mode 100644 index 000000000..d1a867a2f --- /dev/null +++ b/qcsrc/menu/xonotic/tab.qc @@ -0,0 +1,30 @@ +#ifdef INTERFACE +CLASS(XonoticTab) EXTENDS(Tab) + // still to be customized by user + /* + ATTRIB(XonoticTab, intendedWidth, float, 0) + ATTRIB(XonoticTab, rows, float, 3) + ATTRIB(XonoticTab, columns, float, 2) + */ + METHOD(XonoticTab, showNotify, void(entity)) + + ATTRIB(XonoticTab, marginTop, float, 0) // pixels + ATTRIB(XonoticTab, marginBottom, float, 0) // pixels + ATTRIB(XonoticTab, marginLeft, float, 0) // pixels + ATTRIB(XonoticTab, marginRight, float, 0) // pixels + ATTRIB(XonoticTab, columnSpacing, float, SKINMARGIN_COLUMNS) // pixels + ATTRIB(XonoticTab, rowSpacing, float, SKINMARGIN_ROWS) // pixels + ATTRIB(XonoticTab, rowHeight, float, SKINFONTSIZE_NORMAL * SKINHEIGHT_NORMAL) // pixels + ATTRIB(XonoticTab, titleHeight, float, SKINFONTSIZE_TITLE * SKINHEIGHT_TITLE) // pixels + + ATTRIB(XonoticTab, backgroundImage, string, string_null) +ENDCLASS(XonoticTab) +#endif + +#ifdef IMPLEMENTATION +void XonoticTab_showNotify(entity me) +{ + loadAllCvars(me); + SUPER(XonoticTab).showNotify(me); +} +#endif diff --git a/qcsrc/menu/xonotic/tabcontroller.c b/qcsrc/menu/xonotic/tabcontroller.c deleted file mode 100644 index 1faa625ae..000000000 --- a/qcsrc/menu/xonotic/tabcontroller.c +++ /dev/null @@ -1,34 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticTabController) EXTENDS(ModalController) - METHOD(XonoticTabController, configureXonoticTabController, void(entity, float)) - METHOD(XonoticTabController, makeTabButton, entity(entity, string, entity)) - ATTRIB(XonoticTabController, rows, float, 0) - ATTRIB(XonoticTabController, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticTabController, image, string, SKINGFX_BUTTON) -ENDCLASS(XonoticTabController) -entity makeXonoticTabController(float theRows); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticTabController(float theRows) -{ - entity me; - me = spawnXonoticTabController(); - me.configureXonoticTabController(me, theRows); - return me; -} -void XonoticTabController_configureXonoticTabController(entity me, float theRows) -{ - me.rows = theRows; -} -entity XonoticTabController_makeTabButton(entity me, string theTitle, entity tab) -{ - entity b; - if(me.rows != tab.rows) - error("Tab dialog height mismatch!"); - b = makeXonoticButton(theTitle, '0 0 0'); - me.addTab(me, tab, b); - // TODO make this real tab buttons (with color parameters, and different gfx) - return b; -} -#endif diff --git a/qcsrc/menu/xonotic/tabcontroller.qc b/qcsrc/menu/xonotic/tabcontroller.qc new file mode 100644 index 000000000..1faa625ae --- /dev/null +++ b/qcsrc/menu/xonotic/tabcontroller.qc @@ -0,0 +1,34 @@ +#ifdef INTERFACE +CLASS(XonoticTabController) EXTENDS(ModalController) + METHOD(XonoticTabController, configureXonoticTabController, void(entity, float)) + METHOD(XonoticTabController, makeTabButton, entity(entity, string, entity)) + ATTRIB(XonoticTabController, rows, float, 0) + ATTRIB(XonoticTabController, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticTabController, image, string, SKINGFX_BUTTON) +ENDCLASS(XonoticTabController) +entity makeXonoticTabController(float theRows); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticTabController(float theRows) +{ + entity me; + me = spawnXonoticTabController(); + me.configureXonoticTabController(me, theRows); + return me; +} +void XonoticTabController_configureXonoticTabController(entity me, float theRows) +{ + me.rows = theRows; +} +entity XonoticTabController_makeTabButton(entity me, string theTitle, entity tab) +{ + entity b; + if(me.rows != tab.rows) + error("Tab dialog height mismatch!"); + b = makeXonoticButton(theTitle, '0 0 0'); + me.addTab(me, tab, b); + // TODO make this real tab buttons (with color parameters, and different gfx) + return b; +} +#endif diff --git a/qcsrc/menu/xonotic/textlabel.c b/qcsrc/menu/xonotic/textlabel.c deleted file mode 100644 index c0e0806d8..000000000 --- a/qcsrc/menu/xonotic/textlabel.c +++ /dev/null @@ -1,37 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticTextLabel) EXTENDS(Label) - METHOD(XonoticTextLabel, configureXonoticTextLabel, void(entity, float, string)) - METHOD(XonoticTextLabel, draw, void(entity)) - ATTRIB(XonoticTextLabel, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticTextLabel, alpha, float, SKINALPHA_TEXT) - ATTRIB(XonoticTextLabel, disabledAlpha, float, SKINALPHA_DISABLED) -ENDCLASS(XonoticTextLabel) -entity makeXonoticTextLabel(float theAlign, string theText); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticTextLabel(float theAlign, string theText) -{ - entity me; - me = spawnXonoticTextLabel(); - me.configureXonoticTextLabel(me, theAlign, theText); - return me; -} -entity makeXonoticHeaderLabel(string theText) -{ - entity me; - me = makeXonoticTextLabel(0.5, theText); - me.colorL = SKINCOLOR_HEADER; - me.alpha = SKINALPHA_HEADER; - me.isBold = TRUE; - return me; -} -void XonoticTextLabel_configureXonoticTextLabel(entity me, float theAlign, string theText) -{ - me.configureLabel(me, theText, me.fontSize, theAlign); -} -void XonoticTextLabel_draw(entity me) -{ - SUPER(XonoticTextLabel).draw(me); -} -#endif diff --git a/qcsrc/menu/xonotic/textlabel.qc b/qcsrc/menu/xonotic/textlabel.qc new file mode 100644 index 000000000..c0e0806d8 --- /dev/null +++ b/qcsrc/menu/xonotic/textlabel.qc @@ -0,0 +1,37 @@ +#ifdef INTERFACE +CLASS(XonoticTextLabel) EXTENDS(Label) + METHOD(XonoticTextLabel, configureXonoticTextLabel, void(entity, float, string)) + METHOD(XonoticTextLabel, draw, void(entity)) + ATTRIB(XonoticTextLabel, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticTextLabel, alpha, float, SKINALPHA_TEXT) + ATTRIB(XonoticTextLabel, disabledAlpha, float, SKINALPHA_DISABLED) +ENDCLASS(XonoticTextLabel) +entity makeXonoticTextLabel(float theAlign, string theText); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticTextLabel(float theAlign, string theText) +{ + entity me; + me = spawnXonoticTextLabel(); + me.configureXonoticTextLabel(me, theAlign, theText); + return me; +} +entity makeXonoticHeaderLabel(string theText) +{ + entity me; + me = makeXonoticTextLabel(0.5, theText); + me.colorL = SKINCOLOR_HEADER; + me.alpha = SKINALPHA_HEADER; + me.isBold = TRUE; + return me; +} +void XonoticTextLabel_configureXonoticTextLabel(entity me, float theAlign, string theText) +{ + me.configureLabel(me, theText, me.fontSize, theAlign); +} +void XonoticTextLabel_draw(entity me) +{ + SUPER(XonoticTextLabel).draw(me); +} +#endif diff --git a/qcsrc/menu/xonotic/textslider.c b/qcsrc/menu/xonotic/textslider.c deleted file mode 100644 index 844b3efed..000000000 --- a/qcsrc/menu/xonotic/textslider.c +++ /dev/null @@ -1,120 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticTextSlider) EXTENDS(TextSlider) - METHOD(XonoticTextSlider, configureXonoticTextSlider, void(entity, string)) - METHOD(XonoticTextSlider, setValue, void(entity, float)) - METHOD(XonoticTextSlider, configureXonoticTextSliderValues, void(entity)) - ATTRIB(XonoticTextSlider, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticTextSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT) - ATTRIB(XonoticTextSlider, image, string, SKINGFX_SLIDER) - ATTRIB(XonoticTextSlider, tolerance, vector, SKINTOLERANCE_SLIDER) - ATTRIB(XonoticTextSlider, align, float, 0.5) - ATTRIB(XonoticTextSlider, color, vector, SKINCOLOR_SLIDER_N) - ATTRIB(XonoticTextSlider, colorC, vector, SKINCOLOR_SLIDER_C) - ATTRIB(XonoticTextSlider, colorF, vector, SKINCOLOR_SLIDER_F) - ATTRIB(XonoticTextSlider, colorD, vector, SKINCOLOR_SLIDER_D) - ATTRIB(XonoticTextSlider, color2, vector, SKINCOLOR_SLIDER_S) - - ATTRIB(XonoticTextSlider, cvarName, string, string_null) - METHOD(XonoticTextSlider, loadCvars, void(entity)) - METHOD(XonoticTextSlider, saveCvars, void(entity)) - ATTRIB(XonoticTextSlider, sendCvars, float, 0) - - ATTRIB(XonoticTextSlider, alpha, float, SKINALPHA_TEXT) - ATTRIB(XonoticTextSlider, disabledAlpha, float, SKINALPHA_DISABLED) -ENDCLASS(XonoticTextSlider) -entity makeXonoticTextSlider(string); // note: you still need to call addValue and configureXonoticTextSliderValues! -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticTextSlider(string theCvar) -{ - entity me; - me = spawnXonoticTextSlider(); - me.configureXonoticTextSlider(me, theCvar); - return me; -} -void XonoticTextSlider_configureXonoticTextSlider(entity me, string theCvar) -{ - me.configureSliderVisuals(me, me.fontSize, me.align, me.valueSpace, me.image); - if(theCvar) - { - me.cvarName = theCvar; - me.tooltip = getZonedTooltipForIdentifier(theCvar); - // don't load it yet - } -} -void XonoticTextSlider_setValue(entity me, float val) -{ - if(val != me.value) - { - SUPER(XonoticTextSlider).setValue( me, val ); - me.saveCvars(me); - } -} -void XonoticTextSlider_loadCvars(entity me) -{ - if (!me.cvarName) - return; - - var float n = tokenize_console(me.cvarName); - var string s = cvar_string(argv(0)); - float i; - for(i = 1; i < n; ++i) - s = strcat(s, " ", cvar_string(argv(i))); - me.setValueFromIdentifier(me, s); - if(me.value < 0 && n > 1) - { - // if it failed: check if all cvars have the same value - // if yes, try its value as 1-word identifier - for(i = 1; i < n; ++i) - if(cvar_string(argv(i)) != cvar_string(argv(i-1))) - break; - if(i >= n) - me.setValueFromIdentifier(me, cvar_string(argv(0))); - } -} -void XonoticTextSlider_saveCvars(entity me) -{ - if (!me.cvarName) - return; - - if(me.value >= 0 && me.value < me.nValues) - { - var float n = tokenize_console(me.cvarName); - if(n == 1) - { - // this is a special case to allow spaces in the identifiers - cvar_set(argv(0), me.getIdentifier(me)); - CheckSendCvars(me, argv(0)); - } - else - { - float i; - var float m = tokenize_console(strcat(me.cvarName, " ", me.getIdentifier(me))); - if(m == n + 1) - { - for(i = 0; i < n; ++i) - { - cvar_set(argv(i), argv(n)); - CheckSendCvars(me, argv(i)); - } - } - else if(m == n * 2) - { - for(i = 0; i < n; ++i) - { - cvar_set(argv(i), argv(i + n)); - CheckSendCvars(me, argv(i)); - } - } - else - error("XonoticTextSlider: invalid identifier ", me.getIdentifier(me), " does not match cvar list ", me.cvarName); - } - } -} -void XonoticTextSlider_configureXonoticTextSliderValues(entity me) -{ - me.configureTextSliderValues(me, string_null); - me.loadCvars(me); -} -#endif diff --git a/qcsrc/menu/xonotic/textslider.qc b/qcsrc/menu/xonotic/textslider.qc new file mode 100644 index 000000000..844b3efed --- /dev/null +++ b/qcsrc/menu/xonotic/textslider.qc @@ -0,0 +1,120 @@ +#ifdef INTERFACE +CLASS(XonoticTextSlider) EXTENDS(TextSlider) + METHOD(XonoticTextSlider, configureXonoticTextSlider, void(entity, string)) + METHOD(XonoticTextSlider, setValue, void(entity, float)) + METHOD(XonoticTextSlider, configureXonoticTextSliderValues, void(entity)) + ATTRIB(XonoticTextSlider, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticTextSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT) + ATTRIB(XonoticTextSlider, image, string, SKINGFX_SLIDER) + ATTRIB(XonoticTextSlider, tolerance, vector, SKINTOLERANCE_SLIDER) + ATTRIB(XonoticTextSlider, align, float, 0.5) + ATTRIB(XonoticTextSlider, color, vector, SKINCOLOR_SLIDER_N) + ATTRIB(XonoticTextSlider, colorC, vector, SKINCOLOR_SLIDER_C) + ATTRIB(XonoticTextSlider, colorF, vector, SKINCOLOR_SLIDER_F) + ATTRIB(XonoticTextSlider, colorD, vector, SKINCOLOR_SLIDER_D) + ATTRIB(XonoticTextSlider, color2, vector, SKINCOLOR_SLIDER_S) + + ATTRIB(XonoticTextSlider, cvarName, string, string_null) + METHOD(XonoticTextSlider, loadCvars, void(entity)) + METHOD(XonoticTextSlider, saveCvars, void(entity)) + ATTRIB(XonoticTextSlider, sendCvars, float, 0) + + ATTRIB(XonoticTextSlider, alpha, float, SKINALPHA_TEXT) + ATTRIB(XonoticTextSlider, disabledAlpha, float, SKINALPHA_DISABLED) +ENDCLASS(XonoticTextSlider) +entity makeXonoticTextSlider(string); // note: you still need to call addValue and configureXonoticTextSliderValues! +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticTextSlider(string theCvar) +{ + entity me; + me = spawnXonoticTextSlider(); + me.configureXonoticTextSlider(me, theCvar); + return me; +} +void XonoticTextSlider_configureXonoticTextSlider(entity me, string theCvar) +{ + me.configureSliderVisuals(me, me.fontSize, me.align, me.valueSpace, me.image); + if(theCvar) + { + me.cvarName = theCvar; + me.tooltip = getZonedTooltipForIdentifier(theCvar); + // don't load it yet + } +} +void XonoticTextSlider_setValue(entity me, float val) +{ + if(val != me.value) + { + SUPER(XonoticTextSlider).setValue( me, val ); + me.saveCvars(me); + } +} +void XonoticTextSlider_loadCvars(entity me) +{ + if (!me.cvarName) + return; + + var float n = tokenize_console(me.cvarName); + var string s = cvar_string(argv(0)); + float i; + for(i = 1; i < n; ++i) + s = strcat(s, " ", cvar_string(argv(i))); + me.setValueFromIdentifier(me, s); + if(me.value < 0 && n > 1) + { + // if it failed: check if all cvars have the same value + // if yes, try its value as 1-word identifier + for(i = 1; i < n; ++i) + if(cvar_string(argv(i)) != cvar_string(argv(i-1))) + break; + if(i >= n) + me.setValueFromIdentifier(me, cvar_string(argv(0))); + } +} +void XonoticTextSlider_saveCvars(entity me) +{ + if (!me.cvarName) + return; + + if(me.value >= 0 && me.value < me.nValues) + { + var float n = tokenize_console(me.cvarName); + if(n == 1) + { + // this is a special case to allow spaces in the identifiers + cvar_set(argv(0), me.getIdentifier(me)); + CheckSendCvars(me, argv(0)); + } + else + { + float i; + var float m = tokenize_console(strcat(me.cvarName, " ", me.getIdentifier(me))); + if(m == n + 1) + { + for(i = 0; i < n; ++i) + { + cvar_set(argv(i), argv(n)); + CheckSendCvars(me, argv(i)); + } + } + else if(m == n * 2) + { + for(i = 0; i < n; ++i) + { + cvar_set(argv(i), argv(i + n)); + CheckSendCvars(me, argv(i)); + } + } + else + error("XonoticTextSlider: invalid identifier ", me.getIdentifier(me), " does not match cvar list ", me.cvarName); + } + } +} +void XonoticTextSlider_configureXonoticTextSliderValues(entity me) +{ + me.configureTextSliderValues(me, string_null); + me.loadCvars(me); +} +#endif diff --git a/qcsrc/menu/xonotic/weaponarenacheckbox.c b/qcsrc/menu/xonotic/weaponarenacheckbox.c deleted file mode 100644 index 163f9c63b..000000000 --- a/qcsrc/menu/xonotic/weaponarenacheckbox.c +++ /dev/null @@ -1,57 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticWeaponarenaCheckBox) EXTENDS(CheckBox) - METHOD(XonoticWeaponarenaCheckBox, configureXonoticWeaponarenaCheckBox, void(entity, string, string)) - METHOD(XonoticWeaponarenaCheckBox, setChecked, void(entity, float)) - ATTRIB(XonoticWeaponarenaCheckBox, fontSize, float, SKINFONTSIZE_NORMAL) - ATTRIB(XonoticWeaponarenaCheckBox, image, string, SKINGFX_CHECKBOX) - ATTRIB(XonoticWeaponarenaCheckBox, netname, string, string_null) - - METHOD(XonoticWeaponarenaCheckBox, loadCvars, void(entity)) - METHOD(XonoticWeaponarenaCheckBox, saveCvars, void(entity)) -ENDCLASS(XonoticWeaponarenaCheckBox) -entity makeXonoticWeaponarenaCheckBox(string, string); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticWeaponarenaCheckBox(string theWeapon, string theText) -{ - entity me; - me = spawnXonoticWeaponarenaCheckBox(); - me.configureXonoticWeaponarenaCheckBox(me, theWeapon, theText); - return me; -} -void XonoticWeaponarenaCheckBox_configureXonoticWeaponarenaCheckBox(entity me, string theWeapon, string theText) -{ - me.netname = theWeapon; - me.checked = FALSE; - me.loadCvars(me); - me.configureCheckBox(me, theText, me.fontSize, me.image); -} -void XonoticWeaponarenaCheckBox_setChecked(entity me, float foo) -{ - me.checked = !me.checked; - me.saveCvars(me); -} -void XonoticWeaponarenaCheckBox_loadCvars(entity me) -{ - float n = tokenize_console(cvar_string("menu_weaponarena")); - float i; - for(i=0; i<n; ++i) - { - if(argv(i) == me.netname) - { - me.checked = TRUE; - break; - } - } -} - -void XonoticWeaponarenaCheckBox_saveCvars(entity me) -{ - if(me.checked) - localcmd(strcat("\nmenu_cmd addtolist menu_weaponarena ", me.netname, "\n")); - else - localcmd(strcat("\nmenu_cmd removefromlist menu_weaponarena ", me.netname, "\n")); - localcmd("\ng_weaponarena \"$menu_weaponarena\"\n"); -} -#endif diff --git a/qcsrc/menu/xonotic/weaponarenacheckbox.qc b/qcsrc/menu/xonotic/weaponarenacheckbox.qc new file mode 100644 index 000000000..163f9c63b --- /dev/null +++ b/qcsrc/menu/xonotic/weaponarenacheckbox.qc @@ -0,0 +1,57 @@ +#ifdef INTERFACE +CLASS(XonoticWeaponarenaCheckBox) EXTENDS(CheckBox) + METHOD(XonoticWeaponarenaCheckBox, configureXonoticWeaponarenaCheckBox, void(entity, string, string)) + METHOD(XonoticWeaponarenaCheckBox, setChecked, void(entity, float)) + ATTRIB(XonoticWeaponarenaCheckBox, fontSize, float, SKINFONTSIZE_NORMAL) + ATTRIB(XonoticWeaponarenaCheckBox, image, string, SKINGFX_CHECKBOX) + ATTRIB(XonoticWeaponarenaCheckBox, netname, string, string_null) + + METHOD(XonoticWeaponarenaCheckBox, loadCvars, void(entity)) + METHOD(XonoticWeaponarenaCheckBox, saveCvars, void(entity)) +ENDCLASS(XonoticWeaponarenaCheckBox) +entity makeXonoticWeaponarenaCheckBox(string, string); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticWeaponarenaCheckBox(string theWeapon, string theText) +{ + entity me; + me = spawnXonoticWeaponarenaCheckBox(); + me.configureXonoticWeaponarenaCheckBox(me, theWeapon, theText); + return me; +} +void XonoticWeaponarenaCheckBox_configureXonoticWeaponarenaCheckBox(entity me, string theWeapon, string theText) +{ + me.netname = theWeapon; + me.checked = FALSE; + me.loadCvars(me); + me.configureCheckBox(me, theText, me.fontSize, me.image); +} +void XonoticWeaponarenaCheckBox_setChecked(entity me, float foo) +{ + me.checked = !me.checked; + me.saveCvars(me); +} +void XonoticWeaponarenaCheckBox_loadCvars(entity me) +{ + float n = tokenize_console(cvar_string("menu_weaponarena")); + float i; + for(i=0; i<n; ++i) + { + if(argv(i) == me.netname) + { + me.checked = TRUE; + break; + } + } +} + +void XonoticWeaponarenaCheckBox_saveCvars(entity me) +{ + if(me.checked) + localcmd(strcat("\nmenu_cmd addtolist menu_weaponarena ", me.netname, "\n")); + else + localcmd(strcat("\nmenu_cmd removefromlist menu_weaponarena ", me.netname, "\n")); + localcmd("\ng_weaponarena \"$menu_weaponarena\"\n"); +} +#endif diff --git a/qcsrc/menu/xonotic/weaponslist.c b/qcsrc/menu/xonotic/weaponslist.c deleted file mode 100644 index 8a8e2205d..000000000 --- a/qcsrc/menu/xonotic/weaponslist.c +++ /dev/null @@ -1,129 +0,0 @@ -#ifdef INTERFACE -CLASS(XonoticWeaponsList) EXTENDS(XonoticListBox) - METHOD(XonoticWeaponsList, configureXonoticWeaponsList, void(entity)) - METHOD(XonoticWeaponsList, toString, string(entity)) - ATTRIB(XonoticWeaponsList, rowsPerItem, float, 1) - METHOD(XonoticWeaponsList, draw, void(entity)) - METHOD(XonoticWeaponsList, drawListBoxItem, void(entity, float, vector, float)) - METHOD(XonoticWeaponsList, resizeNotify, void(entity, vector, vector, vector, vector)) - METHOD(XonoticWeaponsList, keyDown, float(entity, float, float, float)) - ATTRIB(XonoticWeaponsList, realFontSize, vector, '0 0 0') - ATTRIB(XonoticWeaponsList, realUpperMargin, float, 0) - METHOD(XonoticWeaponsList, mouseDrag, float(entity, vector)) -ENDCLASS(XonoticWeaponsList) -entity makeXonoticWeaponsList(); -void WeaponsList_MoveUp_Click(entity btn, entity me); -void WeaponsList_MoveDown_Click(entity box, entity me); -#endif - -#ifdef IMPLEMENTATION -entity makeXonoticWeaponsList() -{ - entity me; - me = spawnXonoticWeaponsList(); - me.configureXonoticWeaponsList(me); - return me; -} -void XonoticWeaponsList_configureXonoticWeaponsList(entity me) -{ - me.configureXonoticListBox(me); -} -void XonoticWeaponsList_draw(entity me) -{ - // read in cvar? - string s, t; - s = W_NumberWeaponOrder(cvar_string("cl_weaponpriority")); - t = W_FixWeaponOrder(s, 1); - if(t != s) - cvar_set("cl_weaponpriority", W_NameWeaponOrder(t)); - me.nItems = tokenize_console(t); - SUPER(XonoticWeaponsList).draw(me); -} -void WeaponsList_MoveUp_Click(entity box, entity me) -{ - if(me.selectedItem > 0) - { - cvar_set("cl_weaponpriority", swapInPriorityList(cvar_string("cl_weaponpriority"), me.selectedItem - 1, me.selectedItem)); - me.selectedItem -= 1; - } -} -void WeaponsList_MoveDown_Click(entity box, entity me) -{ - if(me.selectedItem < me.nItems - 1) - { - cvar_set("cl_weaponpriority", swapInPriorityList(cvar_string("cl_weaponpriority"), me.selectedItem, me.selectedItem + 1)); - me.selectedItem += 1; - } -} -void XonoticWeaponsList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) -{ - SUPER(XonoticWeaponsList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); - - me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); - me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); - me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); -} -float XonoticWeaponsList_mouseDrag(entity me, vector pos) -{ - float f, i; - i = me.selectedItem; - f = SUPER(XonoticWeaponsList).mouseDrag(me, pos); - - if(me.pressed != 1) // don't change priority if the person is just scrolling - { - if(me.selectedItem != i) - cvar_set("cl_weaponpriority", swapInPriorityList(cvar_string("cl_weaponpriority"), me.selectedItem, i)); - } - - return f; -} -string XonoticWeaponsList_toString(entity me) -{ - float n, i; - string s; - entity e; - n = tokenize_console(W_NumberWeaponOrder(cvar_string("cl_weaponpriority"))); - s = ""; - for(i = 0; i < n; ++i) - { - e = get_weaponinfo(stof(argv(i))); - s = strcat(s, e.message, ", "); - } - return substring(s, 0, strlen(s) - 2); -} -void XonoticWeaponsList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) -{ - entity e; - if(isSelected) - draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); - e = get_weaponinfo(stof(argv(i))); - string msg = e.message; - if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED) - msg = sprintf(_("%s (mutator weapon)"), msg); - - vector save_fontscale = draw_fontscale; - float f = draw_CondensedFontFactor(msg, FALSE, me.realFontSize, 1); - draw_fontscale_x *= f; - vector fs = me.realFontSize; - fs_x *= f; - draw_Text(me.realUpperMargin * eY, msg, fs, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0); - draw_fontscale = save_fontscale; -} - -float XonoticWeaponsList_keyDown(entity me, float scan, float ascii, float shift) -{ - if(ascii == 43) // + - { - WeaponsList_MoveUp_Click(NULL, me); - return 1; - } - else if(ascii == 45) // - - { - WeaponsList_MoveDown_Click(NULL, me); - return 1; - } - else if(SUPER(XonoticWeaponsList).keyDown(me, scan, ascii, shift)) - return 1; - return 0; -} -#endif diff --git a/qcsrc/menu/xonotic/weaponslist.qc b/qcsrc/menu/xonotic/weaponslist.qc new file mode 100644 index 000000000..8a8e2205d --- /dev/null +++ b/qcsrc/menu/xonotic/weaponslist.qc @@ -0,0 +1,129 @@ +#ifdef INTERFACE +CLASS(XonoticWeaponsList) EXTENDS(XonoticListBox) + METHOD(XonoticWeaponsList, configureXonoticWeaponsList, void(entity)) + METHOD(XonoticWeaponsList, toString, string(entity)) + ATTRIB(XonoticWeaponsList, rowsPerItem, float, 1) + METHOD(XonoticWeaponsList, draw, void(entity)) + METHOD(XonoticWeaponsList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticWeaponsList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticWeaponsList, keyDown, float(entity, float, float, float)) + ATTRIB(XonoticWeaponsList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticWeaponsList, realUpperMargin, float, 0) + METHOD(XonoticWeaponsList, mouseDrag, float(entity, vector)) +ENDCLASS(XonoticWeaponsList) +entity makeXonoticWeaponsList(); +void WeaponsList_MoveUp_Click(entity btn, entity me); +void WeaponsList_MoveDown_Click(entity box, entity me); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticWeaponsList() +{ + entity me; + me = spawnXonoticWeaponsList(); + me.configureXonoticWeaponsList(me); + return me; +} +void XonoticWeaponsList_configureXonoticWeaponsList(entity me) +{ + me.configureXonoticListBox(me); +} +void XonoticWeaponsList_draw(entity me) +{ + // read in cvar? + string s, t; + s = W_NumberWeaponOrder(cvar_string("cl_weaponpriority")); + t = W_FixWeaponOrder(s, 1); + if(t != s) + cvar_set("cl_weaponpriority", W_NameWeaponOrder(t)); + me.nItems = tokenize_console(t); + SUPER(XonoticWeaponsList).draw(me); +} +void WeaponsList_MoveUp_Click(entity box, entity me) +{ + if(me.selectedItem > 0) + { + cvar_set("cl_weaponpriority", swapInPriorityList(cvar_string("cl_weaponpriority"), me.selectedItem - 1, me.selectedItem)); + me.selectedItem -= 1; + } +} +void WeaponsList_MoveDown_Click(entity box, entity me) +{ + if(me.selectedItem < me.nItems - 1) + { + cvar_set("cl_weaponpriority", swapInPriorityList(cvar_string("cl_weaponpriority"), me.selectedItem, me.selectedItem + 1)); + me.selectedItem += 1; + } +} +void XonoticWeaponsList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + SUPER(XonoticWeaponsList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); + + me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight); + me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth)); + me.realUpperMargin = 0.5 * (1 - me.realFontSize_y); +} +float XonoticWeaponsList_mouseDrag(entity me, vector pos) +{ + float f, i; + i = me.selectedItem; + f = SUPER(XonoticWeaponsList).mouseDrag(me, pos); + + if(me.pressed != 1) // don't change priority if the person is just scrolling + { + if(me.selectedItem != i) + cvar_set("cl_weaponpriority", swapInPriorityList(cvar_string("cl_weaponpriority"), me.selectedItem, i)); + } + + return f; +} +string XonoticWeaponsList_toString(entity me) +{ + float n, i; + string s; + entity e; + n = tokenize_console(W_NumberWeaponOrder(cvar_string("cl_weaponpriority"))); + s = ""; + for(i = 0; i < n; ++i) + { + e = get_weaponinfo(stof(argv(i))); + s = strcat(s, e.message, ", "); + } + return substring(s, 0, strlen(s) - 2); +} +void XonoticWeaponsList_drawListBoxItem(entity me, float i, vector absSize, float isSelected) +{ + entity e; + if(isSelected) + draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); + e = get_weaponinfo(stof(argv(i))); + string msg = e.message; + if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED) + msg = sprintf(_("%s (mutator weapon)"), msg); + + vector save_fontscale = draw_fontscale; + float f = draw_CondensedFontFactor(msg, FALSE, me.realFontSize, 1); + draw_fontscale_x *= f; + vector fs = me.realFontSize; + fs_x *= f; + draw_Text(me.realUpperMargin * eY, msg, fs, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0); + draw_fontscale = save_fontscale; +} + +float XonoticWeaponsList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(ascii == 43) // + + { + WeaponsList_MoveUp_Click(NULL, me); + return 1; + } + else if(ascii == 45) // - + { + WeaponsList_MoveDown_Click(NULL, me); + return 1; + } + else if(SUPER(XonoticWeaponsList).keyDown(me, scan, ascii, shift)) + return 1; + return 0; +} +#endif