]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/menu/item/listbox.c
More fun stuff
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / listbox.c
index 1087c347943df0273fb1116d3032ade90c60c92a..3466b134bd708890b490879cf607dd4c824fff9d 100644 (file)
@@ -9,6 +9,7 @@ CLASS(ListBox) EXTENDS(Item)
        METHOD(ListBox, mouseRelease, float(entity, vector))
        METHOD(ListBox, focusLeave, void(entity))
        ATTRIB(ListBox, focusable, float, 1)
+       ATTRIB(ListBox, allowFocusSound, float, 1)
        ATTRIB(ListBox, selectedItem, float, 0)
        ATTRIB(ListBox, size, vector, '0 0 0')
        ATTRIB(ListBox, origin, vector, '0 0 0')
@@ -35,8 +36,13 @@ CLASS(ListBox) EXTENDS(Item)
        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))
@@ -47,13 +53,31 @@ CLASS(ListBox) EXTENDS(Item)
        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 = floor(0.5 + bound(0, i, me.nItems - 1));
+       me.selectedItem = bound(0, i, me.nItems - 1);
 }
 void ListBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 {
@@ -242,7 +266,15 @@ float ListBox_mouseRelease(entity me, vector pos)
                // and give it a nice click event
                if(me.nItems > 0)
                {
-                       me.clickListBoxItem(me, me.selectedItem, globalToBox(pos, eY * (me.getItemStart(me, me.selectedItem) - me.scrollPos), eX * (1 - me.controlWidth) + eY * me.getItemHeight(me, me.selectedItem)));
+                       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;
@@ -291,7 +323,7 @@ void ListBox_updateControlTopBottom(entity me)
                me.controlBottom = min((me.scrollPos + 1) / me.getTotalHeight(me), 1);
 
                float minfactor;
-               minfactor = 1 * me.controlWidth / me.size_y * me.size_x;
+               minfactor = 2 * me.controlWidth / me.size_y * me.size_x;
                f = me.controlBottom - me.controlTop;
                if(f < minfactor) // FIXME good default?
                {
@@ -356,7 +388,12 @@ void ListBox_draw(entity me)
 
 void ListBox_clickListBoxItem(entity me, float i, vector where)
 {
-       // itemclick, itemclick, does whatever itemclick does
+       // template method
+}
+
+void ListBox_doubleClickListBoxItem(entity me, float i, vector where)
+{
+       // template method
 }
 
 void ListBox_drawListBoxItem(entity me, float i, vector absSize, float selected)