]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'terencehill/listbox_item_highlight' into 'master'
authorMario <zacjardine@y7mail.com>
Fri, 3 Jul 2015 05:36:13 +0000 (05:36 +0000)
committerMario <zacjardine@y7mail.com>
Fri, 3 Jul 2015 05:36:13 +0000 (05:36 +0000)
Listbox: highlight item under the cursor

* Highlight listbox focused items with a customizable (by skin attributes) fade effect; the same effect is applied to the crosshair picker and to the charmap too

* Crosshair picker now has customizable (by skin attributes) color and alpha, similarly to the charmap ones

* The dot crosshair now appears always white in the crosshair picker

* The crosshair preview is no longer highlighted, nor clickable as it's no longer a button (made no sense)

About the implementation:
Changed the crosshair picker and the crosshair preview from a set of special radio buttons to 2 new different items: a picker with code based on the charmap code and a preview. More precisely the crosshair picker extends the new Picker superclass (same for the charmap).

See merge request !122

47 files changed:
gfx/menu/luma/crosshairbutton_c.tga [deleted file]
gfx/menu/luma/crosshairbutton_d.tga [deleted file]
gfx/menu/luma/crosshairbutton_f.tga [deleted file]
gfx/menu/luma/crosshairbutton_n.tga [deleted file]
gfx/menu/luma/skinvalues.txt
gfx/menu/luminos/crosshairbutton_c.tga [deleted file]
gfx/menu/luminos/crosshairbutton_d.tga [deleted file]
gfx/menu/luminos/crosshairbutton_f.tga [deleted file]
gfx/menu/luminos/crosshairbutton_n.tga [deleted file]
gfx/menu/luminos/skinvalues.txt
gfx/menu/wickedx/crosshairbutton_c.tga [deleted file]
gfx/menu/wickedx/crosshairbutton_d.tga [deleted file]
gfx/menu/wickedx/crosshairbutton_f.tga [deleted file]
gfx/menu/wickedx/crosshairbutton_n.tga [deleted file]
gfx/menu/wickedx/skinvalues.txt
gfx/menu/xaw/crosshairbutton_c.tga [deleted file]
gfx/menu/xaw/crosshairbutton_d.tga [deleted file]
gfx/menu/xaw/crosshairbutton_f.tga [deleted file]
gfx/menu/xaw/crosshairbutton_n.tga [deleted file]
gfx/menu/xaw/skinvalues.txt
qcsrc/menu/classes.inc
qcsrc/menu/item/listbox.qc
qcsrc/menu/skin-customizables.inc
qcsrc/menu/xonotic/campaign.qc
qcsrc/menu/xonotic/charmap.qc
qcsrc/menu/xonotic/credits.qc
qcsrc/menu/xonotic/crosshairbutton.qc [deleted file]
qcsrc/menu/xonotic/crosshairpicker.qc [new file with mode: 0644]
qcsrc/menu/xonotic/crosshairpreview.qc [new file with mode: 0644]
qcsrc/menu/xonotic/cvarlist.qc
qcsrc/menu/xonotic/demolist.qc
qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc
qcsrc/menu/xonotic/gametypelist.qc
qcsrc/menu/xonotic/keybinder.qc
qcsrc/menu/xonotic/languagelist.qc
qcsrc/menu/xonotic/maplist.qc
qcsrc/menu/xonotic/picker.qc [new file with mode: 0644]
qcsrc/menu/xonotic/playerlist.qc
qcsrc/menu/xonotic/playlist.qc
qcsrc/menu/xonotic/screenshotlist.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/skinlist.qc
qcsrc/menu/xonotic/soundlist.qc
qcsrc/menu/xonotic/statslist.qc
qcsrc/menu/xonotic/util.qc
qcsrc/menu/xonotic/util.qh
qcsrc/menu/xonotic/weaponslist.qc

diff --git a/gfx/menu/luma/crosshairbutton_c.tga b/gfx/menu/luma/crosshairbutton_c.tga
deleted file mode 100644 (file)
index ecfd0a8..0000000
Binary files a/gfx/menu/luma/crosshairbutton_c.tga and /dev/null differ
diff --git a/gfx/menu/luma/crosshairbutton_d.tga b/gfx/menu/luma/crosshairbutton_d.tga
deleted file mode 100644 (file)
index 4e7901e..0000000
Binary files a/gfx/menu/luma/crosshairbutton_d.tga and /dev/null differ
diff --git a/gfx/menu/luma/crosshairbutton_f.tga b/gfx/menu/luma/crosshairbutton_f.tga
deleted file mode 100644 (file)
index 604a935..0000000
Binary files a/gfx/menu/luma/crosshairbutton_f.tga and /dev/null differ
diff --git a/gfx/menu/luma/crosshairbutton_n.tga b/gfx/menu/luma/crosshairbutton_n.tga
deleted file mode 100644 (file)
index 4e7901e..0000000
Binary files a/gfx/menu/luma/crosshairbutton_n.tga and /dev/null differ
index 1e87e8869ec5d9443c3147dde51298a675738f94..5a36d90e0722e389e135f6057c931b150dc673da 100644 (file)
@@ -33,8 +33,10 @@ COLOR_CAMPAIGN_SELECTABLE     '0.96 0.99 1'
 // charmap
 ALPHA_CHARMAP_CHAR            0.85
 COLOR_CHARMAP_CHAR            '1 1 1'
-ALPHA_CHARMAP_FOCUS           0.85
-COLOR_CHARMAP_FOCUS           '0.09 0.42 0.69'
+
+// crosshairpicker
+ALPHA_CROSSHAIRPICKER_CROSSHAIR 0.85
+COLOR_CROSSHAIRPICKER_CROSSHAIR '1 1 1'
 
 // checkbox
 COLOR_CHECKBOX_C              '1 1 1'
@@ -142,6 +144,9 @@ ALPHA_LISTBOX_SELECTED        1
 COLOR_LISTBOX_SELECTED        '0.97 0.56 0.27'
 ALPHA_LISTBOX_WAITING         0.8
 COLOR_LISTBOX_WAITING         '0.73 0.82 0.9'
+ALPHA_LISTBOX_FOCUSED         0.8
+FADEALPHA_LISTBOX_FOCUSED     0.4
+COLOR_LISTBOX_FOCUSED         '0.09 0.42 0.69'
 
 // mainmenu
 ALPHAS_MAINMENU               '0.8 0.9 1'
diff --git a/gfx/menu/luminos/crosshairbutton_c.tga b/gfx/menu/luminos/crosshairbutton_c.tga
deleted file mode 100644 (file)
index 586f9b4..0000000
Binary files a/gfx/menu/luminos/crosshairbutton_c.tga and /dev/null differ
diff --git a/gfx/menu/luminos/crosshairbutton_d.tga b/gfx/menu/luminos/crosshairbutton_d.tga
deleted file mode 100755 (executable)
index cba9d88..0000000
Binary files a/gfx/menu/luminos/crosshairbutton_d.tga and /dev/null differ
diff --git a/gfx/menu/luminos/crosshairbutton_f.tga b/gfx/menu/luminos/crosshairbutton_f.tga
deleted file mode 100644 (file)
index 57d7d93..0000000
Binary files a/gfx/menu/luminos/crosshairbutton_f.tga and /dev/null differ
diff --git a/gfx/menu/luminos/crosshairbutton_n.tga b/gfx/menu/luminos/crosshairbutton_n.tga
deleted file mode 100755 (executable)
index ac94535..0000000
Binary files a/gfx/menu/luminos/crosshairbutton_n.tga and /dev/null differ
index 77af6c8dc0dfededc9af62be884e9eb482f55a90..b9c69802e490e28ecc7b6b6cbebf24e3eb479204 100755 (executable)
@@ -108,6 +108,9 @@ COLOR_LISTBOX_SELECTED          '1 0.4375 0'
 ALPHA_LISTBOX_SELECTED          1
 COLOR_LISTBOX_WAITING           '1 1 1'
 ALPHA_LISTBOX_WAITING           0.5
+COLOR_LISTBOX_FOCUSED           '0 0.25 0.5'
+ALPHA_LISTBOX_FOCUSED           0.7
+FADEALPHA_LISTBOX_FOCUSED       0.3
 
 // item: map list
 COLOR_MAPLIST_TITLE             '1 1 1'
@@ -170,9 +173,6 @@ COLOR_CHECKBOX_C                '1 1 1'
 COLOR_CHECKBOX_F                '1 1 1'
 COLOR_CHECKBOX_D                '1 1 1'
 
-// item: crosshair button
-//   uses "crosshairbutton" images
-
 // dialog background colors
 //   uses "border" images
 COLOR_DIALOG_MULTIPLAYER        '1 1 1'
@@ -221,8 +221,10 @@ ALPHA_KEYGRABBER_KEYS           0.7
 // item: charmap
 ALPHA_CHARMAP_CHAR              0.85
 COLOR_CHARMAP_CHAR              '1 1 1'
-ALPHA_CHARMAP_FOCUS             1
-COLOR_CHARMAP_FOCUS             '0 0.25 0.5'
+
+// item: crosshairpicker
+ALPHA_CROSSHAIRPICKER_CROSSHAIR 0.85
+COLOR_CROSSHAIRPICKER_CROSSHAIR '1 1 1'
 
 // item: radio button
 //   uses "radiobutton" images
diff --git a/gfx/menu/wickedx/crosshairbutton_c.tga b/gfx/menu/wickedx/crosshairbutton_c.tga
deleted file mode 100644 (file)
index 1c294f7..0000000
Binary files a/gfx/menu/wickedx/crosshairbutton_c.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/crosshairbutton_d.tga b/gfx/menu/wickedx/crosshairbutton_d.tga
deleted file mode 100755 (executable)
index 110faa1..0000000
Binary files a/gfx/menu/wickedx/crosshairbutton_d.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/crosshairbutton_f.tga b/gfx/menu/wickedx/crosshairbutton_f.tga
deleted file mode 100644 (file)
index 0031c35..0000000
Binary files a/gfx/menu/wickedx/crosshairbutton_f.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/crosshairbutton_n.tga b/gfx/menu/wickedx/crosshairbutton_n.tga
deleted file mode 100755 (executable)
index ac94535..0000000
Binary files a/gfx/menu/wickedx/crosshairbutton_n.tga and /dev/null differ
index 8b56baa1f3c54a54d561f3a335017a68424fa876..09ded4b087c356d741a823ab25293da71bae7dcb 100644 (file)
@@ -108,6 +108,9 @@ COLOR_LISTBOX_SELECTED          '0.875 0.375 0'
 ALPHA_LISTBOX_SELECTED          1
 COLOR_LISTBOX_WAITING           '1 1 1'
 ALPHA_LISTBOX_WAITING           0.5
+COLOR_LISTBOX_FOCUSED           '0 0.375 0.75'
+ALPHA_LISTBOX_FOCUSED           0.35
+FADEALPHA_LISTBOX_FOCUSED       0.75
 
 // item: map list
 COLOR_MAPLIST_TITLE             '1 1 1'
@@ -170,9 +173,6 @@ COLOR_CHECKBOX_C                '0.5 0.75 1'
 COLOR_CHECKBOX_F                '0.5 0.75 1'
 COLOR_CHECKBOX_D                '1 1 1'
 
-// item: crosshair button
-//   uses "crosshairbutton" images
-
 // dialog background colors
 //   uses "border" images
 COLOR_DIALOG_MULTIPLAYER        '1 1 1'
@@ -221,8 +221,10 @@ ALPHA_KEYGRABBER_KEYS           0.7
 // item: charmap
 ALPHA_CHARMAP_CHAR              0.85
 COLOR_CHARMAP_CHAR              '1 1 1'
-ALPHA_CHARMAP_FOCUS             0.75
-COLOR_CHARMAP_FOCUS             '0 0.375 0.75'
+
+// item: crosshairpicker
+ALPHA_CROSSHAIRPICKER_CROSSHAIR 0.85
+COLOR_CROSSHAIRPICKER_CROSSHAIR '1 1 1'
 
 // item: radio button
 //   uses "radiobutton" images
diff --git a/gfx/menu/xaw/crosshairbutton_c.tga b/gfx/menu/xaw/crosshairbutton_c.tga
deleted file mode 100644 (file)
index 646c64e..0000000
Binary files a/gfx/menu/xaw/crosshairbutton_c.tga and /dev/null differ
diff --git a/gfx/menu/xaw/crosshairbutton_d.tga b/gfx/menu/xaw/crosshairbutton_d.tga
deleted file mode 100644 (file)
index 110faa1..0000000
Binary files a/gfx/menu/xaw/crosshairbutton_d.tga and /dev/null differ
diff --git a/gfx/menu/xaw/crosshairbutton_f.tga b/gfx/menu/xaw/crosshairbutton_f.tga
deleted file mode 100644 (file)
index d8f25ef..0000000
Binary files a/gfx/menu/xaw/crosshairbutton_f.tga and /dev/null differ
diff --git a/gfx/menu/xaw/crosshairbutton_n.tga b/gfx/menu/xaw/crosshairbutton_n.tga
deleted file mode 100644 (file)
index 5d678a6..0000000
Binary files a/gfx/menu/xaw/crosshairbutton_n.tga and /dev/null differ
index 57c6f2a35009163a49426aa802b167804474a6f3..00df32498ebdfdb623c9e42d3c9c0348db648a94 100644 (file)
@@ -107,9 +107,6 @@ ALPHA_CREDITS_PERSON            1
 ROWS_CREDITS                    20
 WIDTH_CREDITS                   0.5
 
-// item: crosshair button
-//   uses "crosshairbutton" images
-
 // item: cvar list
 ALPHA_CVARLIST_SAVED            1
 ALPHA_CVARLIST_TEMPORARY        0.7
@@ -152,8 +149,11 @@ COLOR_LISTBOX_SELECTED          '0 0 0'
 ALPHA_LISTBOX_SELECTED          1
 COLOR_LISTBOX_WAITING           '1 0 0'
 ALPHA_LISTBOX_WAITING           0.5
-COLOR_LISTBOX_BACKGROUND               '0 0 0'
-ALPHA_LISTBOX_BACKGROUND               0
+COLOR_LISTBOX_BACKGROUND        '0 0 0'
+ALPHA_LISTBOX_BACKGROUND        0
+COLOR_LISTBOX_FOCUSED           '0 0 0'
+ALPHA_LISTBOX_FOCUSED           0.3
+FADEALPHA_LISTBOX_FOCUSED       0.3
 
 // item: map list
 COLOR_MAPLIST_TITLE             '1 1 1'
@@ -176,8 +176,10 @@ ALPHA_MODELTITLE                1
 // item: charmap
 ALPHA_CHARMAP_CHAR              0.85
 COLOR_CHARMAP_CHAR              '1 1 1'
-ALPHA_CHARMAP_FOCUS             0.5
-COLOR_CHARMAP_FOCUS             '0 0 0'
+
+// item: crosshairpicker
+ALPHA_CROSSHAIRPICKER_CROSSHAIR 0.85
+COLOR_CROSSHAIRPICKER_CROSSHAIR '1 1 1'
 
 // item: radio button
 //   uses "radiobutton" images
index 68b90d586394939a459e81345903a605f7be2e75..5b0e417f94965c5c1f4899b49a904575c3366c4c 100644 (file)
@@ -34,7 +34,8 @@
 #include "xonotic/colorpicker_string.qc"
 #include "xonotic/commandbutton.qc"
 #include "xonotic/credits.qc"
-#include "xonotic/crosshairbutton.qc"
+#include "xonotic/crosshairpicker.qc"
+#include "xonotic/crosshairpreview.qc"
 #include "xonotic/cvarlist.qc"
 #include "xonotic/demolist.qc"
 #include "xonotic/dialog.qc"
 #include "xonotic/mainwindow.qc"
 #include "xonotic/maplist.qc"
 #include "xonotic/nexposee.qc"
+#include "xonotic/picker.qc"
 #include "xonotic/playerlist.qc"
 #include "xonotic/playermodel.qc"
 #include "xonotic/playlist.qc"
index 044c9e34a0feb71d857d9ebb4b0f48d6cb5969c2..f7c17fa6bd888a73e580f825c81c077467d230a5 100644 (file)
@@ -6,11 +6,14 @@ CLASS(ListBox, Item)
        METHOD(ListBox, configureListBox, void(entity, float, float))
        METHOD(ListBox, draw, void(entity))
        METHOD(ListBox, keyDown, float(entity, float, float, float))
+       METHOD(ListBox, mouseMove, float(entity, vector))
        METHOD(ListBox, mousePress, float(entity, vector))
        METHOD(ListBox, mouseDrag, float(entity, vector))
        METHOD(ListBox, mouseRelease, float(entity, vector))
        METHOD(ListBox, focusLeave, void(entity))
        ATTRIB(ListBox, focusable, float, 1)
+       ATTRIB(ListBox, focusedItem, int, -1)
+       ATTRIB(ListBox, focusedItemAlpha, float, 0.3)
        ATTRIB(ListBox, allowFocusSound, float, 1)
        ATTRIB(ListBox, selectedItem, int, 0)
        ATTRIB(ListBox, size, vector, '0 0 0')
@@ -42,7 +45,7 @@ CLASS(ListBox, Item)
        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, drawListBoxItem, void(entity, int, vector, bool, bool)) // item number, width/height, isSelected, isFocused
        METHOD(ListBox, clickListBoxItem, void(entity, float, vector)) // item number, relative clickpos
        METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector)) // item number, relative clickpos
        METHOD(ListBox, setSelected, void(entity, float))
@@ -178,6 +181,22 @@ float ListBox_keyDown(entity me, float key, float ascii, float shift)
                return 0;
        return 1;
 }
+float ListBox_mouseMove(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;
+       if(pos_x < 1 - me.controlWidth)
+       {
+               float x;
+               x = me.focusedItem;
+               me.focusedItem = me.getItemAtPos(me, me.scrollPos + pos.y);
+               if(x != me.focusedItem)
+                       me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED;
+       }
+       return 1;
+}
 float ListBox_mouseDrag(entity me, vector pos)
 {
        float hit;
@@ -288,6 +307,7 @@ void ListBox_focusLeave(entity me)
        // by a mouse click on an item of the list
        // for example showing a dialog on right click
        me.pressed = 0;
+       me.focusedItem = -1;
 }
 void ListBox_updateControlTopBottom(entity me)
 {
@@ -369,6 +389,7 @@ void ListBox_draw(entity me)
        draw_SetClip();
        oldshift = draw_shift;
        oldscale = draw_scale;
+
        float y;
        i = me.getItemAtPos(me, me.scrollPos);
        y = me.getItemStart(me, i) - me.scrollPos;
@@ -378,7 +399,7 @@ void ListBox_draw(entity me)
                vector relSize = eX * (1 - me.controlWidth) + eY * me.getItemHeight(me, i);
                absSize = boxToGlobalSize(relSize, me.size);
                draw_scale = boxToGlobalSize(relSize, oldscale);
-               me.drawListBoxItem(me, i, absSize, (me.selectedItem == i));
+               me.drawListBoxItem(me, i, absSize, (me.selectedItem == i), (me.focusedItem == i));
                y += relSize.y;
        }
        draw_ClearClip();
@@ -398,8 +419,8 @@ void ListBox_doubleClickListBoxItem(entity me, float i, vector where)
        // template method
 }
 
-void ListBox_drawListBoxItem(entity me, float i, vector absSize, float selected)
+void ListBox_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
-       draw_Text('0 0 0', sprintf(_("Item %d"), i), eX * (8 / absSize.x) + eY * (8 / absSize.y), (selected ? '0 1 0' : '1 1 1'), 1, 0);
+       draw_Text('0 0 0', sprintf(_("Item %d"), i), eX * (8 / absSize.x) + eY * (8 / absSize.y), (isSelected ? '0 1 0' : '1 1 1'), 1, 0);
 }
 #endif
index ee0e76f399f7efbde625505d3b2fd59db7f84dae..bf29683f6302b1bc889e68f09017a690ab0e55cd 100644 (file)
@@ -144,9 +144,6 @@ SKINBEGIN
        SKINFLOAT(ROWS_CREDITS, 20);
        SKINFLOAT(WIDTH_CREDITS, 0.5);
 
-       // item: crosshair button
-       SKINSTRING(GFX_CROSSHAIRBUTTON, "crosshairbutton");
-
        // item: cvar list
        SKINFLOAT(ALPHA_CVARLIST_SAVED, 1);
        SKINFLOAT(ALPHA_CVARLIST_TEMPORARY, 0.7);
@@ -191,6 +188,9 @@ SKINBEGIN
        SKINFLOAT(ALPHA_LISTBOX_WAITING, 0.5);
        SKINVECTOR(COLOR_LISTBOX_BACKGROUND, '0 0 0');
        SKINFLOAT(ALPHA_LISTBOX_BACKGROUND, 0.5);
+       SKINVECTOR(COLOR_LISTBOX_FOCUSED, '0 0 1');
+       SKINFLOAT(ALPHA_LISTBOX_FOCUSED, 0.7);
+       SKINFLOAT(FADEALPHA_LISTBOX_FOCUSED, 0.3);
 
        // item: map list
        SKINVECTOR(COLOR_MAPLIST_TITLE, '1 1 1');
@@ -211,11 +211,13 @@ SKINBEGIN
        SKINVECTOR(COLOR_MODELTITLE, '1 1 1');
        SKINFLOAT(ALPHA_MODELTITLE, 1);
 
-       // item: player name editor
+       // item: special character picker
        SKINVECTOR(COLOR_CHARMAP_CHAR, '1 1 1');
        SKINFLOAT(ALPHA_CHARMAP_CHAR, 1);
-       SKINVECTOR(COLOR_CHARMAP_FOCUS, '0 0 1');
-       SKINFLOAT(ALPHA_CHARMAP_FOCUS, 0.5);
+
+       // item: crosshair picker
+       SKINVECTOR(COLOR_CROSSHAIRPICKER_CROSSHAIR, '1 1 1');
+       SKINFLOAT(ALPHA_CROSSHAIRPICKER_CROSSHAIR, 1);
 
        // item: radio button
        SKINSTRING(GFX_RADIOBUTTON, "radiobutton");
index 826a0b4f2d7c6d81cf22f906f3fd7230dbc99a32..e30c038a01b5b14e2dea5e241698ca1e05b0c5fc 100644 (file)
@@ -7,7 +7,7 @@ CLASS(XonoticCampaignList, 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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticCampaignList, doubleClickListBoxItem, void(entity, float, vector))
        METHOD(XonoticCampaignList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticCampaignList, setSelected, void(entity, float))
@@ -239,7 +239,7 @@ void XonoticCampaignList_doubleClickListBoxItem(entity me, float i, vector where
 {
        CampaignList_LoadMap(me, me);
 }
-void XonoticCampaignList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected)
+void XonoticCampaignList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
        vector theColor;
@@ -265,6 +265,11 @@ void XonoticCampaignList_drawListBoxItem(entity me, int i, vector absSize, bool
 
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        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);
index d6bc52461846995ad7f0d09f0e4f3a871a4bd3ac..747d1f03b4568a4a820bdc35cedb170b67570a19 100644 (file)
@@ -1,34 +1,27 @@
 #ifndef CHARMAP_H
 #define CHARMAP_H
-#include "../item.qc"
-CLASS(XonoticCharmap, Item)
+#include "picker.qc"
+CLASS(XonoticCharmap, XonoticPicker)
        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))
+       METHOD(XonoticCharmap, keyDown, float(entity, float, float, float))
        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')
+
+       ATTRIB(XonoticCharmap, rows, float, 10)
+       ATTRIB(XonoticCharmap, columns, float, 14)
+
+       METHOD(XonoticCharmap, cellSelect, void(entity, vector))
+       METHOD(XonoticCharmap, cellIsValid, bool(entity, vector))
+       METHOD(XonoticCharmap, cellDraw, void(entity, vector, vector))
+       METHOD(XonoticCharmap, charOffset, vector)
 ENDCLASS(XonoticCharmap)
 entity makeXonoticCharmap(entity controlledInputBox);
 #endif
 
 #ifdef IMPLEMENTATION
 
-const float CHARMAP_COLS = 14;
-const float CHARMAP_ROWS = 10;
-
 string CHARMAP =
        "★◆■▮▰▬◣◤◥◢◀▲▶▼"
        "🌍🌎🌏🚀🌌👽🔫⌖❇❈←↑→↓"
@@ -46,11 +39,11 @@ string CHARMAP =
        "\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 charmap_cellToChar(entity me, vector cell)
 {
-       string character = substring(CHARMAP, cell.y * CHARMAP_COLS + cell.x, 1);
+       string character = substring(CHARMAP, cell.y * me.columns + cell.x, 1);
 
-       if (character != " ")
+       if(character != " ")
                return character;
        else
                return "";
@@ -67,7 +60,7 @@ entity makeXonoticCharmap(entity controlledInputBox)
 void XonoticCharmap_configureXonoticCharmap(entity me, entity controlledInputBox)
 {
        me.inputBox = controlledInputBox;
-       me.realCellSize = eX / CHARMAP_COLS + eY / CHARMAP_ROWS;
+       me.configureXonoticPicker(me);
 }
 
 void XonoticCharmap_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
@@ -90,153 +83,38 @@ void XonoticCharmap_resizeNotify(entity me, vector relOrigin, vector relSize, ve
 
        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;
+       me.charOffset = eX * me.realCellSize.x / 2 + eY * ((me.realCellSize.y - me.realFontSize.y) / 2);
 }
 
-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)
+float XonoticCharmap_keyDown(entity me, float key, float ascii, float shift)
 {
-       if(!me.pressed)
-               return 0;
-
-       me.mouseMove(me, coords);
-
-       if(me.focusedCell == me.previouslyFocusedCell)
-               me.enterChar(me);
-
-       me.pressed = 0;
-       return 1;
+       if(SUPER(XonoticCharmap).keyDown(me, key, ascii, shift))
+               return 1;
+       return me.inputBox.keyDown(me.inputBox, key, ascii, shift);
 }
 
-float XonoticCharmap_keyDown(entity me, float key, float ascii, float shift)
+void XonoticCharmap_cellSelect(entity me, vector cell)
 {
-       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);
-       }
+       string character = charmap_cellToChar(me, cell);
+       if(character != "")
+               me.inputBox.enterText(me.inputBox, character);
 }
 
-void XonoticCharmap_moveFocus(entity me, vector initialCell, vector step)
+bool XonoticCharmap_cellIsValid(entity me, vector cell)
 {
-       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);
+       if(charmap_cellToChar(me, cell) == "")
+               return false;
+       return true;
 }
 
-void XonoticCharmap_enterChar(entity me)
+void XonoticCharmap_cellDraw(entity me, vector cell, vector cellPos)
 {
-       string character = charmap_cellToChar(me.focusedCell);
-       if(character != "")
-               me.inputBox.enterText(me.inputBox, character);
+       draw_CenterText(cellPos + me.charOffset, charmap_cellToChar(me, cell), me.realFontSize, SKINCOLOR_CHARMAP_CHAR, SKINALPHA_CHARMAP_CHAR, 0);
 }
 
 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
index d7e17f53296c40dc158eb4b97b62464b04e62009..57320a018240e3ac47bf8eae814280674004b705 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticCreditsList, 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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticCreditsList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticCreditsList, keyDown, float(entity, float, float, float))
        METHOD(XonoticCreditsList, destroy, void(entity))
@@ -59,7 +59,7 @@ void XonoticCreditsList_resizeNotify(entity me, vector relOrigin, vector relSize
        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)
+void XonoticCreditsList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        // layout: Ping, Credits name, Map name, NP, TP, MP
        string s;
diff --git a/qcsrc/menu/xonotic/crosshairbutton.qc b/qcsrc/menu/xonotic/crosshairbutton.qc
deleted file mode 100644 (file)
index 466846f..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-#ifndef CROSSHAIRBUTTON_H
-#define CROSSHAIRBUTTON_H
-#include "../item/radiobutton.qc"
-CLASS(XonoticCrosshairButton, 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 = NEW(XonoticCrosshairButton);
-       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/crosshairpicker.qc b/qcsrc/menu/xonotic/crosshairpicker.qc
new file mode 100644 (file)
index 0000000..8922e7f
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef CROSSHAIRPICKER_H
+#define CROSSHAIRPICKER_H
+#include "picker.qc"
+CLASS(XonoticCrosshairPicker, XonoticPicker)
+       METHOD(XonoticCrosshairPicker, configureXonoticCrosshairPicker, void(entity))
+
+       ATTRIB(XonoticCrosshairPicker, rows, float, 3)
+       ATTRIB(XonoticCrosshairPicker, columns, float, 12)
+
+       METHOD(XonoticCrosshairPicker, cellSelect, void(entity, vector))
+       METHOD(XonoticCrosshairPicker, cellIsValid, bool(entity, vector))
+       METHOD(XonoticCrosshairPicker, cellDraw, void(entity, vector, vector))
+ENDCLASS(XonoticCrosshairPicker)
+entity makeXonoticCrosshairPicker();
+#endif
+
+#ifdef IMPLEMENTATION
+
+string crosshairpicker_cellToCrosshair(entity me, vector cell)
+{
+       if(cell.x < 0 || cell.x >= me.columns || cell.y < 0 || cell.y >= me.rows)
+               return "";
+       return ftos(31 + cell.y * me.columns + cell.x);
+}
+
+vector crosshairpicker_crosshairToCell(entity me, string crosshair_str)
+{
+       float crosshair = stof(crosshair_str) - 31;
+       if(crosshair - floor(crosshair) > 0)
+               return '-1 -1 0';
+       return mod(crosshair, me.columns) * eX + floor(crosshair / me.columns) * eY;
+}
+
+entity makeXonoticCrosshairPicker()
+{
+       entity me;
+       me = NEW(XonoticCrosshairPicker);
+       me.configureXonoticCrosshairPicker(me);
+       return me;
+}
+
+void XonoticCrosshairPicker_configureXonoticCrosshairPicker(entity me)
+{
+       me.configureXonoticPicker(me);
+       SUPER(XonoticCrosshairPicker).cellSelect(me, crosshairpicker_crosshairToCell(me, cvar_string("crosshair")));
+}
+
+void XonoticCrosshairPicker_cellSelect(entity me, vector cell)
+{
+       cvar_set("crosshair", crosshairpicker_cellToCrosshair(me, me.focusedCell));
+       SUPER(XonoticCrosshairPicker).cellSelect(me, me.focusedCell);
+}
+
+bool XonoticCrosshairPicker_cellIsValid(entity me, vector cell)
+{
+       if(crosshairpicker_cellToCrosshair(me, cell) == "")
+               return false;
+       return true;
+}
+
+void XonoticCrosshairPicker_cellDraw(entity me, vector cell, vector cellPos)
+{
+       vector sz;
+       string cross = strcat("/gfx/crosshair", crosshairpicker_cellToCrosshair(me, cell));
+       sz = draw_PictureSize(cross);
+       sz = globalToBoxSize(sz, me.size);
+
+       float ar = sz.x / sz.y;
+       sz.x = me.realCellSize.x;
+       sz.y = sz.x / ar;
+       sz = sz * 0.95;
+
+       vector crosshairPos = cellPos + 0.5 * me.realCellSize;
+       draw_Picture(crosshairPos - 0.5 * sz, cross, sz, SKINCOLOR_CROSSHAIRPICKER_CROSSHAIR, SKINALPHA_CROSSHAIRPICKER_CROSSHAIR);
+
+       if(cvar("crosshair_dot"))
+               draw_Picture(crosshairPos - 0.5 * sz * cvar("crosshair_dot_size"), "/gfx/crosshairdot", sz * cvar("crosshair_dot_size"), SKINCOLOR_CROSSHAIRPICKER_CROSSHAIR, SKINALPHA_CROSSHAIRPICKER_CROSSHAIR);
+}
+#endif
diff --git a/qcsrc/menu/xonotic/crosshairpreview.qc b/qcsrc/menu/xonotic/crosshairpreview.qc
new file mode 100644 (file)
index 0000000..f8de857
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef CROSSHAIRPREVIEW_H
+#define CROSSHAIRPREVIEW_H
+#include "../item.qc"
+CLASS(XonoticCrosshairPreview, Item)
+       METHOD(XonoticCrosshairPreview, configureXonoticCrosshairPreview, void(entity))
+       METHOD(XonoticCrosshairPreview, draw, void(entity))
+       ATTRIB(XonoticCrosshairPreview, src, string, string_null)
+       ATTRIB(XonoticCrosshairPreview, src2, string, string_null)
+       ATTRIB(XonoticCrosshairPreview, disabled, float, 0)
+       ATTRIB(XonoticCrosshairPreview, disabledAlpha, float, SKINALPHA_DISABLED)
+ENDCLASS(XonoticCrosshairPreview)
+entity makeXonoticCrosshairPreview();
+#endif
+
+#ifdef IMPLEMENTATION
+entity makeXonoticCrosshairPreview()
+{
+       entity me;
+       me = NEW(XonoticCrosshairPreview);
+       me.configureXonoticCrosshairPreview(me);
+       return me;
+}
+
+void XonoticCrosshairPreview_configureXonoticCrosshairPreview(entity me)
+{
+       me.src = strzone(strcat("/gfx/crosshair", cvar_string("crosshair")));
+       me.src2 = "/gfx/crosshairdot";
+}
+
+void XonoticCrosshairPreview_draw(entity me)
+{
+       float save;
+       save = draw_alpha;
+       if(me.disabled)
+               draw_alpha *= me.disabledAlpha;
+
+       vector sz, rgb;
+       float a;
+       rgb = stov(cvar_string("crosshair_color"));
+       a = cvar("crosshair_alpha");
+       if(me.src)
+               strunzone(me.src);
+       me.src = strzone(strcat("/gfx/crosshair", cvar_string("crosshair")));
+
+       sz = draw_PictureSize(me.src);
+       sz = globalToBoxSize(sz, me.size);
+       sz = sz * cvar("crosshair_size");
+
+       draw_Picture('0.5 0.5 0' - 0.5 * sz, me.src, 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.src2, sz * cvar("crosshair_dot_size"), rgb, a * cvar("crosshair_dot_alpha"));
+       }
+
+       draw_alpha = save;
+
+       SUPER(XonoticCrosshairPreview).draw(me);
+}
+#endif
index 44520c1f22f58857b72d43d71e63ae97e9556843..9a95ed163963c58607afd2a0709bd408e6d5cad6 100644 (file)
@@ -4,7 +4,7 @@
 CLASS(XonoticCvarList, XonoticListBox)
        METHOD(XonoticCvarList, configureXonoticCvarList, void(entity))
        ATTRIB(XonoticCvarList, rowsPerItem, float, 1)
-       METHOD(XonoticCvarList, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticCvarList, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticCvarList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticCvarList, keyDown, float(entity, float, float, float))
 
@@ -154,7 +154,7 @@ void XonoticCvarList_resizeNotify(entity me, vector relOrigin, vector relSize, v
 
        me.setSelected(me, me.selectedItem);
 }
-void XonoticCvarList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticCvarList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string k, v, d;
        float t;
@@ -166,6 +166,11 @@ void XonoticCvarList_drawListBoxItem(entity me, float i, vector absSize, float i
 
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        k = bufstr_get(me.handle, i);
 
index 4f759f68ad7e6e58bd70e60c5d003014052e5dfd..f46ee407b6c82ecc8fa272df54e6eb7df379645c 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticDemoList, 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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticDemoList, getDemos, void(entity))
        METHOD(XonoticDemoList, startDemo, void(entity))
        METHOD(XonoticDemoList, timeDemo, void(entity))
@@ -135,11 +135,16 @@ void XonoticDemoList_resizeNotify(entity me, vector relOrigin, vector relSize, v
        me.columnNameSize = 1 - 2 * me.realFontSize.x;
 }
 
-void XonoticDemoList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticDemoList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        s = me.demoName(me,i);
        s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
index bda4fadd7a44ba00942de5b16e46fe091dc165d0..0122abf3290fe566b8dd9f59014c7f7cc29709a7 100644 (file)
@@ -29,7 +29,6 @@ entity makeXonoticGameCrosshairSettingsTab()
 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?
@@ -42,26 +41,12 @@ void XonoticGameCrosshairSettingsTab_fill(entity me)
                me.TD(me, 1, 1, e = makeXonoticRadioButton(3, "crosshair_enabled", "2", _("Custom")));
        me.TR(me);
                me.TDempty(me, 0.1);
-               for(i = 31; i <= 42; ++i) {
-                       me.TDNoMargin(me, 1, 2 / 12, 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
+               me.TD(me, 3, 2, e = makeXonoticCrosshairPicker());
+                       setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2);
+               me.TD(me, 3, 0.9, e = makeXonoticCrosshairPreview());
                        setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2);
        me.TR(me);
-               me.TDempty(me, 0.1);
-               for(i = 43; i <= 54; ++i) {
-                       me.TDNoMargin(me, 1, 2 / 12, e = makeXonoticCrosshairButton(4, i), '1 1 0');
-                               setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2);
-               }
        me.TR(me);
-               me.TDempty(me, 0.1);
-               for(i = 55; i <= 66; ++i) {
-                       me.TDNoMargin(me, 1, 2 / 12, e = makeXonoticCrosshairButton(4, i), '1 1 0');
-                               setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2);
-               }
        me.TR(me);
                me.TDempty(me, 0.1);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Crosshair size:")));
index d8dbc8838ea5bdb709931008cf7f3207a614ad9a..26845f0946430469120b374d59bfc0f0d785f7a3 100644 (file)
@@ -4,7 +4,7 @@
 CLASS(XonoticGametypeList, XonoticListBox)
        METHOD(XonoticGametypeList, configureXonoticGametypeList, void(entity))
        ATTRIB(XonoticGametypeList, rowsPerItem, float, 2)
-       METHOD(XonoticGametypeList, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticGametypeList, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticGametypeList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticGametypeList, setSelected, void(entity, float))
        METHOD(XonoticGametypeList, loadCvars, void(entity))
@@ -78,12 +78,17 @@ void XonoticGametypeList_saveCvars(entity me)
                owner.gameTypeChangeNotify(owner);
        }
 }
-void XonoticGametypeList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticGametypeList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s1, s2;
 
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        draw_Picture(me.columnIconOrigin * eX, GameType_GetIcon(i), me.columnIconSize * eX + eY, '1 1 1', SKINALPHA_LISTBOX_SELECTED);
        s1 = GameType_GetName(i);
index 82d3db4e5d7d5489cae3c1d9fb414a7fa1132cc7..8953b1db9b3f716e11dd0d49eb83a2566c8cf859 100644 (file)
@@ -4,7 +4,7 @@
 CLASS(XonoticKeyBinder, XonoticListBox)
        METHOD(XonoticKeyBinder, configureXonoticKeyBinder, void(entity))
        ATTRIB(XonoticKeyBinder, rowsPerItem, int, 1)
-       METHOD(XonoticKeyBinder, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticKeyBinder, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticKeyBinder, doubleClickListBoxItem, void(entity, float, vector))
        METHOD(XonoticKeyBinder, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticKeyBinder, setSelected, void(entity, float))
@@ -302,7 +302,7 @@ float XonoticKeyBinder_keyDown(entity me, int key, bool ascii, float shift)
        }
        return r;
 }
-void XonoticKeyBinder_drawListBoxItem(entity me, int i, vector absSize, bool isSelected)
+void XonoticKeyBinder_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
        int j, n;
@@ -331,6 +331,12 @@ void XonoticKeyBinder_drawListBoxItem(entity me, int i, vector absSize, bool isS
                        else
                                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
                }
+               else if(isFocused)
+               {
+                       me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+                       draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+               }
+
                theAlpha = SKINALPHA_KEYGRABBER_KEYS;
                theColor = SKINCOLOR_KEYGRABBER_KEYS;
                extraMargin = me.realFontSize.x * 0.5;
index 367da94dfb5df0ad26d6f001866c77896da4415b..af9d75211b3987809ec4bedb3eff1e85d3813990 100644 (file)
@@ -4,7 +4,7 @@
 CLASS(XonoticLanguageList, XonoticListBox)
        METHOD(XonoticLanguageList, configureXonoticLanguageList, void(entity))
        ATTRIB(XonoticLanguageList, rowsPerItem, float, 1)
-       METHOD(XonoticLanguageList, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticLanguageList, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticLanguageList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticLanguageList, setSelected, void(entity, float))
        METHOD(XonoticLanguageList, loadCvars, void(entity))
@@ -57,11 +57,16 @@ void XonoticLanguageList_configureXonoticLanguageList(entity me)
        me.loadCvars(me);
 }
 
-void XonoticLanguageList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticLanguageList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s, p;
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        s = me.languageParameter(me, i, LANGPARM_NAME_LOCALIZED);
 
index ec9aa1f4c7bc104216e3329d0d4c710e88c4e95b..f2749abb5ce17847a399e06d7f87a0fa872637b3 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticMapList, 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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticMapList, clickListBoxItem, void(entity, float, vector))
        METHOD(XonoticMapList, doubleClickListBoxItem, void(entity, float, vector))
        METHOD(XonoticMapList, resizeNotify, void(entity, vector, vector, vector, vector))
@@ -161,7 +161,7 @@ void XonoticMapList_doubleClickListBoxItem(entity me, float i, vector where)
                }
 }
 
-void XonoticMapList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticMapList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        // layout: Ping, Map name, Map name, NP, TP, MP
        string s;
@@ -179,8 +179,16 @@ void XonoticMapList_drawListBoxItem(entity me, float i, vector absSize, float is
 
        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);
+       else
+       {
+               if(included)
+                       draw_Fill('0 0 0', '1 1 0', SKINCOLOR_MAPLIST_INCLUDEDBG, SKINALPHA_MAPLIST_INCLUDEDBG);
+               if(isFocused)
+               {
+                       me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+                       draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+               }
+       }
 
        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);
diff --git a/qcsrc/menu/xonotic/picker.qc b/qcsrc/menu/xonotic/picker.qc
new file mode 100644 (file)
index 0000000..dd57467
--- /dev/null
@@ -0,0 +1,207 @@
+#ifndef PICKER_H
+#define PICKER_H
+#include "../item.qc"
+CLASS(XonoticPicker, Item)
+       METHOD(XonoticPicker, configureXonoticPicker, void(entity))
+       METHOD(XonoticPicker, mousePress, float(entity, vector))
+       METHOD(XonoticPicker, mouseRelease, float(entity, vector))
+       METHOD(XonoticPicker, mouseMove, float(entity, vector))
+       METHOD(XonoticPicker, mouseDrag, float(entity, vector))
+       METHOD(XonoticPicker, keyDown, float(entity, float, float, float))
+       METHOD(XonoticPicker, draw, void(entity))
+       ATTRIB(XonoticPicker, focusable, float, 1)
+       ATTRIB(XonoticPicker, disabled, float, 0)
+       ATTRIB(XonoticPicker, alpha, float, 1)
+       ATTRIB(XonoticPicker, disabledAlpha, float, SKINALPHA_DISABLED)
+
+       ATTRIB(XonoticPicker, rows, float, 3)
+       ATTRIB(XonoticPicker, columns, float, 2)
+
+       METHOD(XonoticPicker, moveFocus, void(entity, vector, vector))
+       METHOD(XonoticPicker, cellSelect, void(entity, vector))
+       METHOD(XonoticPicker, cellDraw, void(entity, vector, vector))
+       METHOD(XonoticPicker, cellIsValid, bool(entity, vector))
+       ATTRIB(XonoticPicker, realCellSize, vector, '0 0 0')
+       ATTRIB(XonoticPicker, selectedCell, vector, '-1 -1 0')
+       ATTRIB(XonoticPicker, focusedCell, vector, '-1 -1 0')
+       ATTRIB(XonoticPicker, focusedCellAlpha, float, 0)
+       ATTRIB(XonoticPicker, focusedCellTime, float, 0)
+       ATTRIB(XonoticPicker, pressedCell, vector, '-1 -1 0')
+ENDCLASS(XonoticPicker)
+entity makeXonoticPicker();
+#endif
+
+#ifdef IMPLEMENTATION
+
+entity makeXonoticPicker()
+{
+       entity me;
+       me = NEW(XonoticPicker);
+       me.configureXonoticPicker(me);
+       return me;
+}
+
+void XonoticPicker_configureXonoticPicker(entity me)
+{
+       me.realCellSize = eX / me.columns + eY / me.rows;
+}
+
+float XonoticPicker_mouseMove(entity me, vector coords)
+{
+       vector prevFocusedCell = me.focusedCell;
+       me.focusedCell_x = floor(coords.x * me.columns);
+       me.focusedCell_y = floor(coords.y * me.rows);
+
+       if(me.focusedCell.x < 0 || me.focusedCell.y < 0 ||
+          me.focusedCell.x >= me.columns || me.focusedCell.y >= me.rows)
+       {
+               me.focusedCell = '-1 -1 0';
+               return 0;
+       }
+
+       if(me.focusedCell != prevFocusedCell)
+               me.focusedCellAlpha = SKINALPHA_LISTBOX_FOCUSED;
+
+       return 1;
+}
+
+float XonoticPicker_mouseDrag(entity me, vector coords)
+{
+       return me.mouseMove(me, coords);
+}
+
+float XonoticPicker_mousePress(entity me, vector coords)
+{
+       me.mouseMove(me, coords);
+
+       if(me.focusedCell.x >= 0)
+       {
+               me.pressed = 1;
+               me.pressedCell = me.focusedCell;
+       }
+
+       return 1;
+}
+
+float XonoticPicker_mouseRelease(entity me, vector coords)
+{
+       if(!me.pressed)
+               return 0;
+
+       me.mouseMove(me, coords);
+
+       if(me.focusedCell == me.pressedCell)
+               me.cellSelect(me, me.focusedCell);
+
+       me.pressed = 0;
+       return 1;
+}
+
+float XonoticPicker_keyDown(entity me, float key, float ascii, float shift)
+{
+       switch(key)
+       {
+               case K_END:
+               case K_KP_END:
+                       // lower left cell then left arrow to select the last valid cell
+                       me.focusedCell = eY * (me.rows - 1);
+               case K_LEFTARROW:
+               case K_KP_LEFTARROW:
+                       me.moveFocus(me, me.focusedCell, '-1 0 0');
+                       return 1;
+               case K_HOME:
+               case K_KP_HOME:
+                       // upper right cell then right arrow to select the first valid cell
+                       me.focusedCell = eX * (me.columns - 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_ENTER:
+               case K_KP_ENTER:
+               case K_INS:
+               case K_KP_INS:
+                       me.cellSelect(me, me.focusedCell);
+                       return 1;
+       }
+       return 0;
+}
+
+void XonoticPicker_moveFocus(entity me, vector initialCell, vector step)
+{
+       me.focusedCell_x = mod(me.focusedCell.x + step.x + me.columns, me.columns);
+       me.focusedCell_y = mod(me.focusedCell.y + step.y + me.rows, me.rows);
+
+       if(me.focusedCell != initialCell) // Recursion break
+               if(!me.cellIsValid(me, me.focusedCell))
+                       me.moveFocus(me, initialCell, step);
+
+       me.focusedCellAlpha = SKINALPHA_LISTBOX_FOCUSED;
+}
+
+void XonoticPicker_cellSelect(entity me, vector cell)
+{
+       me.selectedCell = cell;
+}
+
+bool XonoticPicker_cellIsValid(entity me, vector cell)
+{
+       return true;
+}
+
+void XonoticPicker_cellDraw(entity me, vector cell, vector cellPos)
+{
+}
+
+void XonoticPicker_draw(entity me)
+{
+       float save;
+
+       me.focusable = !me.disabled;
+
+       save = draw_alpha;
+       if(me.disabled)
+               draw_alpha *= me.disabledAlpha;
+
+       vector cell, cellPos;
+       cell = '0 0 0';
+       cellPos = '0 0 0';
+
+       for(cell_y = 0; cell.y < me.rows; ++cell.y)
+       {
+               cellPos_y = mod(cell.y, me.rows) / me.rows;
+               for(cell_x = 0; cell.x < me.columns; ++cell.x)
+               {
+                       if(!me.cellIsValid(me, cell))
+                               continue;
+
+                       cellPos_x = mod(cell.x, me.columns) / me.columns;
+
+                       if(cell == me.selectedCell)
+                               draw_Fill(cellPos, me.realCellSize, SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+                       else if(cell == me.focusedCell && me.focused)
+                       {
+                               if(!me.pressed || me.focusedCell == me.pressedCell)
+                               {
+                                       me.focusedCellAlpha = getFadedAlpha(me.focusedCellAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+                                       draw_Fill(cellPos, me.realCellSize, SKINCOLOR_LISTBOX_FOCUSED, me.focusedCellAlpha);
+                               }
+                       }
+
+                       me.cellDraw(me, cell, cellPos);
+               }
+       }
+
+       draw_alpha = save;
+
+       SUPER(XonoticPicker).draw(me);
+}
+#endif
index 437206b881352bbd59cff5caade6eade963125a8..db3ac8a207aae1b99524a3cc11c1aa40adfed1f1 100644 (file)
@@ -4,7 +4,7 @@
 CLASS(XonoticPlayerList, XonoticListBox)
        ATTRIB(XonoticPlayerList, rowsPerItem, float, 1)
        METHOD(XonoticPlayerList, resizeNotify, void(entity, vector, vector, vector, vector))
-       METHOD(XonoticPlayerList, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticPlayerList, drawListBoxItem, void(entity, int, vector, bool, bool))
        ATTRIB(XonoticPlayerList, allowFocusSound, float, 0)
        ATTRIB(XonoticPlayerList, realFontSize, vector, '0 0 0')
        ATTRIB(XonoticPlayerList, columnNameOrigin, float, 0)
@@ -94,7 +94,7 @@ void XonoticPlayerList_resizeNotify(entity me, vector relOrigin, vector relSize,
        me.columnScoreOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize.x;
 }
 
-void XonoticPlayerList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticPlayerList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
        string score;
index e912f8f081a4c2e3b45e7b0a6ff653c02c1a6ae4..5dd7b6b926d0862185524f522bd12a7513939562 100644 (file)
@@ -6,7 +6,7 @@ CLASS(XonoticPlayList, XonoticListBox)
        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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticPlayList, stopSound, void(entity))
        METHOD(XonoticPlayList, startSound, void(entity, float))
        METHOD(XonoticPlayList, resumeSound, void(entity))
@@ -172,11 +172,16 @@ void XonoticPlayList_draw(entity me)
        SUPER(XonoticPlayList).draw(me);
 }
 
-void XonoticPlayList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticPlayList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        if(i == me.playingTrack)
        {
index 650b3381fd5defa893145a8841184b570bc0eeee..d6fcaf86e3d0d97b0494e823ac311df0fb2183af 100644 (file)
@@ -7,7 +7,7 @@ CLASS(XonoticScreenshotList, XonoticListBox)
        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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticScreenshotList, getScreenshots, void(entity))
        METHOD(XonoticScreenshotList, previewScreenshot, void(entity))
        METHOD(XonoticScreenshotList, startScreenshot, void(entity))
@@ -167,11 +167,16 @@ void XonoticScreenshotList_setSelected(entity me, float i)
        }
 }
 
-void XonoticScreenshotList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticScreenshotList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        s = me.screenshotName(me,i);
        s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
index 3f9648be66566f57ca681862ae82e1f9d4aa4ea5..8bf70cc33307d06fe1ae5130649d602a8ef164fc 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticServerList, 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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticServerList, doubleClickListBoxItem, void(entity, float, vector))
        METHOD(XonoticServerList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticServerList, keyDown, float(entity, float, float, float))
@@ -963,7 +963,7 @@ void XonoticServerList_doubleClickListBoxItem(entity me, int i, vector where)
 {
        ServerList_Connect_Click(NULL, me);
 }
-void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected)
+void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        // layout: Ping, Server name, Map name, NP, TP, MP
        float p;
@@ -1019,6 +1019,11 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
 
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        s = gethostcachestring(SLIST_FIELD_QCSTATUS, i);
        m = tokenizebyseparator(s, ":");
index 936ca7baf1125253a3698b784b2fc433721a30d0..46babc3f9517f5c9ae63c390e68e9d4bfdaa0960 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticSkinList, 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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticSkinList, getSkins, void(entity))
        METHOD(XonoticSkinList, setSkin, void(entity))
        METHOD(XonoticSkinList, loadCvars, void(entity))
@@ -151,12 +151,17 @@ void XonoticSkinList_resizeNotify(entity me, vector relOrigin, vector relSize, v
        me.columnNameSize = 1 - me.columnPreviewSize - 2 * me.realFontSize.x;
 }
 
-void XonoticSkinList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticSkinList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
 
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        s = me.skinParameter(me, i, SKINPARM_PREVIEW);
        draw_Picture(me.columnPreviewOrigin * eX, s, me.columnPreviewSize * eX + eY, '1 1 1', 1);
index bba66d19d16a651f50ceb5be5ac5a4fd441e67c3..2b98c5fe52296a8f287c4294a3766019487262ea 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticSoundList, 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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticSoundList, getSounds, void(entity))
        METHOD(XonoticSoundList, soundName, string(entity, float))
        METHOD(XonoticSoundList, doubleClickListBoxItem, void(entity, float, vector))
@@ -103,11 +103,16 @@ void XonoticSoundList_resizeNotify(entity me, vector relOrigin, vector relSize,
        me.columnNameSize = 1 - me.columnNameOrigin - me.realFontSize.x;
 }
 
-void XonoticSoundList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticSoundList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        s = me.soundName(me,i);
        if(s == cvar_string("menu_cdtrack")) // current menu track
index 1cf4a688e0b82e5ba4487bc1dc85301dfdaa9e1d..d9a22ec6e78f1a8e71aeadf9d3824f44069664c1 100644 (file)
@@ -8,7 +8,7 @@ CLASS(XonoticStatsList, 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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticStatsList, getStats, void(entity))
        METHOD(XonoticStatsList, doubleClickListBoxItem, void(entity, float, vector))
        METHOD(XonoticStatsList, keyDown, float(entity, float, float, float))
@@ -315,10 +315,15 @@ void XonoticStatsList_resizeNotify(entity me, vector relOrigin, vector relSize,
 #endif
 }
 
-void XonoticStatsList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticStatsList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        string data = bufstr_get(me.listStats, i);
        string s = car(data);
index 444292712d1a968861d673f960441bd8d7d48347..216b57585e48a4a77acf560158c59c3db09a49c7 100644 (file)
@@ -797,6 +797,15 @@ void dialog_hudpanel_common_notoggle(entity me, string panelname)
                                e.configureXonoticTextSliderValues(e);
 }
 
+float getFadedAlpha(float currentAlpha, float startAlpha, float targetAlpha)
+{
+       if(startAlpha < targetAlpha)
+               currentAlpha = min(currentAlpha + frametime * 0.5, targetAlpha);
+       else
+               currentAlpha = max(currentAlpha - frametime * 0.5, targetAlpha);
+       return currentAlpha;
+}
+
 void CheckSendCvars(entity me, string cvarnamestring)
 {
        if(me.sendCvars)
index 80803f8544df735f4363112b466441da3ad34f35..2564a86ed4b724f69640797542b083109d1fd4c5 100644 (file)
@@ -48,6 +48,8 @@ void dialog_hudpanel_common_notoggle(entity me, string panelname);
                me.TD(me, 1, 4, e = makeXonoticCheckBox(0, strzone(strcat("hud_panel_", panelname)), _("Enable panel"))); \
        DIALOG_HUDPANEL_COMMON_NOTOGGLE()
 
+float getFadedAlpha(float currentAlpha, float startAlpha, float targetAlpha);
+
 string _Nex_ExtResponseSystem_BannedServers;
 float _Nex_ExtResponseSystem_BannedServersNeedsRefresh;
 string _Nex_ExtResponseSystem_PromotedServers;
index 622505af838703e637330daa709687d61d073352..adc7fc2115bb4634dbae79b6fab9236d286fa05b 100644 (file)
@@ -6,7 +6,7 @@ CLASS(XonoticWeaponsList, XonoticListBox)
        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, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticWeaponsList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticWeaponsList, keyDown, float(entity, float, float, float))
        ATTRIB(XonoticWeaponsList, realFontSize, vector, '0 0 0')
@@ -92,11 +92,16 @@ string XonoticWeaponsList_toString(entity me)
        }
        return substring(s, 0, strlen(s) - 2);
 }
-void XonoticWeaponsList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticWeaponsList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        entity e;
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
        e = get_weaponinfo(stof(argv(i)));
        string msg = e.message;
        if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)