Added support for selecting GUI skin through user interface; aded skins by Dakal as a proof it works
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5442 178a84e3-b1eb-0310-8ba1-8eac791a3b58
@ -18,8 +18,14 @@
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
|
||||
|
||||
<spacer height="20" width="10"/>
|
||||
|
||||
<label width="100%" I18N="In the graphics settings" text="Skin"/>
|
||||
<!-- FIXME: don't hardcode size -->
|
||||
<spinner id="skinchoice" width="300" height="50" />
|
||||
|
||||
<spacer height="40" width="10"/>
|
||||
<label width="100%" I18N="In the graphics settings" text="Resolution"/>
|
||||
|
||||
<scrollable_ribbon id="resolutions" proportion="2" label_location="each"
|
||||
width="100%" square_items="false"
|
||||
|
193
data/gui/skins/Ocean.stkskin
Normal file
@ -0,0 +1,193 @@
|
||||
<!--
|
||||
|
||||
Ocean skin by Dakal and Marianne Gagnon, released under creative-commons BY-SA 3.0+
|
||||
Except background.jpg, by elisee
|
||||
|
||||
To make your own skin, I suggest simply duplicating this file and modifying it as needed.
|
||||
There are two types of images : some will be simply stretched as a whole, others will
|
||||
have non-stretchable borders (you cannot choose which one you must use, it's hardcoded
|
||||
for each element type; though, as you will see below, for all "advanced stretching" images
|
||||
you can easily fake "simple stretch")
|
||||
|
||||
All elements will have at least 2 properties :
|
||||
type="X" sets what you're skinning with this entry
|
||||
image="skinDirectory/imageName.png" sets which image is used for this element
|
||||
|
||||
Most elements also support states :
|
||||
state="neutral"
|
||||
state="focused"
|
||||
state="down"
|
||||
You can thus give different looks for different states. Not all widgets support all states,
|
||||
see entries and comments below to know what's supported.
|
||||
Note that checkboxes are an exception and have the following styles :
|
||||
"neutral+unchecked"
|
||||
"neutral+checked"
|
||||
"focused+unchecked"
|
||||
"focused+checked"
|
||||
|
||||
"Advanced stretching" images are split this way :
|
||||
|
||||
+----+--------------------+----+
|
||||
| | | |
|
||||
+----+--------------------+----+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+----+--------------------+----+
|
||||
| | | |
|
||||
+----+--------------------+----+
|
||||
|
||||
The center border will be stretched in all directions. The 4 corners will not stretch at all.
|
||||
Horizontal borders will stretch horizontally, verticallt borders will stretch vertically.
|
||||
Use properties left_border="X" right_border="X" top_border="X" bottom_border="X" to specify
|
||||
the size of each border in pixels (setting all borders to '0' makes the whole image scaled).
|
||||
|
||||
In some cases, you may not want vertical stretching to occur (like if the left and right sides
|
||||
of the image must not be stretched vertically, e.g. for the spinner). In this case, pass
|
||||
parameter preserve_h_aspect_ratios="true" to make the left and right areas stretch by keeping
|
||||
their aspect ratio.
|
||||
|
||||
Some components may fill the full inner area with stuff; others will only take a smaller
|
||||
area at the center. To adjust for this, there are properties "hborder_out_portion" and "vborder_out_portion"
|
||||
that take a float from 0 to 1, representing the percentage of each border that goes out of the widget's
|
||||
area (this might include stuff like shadows, etc.). The 'h' one is for horizontal borders,
|
||||
the 'v' one is for vertical borders.
|
||||
|
||||
Finnally : the image is split, as shown above, into 9 areas. In osme cases, you may not want
|
||||
all areas to be rendered. Then you can pass parameter areas="body+left+right+top+bottom"
|
||||
and explicitely specify which parts you want to see. The 4 corner areas are only visible
|
||||
when the border that intersect at this corner are enabled.
|
||||
|
||||
-->
|
||||
|
||||
<skin name="Ocean" author="Dakal & Marianne Gagnon (Auria)">
|
||||
|
||||
<!-- Stateless -->
|
||||
<element type="background" image="ocean/background.jpg" />
|
||||
|
||||
<element type="button" state="focused" image="ocean/glassbutton_focused.png"
|
||||
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" />
|
||||
|
||||
<element type="button" state="neutral" image="ocean/glassbutton.png"
|
||||
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" />
|
||||
|
||||
<!-- TODO : buttons could support 'pressed' state -->
|
||||
|
||||
|
||||
<element type="tab" state="neutral" image="ocean/glasstab.png"
|
||||
left_border="75" right_border="75" top_border="0" bottom_border="15"
|
||||
hborder_out_portion="0.2" />
|
||||
|
||||
<element type="tab" state="focused" image="ocean/glasstab_focus.png"
|
||||
left_border="75" right_border="75" top_border="0" bottom_border="15"
|
||||
hborder_out_portion="0.2" />
|
||||
|
||||
<element type="tab" state="down" image="ocean/glasstab_down.png"
|
||||
left_border="75" right_border="75" top_border="0" bottom_border="15"
|
||||
hborder_out_portion="0.2" />
|
||||
|
||||
|
||||
<!-- Stateless -->
|
||||
<element type="squareFocusHalo" image="ocean/glass_square_focused.png"
|
||||
left_border="6" right_border ="6" top_border="6" bottom_border="6"
|
||||
hborder_out_portion="1.0" />
|
||||
<element type="squareFocusHalo2" image="ocean/glass_square_focused2.png"
|
||||
left_border="6" right_border ="6" top_border="6" bottom_border="6"
|
||||
hborder_out_portion="1.0" />
|
||||
<element type="squareFocusHalo3" image="ocean/glass_square_focused3.png"
|
||||
left_border="6" right_border ="6" top_border="6" bottom_border="6"
|
||||
hborder_out_portion="1.0" />
|
||||
<element type="squareFocusHalo4" image="ocean/glass_square_focused4.png"
|
||||
left_border="6" right_border ="6" top_border="6" bottom_border="6"
|
||||
hborder_out_portion="1.0" />
|
||||
|
||||
<!-- Stateless. No splitting into 9 areas is done; the image is just resized. -->
|
||||
<element type="selectionHalo" image="ocean/bubble.png" />
|
||||
<element type="focusHalo" image="ocean/glass_iconhighlight_focus.png" />
|
||||
|
||||
<element type="spinner" state="neutral" image="ocean/glassspinner.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner" state="focused" image="ocean/glassspinner_focus.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner2" state="neutral" image="ocean/glassspinner2.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner2" state="focused" image="ocean/glassspinner2_focus.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<!-- This one is a bit special. Only area(s) LEFT and/or RIGHT will be rendered. They will be overlaid
|
||||
on top of the spinner's background -->
|
||||
<element type="spinner" state="down" image="ocean/glassspinner_down.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner2" state="down" image="ocean/glassspinner2_down.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<!-- For checkboxes, no splitting into 9 areas is done; the image is just stretched -->
|
||||
<element type="checkbox" state="neutral+unchecked" image="ocean/glasscheckbox.png"/>
|
||||
<element type="checkbox" state="neutral+checked" image="ocean/glasscheckbox_checked.png"/>
|
||||
<element type="checkbox" state="focused+unchecked" image="ocean/glasscheckbox_focus.png"/>
|
||||
<element type="checkbox" state="focused+checked" image="ocean/glasscheckbox_checked_focus.png"/>
|
||||
|
||||
<!-- are always in neutral state for now. No splitting into 9 areas is done; the image is just stretched.
|
||||
Note: the body of a guage is the same as for for spinners. -->
|
||||
<element type="gaugefill" image="ocean/glasssgauge_fill.png" />
|
||||
|
||||
<!-- Lists are always in neutral state for now -->
|
||||
<element type="list" image="ocean/glass_section.png"
|
||||
left_border="15" right_border="15" top_border="15" bottom_border="15"
|
||||
hborder_out_portion="0.5" vborder_out_portion="1.0" />
|
||||
|
||||
<element type="listitem" state="focused" image="ocean/select.png"
|
||||
left_border="0" right_border="0" top_border="0" bottom_border="0"
|
||||
hborder_out_portion="0.0" vborder_out_portion="0.0" />
|
||||
|
||||
<element type="listitem" state="down" image="ocean/glassbutton.png"
|
||||
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||
hborder_out_portion="1.0" vborder_out_portion="1.0"
|
||||
areas="body" />
|
||||
|
||||
<!-- Scrollbars. Background and thumb have no state (always neutral state).
|
||||
The buttons are the top and bottom arrows. Image must be top arrow, will
|
||||
be mirrorred for bottom. Buttons can be in neutral or down state.
|
||||
Advanced stretching is not used here.
|
||||
-->
|
||||
<element type="scrollbar_background" image="ocean/scrollbar_bg.png" />
|
||||
<element type="scrollbar_thumb" image="ocean/scrollbar_thumb.png" />
|
||||
<element type="scrollbar_button" image="ocean/scrollbar_btn.png" />
|
||||
<element type="scrollbar_button" state="down" image="ocean/scrollbar_btn_down.png" />
|
||||
|
||||
<!-- Stateless -->
|
||||
<element type="section" image="ocean/glass_section.png"
|
||||
left_border="15" right_border="15" top_border="15" bottom_border="15"
|
||||
hborder_out_portion="1.0" vborder_out_portion="0.2" />
|
||||
|
||||
<!-- Stateless -->
|
||||
<element type="window" image="ocean/dialog.png"
|
||||
left_border="7" right_border="7" top_border="50" bottom_border="50"
|
||||
hborder_out_portion="1.0" vborder_out_portion="0.2" />
|
||||
|
||||
<!-- Colors -->
|
||||
<color type="text" state="neutral" r="0" g="0" b="0" />
|
||||
|
||||
<!-- For highlighted items, e.g. in list -->
|
||||
<color type="text" state="focused" r="255" g="255" b="255" />
|
||||
|
||||
<!-- Color used to fade out background when a dialog is shown -->
|
||||
<color type="dialog_background" state="neutral" a="120" r="0" g="0" b="0" />
|
||||
|
||||
<!-- Text field color -->
|
||||
<color type="text_field" state="neutral" a="255" r="215" g="215" b="215" />
|
||||
<color type="text_field" state="focused" a="255" r="138" g="138" b="138" />
|
||||
|
||||
</skin>
|
193
data/gui/skins/Peach.stkskin
Normal file
@ -0,0 +1,193 @@
|
||||
<!--
|
||||
|
||||
Peach skin by Dakal and Marianne Gagnon, released under creative-commons BY-SA 3.0+
|
||||
Except background.jpg, by elisee
|
||||
|
||||
To make your own skin, I suggest simply duplicating this file and modifying it as needed.
|
||||
There are two types of images : some will be simply stretched as a whole, others will
|
||||
have non-stretchable borders (you cannot choose which one you must use, it's hardcoded
|
||||
for each element type; though, as you will see below, for all "advanced stretching" images
|
||||
you can easily fake "simple stretch")
|
||||
|
||||
All elements will have at least 2 properties :
|
||||
type="X" sets what you're skinning with this entry
|
||||
image="skinDirectory/imageName.png" sets which image is used for this element
|
||||
|
||||
Most elements also support states :
|
||||
state="neutral"
|
||||
state="focused"
|
||||
state="down"
|
||||
You can thus give different looks for different states. Not all widgets support all states,
|
||||
see entries and comments below to know what's supported.
|
||||
Note that checkboxes are an exception and have the following styles :
|
||||
"neutral+unchecked"
|
||||
"neutral+checked"
|
||||
"focused+unchecked"
|
||||
"focused+checked"
|
||||
|
||||
"Advanced stretching" images are split this way :
|
||||
|
||||
+----+--------------------+----+
|
||||
| | | |
|
||||
+----+--------------------+----+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+----+--------------------+----+
|
||||
| | | |
|
||||
+----+--------------------+----+
|
||||
|
||||
The center border will be stretched in all directions. The 4 corners will not stretch at all.
|
||||
Horizontal borders will stretch horizontally, verticallt borders will stretch vertically.
|
||||
Use properties left_border="X" right_border="X" top_border="X" bottom_border="X" to specify
|
||||
the size of each border in pixels (setting all borders to '0' makes the whole image scaled).
|
||||
|
||||
In some cases, you may not want vertical stretching to occur (like if the left and right sides
|
||||
of the image must not be stretched vertically, e.g. for the spinner). In this case, pass
|
||||
parameter preserve_h_aspect_ratios="true" to make the left and right areas stretch by keeping
|
||||
their aspect ratio.
|
||||
|
||||
Some components may fill the full inner area with stuff; others will only take a smaller
|
||||
area at the center. To adjust for this, there are properties "hborder_out_portion" and "vborder_out_portion"
|
||||
that take a float from 0 to 1, representing the percentage of each border that goes out of the widget's
|
||||
area (this might include stuff like shadows, etc.). The 'h' one is for horizontal borders,
|
||||
the 'v' one is for vertical borders.
|
||||
|
||||
Finnally : the image is split, as shown above, into 9 areas. In osme cases, you may not want
|
||||
all areas to be rendered. Then you can pass parameter areas="body+left+right+top+bottom"
|
||||
and explicitely specify which parts you want to see. The 4 corner areas are only visible
|
||||
when the border that intersect at this corner are enabled.
|
||||
|
||||
-->
|
||||
|
||||
<skin name="Peach" author="Dakal & Marianne Gagnon (Auria)">
|
||||
|
||||
<!-- Stateless -->
|
||||
<element type="background" image="peach/background.jpg" />
|
||||
|
||||
<element type="button" state="focused" image="peach/glassbutton_focused.png"
|
||||
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" />
|
||||
|
||||
<element type="button" state="neutral" image="peach/glassbutton.png"
|
||||
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" />
|
||||
|
||||
<!-- TODO : buttons could support 'pressed' state -->
|
||||
|
||||
|
||||
<element type="tab" state="neutral" image="peach/glasstab.png"
|
||||
left_border="75" right_border="75" top_border="0" bottom_border="15"
|
||||
hborder_out_portion="0.2" />
|
||||
|
||||
<element type="tab" state="focused" image="peach/glasstab_focus.png"
|
||||
left_border="75" right_border="75" top_border="0" bottom_border="15"
|
||||
hborder_out_portion="0.2" />
|
||||
|
||||
<element type="tab" state="down" image="peach/glasstab_down.png"
|
||||
left_border="75" right_border="75" top_border="0" bottom_border="15"
|
||||
hborder_out_portion="0.2" />
|
||||
|
||||
|
||||
<!-- Stateless -->
|
||||
<element type="squareFocusHalo" image="peach/glass_square_focused.png"
|
||||
left_border="6" right_border ="6" top_border="6" bottom_border="6"
|
||||
hborder_out_portion="1.0" />
|
||||
<element type="squareFocusHalo2" image="peach/glass_square_focused2.png"
|
||||
left_border="6" right_border ="6" top_border="6" bottom_border="6"
|
||||
hborder_out_portion="1.0" />
|
||||
<element type="squareFocusHalo3" image="peach/glass_square_focused3.png"
|
||||
left_border="6" right_border ="6" top_border="6" bottom_border="6"
|
||||
hborder_out_portion="1.0" />
|
||||
<element type="squareFocusHalo4" image="peach/glass_square_focused4.png"
|
||||
left_border="6" right_border ="6" top_border="6" bottom_border="6"
|
||||
hborder_out_portion="1.0" />
|
||||
|
||||
<!-- Stateless. No splitting into 9 areas is done; the image is just resized. -->
|
||||
<element type="selectionHalo" image="peach/bubble.png" />
|
||||
<element type="focusHalo" image="peach/glass_iconhighlight_focus.png" />
|
||||
|
||||
<element type="spinner" state="neutral" image="peach/glassspinner.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner" state="focused" image="peach/glassspinner_focus.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner2" state="neutral" image="peach/glassspinner2.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner2" state="focused" image="peach/glassspinner2_focus.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<!-- This one is a bit special. Only area(s) LEFT and/or RIGHT will be rendered. They will be overlaid
|
||||
on top of the spinner's background -->
|
||||
<element type="spinner" state="down" image="peach/glassspinner_down.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner2" state="down" image="peach/glassspinner2_down.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<!-- For checkboxes, no splitting into 9 areas is done; the image is just stretched -->
|
||||
<element type="checkbox" state="neutral+unchecked" image="peach/glasscheckbox.png"/>
|
||||
<element type="checkbox" state="neutral+checked" image="peach/glasscheckbox_checked.png"/>
|
||||
<element type="checkbox" state="focused+unchecked" image="peach/glasscheckbox_focus.png"/>
|
||||
<element type="checkbox" state="focused+checked" image="peach/glasscheckbox_checked_focus.png"/>
|
||||
|
||||
<!-- are always in neutral state for now. No splitting into 9 areas is done; the image is just stretched.
|
||||
Note: the body of a guage is the same as for for spinners. -->
|
||||
<element type="gaugefill" image="peach/glasssgauge_fill.png" />
|
||||
|
||||
<!-- Lists are always in neutral state for now -->
|
||||
<element type="list" image="peach/glass_section.png"
|
||||
left_border="15" right_border="15" top_border="15" bottom_border="15"
|
||||
hborder_out_portion="0.5" vborder_out_portion="1.0" />
|
||||
|
||||
<element type="listitem" state="focused" image="peach/select.png"
|
||||
left_border="0" right_border="0" top_border="0" bottom_border="0"
|
||||
hborder_out_portion="0.0" vborder_out_portion="0.0" />
|
||||
|
||||
<element type="listitem" state="down" image="peach/glassbutton.png"
|
||||
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||
hborder_out_portion="1.0" vborder_out_portion="1.0"
|
||||
areas="body" />
|
||||
|
||||
<!-- Scrollbars. Background and thumb have no state (always neutral state).
|
||||
The buttons are the top and bottom arrows. Image must be top arrow, will
|
||||
be mirrorred for bottom. Buttons can be in neutral or down state.
|
||||
Advanced stretching is not used here.
|
||||
-->
|
||||
<element type="scrollbar_background" image="peach/scrollbar_bg.png" />
|
||||
<element type="scrollbar_thumb" image="peach/scrollbar_thumb.png" />
|
||||
<element type="scrollbar_button" image="peach/scrollbar_btn.png" />
|
||||
<element type="scrollbar_button" state="down" image="peach/scrollbar_btn_down.png" />
|
||||
|
||||
<!-- Stateless -->
|
||||
<element type="section" image="peach/glass_section.png"
|
||||
left_border="15" right_border="15" top_border="15" bottom_border="15"
|
||||
hborder_out_portion="1.0" vborder_out_portion="0.2" />
|
||||
|
||||
<!-- Stateless -->
|
||||
<element type="window" image="peach/dialog.png"
|
||||
left_border="7" right_border="7" top_border="50" bottom_border="50"
|
||||
hborder_out_portion="1.0" vborder_out_portion="0.2" />
|
||||
|
||||
<!-- Colors -->
|
||||
<color type="text" state="neutral" r="0" g="0" b="0" />
|
||||
|
||||
<!-- For highlighted items, e.g. in list -->
|
||||
<color type="text" state="focused" r="255" g="255" b="255" />
|
||||
|
||||
<!-- Color used to fade out background when a dialog is shown -->
|
||||
<color type="dialog_background" state="neutral" a="120" r="0" g="0" b="0" />
|
||||
|
||||
<!-- Text field color -->
|
||||
<color type="text_field" state="neutral" a="255" r="215" g="215" b="215" />
|
||||
<color type="text_field" state="focused" a="255" r="138" g="138" b="138" />
|
||||
|
||||
</skin>
|
2
data/gui/skins/ocean/LICENSE
Normal file
@ -0,0 +1,2 @@
|
||||
This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
|
BIN
data/gui/skins/ocean/background.jpg
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
data/gui/skins/ocean/bubble.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
data/gui/skins/ocean/dialog.png
Normal file
After Width: | Height: | Size: 257 KiB |
BIN
data/gui/skins/ocean/glass_iconhighlight_focus.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
data/gui/skins/ocean/glass_section.png
Normal file
After Width: | Height: | Size: 257 KiB |
BIN
data/gui/skins/ocean/glass_square_focused.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
data/gui/skins/ocean/glass_square_focused2.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
data/gui/skins/ocean/glass_square_focused3.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
data/gui/skins/ocean/glass_square_focused4.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
data/gui/skins/ocean/glassbutton.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
data/gui/skins/ocean/glassbutton_focused.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
data/gui/skins/ocean/glasscheckbox.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
data/gui/skins/ocean/glasscheckbox_checked.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
data/gui/skins/ocean/glasscheckbox_checked_focus.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
data/gui/skins/ocean/glasscheckbox_focus.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
data/gui/skins/ocean/glasssgauge_fill.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
data/gui/skins/ocean/glassspinner.png
Normal file
After Width: | Height: | Size: 128 KiB |
BIN
data/gui/skins/ocean/glassspinner_down.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
data/gui/skins/ocean/glassspinner_focus.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
data/gui/skins/ocean/glassspinner_halo.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
data/gui/skins/ocean/glasstab.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
data/gui/skins/ocean/glasstab_down.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
data/gui/skins/ocean/glasstab_focus.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
data/gui/skins/ocean/scrollbar_bg.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
data/gui/skins/ocean/scrollbar_btn.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
data/gui/skins/ocean/scrollbar_btn_down.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
data/gui/skins/ocean/scrollbar_thumb.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
data/gui/skins/ocean/select.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
2
data/gui/skins/peach/LICENSE
Normal file
@ -0,0 +1,2 @@
|
||||
This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
|
BIN
data/gui/skins/peach/background.jpg
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
data/gui/skins/peach/bubble.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
data/gui/skins/peach/dialog.png
Normal file
After Width: | Height: | Size: 257 KiB |
BIN
data/gui/skins/peach/glass_iconhighlight_focus.png
Normal file
After Width: | Height: | Size: 257 KiB |
BIN
data/gui/skins/peach/glass_section.png
Normal file
After Width: | Height: | Size: 257 KiB |
BIN
data/gui/skins/peach/glass_square_focused.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
data/gui/skins/peach/glass_square_focused2.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
data/gui/skins/peach/glass_square_focused3.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
data/gui/skins/peach/glass_square_focused4.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
data/gui/skins/peach/glassbutton.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
data/gui/skins/peach/glassbutton_focused.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
data/gui/skins/peach/glasscheckbox.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
data/gui/skins/peach/glasscheckbox_checked.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
data/gui/skins/peach/glasscheckbox_checked_focus.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
data/gui/skins/peach/glasscheckbox_focus.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
data/gui/skins/peach/glasssgauge_fill.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
data/gui/skins/peach/glassspinner.png
Normal file
After Width: | Height: | Size: 128 KiB |
BIN
data/gui/skins/peach/glassspinner_down.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
data/gui/skins/peach/glassspinner_focus.png
Normal file
After Width: | Height: | Size: 128 KiB |
BIN
data/gui/skins/peach/glassspinner_halo.png
Normal file
After Width: | Height: | Size: 128 KiB |
BIN
data/gui/skins/peach/glasstab.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
data/gui/skins/peach/glasstab_down.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
data/gui/skins/peach/glasstab_focus.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
data/gui/skins/peach/scrollbar_bg.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
data/gui/skins/peach/scrollbar_btn.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
data/gui/skins/peach/scrollbar_btn_down.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
data/gui/skins/peach/scrollbar_thumb.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
data/gui/skins/peach/select.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
@ -116,15 +116,22 @@ void GroupUserConfigParam::addChild(UserConfigParam* child)
|
||||
|
||||
IntUserConfigParam::IntUserConfigParam(int defaultValue, const char* paramName, const char* comment)
|
||||
{
|
||||
this->value = defaultValue;
|
||||
m_value = defaultValue;
|
||||
m_default_value = defaultValue;
|
||||
|
||||
this->paramName = paramName;
|
||||
all_params.push_back(this);
|
||||
if(comment != NULL) this->comment = comment;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
IntUserConfigParam::IntUserConfigParam(int defaultValue, const char* paramName,
|
||||
GroupUserConfigParam* group, const char* comment)
|
||||
{
|
||||
this->value = defaultValue;
|
||||
m_value = defaultValue;
|
||||
m_default_value = defaultValue;
|
||||
|
||||
this->paramName = paramName;
|
||||
group->addChild(this);
|
||||
if(comment != NULL) this->comment = comment;
|
||||
@ -133,13 +140,13 @@ IntUserConfigParam::IntUserConfigParam(int defaultValue, const char* paramName,
|
||||
void IntUserConfigParam::write(std::ofstream& stream) const
|
||||
{
|
||||
if(comment.size() > 0) stream << " <!-- " << comment.c_str() << " -->\n";
|
||||
stream << " <" << paramName << " value=\"" << value << "\" />\n\n";
|
||||
stream << " <" << paramName << " value=\"" << m_value << "\" />\n\n";
|
||||
}
|
||||
|
||||
std::string IntUserConfigParam::toString() const
|
||||
{
|
||||
char buffer[16];
|
||||
sprintf(buffer, "%i", value);
|
||||
sprintf(buffer, "%i", m_value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -152,19 +159,22 @@ void IntUserConfigParam::findYourDataInAChildOf(const XMLNode* node)
|
||||
return;
|
||||
}
|
||||
|
||||
child->get( "value", &value );
|
||||
child->get( "value", &m_value );
|
||||
//std::cout << "read int " << paramName << ", value=" << value << std::endl;
|
||||
}
|
||||
void IntUserConfigParam::findYourDataInAnAttributeOf(const XMLNode* node)
|
||||
{
|
||||
node->get( paramName, &value );
|
||||
node->get( paramName, &m_value );
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
StringUserConfigParam::StringUserConfigParam(const char* defaultValue, const char* paramName, const char* comment)
|
||||
{
|
||||
this->value = defaultValue;
|
||||
|
||||
m_value = defaultValue;
|
||||
m_default_value = defaultValue;
|
||||
|
||||
this->paramName = paramName;
|
||||
all_params.push_back(this);
|
||||
if(comment != NULL) this->comment = comment;
|
||||
@ -172,7 +182,9 @@ StringUserConfigParam::StringUserConfigParam(const char* defaultValue, const cha
|
||||
StringUserConfigParam::StringUserConfigParam(const char* defaultValue, const char* paramName,
|
||||
GroupUserConfigParam* group, const char* comment)
|
||||
{
|
||||
this->value = defaultValue;
|
||||
m_value = defaultValue;
|
||||
m_default_value = defaultValue;
|
||||
|
||||
this->paramName = paramName;
|
||||
group->addChild(this);
|
||||
if(comment != NULL) this->comment = comment;
|
||||
@ -182,30 +194,32 @@ StringUserConfigParam::StringUserConfigParam(const char* defaultValue, const cha
|
||||
void StringUserConfigParam::write(std::ofstream& stream) const
|
||||
{
|
||||
if(comment.size() > 0) stream << " <!-- " << comment.c_str() << " -->\n";
|
||||
stream << " <" << paramName << " value=\"" << value << "\" />\n\n";
|
||||
stream << " <" << paramName << " value=\"" << m_value << "\" />\n\n";
|
||||
}
|
||||
void StringUserConfigParam::findYourDataInAChildOf(const XMLNode* node)
|
||||
{
|
||||
const XMLNode* child = node->getNode( paramName );
|
||||
if(child == NULL) return;
|
||||
|
||||
child->get( "value", &value );
|
||||
child->get( "value", &m_value );
|
||||
}
|
||||
void StringUserConfigParam::findYourDataInAnAttributeOf(const XMLNode* node)
|
||||
{
|
||||
node->get( paramName, &value );
|
||||
node->get( paramName, &m_value );
|
||||
}
|
||||
|
||||
std::string StringUserConfigParam::toString() const
|
||||
{
|
||||
return value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
BoolUserConfigParam::BoolUserConfigParam(bool defaultValue, const char* paramName, const char* comment)
|
||||
{
|
||||
this->value = defaultValue;
|
||||
m_value = defaultValue;
|
||||
m_default_value = defaultValue;
|
||||
|
||||
this->paramName = paramName;
|
||||
all_params.push_back(this);
|
||||
if(comment != NULL) this->comment = comment;
|
||||
@ -213,7 +227,9 @@ BoolUserConfigParam::BoolUserConfigParam(bool defaultValue, const char* paramNam
|
||||
BoolUserConfigParam::BoolUserConfigParam(bool defaultValue, const char* paramName,
|
||||
GroupUserConfigParam* group, const char* comment)
|
||||
{
|
||||
this->value = defaultValue;
|
||||
m_value = defaultValue;
|
||||
m_default_value = defaultValue;
|
||||
|
||||
this->paramName = paramName;
|
||||
group->addChild(this);
|
||||
if(comment != NULL) this->comment = comment;
|
||||
@ -223,7 +239,7 @@ BoolUserConfigParam::BoolUserConfigParam(bool defaultValue, const char* paramNam
|
||||
void BoolUserConfigParam::write(std::ofstream& stream) const
|
||||
{
|
||||
if(comment.size() > 0) stream << " <!-- " << comment.c_str() << " -->\n";
|
||||
stream << " <" << paramName << " value=\"" << (value ? "true" : "false" ) << "\" />\n\n";
|
||||
stream << " <" << paramName << " value=\"" << (m_value ? "true" : "false" ) << "\" />\n\n";
|
||||
}
|
||||
void BoolUserConfigParam::findYourDataInAChildOf(const XMLNode* node)
|
||||
{
|
||||
@ -235,35 +251,40 @@ void BoolUserConfigParam::findYourDataInAChildOf(const XMLNode* node)
|
||||
|
||||
if(textValue == "true")
|
||||
{
|
||||
value = true;
|
||||
m_value = true;
|
||||
}
|
||||
else if(textValue == "false")
|
||||
{
|
||||
value = false;
|
||||
m_value = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unknown value for " << paramName << "; expected true or false\n";
|
||||
}
|
||||
}
|
||||
|
||||
void BoolUserConfigParam::findYourDataInAnAttributeOf(const XMLNode* node)
|
||||
{
|
||||
std::string textValue = "";
|
||||
node->get( paramName, &textValue );
|
||||
|
||||
if(textValue == "true")
|
||||
if (textValue == "true")
|
||||
{
|
||||
value = true;
|
||||
m_value = true;
|
||||
}
|
||||
else if(textValue == "false")
|
||||
else if (textValue == "false")
|
||||
{
|
||||
value = false;
|
||||
m_value = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unknown value for " << paramName << "; expected true or false\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::string BoolUserConfigParam::toString() const
|
||||
{
|
||||
return (value ? "true" : "false" );
|
||||
return (m_value ? "true" : "false" );
|
||||
}
|
||||
|
||||
|
||||
@ -271,15 +292,20 @@ std::string BoolUserConfigParam::toString() const
|
||||
|
||||
FloatUserConfigParam::FloatUserConfigParam(float defaultValue, const char* paramName, const char* comment)
|
||||
{
|
||||
this->value = defaultValue;
|
||||
m_value = defaultValue;
|
||||
m_default_value = defaultValue;
|
||||
|
||||
this->paramName = paramName;
|
||||
all_params.push_back(this);
|
||||
if(comment != NULL) this->comment = comment;
|
||||
}
|
||||
|
||||
FloatUserConfigParam::FloatUserConfigParam(float defaultValue, const char* paramName,
|
||||
GroupUserConfigParam* group, const char* comment)
|
||||
{
|
||||
this->value = defaultValue;
|
||||
m_value = defaultValue;
|
||||
m_default_value = defaultValue;
|
||||
|
||||
this->paramName = paramName;
|
||||
group->addChild(this);
|
||||
if(comment != NULL) this->comment = comment;
|
||||
@ -288,24 +314,26 @@ FloatUserConfigParam::FloatUserConfigParam(float defaultValue, const char* param
|
||||
void FloatUserConfigParam::write(std::ofstream& stream) const
|
||||
{
|
||||
if(comment.size() > 0) stream << " <!-- " << comment.c_str() << " -->\n";
|
||||
stream << " <" << paramName << " value=\"" << value << "\" />\n\n";
|
||||
stream << " <" << paramName << " value=\"" << m_value << "\" />\n\n";
|
||||
}
|
||||
|
||||
void FloatUserConfigParam::findYourDataInAChildOf(const XMLNode* node)
|
||||
{
|
||||
const XMLNode* child = node->getNode( paramName );
|
||||
if(child == NULL) return;
|
||||
|
||||
child->get( "value", &value );
|
||||
child->get( "value", &m_value );
|
||||
}
|
||||
|
||||
void FloatUserConfigParam::findYourDataInAnAttributeOf(const XMLNode* node)
|
||||
{
|
||||
node->get( paramName, &value );
|
||||
node->get( paramName, &m_value );
|
||||
}
|
||||
|
||||
std::string FloatUserConfigParam::toString() const
|
||||
{
|
||||
char buffer[16];
|
||||
sprintf(buffer, "%f", value);
|
||||
sprintf(buffer, "%f", m_value);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -83,8 +83,11 @@ public:
|
||||
|
||||
class IntUserConfigParam : public UserConfigParam
|
||||
{
|
||||
int value;
|
||||
int m_value;
|
||||
int m_default_value;
|
||||
|
||||
public:
|
||||
|
||||
IntUserConfigParam(int defaultValue, const char* paramName, const char* comment = NULL);
|
||||
IntUserConfigParam(int defaultValue, const char* paramName, GroupUserConfigParam* group, const char* comment = NULL);
|
||||
|
||||
@ -93,17 +96,21 @@ public:
|
||||
void findYourDataInAnAttributeOf(const XMLNode* node);
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
operator int() const { return value; }
|
||||
int& operator++(int dummy) { value++; return value; }
|
||||
int& operator=(const int& v) { value = v; return value; }
|
||||
int& operator=(const IntUserConfigParam& v) { value = (int)v; return value; }
|
||||
void revertToDefaults() { m_value = m_default_value; }
|
||||
|
||||
operator int() const { return m_value; }
|
||||
int& operator++(int dummy) { m_value++; return m_value; }
|
||||
int& operator=(const int& v) { m_value = v; return m_value; }
|
||||
int& operator=(const IntUserConfigParam& v) { m_value = (int)v; return m_value; }
|
||||
};
|
||||
|
||||
class StringUserConfigParam : public UserConfigParam
|
||||
{
|
||||
std::string value;
|
||||
std::string m_value;
|
||||
std::string m_default_value;
|
||||
|
||||
public:
|
||||
|
||||
StringUserConfigParam(const char* defaultValue, const char* paramName, const char* comment = NULL);
|
||||
StringUserConfigParam(const char* defaultValue, const char* paramName, GroupUserConfigParam* group, const char* comment = NULL);
|
||||
|
||||
@ -112,18 +119,22 @@ public:
|
||||
void findYourDataInAChildOf(const XMLNode* node);
|
||||
void findYourDataInAnAttributeOf(const XMLNode* node);
|
||||
|
||||
void revertToDefaults() { m_value = m_default_value; }
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
operator std::string() const { return value; }
|
||||
std::string& operator=(const std::string& v) { value = v; return value; }
|
||||
std::string& operator=(const StringUserConfigParam& v) { value = (std::string)v; return value; }
|
||||
operator std::string() const { return m_value; }
|
||||
std::string& operator=(const std::string& v) { m_value = v; return m_value; }
|
||||
std::string& operator=(const StringUserConfigParam& v) { m_value = (std::string)v; return m_value; }
|
||||
|
||||
const char* c_str() const { return value.c_str(); }
|
||||
const char* c_str() const { return m_value.c_str(); }
|
||||
};
|
||||
|
||||
class BoolUserConfigParam : public UserConfigParam
|
||||
{
|
||||
bool value;
|
||||
bool m_value;
|
||||
bool m_default_value;
|
||||
|
||||
public:
|
||||
BoolUserConfigParam(bool defaultValue, const char* paramName, const char* comment = NULL);
|
||||
BoolUserConfigParam(bool defaultValue, const char* paramName, GroupUserConfigParam* group, const char* comment = NULL);
|
||||
@ -134,15 +145,18 @@ public:
|
||||
void findYourDataInAnAttributeOf(const XMLNode* node);
|
||||
|
||||
std::string toString() const;
|
||||
void revertToDefaults() { m_value = m_default_value; }
|
||||
|
||||
operator bool() const { return value; }
|
||||
bool& operator=(const bool& v) { value = v; return value; }
|
||||
bool& operator=(const BoolUserConfigParam& v) { value = (bool)v; return value; }
|
||||
operator bool() const { return m_value; }
|
||||
bool& operator=(const bool& v) { m_value = v; return m_value; }
|
||||
bool& operator=(const BoolUserConfigParam& v) { m_value = (bool)v; return m_value; }
|
||||
};
|
||||
|
||||
class FloatUserConfigParam : public UserConfigParam
|
||||
{
|
||||
float value;
|
||||
float m_value;
|
||||
float m_default_value;
|
||||
|
||||
public:
|
||||
FloatUserConfigParam(float defaultValue, const char* paramName, const char* comment = NULL);
|
||||
FloatUserConfigParam(float defaultValue, const char* paramName, GroupUserConfigParam* group, const char* comment = NULL);
|
||||
@ -152,10 +166,11 @@ public:
|
||||
void findYourDataInAnAttributeOf(const XMLNode* node);
|
||||
|
||||
std::string toString() const;
|
||||
void revertToDefaults() { m_value = m_default_value; }
|
||||
|
||||
operator float() const { return value; }
|
||||
float& operator=(const float& v) { value = v; return value; }
|
||||
float& operator=(const FloatUserConfigParam& v) { value = (float)v; return value; }
|
||||
operator float() const { return m_value; }
|
||||
float& operator=(const float& v) { m_value = v; return m_value; }
|
||||
float& operator=(const FloatUserConfigParam& v) { m_value = (float)v; return m_value; }
|
||||
};
|
||||
|
||||
|
||||
@ -295,7 +310,7 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT( StringUserConfigParam("jungle", "last_track", "Name of the last track used.") );
|
||||
|
||||
PARAM_PREFIX StringUserConfigParam m_skin_file
|
||||
PARAM_DEFAULT( StringUserConfigParam("glass.stkskin", "skin_file", "Name of the skin to use") );
|
||||
PARAM_DEFAULT( StringUserConfigParam("Glass.stkskin", "skin_file", "Name of the skin to use") );
|
||||
|
||||
PARAM_PREFIX bool m_no_start_screen PARAM_DEFAULT( false ); // not saved to file
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
\li \ref widget9
|
||||
\li \ref widget10
|
||||
\li \ref widget11
|
||||
|
||||
|
||||
\ref props
|
||||
\li \ref prop1
|
||||
\li \ref prop2
|
||||
@ -72,7 +72,7 @@
|
||||
\li \ref prop16
|
||||
\li \ref prop17
|
||||
\li \ref prop18
|
||||
|
||||
|
||||
\ref code
|
||||
|
||||
\n
|
||||
@ -97,12 +97,12 @@
|
||||
Orientation of tabs (up or down) is automatically inferred from on-screen position
|
||||
|
||||
\note Ribbon widgets are of spawn type (\<ribbon\> ... \</ribbon\>) and may contain icon-buttons or buttons
|
||||
as children.
|
||||
as children.
|
||||
\note Property PROP_SQUARE can be set to tell the engine if the ribbon's contents are rectangular or not
|
||||
(this will affect the type of highlighting used)
|
||||
(this will affect the type of highlighting used)
|
||||
\note All elements within a ribbon must have an 'ID' property
|
||||
\note Ribbons (e.g. tabs) can have their elements dynamically added at runtime, too. Just add
|
||||
no children to the ribbon in the XML file, and add them at runtime through the method for this.
|
||||
no children to the ribbon in the XML file, and add them at runtime through the method for this.
|
||||
|
||||
\n
|
||||
\subsection widget2 WTYPE_SPINNER
|
||||
@ -412,7 +412,7 @@ using namespace irr::video;
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
|
||||
|
||||
namespace Private
|
||||
{
|
||||
IGUIEnvironment* g_env;
|
||||
@ -431,12 +431,12 @@ namespace GUIEngine
|
||||
int small_font_height;
|
||||
}
|
||||
using namespace Private;
|
||||
|
||||
|
||||
ptr_vector<Widget, REF> needsUpdate;
|
||||
|
||||
//FIXME: the contents of this vector are never ever freed
|
||||
ptr_vector<Screen, REF> g_loaded_screens;
|
||||
|
||||
|
||||
float dt = 0;
|
||||
|
||||
float getLatestDt()
|
||||
@ -466,7 +466,7 @@ namespace GUIEngine
|
||||
|
||||
// add message
|
||||
gui_messages.push_back( MenuMessage(message, time) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
Widget* getFocusForPlayer(const int playerID)
|
||||
@ -495,7 +495,7 @@ namespace GUIEngine
|
||||
// otherwise check if the focus is the given widget
|
||||
return g_focus_for_player[playerID]->isSameIrrlichtWidgetAs(w);
|
||||
}
|
||||
|
||||
|
||||
int getFontHeight()
|
||||
{
|
||||
return Private::font_height;
|
||||
@ -506,311 +506,357 @@ namespace GUIEngine
|
||||
return Private::small_font_height;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void clear()
|
||||
{
|
||||
g_env->clear();
|
||||
if (g_current_screen != NULL) g_current_screen->elementsWereDeleted();
|
||||
g_current_screen = NULL;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void cleanForGame()
|
||||
{
|
||||
clear();
|
||||
|
||||
//FIXME: I'm not very sure why this isn't called in the regular clear() method??
|
||||
needsUpdate.clearWithoutDeleting();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void switchToScreen(const char* screen_name)
|
||||
{
|
||||
needsUpdate.clearWithoutDeleting();
|
||||
|
||||
// clean what was left by the previous screen
|
||||
g_env->clear();
|
||||
if (g_current_screen != NULL) g_current_screen->elementsWereDeleted();
|
||||
g_current_screen = NULL;
|
||||
Widget::resetIDCounters();
|
||||
|
||||
// check if we already loaded this screen
|
||||
const int screen_amount = g_loaded_screens.size();
|
||||
for(int n=0; n<screen_amount; n++)
|
||||
// -----------------------------------------------------------------------------
|
||||
void clear()
|
||||
{
|
||||
if (g_loaded_screens[n].getName() == screen_name)
|
||||
{
|
||||
g_current_screen = g_loaded_screens.get(n);
|
||||
break;
|
||||
}
|
||||
g_env->clear();
|
||||
if (g_current_screen != NULL) g_current_screen->elementsWereDeleted();
|
||||
g_current_screen = NULL;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// screen not found in list of existing ones
|
||||
if (g_current_screen == NULL)
|
||||
void cleanForGame()
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// show screen
|
||||
g_current_screen->addWidgets();
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void addScreenToList(Screen* cutscene)
|
||||
{
|
||||
g_loaded_screens.push_back(cutscene);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void reshowCurrentScreen()
|
||||
{
|
||||
needsUpdate.clearWithoutDeleting();
|
||||
g_state_manager->reshowTopMostMenu();
|
||||
//g_current_screen->addWidgets();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void cleanUp()
|
||||
{
|
||||
if (g_skin != NULL) delete g_skin;
|
||||
g_skin = NULL;
|
||||
|
||||
for (int i=0; i<g_loaded_screens.size(); i++)
|
||||
{
|
||||
g_loaded_screens[i].unload();
|
||||
}
|
||||
|
||||
g_current_screen = NULL;
|
||||
needsUpdate.clearWithoutDeleting();
|
||||
|
||||
if (ModalDialog::isADialogActive()) ModalDialog::dismiss();
|
||||
|
||||
delete g_font;
|
||||
g_font = NULL;
|
||||
delete g_title_font;
|
||||
g_title_font = NULL;
|
||||
delete g_small_font;
|
||||
g_small_font = NULL;
|
||||
clear();
|
||||
|
||||
// nothing else to delete for now AFAIK, irrlicht will automatically kill everything along the device
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void init(IrrlichtDevice* device_a, IVideoDriver* driver_a, AbstractStateManager* state_manager )
|
||||
{
|
||||
g_env = device_a->getGUIEnvironment();
|
||||
g_device = device_a;
|
||||
g_driver = driver_a;
|
||||
g_state_manager = state_manager;
|
||||
|
||||
for (int n=0; n<MAX_PLAYER_COUNT; n++)
|
||||
{
|
||||
g_focus_for_player[n] = NULL;
|
||||
//FIXME: I'm not very sure why this isn't called in the regular clear() method??
|
||||
needsUpdate.clearWithoutDeleting();
|
||||
}
|
||||
|
||||
/*
|
||||
To make the g_font a little bit nicer, we load an external g_font
|
||||
and set it as the new default g_font in the g_skin.
|
||||
To keep the standard g_font for tool tip text, we set it to
|
||||
the built-in g_font.
|
||||
*/
|
||||
g_skin = new Skin(g_env->getSkin());
|
||||
g_env->setSkin(g_skin);
|
||||
//g_skin = g_env->getSkin();
|
||||
// -----------------------------------------------------------------------------
|
||||
void switchToScreen(const char* screen_name)
|
||||
{
|
||||
needsUpdate.clearWithoutDeleting();
|
||||
|
||||
// clean what was left by the previous screen
|
||||
g_env->clear();
|
||||
if (g_current_screen != NULL) g_current_screen->elementsWereDeleted();
|
||||
g_current_screen = NULL;
|
||||
Widget::resetIDCounters();
|
||||
|
||||
// check if we already loaded this screen
|
||||
const int screen_amount = g_loaded_screens.size();
|
||||
for(int n=0; n<screen_amount; n++)
|
||||
{
|
||||
if (g_loaded_screens[n].getName() == screen_name)
|
||||
{
|
||||
g_current_screen = g_loaded_screens.get(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// screen not found in list of existing ones
|
||||
if (g_current_screen == NULL)
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// show screen
|
||||
g_current_screen->addWidgets();
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// font size is resolution-dependent.
|
||||
// normal text will range from 0.8, in 640x* resolutions (won't scale below that) to
|
||||
// 1.0, in 1024x* resolutions, and linearly up
|
||||
// normal text will range from 0.2, in 640x* resolutions (won't scale below that) to
|
||||
// 0.4, in 1024x* resolutions, and linearly up
|
||||
const int screen_width = irr_driver->getFrameSize().Width;
|
||||
const float normal_text_scale = 0.7f + 0.2f*std::max(0, screen_width - 640)/564.0f;
|
||||
const float title_text_scale = 0.2f + 0.2f*std::max(0, screen_width - 640)/564.0f;
|
||||
|
||||
//ScalableFont* sfont = new ScalableFont(g_env, (file_manager->getGUIDir() + "/okolaks.xml").c_str());
|
||||
ScalableFont* sfont = new ScalableFont(g_env, file_manager->getFontFile("StkFont.xml").c_str() );
|
||||
sfont->setScale(normal_text_scale);
|
||||
sfont->setKerningHeight(-5);
|
||||
g_font = sfont;
|
||||
void addScreenToList(Screen* cutscene)
|
||||
{
|
||||
g_loaded_screens.push_back(cutscene);
|
||||
}
|
||||
|
||||
Private::font_height = g_font->getDimension( L"X" ).Height;
|
||||
|
||||
//ScalableFont* sfont_smaller = new ScalableFont(g_env, file_manager->getFontFile("StkFont.xml").c_str() );
|
||||
ScalableFont* sfont_smaller = sfont->getHollowCopy();
|
||||
sfont_smaller->setScale(normal_text_scale*0.8f);
|
||||
sfont_smaller->setKerningHeight(-5);
|
||||
g_small_font = sfont_smaller;
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Private::small_font_height = g_small_font->getDimension( L"X" ).Height;
|
||||
|
||||
ScalableFont* sfont2 = new ScalableFont(g_env, file_manager->getFontFile("title_font.xml").c_str() );
|
||||
sfont2->m_fallback_font = sfont;
|
||||
sfont2->m_fallback_font_scale = 4.0f; // because the fallback font is much smaller than the title font
|
||||
sfont2->m_fallback_kerning_width = 15;
|
||||
sfont2->setScale(title_text_scale);
|
||||
sfont2->setKerningWidth(-18);
|
||||
sfont2->m_black_border = true;
|
||||
g_title_font = sfont2;
|
||||
void reshowCurrentScreen()
|
||||
{
|
||||
needsUpdate.clearWithoutDeleting();
|
||||
g_state_manager->reshowTopMostMenu();
|
||||
//g_current_screen->addWidgets();
|
||||
}
|
||||
|
||||
|
||||
if (g_font != NULL) g_skin->setFont(g_font);
|
||||
// -----------------------------------------------------------------------------
|
||||
void cleanUp()
|
||||
{
|
||||
if (g_skin != NULL) delete g_skin;
|
||||
g_skin = NULL;
|
||||
|
||||
for (int i=0; i<g_loaded_screens.size(); i++)
|
||||
{
|
||||
g_loaded_screens[i].unload();
|
||||
}
|
||||
|
||||
g_current_screen = NULL;
|
||||
needsUpdate.clearWithoutDeleting();
|
||||
|
||||
if (ModalDialog::isADialogActive()) ModalDialog::dismiss();
|
||||
|
||||
delete g_font;
|
||||
g_font = NULL;
|
||||
delete g_title_font;
|
||||
g_title_font = NULL;
|
||||
delete g_small_font;
|
||||
g_small_font = NULL;
|
||||
|
||||
// nothing else to delete for now AFAIK, irrlicht will automatically kill everything along the device
|
||||
}
|
||||
|
||||
//g_skin->setFont(g_env->getBuiltInFont(), EGDF_TOOLTIP);
|
||||
// -----------------------------------------------------------------------------
|
||||
void init(IrrlichtDevice* device_a, IVideoDriver* driver_a, AbstractStateManager* state_manager )
|
||||
{
|
||||
g_env = device_a->getGUIEnvironment();
|
||||
g_device = device_a;
|
||||
g_driver = driver_a;
|
||||
g_state_manager = state_manager;
|
||||
|
||||
for (int n=0; n<MAX_PLAYER_COUNT; n++)
|
||||
{
|
||||
g_focus_for_player[n] = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
To make the g_font a little bit nicer, we load an external g_font
|
||||
and set it as the new default g_font in the g_skin.
|
||||
To keep the standard g_font for tool tip text, we set it to
|
||||
the built-in g_font.
|
||||
*/
|
||||
try
|
||||
{
|
||||
g_skin = new Skin(g_env->getSkin());
|
||||
g_env->setSkin(g_skin);
|
||||
}
|
||||
catch (std::runtime_error& err)
|
||||
{
|
||||
std::cerr << "ERROR, cannot load skin specified in user config. Falling back to defaults.\n";
|
||||
UserConfigParams::m_skin_file.revertToDefaults();
|
||||
|
||||
try
|
||||
{
|
||||
g_skin = new Skin(g_env->getSkin());
|
||||
g_env->setSkin(g_skin);
|
||||
}
|
||||
catch (std::runtime_error& err)
|
||||
{
|
||||
std::cerr << "FATAL, cannot load default GUI skin\n";
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
//g_skin = g_env->getSkin();
|
||||
|
||||
// font size is resolution-dependent.
|
||||
// normal text will range from 0.8, in 640x* resolutions (won't scale below that) to
|
||||
// 1.0, in 1024x* resolutions, and linearly up
|
||||
// normal text will range from 0.2, in 640x* resolutions (won't scale below that) to
|
||||
// 0.4, in 1024x* resolutions, and linearly up
|
||||
const int screen_width = irr_driver->getFrameSize().Width;
|
||||
const float normal_text_scale = 0.7f + 0.2f*std::max(0, screen_width - 640)/564.0f;
|
||||
const float title_text_scale = 0.2f + 0.2f*std::max(0, screen_width - 640)/564.0f;
|
||||
|
||||
//ScalableFont* sfont = new ScalableFont(g_env, (file_manager->getGUIDir() + "/okolaks.xml").c_str());
|
||||
ScalableFont* sfont = new ScalableFont(g_env, file_manager->getFontFile("StkFont.xml").c_str() );
|
||||
sfont->setScale(normal_text_scale);
|
||||
sfont->setKerningHeight(-5);
|
||||
g_font = sfont;
|
||||
|
||||
Private::font_height = g_font->getDimension( L"X" ).Height;
|
||||
|
||||
//ScalableFont* sfont_smaller = new ScalableFont(g_env, file_manager->getFontFile("StkFont.xml").c_str() );
|
||||
ScalableFont* sfont_smaller = sfont->getHollowCopy();
|
||||
sfont_smaller->setScale(normal_text_scale*0.8f);
|
||||
sfont_smaller->setKerningHeight(-5);
|
||||
g_small_font = sfont_smaller;
|
||||
|
||||
Private::small_font_height = g_small_font->getDimension( L"X" ).Height;
|
||||
|
||||
ScalableFont* sfont2 = new ScalableFont(g_env, file_manager->getFontFile("title_font.xml").c_str() );
|
||||
sfont2->m_fallback_font = sfont;
|
||||
sfont2->m_fallback_font_scale = 4.0f; // because the fallback font is much smaller than the title font
|
||||
sfont2->m_fallback_kerning_width = 15;
|
||||
sfont2->setScale(title_text_scale);
|
||||
sfont2->setKerningWidth(-18);
|
||||
sfont2->m_black_border = true;
|
||||
g_title_font = sfont2;
|
||||
|
||||
|
||||
if (g_font != NULL) g_skin->setFont(g_font);
|
||||
|
||||
//g_skin->setFont(g_env->getBuiltInFont(), EGDF_TOOLTIP);
|
||||
|
||||
// set event receiver
|
||||
g_device->setEventReceiver(EventHandler::get());
|
||||
}
|
||||
|
||||
// set event receiver
|
||||
g_device->setEventReceiver(EventHandler::get());
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void render(float elapsed_time)
|
||||
{
|
||||
GUIEngine::dt = elapsed_time;
|
||||
void reloadSkin()
|
||||
{
|
||||
assert(g_skin != NULL);
|
||||
|
||||
irr::gui::IGUISkin* fallbackSkin = g_skin->getFallbackSkin();
|
||||
|
||||
Skin* newSkin;
|
||||
try
|
||||
{
|
||||
// it's important to create the new skin before deleting the old one
|
||||
//so that the fallback skin is not dropped
|
||||
newSkin = new Skin(fallbackSkin);
|
||||
}
|
||||
catch (std::runtime_error& err)
|
||||
{
|
||||
std::cerr << "ERROR, cannot load newly specified skin!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
delete g_skin;
|
||||
|
||||
g_skin = newSkin;
|
||||
g_env->setSkin(g_skin);
|
||||
}
|
||||
|
||||
// ---- menu drawing
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// draw background image and sections
|
||||
void render(float elapsed_time)
|
||||
{
|
||||
GUIEngine::dt = elapsed_time;
|
||||
|
||||
// ---- menu drawing
|
||||
|
||||
// draw background image and sections
|
||||
|
||||
const GameState gamestate = g_state_manager->getGameState();
|
||||
|
||||
if (gamestate == MENU && !GUIEngine::getCurrentScreen()->needs3D())
|
||||
{
|
||||
g_skin->drawBgImage();
|
||||
}
|
||||
else if (gamestate == INGAME_MENU)
|
||||
{
|
||||
g_skin->drawBGFadeColor();
|
||||
}
|
||||
|
||||
g_driver->enableMaterial2D();
|
||||
|
||||
if (gamestate == MENU || gamestate == INGAME_MENU)
|
||||
{
|
||||
g_skin->renderSections();
|
||||
}
|
||||
|
||||
// let irrLicht do the rest (the Skin object will be called for further render)
|
||||
g_env->drawAll();
|
||||
|
||||
// ---- some menus may need updating
|
||||
if (gamestate != GAME)
|
||||
{
|
||||
if (ModalDialog::isADialogActive()) ModalDialog::getCurrent()->onUpdate(dt);
|
||||
else getCurrentScreen()->onUpdate(elapsed_time, g_driver);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ModalDialog::isADialogActive()) ModalDialog::getCurrent()->onUpdate(dt);
|
||||
else World::getWorld()->getRaceGUI()->renderGlobal(elapsed_time);
|
||||
}
|
||||
|
||||
if (gamestate != GAME && !gui_messages.empty())
|
||||
{
|
||||
core::dimension2d<u32> screen_size = irr_driver->getFrameSize();
|
||||
const int text_height = getFontHeight() + 20;
|
||||
const int y_from = screen_size.Height - text_height;
|
||||
|
||||
int count = 0;
|
||||
|
||||
std::vector<MenuMessage>::iterator it;
|
||||
for (it=gui_messages.begin(); it != gui_messages.end();)
|
||||
{
|
||||
if ((*it).m_time > 0.0f)
|
||||
{
|
||||
(*it).m_time -= dt;
|
||||
|
||||
core::rect<s32> msgRect(core::position2d<s32>(0, y_from - count*text_height),
|
||||
core::dimension2d<s32>(screen_size.Width, text_height) );
|
||||
|
||||
Private::g_driver->draw2DRectangle( SColor(255,252,248,230), msgRect);
|
||||
Private::g_font->draw((*it).m_message.c_str(),
|
||||
msgRect,
|
||||
video::SColor(255, 255, 0, 0),
|
||||
true /* hcenter */, true /* vcenter */);
|
||||
count++;
|
||||
it++;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = gui_messages.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_driver->enableMaterial2D(false);
|
||||
|
||||
} // render
|
||||
|
||||
const GameState gamestate = g_state_manager->getGameState();
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
if (gamestate == MENU && !GUIEngine::getCurrentScreen()->needs3D())
|
||||
void renderLoading()
|
||||
{
|
||||
g_skin->drawBgImage();
|
||||
}
|
||||
else if (gamestate == INGAME_MENU)
|
||||
{
|
||||
g_skin->drawBGFadeColor();
|
||||
}
|
||||
|
||||
g_driver->enableMaterial2D();
|
||||
|
||||
if (gamestate == MENU || gamestate == INGAME_MENU)
|
||||
{
|
||||
g_skin->renderSections();
|
||||
}
|
||||
|
||||
// let irrLicht do the rest (the Skin object will be called for further render)
|
||||
g_env->drawAll();
|
||||
|
||||
// ---- some menus may need updating
|
||||
if (gamestate != GAME)
|
||||
{
|
||||
if (ModalDialog::isADialogActive()) ModalDialog::getCurrent()->onUpdate(dt);
|
||||
else getCurrentScreen()->onUpdate(elapsed_time, g_driver);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ModalDialog::isADialogActive()) ModalDialog::getCurrent()->onUpdate(dt);
|
||||
else World::getWorld()->getRaceGUI()->renderGlobal(elapsed_time);
|
||||
}
|
||||
|
||||
if (gamestate != GAME && !gui_messages.empty())
|
||||
{
|
||||
core::dimension2d<u32> screen_size = irr_driver->getFrameSize();
|
||||
const int text_height = getFontHeight() + 20;
|
||||
const int y_from = screen_size.Height - text_height;
|
||||
ITexture* loading = irr_driver->getTexture( file_manager->getGUIDir() + "/loading.png" );
|
||||
|
||||
int count = 0;
|
||||
const int texture_w = loading->getSize().Width;
|
||||
const int texture_h = loading->getSize().Height;
|
||||
|
||||
std::vector<MenuMessage>::iterator it;
|
||||
for (it=gui_messages.begin(); it != gui_messages.end();)
|
||||
core::dimension2d<u32> frame_size = GUIEngine::getDriver()->getCurrentRenderTargetSize();
|
||||
const int screen_w = frame_size.Width;
|
||||
const int screen_h = frame_size.Height;
|
||||
|
||||
const core::rect< s32 > dest_area = core::rect< s32 >(screen_w/2 - texture_w/2,
|
||||
screen_h/2 - texture_h/2,
|
||||
screen_w/2 + texture_w/2,
|
||||
screen_h/2 + texture_h/2);
|
||||
|
||||
const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h);
|
||||
|
||||
GUIEngine::getDriver()->draw2DImage( loading, dest_area, source_area,
|
||||
0 /* no clipping */, 0, true /* alpha */);
|
||||
|
||||
|
||||
g_title_font->draw(_("Loading"),
|
||||
core::rect< s32 >( 0, screen_h/2 + texture_h/2, screen_w, screen_h ),
|
||||
SColor(255,255,255,255),
|
||||
true/* center h */, false /* center v */ );
|
||||
|
||||
} // renderLoading
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Widget* getWidget(const char* name)
|
||||
{
|
||||
// if a modal dialog is shown, search within it too
|
||||
if (ModalDialog::isADialogActive())
|
||||
{
|
||||
if ((*it).m_time > 0.0f)
|
||||
{
|
||||
(*it).m_time -= dt;
|
||||
|
||||
core::rect<s32> msgRect(core::position2d<s32>(0, y_from - count*text_height),
|
||||
core::dimension2d<s32>(screen_size.Width, text_height) );
|
||||
|
||||
Private::g_driver->draw2DRectangle( SColor(255,252,248,230), msgRect);
|
||||
Private::g_font->draw((*it).m_message.c_str(),
|
||||
msgRect,
|
||||
video::SColor(255, 255, 0, 0),
|
||||
true /* hcenter */, true /* vcenter */);
|
||||
count++;
|
||||
it++;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = gui_messages.erase(it);
|
||||
}
|
||||
Widget* widgetWithinDialog = Screen::getWidget(name, &(ModalDialog::getCurrent()->m_children));
|
||||
if (widgetWithinDialog != NULL) return widgetWithinDialog;
|
||||
}
|
||||
}
|
||||
|
||||
g_driver->enableMaterial2D(false);
|
||||
|
||||
} // render
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void renderLoading()
|
||||
{
|
||||
g_skin->drawBgImage();
|
||||
ITexture* loading = irr_driver->getTexture( file_manager->getGUIDir() + "/loading.png" );
|
||||
|
||||
const int texture_w = loading->getSize().Width;
|
||||
const int texture_h = loading->getSize().Height;
|
||||
|
||||
core::dimension2d<u32> frame_size = GUIEngine::getDriver()->getCurrentRenderTargetSize();
|
||||
const int screen_w = frame_size.Width;
|
||||
const int screen_h = frame_size.Height;
|
||||
|
||||
const core::rect< s32 > dest_area = core::rect< s32 >(screen_w/2 - texture_w/2,
|
||||
screen_h/2 - texture_h/2,
|
||||
screen_w/2 + texture_w/2,
|
||||
screen_h/2 + texture_h/2);
|
||||
|
||||
const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h);
|
||||
|
||||
GUIEngine::getDriver()->draw2DImage( loading, dest_area, source_area,
|
||||
0 /* no clipping */, 0, true /* alpha */);
|
||||
|
||||
|
||||
g_title_font->draw(_("Loading"),
|
||||
core::rect< s32 >( 0, screen_h/2 + texture_h/2, screen_w, screen_h ),
|
||||
SColor(255,255,255,255),
|
||||
true/* center h */, false /* center v */ );
|
||||
|
||||
} // renderLoading
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Widget* getWidget(const char* name)
|
||||
{
|
||||
// if a modal dialog is shown, search within it too
|
||||
if (ModalDialog::isADialogActive())
|
||||
{
|
||||
Widget* widgetWithinDialog = Screen::getWidget(name, &(ModalDialog::getCurrent()->m_children));
|
||||
if (widgetWithinDialog != NULL) return widgetWithinDialog;
|
||||
}
|
||||
|
||||
Screen* screen = getCurrentScreen();
|
||||
|
||||
if (screen == NULL) return NULL;
|
||||
|
||||
return screen->getWidget(name);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Widget* getWidget(const int id)
|
||||
{
|
||||
// if a modal dialog is shown, search within it too
|
||||
if (ModalDialog::isADialogActive())
|
||||
{
|
||||
Widget* widgetWithinDialog = Screen::getWidget(id, &(ModalDialog::getCurrent()->m_children));
|
||||
if (widgetWithinDialog != NULL) return widgetWithinDialog;
|
||||
}
|
||||
|
||||
Screen* screen = getCurrentScreen();
|
||||
|
||||
if (screen == NULL) return NULL;
|
||||
|
||||
return screen->getWidget(id);
|
||||
}
|
||||
|
||||
|
||||
Screen* screen = getCurrentScreen();
|
||||
|
||||
if (screen == NULL) return NULL;
|
||||
|
||||
return screen->getWidget(name);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Widget* getWidget(const int id)
|
||||
{
|
||||
// if a modal dialog is shown, search within it too
|
||||
if (ModalDialog::isADialogActive())
|
||||
{
|
||||
Widget* widgetWithinDialog = Screen::getWidget(id, &(ModalDialog::getCurrent()->m_children));
|
||||
if (widgetWithinDialog != NULL) return widgetWithinDialog;
|
||||
}
|
||||
|
||||
Screen* screen = getCurrentScreen();
|
||||
|
||||
if (screen == NULL) return NULL;
|
||||
|
||||
return screen->getWidget(id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -208,6 +208,11 @@ namespace GUIEngine
|
||||
* \return the widget that bears that irrlicht ID, or NULL if it was not found
|
||||
*/
|
||||
Widget* getWidget(const int id);
|
||||
|
||||
/**
|
||||
* \brief call when skin in user config was updated
|
||||
*/
|
||||
void reloadSkin();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -82,6 +82,7 @@ Screen::~Screen()
|
||||
void Screen::loadFromFile()
|
||||
{
|
||||
assert(m_magic_number == 0xCAFEC001);
|
||||
//FIXME: need to delete this pointer
|
||||
IrrXMLReader* xml = irr::io::createIrrXMLReader( (file_manager->getGUIDir() + "/" + m_filename).c_str() );
|
||||
parseScreenFileDiv(xml, m_widgets);
|
||||
m_loaded = true;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "io/file_manager.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
using namespace GUIEngine;
|
||||
@ -133,12 +134,17 @@ namespace SkinConfig
|
||||
m_colors[type+"::"+state] = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief loads skin information from a STK skin file
|
||||
* \throw std::runtime_error if file cannot be read
|
||||
*/
|
||||
static void loadFromFile(std::string file)
|
||||
{
|
||||
XMLNode* root = file_manager->createXMLTree(file);
|
||||
if(!root)
|
||||
{
|
||||
std::cerr << "Could not read XML file " << file.c_str() << std::endl;
|
||||
throw std::runtime_error("Invalid skin file");
|
||||
}
|
||||
|
||||
const int amount = root->getNumNodes();
|
||||
|
@ -271,8 +271,15 @@ namespace GUIEngine
|
||||
bool m_dialog;
|
||||
float m_dialog_size;
|
||||
|
||||
/**
|
||||
* \brief load a skin from the file specified in the user configuration file
|
||||
* \throw std::runtime_error if file cannot be read
|
||||
*/
|
||||
Skin(irr::gui::IGUISkin* fallback_skin);
|
||||
|
||||
~Skin();
|
||||
|
||||
irr::gui::IGUISkin* getFallbackSkin() { return m_fallback_skin; }
|
||||
|
||||
void renderSections(ptr_vector<Widget>* within_vector=NULL);
|
||||
void drawBgImage();
|
||||
|
@ -53,15 +53,29 @@ void SpinnerWidget::add()
|
||||
int i;
|
||||
std::istringstream myStream(min_s);
|
||||
bool is_number = (myStream >> i)!=0;
|
||||
if(is_number) m_min = i;
|
||||
else m_min = 0;
|
||||
if (is_number)
|
||||
{
|
||||
m_min = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "WARNING : invalid value from spinner widget minimum value '" << min_s << "'\n";
|
||||
m_min = 0;
|
||||
}
|
||||
}
|
||||
{
|
||||
int i;
|
||||
std::istringstream myStream(max_s);
|
||||
bool is_number = (myStream >> i)!=0;
|
||||
if(is_number) m_max = i;
|
||||
else m_max = 10;
|
||||
if (is_number)
|
||||
{
|
||||
m_max = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "WARNING : invalid value from spinner widget maximal value '" << max_s << "'\n";
|
||||
m_max = 10;
|
||||
}
|
||||
}
|
||||
|
||||
m_value = (m_min + m_max)/2;
|
||||
@ -146,6 +160,9 @@ void SpinnerWidget::add()
|
||||
m_children[2].m_event_handler = this;
|
||||
m_children[2].m_properties[PROP_ID] = "right";
|
||||
m_children[2].id = m_children[2].m_element->getID();
|
||||
|
||||
// refresh display
|
||||
setValue(m_value);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -262,7 +279,8 @@ void SpinnerWidget::addLabel(stringw label)
|
||||
m_labels.push_back(label);
|
||||
m_min = 0;
|
||||
m_max = m_labels.size()-1;
|
||||
setValue(0);
|
||||
|
||||
if (m_element != NULL) setValue(0);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -280,6 +298,8 @@ void SpinnerWidget::setValue(const int new_value)
|
||||
}
|
||||
else if (m_labels.size() > 0)
|
||||
{
|
||||
assert(new_value >= 0);
|
||||
assert(new_value < (int)m_labels.size());
|
||||
m_children[1].m_element->setText(m_labels[new_value].c_str() );
|
||||
}
|
||||
else if (m_text.size() > 0)
|
||||
|
@ -68,7 +68,7 @@ namespace GUIEngine
|
||||
|
||||
/** Call only if this spinner is graphical. Returns the current texture to display */
|
||||
irr::video::ITexture* getTexture();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
SpinnerWidget(const bool gauge=false);
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "guiengine/widget.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@ -52,6 +52,45 @@ OptionsScreenVideo::OptionsScreenVideo() : Screen("options_video.stkgui")
|
||||
void OptionsScreenVideo::loadedFromFile()
|
||||
{
|
||||
m_inited = false;
|
||||
|
||||
GUIEngine::SpinnerWidget* skinSelector = this->getWidget<GUIEngine::SpinnerWidget>("skinchoice");
|
||||
assert( skinSelector != NULL );
|
||||
|
||||
skinSelector->m_properties[PROP_WARP_AROUND] = "true";
|
||||
|
||||
m_skins.clear();
|
||||
skinSelector->clearLabels();
|
||||
|
||||
std::set<std::string> skinFiles;
|
||||
file_manager->listFiles(skinFiles /* out */, file_manager->getGUIDir() + "/skins",
|
||||
true /* is full path */, true /* make full path */ );
|
||||
|
||||
for (std::set<std::string>::iterator it = skinFiles.begin(); it != skinFiles.end(); it++)
|
||||
{
|
||||
if ( (*it).find(".stkskin") != std::string::npos )
|
||||
{
|
||||
m_skins.push_back( *it );
|
||||
}
|
||||
}
|
||||
|
||||
if (m_skins.size() == 0)
|
||||
{
|
||||
std::cerr << "WARNING: could not find a single skin, make sure that "
|
||||
"the data files are correctly installed\n";
|
||||
skinSelector->m_deactivated = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const int skinCount = m_skins.size();
|
||||
for (int n=0; n<skinCount; n++)
|
||||
{
|
||||
const std::string skinFileName = StringUtils::getBasename(m_skins[n]);
|
||||
const std::string skinName = StringUtils::removeExtension( skinFileName );
|
||||
skinSelector->addLabel( core::stringw(skinName.c_str()) );
|
||||
}
|
||||
skinSelector->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
|
||||
skinSelector->m_properties[GUIEngine::PROP_MAX_VALUE] = StringUtils::toString(skinCount-1);
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -61,6 +100,9 @@ void OptionsScreenVideo::init()
|
||||
RibbonWidget* ribbon = this->getWidget<RibbonWidget>("options_choice");
|
||||
if (ribbon != NULL) ribbon->select( "tab_video", PLAYER_ID_GAME_MASTER );
|
||||
|
||||
GUIEngine::SpinnerWidget* skinSelector = this->getWidget<GUIEngine::SpinnerWidget>("skinchoice");
|
||||
assert( skinSelector != NULL );
|
||||
|
||||
// ---- video modes
|
||||
DynamicRibbonWidget* res = this->getWidget<DynamicRibbonWidget>("resolutions");
|
||||
assert( res != NULL );
|
||||
@ -125,6 +167,28 @@ void OptionsScreenVideo::init()
|
||||
}
|
||||
} // end for
|
||||
|
||||
// --- select the right skin in the spinner
|
||||
|
||||
bool currSkinFound = false;
|
||||
const int skinCount = m_skins.size();
|
||||
for (int n=0; n<skinCount; n++)
|
||||
{
|
||||
const std::string skinFileName = StringUtils::getBasename(m_skins[n]);
|
||||
|
||||
if (UserConfigParams::m_skin_file.c_str() == skinFileName)
|
||||
{
|
||||
skinSelector->setValue(n);
|
||||
currSkinFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!currSkinFound)
|
||||
{
|
||||
std::cerr << "WARNING: couldn't find current skin in the list of skins!!\n";
|
||||
skinSelector->setValue(0);
|
||||
GUIEngine::reloadSkin();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -166,6 +230,15 @@ void OptionsScreenVideo::eventCallback(Widget* widget, const std::string& name,
|
||||
|
||||
irr_driver->changeResolution(w, h, w2->getState());
|
||||
}
|
||||
else if (name == "skinchoice")
|
||||
{
|
||||
GUIEngine::SpinnerWidget* skinSelector = this->getWidget<GUIEngine::SpinnerWidget>("skinchoice");
|
||||
assert( skinSelector != NULL );
|
||||
|
||||
const core::stringw selectedSkin = skinSelector->getStringValue();
|
||||
UserConfigParams::m_skin_file = core::stringc(selectedSkin.c_str()).c_str() + std::string(".stkskin");
|
||||
GUIEngine::reloadSkin();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -173,6 +246,8 @@ void OptionsScreenVideo::eventCallback(Widget* widget, const std::string& name,
|
||||
|
||||
void OptionsScreenVideo::tearDown()
|
||||
{
|
||||
// save changes when leaving screen
|
||||
user_config->saveConfig();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -37,6 +37,8 @@ class OptionsScreenVideo : public GUIEngine::Screen, public GUIEngine::ScreenSin
|
||||
OptionsScreenVideo();
|
||||
bool m_inited;
|
||||
|
||||
std::vector<std::string> m_skins;
|
||||
|
||||
public:
|
||||
friend class GUIEngine::ScreenSingleton<OptionsScreenVideo>;
|
||||
|
||||
|