Merge branch 'master' into TimePath/scrollpanel 268/head
authorterencehill <piuntn@gmail.com>
Sun, 18 Feb 2018 12:43:39 +0000 (13:43 +0100)
committerterencehill <piuntn@gmail.com>
Sun, 18 Feb 2018 12:43:39 +0000 (13:43 +0100)
32 files changed:
qcsrc/menu/draw.qc
qcsrc/menu/item.qc
qcsrc/menu/item.qh
qcsrc/menu/item/button.qc
qcsrc/menu/item/button.qh
qcsrc/menu/item/container.qc
qcsrc/menu/item/container.qh
qcsrc/menu/item/image.qc
qcsrc/menu/item/inputbox.qc
qcsrc/menu/item/inputbox.qh
qcsrc/menu/item/inputcontainer.qc
qcsrc/menu/item/inputcontainer.qh
qcsrc/menu/item/listbox.qc
qcsrc/menu/item/listbox.qh
qcsrc/menu/item/nexposee.qc
qcsrc/menu/item/nexposee.qh
qcsrc/menu/item/slider.qc
qcsrc/menu/item/slider.qh
qcsrc/menu/xonotic/_mod.inc
qcsrc/menu/xonotic/_mod.qh
qcsrc/menu/xonotic/colorpicker.qc
qcsrc/menu/xonotic/colorpicker.qh
qcsrc/menu/xonotic/colorpicker_string.qc
qcsrc/menu/xonotic/colorpicker_string.qh
qcsrc/menu/xonotic/dialog_settings_game.qc
qcsrc/menu/xonotic/dialog_settings_game.qh
qcsrc/menu/xonotic/picker.qc
qcsrc/menu/xonotic/picker.qh
qcsrc/menu/xonotic/screenshotimage.qc
qcsrc/menu/xonotic/screenshotimage.qh
qcsrc/menu/xonotic/scrollpanel.qc [new file with mode: 0644]
qcsrc/menu/xonotic/scrollpanel.qh [new file with mode: 0644]

index 01184a4..ae6967e 100644 (file)
@@ -312,32 +312,55 @@ float draw_CondensedFontFactor(string theText, float ICanHasKallerz, vector Size
        return 1.0;
 }
 
-float draw_clipSet;
+IntrusiveList draw_clip;
+STATIC_INIT(draw_clip) { draw_clip = IL_NEW(); }
+CLASS(ClipFrame, Object)
+       ATTRIB(ClipFrame, clip_shift, vector, '0 0 0');
+       ATTRIB(ClipFrame, clip_scale, vector, '0 0 0');
+ENDCLASS(ClipFrame)
+
+void _draw_SetClip(vector o, vector s)
+{
+       ClipFrame prev = IL_PEEK(draw_clip);
+       if (prev) {
+               o.x = bound(prev.clip_shift.x, o.x, prev.clip_shift.x + prev.clip_scale.x);
+               o.y = bound(prev.clip_shift.y, o.y, prev.clip_shift.y + prev.clip_scale.y);
+               s.x = bound(0, s.x, prev.clip_scale.x - (o.x - prev.clip_shift.x));
+               s.y = bound(0, s.y, prev.clip_scale.y - (o.y - prev.clip_shift.y));
+       }
+       ClipFrame e = NEW(ClipFrame);
+       e.clip_shift = o;
+       e.clip_scale = s;
+       IL_PUSH(draw_clip, e);
+       drawsetcliparea(o.x, o.y, s.x, s.y);
+}
+
 void draw_SetClip()
 {
-       if(draw_clipSet)
-               error("Already clipping, no stack implemented here, sorry");
-       drawsetcliparea(draw_shift.x, draw_shift.y, draw_scale.x, draw_scale.y);
-       draw_clipSet = 1;
+       _draw_SetClip(draw_shift, draw_scale);
 }
 
 void draw_SetClipRect(vector theOrigin, vector theScale)
 {
-       vector o, s;
-       if(draw_clipSet)
-               error("Already clipping, no stack implemented here, sorry");
-       o = boxToGlobal(theOrigin, draw_shift, draw_scale);
-       s = boxToGlobalSize(theScale, draw_scale);
-       drawsetcliparea(o.x, o.y, s.x, s.y);
-       draw_clipSet = 1;
+       _draw_SetClip(
+               boxToGlobal(theOrigin, draw_shift, draw_scale),
+               boxToGlobalSize(theScale, draw_scale)
+       );
 }
 
 void draw_ClearClip()
 {
-       if(!draw_clipSet)
-               error("Not clipping, can't clear it then");
+       if (IL_EMPTY(draw_clip)) {
+               LOG_FATAL("Not clipping, can't clear it then");
+       }
+       entity currentSettings = IL_PEEK(draw_clip);
+       IL_REMOVE(draw_clip, currentSettings);
+       delete(currentSettings);
        drawresetcliparea();
-       draw_clipSet = 0;
+       ClipFrame e = IL_PEEK(draw_clip);
+       if (e) {
+               drawsetcliparea(e.clip_shift.x, e.clip_shift.y, e.clip_scale.x, e.clip_scale.y);
+       }
 }
 
 string draw_TextShortenToWidth(string theText, float maxWidth, float ICanHasKallerz, vector SizeThxBye)
index 1d31e95..a5c7cfa 100644 (file)
@@ -74,9 +74,9 @@
                return 0;  // unhandled
        }
 
-       METHOD(Item, mousePress, float(Item this, vector pos))
+       METHOD(Item, mousePress, bool(Item this, vector pos))
        {
-               return 0;  // unhandled
+               return false;  // unhandled
        }
 
        METHOD(Item, mouseDrag, float(Item this, vector pos))
index a5df526..6cee17b 100644 (file)
@@ -10,7 +10,7 @@ CLASS(Item, Object)
        METHOD(Item, keyDown, float(Item, float, float, float));
        METHOD(Item, keyUp, float(Item, float, float, float));
        METHOD(Item, mouseMove, float(Item, vector));
-       METHOD(Item, mousePress, float(Item, vector));
+       METHOD(Item, mousePress, bool(Item this, vector pos));
        METHOD(Item, mouseDrag, float(Item, vector));
        METHOD(Item, mouseRelease, float(Item, vector));
        METHOD(Item, focusEnter, void(Item));
index 8299a68..77e4cca 100644 (file)
                if (pos.y >= 1) me.pressed = 0;
                return 1;
        }
-       float Button_mousePress(entity me, vector pos)
+       METHOD(Button, mousePress, bool(Button this, vector pos))
        {
-               me.mouseDrag(me, pos);  // verify coordinates
-               return 1;
+               this.mouseDrag(this, pos);  // verify coordinates
+               return true;
        }
        float Button_mouseRelease(entity me, vector pos)
        {
index 1a16424..2077da7 100644 (file)
@@ -9,7 +9,7 @@ CLASS(Button, Label)
        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, mousePress, bool(Button this, vector pos));
        METHOD(Button, mouseDrag, float(entity, vector));
        METHOD(Button, mouseRelease, float(entity, vector));
        METHOD(Button, playClickSound, void(entity));
index 56535bf..04e1bc6 100644 (file)
                }
                return 0;
        }
-       float Container_mousePress(entity me, vector pos)
+       METHOD(Container, mousePress, bool(Container this, vector pos))
        {
-               entity f;
-               float r;
-               f = me.focusedChild;
+               entity f = this.focusedChild;
                if (f)
                {
-                       me.enterSubitem(me, f);
-                       r = f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size));
-                       me.leaveSubitem(me);
+                       this.enterSubitem(this, f);
+                       bool r = f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size));
+                       this.leaveSubitem(this);
                        return r;
                }
-               return 0;
+               return false;
        }
        float Container_mouseDrag(entity me, vector pos)
        {
index 8273f5d..b737526 100644 (file)
@@ -7,7 +7,7 @@ CLASS(Container, Item)
        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, mousePress, bool(Container this, vector pos));
        METHOD(Container, mouseDrag, float(entity, vector));
        METHOD(Container, mouseRelease, float(entity, vector));
        METHOD(Container, focusLeave, void(entity));
index 59405ec..73b302c 100644 (file)
 
        void Image_draw(entity me)
        {
-               if (me.imgSize.x > 1 || me.imgSize.y > 1) draw_SetClip();
+               bool willClip = me.imgSize.x > 1 || me.imgSize.y > 1;
+               if (willClip) draw_SetClip();
                draw_Picture(me.imgOrigin, me.src, me.imgSize, me.color, 1);
-               if (me.imgSize.x > 1 || me.imgSize.y > 1) draw_ClearClip();
+               if (willClip) draw_ClearClip();
                SUPER(Image).draw(me);
        }
        void Image_updateAspect(entity me)
index 6f7ed9f..a418dc2 100644 (file)
                return 1;
        }
 
-       float InputBox_mousePress(entity me, vector pos)
+       METHOD(InputBox, mousePress, bool(InputBox this, vector pos))
        {
-               if (me.enableClearButton)
-                       if (over_ClearButton(me, pos))
+               if (this.enableClearButton)
+                       if (over_ClearButton(this, pos))
                        {
-                               me.cb_pressed = 1;
-                               return 1;
+                               this.cb_pressed = 1;
+                               return true;
                        }
-               me.dragScrollTimer = time;
-               me.pressed = 1;
-               return InputBox_mouseDrag(me, pos);
+               this.dragScrollTimer = time;
+               this.pressed = 1;
+               return InputBox_mouseDrag(this, pos);
        }
 
        float InputBox_mouseRelease(entity me, vector pos)
index e3eede6..5b0c28f 100644 (file)
@@ -9,7 +9,7 @@ CLASS(InputBox, Label)
        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, mousePress, bool(InputBox this, vector pos));
        METHOD(InputBox, mouseDrag, float(entity, vector));
        METHOD(InputBox, showNotify, void(entity));
        METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector));
index 37c4624..641e477 100644 (file)
                if (pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1) return 1;
                return 0;
        }
-       float InputContainer_mousePress(entity me, vector pos)
+       METHOD(InputContainer, mousePress, bool(InputContainer this, 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;
+               this.mouseFocusedChild = NULL;  // force focusing
+               if (this._changeFocusXY(this, pos))
+                       if (SUPER(InputContainer).mousePress(this, pos)) return true;
+               if (pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1) return true;
+               return false;
        }
        float InputContainer_mouseRelease(entity me, vector pos)
        {
index 9ae4a53..8ded2e6 100644 (file)
@@ -4,7 +4,7 @@
 CLASS(InputContainer, Container)
        METHOD(InputContainer, keyDown, float(entity, float, float, float));
        METHOD(InputContainer, mouseMove, float(entity, vector));
-       METHOD(InputContainer, mousePress, float(entity, vector));
+       METHOD(InputContainer, mousePress, bool(InputContainer this, vector pos));
        METHOD(InputContainer, mouseRelease, float(entity, vector));
        METHOD(InputContainer, mouseDrag, float(entity, vector));
        METHOD(InputContainer, focusLeave, void(entity));
index aa10c20..07385e9 100644 (file)
                }
                return 1;
        }
-       float ListBox_mousePress(entity me, vector pos)
+       METHOD(ListBox, mousePress, bool(ListBox this, vector pos))
        {
-               if (pos.x < 0) return 0;
-               if (pos.y < 0) return 0;
-               if (pos.x >= 1) return 0;
-               if (pos.y >= 1) return 0;
-               me.dragScrollPos = pos;
-               me.updateControlTopBottom(me);
-               if (pos.x >= 1 - me.controlWidth)
+               if (pos.x < 0) return false;
+               if (pos.y < 0) return false;
+               if (pos.x >= 1) return false;
+               if (pos.y >= 1) return false;
+               this.dragScrollPos = pos;
+               this.updateControlTopBottom(this);
+               if (pos.x >= 1 - this.controlWidth)
                {
-                       // if hit, set me.pressed, otherwise scroll by one page
-                       if (pos.y < me.controlTop)
+                       // if hit, set this.pressed, otherwise scroll by one page
+                       if (pos.y < this.controlTop)
                        {
                                // page up
-                               me.scrollPosTarget = max(me.scrollPosTarget - 1, 0);
+                               this.scrollPosTarget = max(this.scrollPosTarget - 1, 0);
                        }
-                       else if (pos.y > me.controlBottom)
+                       else if (pos.y > this.controlBottom)
                        {
                                // page down
-                               me.scrollPosTarget = min(me.scrollPosTarget + 1, me.getTotalHeight(me) - 1);
+                               this.scrollPosTarget = min(this.scrollPosTarget + 1, this.getTotalHeight(this) - 1);
                        }
                        else
                        {
-                               me.pressed = 1;
-                               me.pressOffset = pos.y;
-                               me.previousValue = me.scrollPos;
+                               this.pressed = 1;
+                               this.pressOffset = pos.y;
+                               this.previousValue = this.scrollPos;
                        }
                }
                else
                {
                        // continue doing that while dragging (even when dragging outside). When releasing, forward the click to the then selected item.
-                       me.pressed = 2;
+                       this.pressed = 2;
                        // an item has been clicked. Select it, ...
-                       me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
-                       me.setFocusedItem(me, me.selectedItem);
+                       this.setSelected(this, this.getItemAtPos(this, this.scrollPos + pos.y));
+                       this.setFocusedItem(this, this.selectedItem);
                }
-               return 1;
+               return true;
        }
        void ListBox_setFocusedItem(entity me, int item)
        {
        AUTOCVAR(menu_scroll_averaging_time_pressed, float, 0.06, "smooth scroll averaging time when dragging the scrollbar");
        void ListBox_draw(entity me)
        {
-               float i;
-               vector absSize, fillSize = '0 0 0';
-               vector oldshift, oldscale;
+               vector fillSize = '0 0 0';
 
                // we can't do this in mouseMove as the list can scroll without moving the cursor
                if (me.mouseMoveOffset != -1) me.setFocusedItem(me, me.getItemAtPos(me, me.scrollPos + me.mouseMoveOffset));
                        }
                }
                draw_SetClip();
-               oldshift = draw_shift;
-               oldscale = draw_scale;
+               vector oldshift = draw_shift;
+               vector oldscale = draw_scale;
 
-               i = me.getItemAtPos(me, me.scrollPos);
-               float j = me.getItemStart(me, i) - me.scrollPos;
-               for ( ; i < me.nItems && j < 1; ++i)
+               int i = me.getItemAtPos(me, me.scrollPos);
+               float y = me.getItemStart(me, i) - me.scrollPos;
+               for ( ; i < me.nItems && y < 1; ++i)
                {
-                       draw_shift = boxToGlobal(eY * j, oldshift, oldscale);
+                       draw_shift = boxToGlobal(eY * y, oldshift, oldscale);
                        vector relSize = eX * (1 - me.controlWidth) + eY * me.getItemHeight(me, i);
-                       absSize = boxToGlobalSize(relSize, me.size);
+                       vector absSize = boxToGlobalSize(relSize, me.size);
                        draw_scale = boxToGlobalSize(relSize, oldscale);
                        me.drawListBoxItem(me, i, absSize, (me.selectedItem == i), (me.focusedItem == i));
-                       j += relSize.y;
+                       y += relSize.y;
                }
                draw_ClearClip();
 
index 56fda91..b3f5164 100644 (file)
@@ -7,7 +7,7 @@ CLASS(ListBox, Item)
        METHOD(ListBox, draw, void(entity));
        METHOD(ListBox, keyDown, float(entity, float, float, float));
        METHOD(ListBox, mouseMove, float(entity, vector));
-       METHOD(ListBox, mousePress, float(entity, vector));
+       METHOD(ListBox, mousePress, bool(ListBox this, vector pos));
        METHOD(ListBox, mouseDrag, float(entity, vector));
        METHOD(ListBox, mouseRelease, float(entity, vector));
        METHOD(ListBox, focusLeave, void(entity));
index c0f18cf..d42fceb 100644 (file)
@@ -154,35 +154,35 @@ LABEL(have_overlap)
                SUPER(Nexposee).draw(me);
        }
 
-       float Nexposee_mousePress(entity me, vector pos)
+       METHOD(Nexposee, mousePress, bool(Nexposee this, vector pos))
        {
-               if (me.animationState == 0)
+               if (this.animationState == 0)
                {
-                       me.mouseFocusedChild = NULL;
-                       Nexposee_mouseMove(me, pos);
-                       if (me.mouseFocusedChild)
+                       this.mouseFocusedChild = NULL;
+                       Nexposee_mouseMove(this, pos);
+                       if (this.mouseFocusedChild)
                        {
                                m_play_click_sound(MENU_SOUND_OPEN);
-                               me.animationState = 1;
-                               SUPER(Nexposee).setFocus(me, NULL);
+                               this.animationState = 1;
+                               SUPER(Nexposee).setFocus(this, NULL);
                        }
                        else
                        {
-                               me.close(me);
+                               this.close(this);
                        }
-                       return 1;
+                       return true;
                }
-               else if (me.animationState == 2)
+               else if (this.animationState == 2)
                {
-                       if (!(SUPER(Nexposee).mousePress(me, pos)))
+                       if (!(SUPER(Nexposee).mousePress(this, pos)))
                        {
                                m_play_click_sound(MENU_SOUND_CLOSE);
-                               me.animationState = 3;
-                               SUPER(Nexposee).setFocus(me, NULL);
+                               this.animationState = 3;
+                               SUPER(Nexposee).setFocus(this, NULL);
                        }
-                       return 1;
+                       return true;
                }
-               return 0;
+               return false;
        }
 
        float Nexposee_mouseRelease(entity me, vector pos)
index 4159648..440413b 100644 (file)
@@ -5,7 +5,7 @@ CLASS(Nexposee, Container)
        METHOD(Nexposee, draw, void(entity));
        METHOD(Nexposee, keyDown, float(entity, float, float, float));
        METHOD(Nexposee, keyUp, float(entity, float, float, float));
-       METHOD(Nexposee, mousePress, float(entity, vector));
+       METHOD(Nexposee, mousePress, bool(Nexposee this, vector pos));
        METHOD(Nexposee, mouseMove, float(entity, vector));
        METHOD(Nexposee, mouseRelease, float(entity, vector));
        METHOD(Nexposee, mouseDrag, float(entity, vector));
index 2e89bb6..b569c3b 100644 (file)
 
                return 1;
        }
-       float Slider_mousePress(entity me, vector pos)
+       METHOD(Slider, mousePress, bool(Slider this, 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)
+               if (this.disabled) return false;
+               if (pos.x < 0) return false;
+               if (pos.y < 0) return false;
+               if (pos.x >= 1 - this.textSpace) return false;
+               if (pos.y >= 1) return false;
+               controlCenter = (this.value - this.valueMin) / (this.valueMax - this.valueMin) * (1 - this.textSpace - this.controlWidth) + 0.5 * this.controlWidth;
+               if (fabs(pos.x - controlCenter) <= 0.5 * this.controlWidth)
                {
-                       me.pressed = 1;
-                       me.pressOffset = pos.x - controlCenter;
-                       me.previousValue = me.value;
-                       // me.mouseDrag(me, pos);
+                       this.pressed = 1;
+                       this.pressOffset = pos.x - controlCenter;
+                       this.previousValue = this.value;
+                       // this.mouseDrag(this, 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));
+                       clickValue = median(0, (pos.x - this.pressOffset - 0.5 * this.controlWidth) / (1 - this.textSpace - this.controlWidth), 1) * (this.valueMax - this.valueMin) + this.valueMin;
+                       inRange = (almost_in_bounds(this.valueMin, this.value, this.valueMax));
                        if (pos.x < controlCenter)
                        {
-                               pageValue = me.value - me.valuePageStep;
-                               if (me.valueStep) clickValue = floor(clickValue / me.valueStep) * me.valueStep;
+                               pageValue = this.value - this.valuePageStep;
+                               if (this.valueStep) clickValue = floor(clickValue / this.valueStep) * this.valueStep;
                                pageValue = max(pageValue, clickValue);
                        }
                        else
                        {
-                               pageValue = me.value + me.valuePageStep;
-                               if (me.valueStep) clickValue = ceil(clickValue / me.valueStep) * me.valueStep;
+                               pageValue = this.value + this.valuePageStep;
+                               if (this.valueStep) clickValue = ceil(clickValue / this.valueStep) * this.valueStep;
                                pageValue = min(pageValue, clickValue);
                        }
-                       if (inRange) me.setValue(me, median(me.valueMin, pageValue, me.valueMax));
-                       else me.setValue(me, me.valueMax);
-                       if(me.applyButton)
-                               me.applyButton.disabled = false;
+                       if (inRange) this.setValue(this, median(this.valueMin, pageValue, this.valueMax));
+                       else this.setValue(this, this.valueMax);
+                       if(this.applyButton)
+                               this.applyButton.disabled = false;
                        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);
+                               controlCenter = (this.value - this.valueMin) / (this.valueMax - this.valueMin) * (1 - this.textSpace - this.controlWidth) + 0.5 * this.controlWidth;
+                               this.pressed = 1;
+                               this.pressOffset = pos.x - controlCenter;
+                               this.previousValue = this.value;
+                               // this.mouseDrag(this, pos);
                        }
                }
-               return 1;
+               return true;
        }
        float Slider_mouseRelease(entity me, vector pos)
        {
index 3b73277..c798aae 100644 (file)
@@ -10,7 +10,7 @@ CLASS(Slider, Label)
        METHOD(Slider, draw, void(entity));
        METHOD(Slider, keyDown, float(entity, float, float, float));
        METHOD(Slider, keyUp, float(entity, float, float, float));
-       METHOD(Slider, mousePress, float(entity, vector));
+       METHOD(Slider, mousePress, bool(Slider this, vector pos));
        METHOD(Slider, mouseDrag, float(entity, vector));
        METHOD(Slider, mouseRelease, float(entity, vector));
        METHOD(Slider, valueToText, string(entity, float));
index 577c822..fd83718 100644 (file)
@@ -98,6 +98,7 @@
 #include <menu/xonotic/rootdialog.qc>
 #include <menu/xonotic/screenshotimage.qc>
 #include <menu/xonotic/screenshotlist.qc>
+#include <menu/xonotic/scrollpanel.qc>
 #include <menu/xonotic/serverlist.qc>
 #include <menu/xonotic/skinlist.qc>
 #include <menu/xonotic/slider.qc>
index b6e34ef..f1644a2 100644 (file)
@@ -98,6 +98,7 @@
 #include <menu/xonotic/rootdialog.qh>
 #include <menu/xonotic/screenshotimage.qh>
 #include <menu/xonotic/screenshotlist.qh>
+#include <menu/xonotic/scrollpanel.qh>
 #include <menu/xonotic/serverlist.qh>
 #include <menu/xonotic/skinlist.qh>
 #include <menu/xonotic/slider.qh>
index 357276e..d8aedf6 100644 (file)
@@ -16,10 +16,10 @@ void XonoticColorpicker_configureXonoticColorpicker(entity me, entity theTextbox
        me.configureImage(me, me.image);
 }
 
-float XonoticColorpicker_mousePress(entity me, vector coords)
+METHOD(XonoticColorpicker, mousePress, bool(XonoticColorpicker this, vector pos))
 {
-       me.mouseDrag(me, coords);
-       return 1;
+       this.mouseDrag(this, pos);
+       return true;
 }
 
 // must match hslimage.c
index b1c9d1e..149357d 100644 (file)
@@ -3,7 +3,7 @@
 #include "../item/image.qh"
 CLASS(XonoticColorpicker, Image)
        METHOD(XonoticColorpicker, configureXonoticColorpicker, void(entity, entity));
-       METHOD(XonoticColorpicker, mousePress, float(entity, vector));
+       METHOD(XonoticColorpicker, mousePress, bool(XonoticColorpicker this, vector pos));
        METHOD(XonoticColorpicker, mouseRelease, float(entity, vector));
        METHOD(XonoticColorpicker, mouseDrag, float(entity, vector));
        ATTRIB(XonoticColorpicker, controlledTextbox, entity);
index 200204c..5a44e58 100644 (file)
@@ -50,10 +50,10 @@ void XonoticColorpickerString_saveCvars(entity me)
                cvar_set(me.cvarName, sprintf("%v", hslimage_color(me.prevcoords, me.imagemargin)));
 }
 
-float XonoticColorpickerString_mousePress(entity me, vector coords)
+METHOD(XonoticColorpickerString, mousePress, bool(XonoticColorpickerString this, vector pos))
 {
-       me.mouseDrag(me, coords);
-       return 1;
+       this.mouseDrag(this, pos);
+       return true;
 }
 
 float XonoticColorpickerString_mouseDrag(entity me, vector coords)
index e990234..aa4a10c 100644 (file)
@@ -5,7 +5,7 @@
 #include "../item/image.qh"
 CLASS(XonoticColorpickerString, Image)
        METHOD(XonoticColorpickerString, configureXonoticColorpickerString, void(entity, string, string));
-       METHOD(XonoticColorpickerString, mousePress, float(entity, vector));
+       METHOD(XonoticColorpickerString, mousePress, bool(XonoticColorpickerString this, vector pos));
        METHOD(XonoticColorpickerString, mouseRelease, float(entity, vector));
        METHOD(XonoticColorpickerString, mouseDrag, float(entity, vector));
 
index d2ce368..87134cb 100644 (file)
@@ -94,7 +94,9 @@ CONSTRUCTOR(XonoticRegisteredSettingsList, DataSource _source) {
 
 METHOD(XonoticGameSettingsTab, topicChangeNotify, void(entity, entity this))
 {
-    entity c = this.currentPanel;
+    entity s = this.currentPanel;
+    s.viewportHeight = 15.5;
+    entity c = s.currentPanel;
     entity removing = this.currentItem;
     DataSource data = this.topicList.source;
     entity adding = data.getEntry(data, this.topicList.selectedItem, func_null);
@@ -107,6 +109,7 @@ METHOD(XonoticGameSettingsTab, topicChangeNotify, void(entity, entity this))
         this.currentItem = adding;
         adding.resizeNotify(adding, '0 0 0', c.size, '0 0 0', c.size);
         c.addItem(c, adding, '0 0 0', '1 1 0', 1);
+               s.resizeNotify(s, '0 0 0', s.size, '0 0 0', s.size);
     }
 }
 METHOD(XonoticGameSettingsTab, fill, void(entity this))
index b923164..c9617f5 100644 (file)
@@ -32,13 +32,14 @@ CLASS(XonoticRegisteredSettingsList, XonoticListBox)
 ENDCLASS(XonoticRegisteredSettingsList)
 
 #include "tab.qh"
+#include "scrollpanel.qh"
 CLASS(XonoticGameSettingsTab, XonoticTab)
        ATTRIB(XonoticGameSettingsTab, intendedWidth, float, 0.9);
        ATTRIB(XonoticGameSettingsTab, rows, float, 15.5);
        ATTRIB(XonoticGameSettingsTab, columns, float, 6.5);
        ATTRIB(XonoticGameSettingsTab, source, DataSource, NEW(SettingSource));
        ATTRIB(XonoticGameSettingsTab, topicList, entity, NEW(XonoticRegisteredSettingsList, this.source));
-       ATTRIB(XonoticGameSettingsTab, currentPanel, entity, NEW(XonoticTab));
+       ATTRIB(XonoticGameSettingsTab, currentPanel, entity, NEW(XonoticScrollPanel));
        ATTRIB(XonoticGameSettingsTab, currentItem, entity);
        METHOD(XonoticGameSettingsTab, topicChangeNotify, void(entity, entity this));
        METHOD(XonoticGameSettingsTab, fill, void(entity this));
index db302e9..5276976 100644 (file)
@@ -39,17 +39,17 @@ float XonoticPicker_mouseDrag(entity me, vector coords)
        return me.mouseMove(me, coords);
 }
 
-float XonoticPicker_mousePress(entity me, vector coords)
+METHOD(XonoticPicker, mousePress, bool(XonoticPicker this, vector pos))
 {
-       me.mouseMove(me, coords);
+       this.mouseMove(this, pos);
 
-       if(me.focusedCell.x >= 0)
+       if(this.focusedCell.x >= 0)
        {
-               me.pressed = 1;
-               me.pressedCell = me.focusedCell;
+               this.pressed = 1;
+               this.pressedCell = this.focusedCell;
        }
 
-       return 1;
+       return true;
 }
 
 float XonoticPicker_mouseRelease(entity me, vector coords)
index b8e19cf..c98e9fc 100644 (file)
@@ -3,7 +3,7 @@
 #include "../item.qh"
 CLASS(XonoticPicker, Item)
        METHOD(XonoticPicker, configureXonoticPicker, void(entity));
-       METHOD(XonoticPicker, mousePress, float(entity, vector));
+       METHOD(XonoticPicker, mousePress, bool(XonoticPicker this, vector pos));
        METHOD(XonoticPicker, mouseRelease, float(entity, vector));
        METHOD(XonoticPicker, mouseMove, float(entity, vector));
        METHOD(XonoticPicker, mouseDrag, float(entity, vector));
index 42e168b..8e8f3cc 100644 (file)
@@ -27,9 +27,9 @@ void XonoticScreenshotImage_load(entity me, string theImage)
        me.setZoom(me, 0, 0);
 }
 
-float XonoticScreenshotImage_mousePress(entity me, vector coords)
+METHOD(XonoticScreenshotImage, mousePress, bool(XonoticScreenshotImage this, vector pos))
 {
-       return me.drag_setStartPos(me, coords);
+       return this.drag_setStartPos(this, pos);
 }
 
 float XonoticScreenshotImage_mouseDrag(entity me, vector coords)
index 8920bed..c27a853 100644 (file)
@@ -6,7 +6,7 @@ CLASS(XonoticScreenshotImage, XonoticImage)
        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, mousePress, bool(XonoticScreenshotImage this, vector pos));
        METHOD(XonoticScreenshotImage, mouseDrag, float(entity, vector));
        METHOD(XonoticScreenshotImage, mouseMove, float(entity, vector));
        METHOD(XonoticScreenshotImage, resizeNotify, void(entity, vector, vector, vector, vector));
diff --git a/qcsrc/menu/xonotic/scrollpanel.qc b/qcsrc/menu/xonotic/scrollpanel.qc
new file mode 100644 (file)
index 0000000..874a0af
--- /dev/null
@@ -0,0 +1,46 @@
+#include "scrollpanel.qh"
+
+METHOD(XonoticScrollPanel, drawListBoxItem, void(XonoticScrollPanel this, int i, vector absSize, bool isSelected, bool isFocused))
+{
+       XonoticTab p = this.currentPanel;
+       p.draw(p);
+}
+
+METHOD(XonoticScrollPanel, resizeNotify, void(XonoticScrollPanel this, vector relOrigin, vector relSize, vector absOrigin, vector absSize))
+{
+       SUPER(XonoticScrollPanel).resizeNotify(this, relOrigin, relSize, absOrigin, absSize);
+       this.scrollToItem(this, 0);
+       XonoticTab p = this.currentPanel;
+       float m = p.firstChild.rows / this.viewportHeight;
+       this.itemHeight = m;
+       relSize.y *= m;
+       absSize.y *= m;
+       p.resizeNotify(p, relOrigin, relSize, absOrigin, absSize);
+}
+
+#define X(x) \
+METHOD(XonoticScrollPanel, x, bool(XonoticScrollPanel this, vector pos)) \
+{ \
+       SUPER(XonoticScrollPanel).x(this, pos); \
+       XonoticTab p = this.currentPanel; \
+       this.setFocus(this, p); \
+       \
+       vector o = -eY * this.scrollPos; \
+       vector s = eX * (1 - this.controlWidth) + eY * this.itemHeight; \
+       return p.x(p, globalToBox(pos, o, s)); \
+}
+X(mouseMove)
+X(mousePress)
+X(mouseDrag)
+X(mouseRelease)
+#undef X
+
+#define X(x) \
+METHOD(XonoticScrollPanel, x, bool(XonoticScrollPanel this, int key, int ascii, bool shift)) \
+{ \
+       XonoticTab p = this.currentPanel; \
+       return p.x(p, key, ascii, shift) || SUPER(XonoticScrollPanel).x(this, key, ascii, shift); \
+}
+X(keyDown)
+X(keyUp)
+#undef X
diff --git a/qcsrc/menu/xonotic/scrollpanel.qh b/qcsrc/menu/xonotic/scrollpanel.qh
new file mode 100644 (file)
index 0000000..f675e86
--- /dev/null
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "listbox.qh"
+#include "tab.qh"
+CLASS(XonoticScrollPanel, XonoticListBox)
+       /** container for single child panel */
+       ATTRIB(XonoticScrollPanel, currentPanel, entity, NEW(XonoticTab));
+       ATTRIB(XonoticScrollPanel, nItems, int, 1);
+       ATTRIB(XonoticScrollPanel, selectionDoesntMatter, bool, true);
+       ATTRIB(XonoticScrollPanel, itemHeight, float, 1);
+       /** number of rows to show at once */
+       ATTRIB(XonoticScrollPanel, viewportHeight, float, 12);
+       ATTRIB(XonoticScrollPanel, alphaBG, float, 0);
+
+       METHOD(XonoticScrollPanel, getItemAtPos, float(XonoticScrollPanel this, float pos)) { return 0; }
+       METHOD(XonoticScrollPanel, getItemHeight, float(XonoticScrollPanel this, int i)) { return this.itemHeight; }
+       METHOD(XonoticScrollPanel, getItemStart, float(XonoticScrollPanel this, int i)) { return 0; }
+       METHOD(XonoticScrollPanel, getTotalHeight, float(XonoticScrollPanel this)) { return this.itemHeight; }
+       METHOD(XonoticScrollPanel, setFocus, void(XonoticScrollPanel this, entity other)) { Container_setFocus(this, other); }
+       METHOD(XonoticScrollPanel, setSelected, void(XonoticScrollPanel this, int i)) { }
+
+       METHOD(XonoticScrollPanel, drawListBoxItem, void(XonoticScrollPanel this, int i, vector absSize, bool isSelected, bool isFocused));
+       METHOD(XonoticScrollPanel, resizeNotify, void(XonoticScrollPanel this, vector relOrigin, vector relSize, vector absOrigin, vector absSize));
+ENDCLASS(XonoticScrollPanel)