OSDN Git Service

16661f2a36902b538a183c68a8ce5675e3ed3747
[mikumikustudio/libgdx-mikumikustudio.git] / gdx / src / com / badlogic / gdx / scenes / scene2d / ui / List.java
1 /*******************************************************************************\r
2  * Copyright 2011 See AUTHORS file.\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  * \r
8  *   http://www.apache.org/licenses/LICENSE-2.0\r
9  * \r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  ******************************************************************************/\r
16 \r
17 package com.badlogic.gdx.scenes.scene2d.ui;\r
18 \r
19 import com.badlogic.gdx.graphics.Color;\r
20 import com.badlogic.gdx.graphics.g2d.BitmapFont;\r
21 import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;\r
22 import com.badlogic.gdx.graphics.g2d.NinePatch;\r
23 import com.badlogic.gdx.graphics.g2d.SpriteBatch;\r
24 import com.badlogic.gdx.math.Rectangle;\r
25 import com.badlogic.gdx.scenes.scene2d.ActorEvent;\r
26 import com.badlogic.gdx.scenes.scene2d.ActorListener;\r
27 import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent;\r
28 import com.badlogic.gdx.scenes.scene2d.utils.Cullable;\r
29 import com.badlogic.gdx.scenes.scene2d.utils.Drawable;\r
30 import com.badlogic.gdx.utils.GdxRuntimeException;\r
31 \r
32 /** A list (aka list box) displays textual items and highlights the currently selected item.\r
33  * <p>\r
34  * The preferred size of the list is determined by the text bounds of the items and the size of the {@link ListStyle#selection}.\r
35  * @author mzechner */\r
36 public class List extends Widget implements Cullable {\r
37         private ListStyle style;\r
38         private String[] items;\r
39         private int selectedIndex;\r
40         private Rectangle cullingArea;\r
41         private float prefWidth, prefHeight;\r
42         private float itemHeight;\r
43         private float textOffsetX, textOffsetY;\r
44 \r
45         public List (Skin skin) {\r
46                 this(new Object[0], skin);\r
47         }\r
48 \r
49         public List (Object[] items, Skin skin) {\r
50                 this(items, skin.get(ListStyle.class));\r
51         }\r
52 \r
53         public List (Object[] items, ListStyle style) {\r
54                 setStyle(style);\r
55                 setItems(items);\r
56                 setWidth(getPrefWidth());\r
57                 setHeight(getPrefHeight());\r
58 \r
59                 addListener(new ActorListener() {\r
60                         public boolean touchDown (ActorEvent event, float x, float y, int pointer, int button) {\r
61                                 if (pointer != 0) return false;\r
62                                 List.this.touchDown(y);\r
63                                 return true;\r
64                         }\r
65                 });\r
66         }\r
67 \r
68         void touchDown (float y) {\r
69                 int oldIndex = selectedIndex;\r
70                 selectedIndex = (int)((getHeight() - y) / itemHeight);\r
71                 selectedIndex = Math.max(0, selectedIndex);\r
72                 selectedIndex = Math.min(items.length - 1, selectedIndex);\r
73                 if (fire(new ChangeEvent())) selectedIndex = oldIndex;\r
74         }\r
75 \r
76         public void setStyle (ListStyle style) {\r
77                 if (style == null) throw new IllegalArgumentException("style cannot be null.");\r
78                 this.style = style;\r
79                 if (items != null)\r
80                         setItems(items);\r
81                 else\r
82                         invalidateHierarchy();\r
83         }\r
84 \r
85         /** Returns the list's style. Modifying the returned style may not have an effect until {@link #setStyle(ListStyle)} is called. */\r
86         public ListStyle getStyle () {\r
87                 return style;\r
88         }\r
89 \r
90         @Override\r
91         public void draw (SpriteBatch batch, float parentAlpha) {\r
92                 BitmapFont font = style.font;\r
93                 Drawable selectedDrawable = style.selection;\r
94                 Color fontColorSelected = style.fontColorSelected;\r
95                 Color fontColorUnselected = style.fontColorUnselected;\r
96 \r
97                 Color color = getColor();\r
98                 batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);\r
99 \r
100                 float x = getX();\r
101                 float y = getY();\r
102 \r
103                 font.setColor(fontColorUnselected.r, fontColorUnselected.g, fontColorUnselected.b, fontColorUnselected.a * parentAlpha);\r
104                 float itemY = getHeight();\r
105                 for (int i = 0; i < items.length; i++) {\r
106                         if (cullingArea == null || (itemY - itemHeight <= cullingArea.y + cullingArea.height && itemY >= cullingArea.y)) {\r
107                                 if (selectedIndex == i) {\r
108                                         selectedDrawable.draw(batch, x, y + itemY - itemHeight, Math.max(prefWidth, getWidth()), itemHeight);\r
109                                         font.setColor(fontColorSelected.r, fontColorSelected.g, fontColorSelected.b, fontColorSelected.a * parentAlpha);\r
110                                 }\r
111                                 font.draw(batch, items[i], x + textOffsetX, y + itemY - textOffsetY);\r
112                                 if (selectedIndex == i) {\r
113                                         font.setColor(fontColorUnselected.r, fontColorUnselected.g, fontColorUnselected.b, fontColorUnselected.a\r
114                                                 * parentAlpha);\r
115                                 }\r
116                         } else if (itemY < cullingArea.y) {\r
117                                 break;\r
118                         }\r
119                         itemY -= itemHeight;\r
120                 }\r
121         }\r
122 \r
123         /** @return The index of the currently selected item. The top item has an index of 0. */\r
124         public int getSelectedIndex () {\r
125                 return selectedIndex;\r
126         }\r
127 \r
128         public void setSelectedIndex (int index) {\r
129                 if (index < 0 || index >= items.length)\r
130                         throw new GdxRuntimeException("index must be >= 0 and < " + items.length + ": " + index);\r
131                 selectedIndex = index;\r
132         }\r
133 \r
134         /** @return The text of the currently selected item or null if the list is empty. */\r
135         public String getSelection () {\r
136                 if (items.length == 0) return null;\r
137                 return items[selectedIndex];\r
138         }\r
139 \r
140         /** @return The index of the item that was selected, or -1. */\r
141         public int setSelection (String item) {\r
142                 selectedIndex = -1;\r
143                 for (int i = 0, n = items.length; i < n; i++) {\r
144                         if (items[i].equals(item)) {\r
145                                 selectedIndex = i;\r
146                                 break;\r
147                         }\r
148                 }\r
149                 return selectedIndex;\r
150         }\r
151 \r
152         public void setItems (Object[] objects) {\r
153                 if (objects == null) throw new IllegalArgumentException("items cannot be null.");\r
154 \r
155                 if (!(objects instanceof String[])) {\r
156                         String[] strings = new String[objects.length];\r
157                         for (int i = 0, n = objects.length; i < n; i++)\r
158                                 strings[i] = String.valueOf(objects[i]);\r
159                         items = strings;\r
160                 } else\r
161                         items = (String[])objects;\r
162 \r
163                 selectedIndex = 0;\r
164 \r
165                 final BitmapFont font = style.font;\r
166                 final Drawable selectedDrawable = style.selection;\r
167 \r
168                 itemHeight = font.getCapHeight() - font.getDescent() * 2;\r
169                 itemHeight += selectedDrawable.getTopHeight() + selectedDrawable.getBottomHeight();\r
170                 prefWidth += selectedDrawable.getLeftWidth() + selectedDrawable.getRightWidth();\r
171                 textOffsetX = selectedDrawable.getLeftWidth();\r
172                 textOffsetY = selectedDrawable.getTopHeight() - font.getDescent();\r
173 \r
174                 prefWidth = 0;\r
175                 for (int i = 0; i < items.length; i++) {\r
176                         TextBounds bounds = font.getBounds(items[i]);\r
177                         prefWidth = Math.max(bounds.width, prefWidth);\r
178                 }\r
179                 prefHeight = items.length * itemHeight;\r
180 \r
181                 invalidateHierarchy();\r
182         }\r
183 \r
184         public String[] getItems () {\r
185                 return items;\r
186         }\r
187 \r
188         public float getPrefWidth () {\r
189                 return prefWidth;\r
190         }\r
191 \r
192         public float getPrefHeight () {\r
193                 return prefHeight;\r
194         }\r
195 \r
196         public void setCullingArea (Rectangle cullingArea) {\r
197                 this.cullingArea = cullingArea;\r
198         }\r
199 \r
200         /** The style for a list, see {@link List}.\r
201          * @author mzechner\r
202          * @author Nathan Sweet */\r
203         static public class ListStyle {\r
204                 public BitmapFont font;\r
205                 public Color fontColorSelected = new Color(1, 1, 1, 1);\r
206                 public Color fontColorUnselected = new Color(1, 1, 1, 1);\r
207                 public Drawable selection;\r
208 \r
209                 public ListStyle () {\r
210                 }\r
211 \r
212                 public ListStyle (BitmapFont font, Color fontColorSelected, Color fontColorUnselected, Drawable selection) {\r
213                         this.font = font;\r
214                         this.fontColorSelected.set(fontColorSelected);\r
215                         this.fontColorUnselected.set(fontColorUnselected);\r
216                         this.selection = selection;\r
217                 }\r
218 \r
219                 public ListStyle (ListStyle style) {\r
220                         this.font = style.font;\r
221                         this.fontColorSelected.set(style.fontColorSelected);\r
222                         this.fontColorUnselected.set(style.fontColorUnselected);\r
223                         this.selection = style.selection;\r
224                 }\r
225         }\r
226 }\r