Unityでテーブルレイアウトをやる場合はGUI.SelectionGridを使うのがいいかと思いますが、
1行を1つのアイテムに見せるような一覧表示をするのはちょっと難しそうです。
なので、ラベルを組み合わせてテーブルっぽく見せるスクリプトを作ってみました。
ListBox.js
class ListBox {
static private var clickTimeDelta : float = 1.0;
private var mouseDownTimeWindow : float;
var itemHeight:float = Screen.height / 12;
var list:List.<System.Object>;
var callback:Function;
var top:float;
var left:float;
var width:float;
var height:float;
var scrollPosition: Vector2 = Vector2.zero;;
var selectedInt : int = -1;
var hoverInt:int = -1;
var columns : String[];
var filteredColumns:String[];
var labelTexture:Texture;
var labelHoverTexture:Texture;
var labelOnTexture:Texture;
var labelStyle:GUIStyle;
var labelStyleCenter:GUIStyle;
var labelStyleRight:GUIStyle;
private function refresh(){
var first = list[0];
var filteredColumnsArray = new Array();
if(!first) {
return;
}
var firstDict:Dictionary.<String, System.Object> = first as Dictionary.<String, System.Object>;
if(firstDict) {
var keys:Dictionary.KeyCollection.<String, System.Object> = firstDict.Keys;
if(columns && columns.Length > 0) {
for(var key in keys){
for(var key2 in columns){
if(key2 == key){
filteredColumnsArray.Add(key);
}
}
}
} else {
for(var key in keys){
filteredColumnsArray.Add(key);
}
}
filteredColumns = filteredColumnsArray.ToBuiltin(String);
}
setItemWidth(this.width);
if(filteredColumns && filteredColumns.Length > 0) {
setItemWidth(Mathf.Round(this.width / filteredColumns.Length));
}
}
private function Initialize(list:List.<System.Object>, callback:Function, top:float, left:float, width:float, height:float){
labelTexture = Resources.Load("textures/list");
labelOnTexture = Resources.Load("textures/list_on");
labelHoverTexture = Resources.Load("textures/list_hover");
labelStyle = new GUIStyle(GUI.skin.box);
labelStyle.fontSize = Screen.height / 32;
labelStyle.fixedHeight = itemHeight;
labelStyle.alignment = TextAnchor.MiddleLeft;
labelStyle.margin = RectOffset(0, 0, 0, 0);
labelStyle.padding = RectOffset(16, 16, 0, 0);
labelStyle.normal.background = labelTexture;
labelStyleCenter = new GUIStyle(labelStyle);
labelStyleCenter.alignment = TextAnchor.MiddleCenter;
labelStyleRight = new GUIStyle(labelStyle);
labelStyleRight.alignment = TextAnchor.MiddleRight;
mouseDownTimeWindow = -1;
this.list = list;
this.callback = callback;
this.top = top;
this.left = left;
this.width = width;
this.height = height;
refresh();
}
private function Initialize(list:List.<System.Object>, callback:Function, top:float, left:float){
Initialize(list, callback, top, left, Screen.width - (left * 2), Screen.height - (top + itemHeight));
}
function ListBox(list:List.<System.Object>, callback:Function, top:float, left:float, width:float, height:float){
Initialize(list, callback, top, left, width, height);
}
function ListBox(list:List.<System.Object>, callback:Function, top:float, left:float){
Initialize(list, callback, top, left, Screen.width - (left * 2), Screen.height - (top + itemHeight));
}
function ListBox(list:List.<System.Object>, callback:Function){
Initialize(list, callback, itemHeight, itemHeight);
}
function setItemHeight(_itemHeight:float){
itemHeight = _itemHeight;
}
function setList(list:List.<System.Object>){
this.list = list;
refresh();
}
function setColumns(columns:String[]){
this.columns = columns;
refresh();
}
function setItemWidth(width:float) {
labelStyle.fixedWidth = width;
labelStyleCenter.fixedWidth = width;
labelStyleRight.fixedWidth = width;
}
function setItemTexture(texture:Texture) {
labelStyle.normal.background = texture;
labelStyleCenter.normal.background = texture;
labelStyleRight.normal.background = texture;
}
function OnGUI() {
if ( mouseDownTimeWindow > 0 ) {
mouseDownTimeWindow -= Time.deltaTime;
if(mouseDownTimeWindow < 0){
mouseDownTimeWindow = 0;
}
}
var selectStyle:GUIStyle = GUIStyle.none;
if(this.list){
var oldSelected:int = selectedInt;
var currentHeight:float = itemHeight * this.list.Count;
var mouseHover = false;
scrollPosition = GUI.BeginScrollView (Rect (top, left, width, height), scrollPosition, Rect (0, 0, width, currentHeight));
GUILayout.BeginVertical();
var i:int=0;
for (var item in this.list){
if(i == oldSelected){
setItemTexture(labelOnTexture);
} else if(i == hoverInt){
setItemTexture(labelHoverTexture);
} else {
setItemTexture(labelTexture);
}
GUILayout.BeginHorizontal();
var dict:Dictionary.<String, System.Object> = item as Dictionary.<String, System.Object>;
if(dict){
var j:int = 0;
for(var column in filteredColumns) {
var itemString = "";
if(dict.ContainsKey(column)){
itemString = dict[column];
}
if(j == 0) {
GUILayout.Label(itemString, labelStyle);
} else if(j == filteredColumns.Length - 1) {
GUILayout.Label(itemString, labelStyleRight);
} else {
GUILayout.Label(itemString, labelStyleCenter);
}
j++;
}
} else {
GUILayout.Label(item as String, labelStyle);
}
GUILayout.EndHorizontal();
var rect:Rect = GUILayoutUtility.GetLastRect();
var pos:Vector2 = Vector2(Input.mousePosition.x - left, (Screen.height - Input.mousePosition.y) - top);
if (rect.Contains(pos)) {
mouseHover = true;
hoverInt = i;
if(Input.GetMouseButton(0) || Input.GetMouseButtonUp(0)){
selectedInt = i;
} else {
selectedInt = -1;
}
}
i++;
}
GUILayout.EndVertical();
GUI.EndScrollView ();
if (selectedInt >= 0) {
var mouseOut = ((selectedInt != oldSelected) && (oldSelected >= 0));
if(mouseOut){
mouseDownTimeWindow = 0;
selectedInt = -1;
} else if(Input.GetMouseButton(0) && mouseDownTimeWindow < 0) {
mouseDownTimeWindow = clickTimeDelta;
} else if(!Input.GetMouseButton(0) && (mouseDownTimeWindow > 0)) {
if(callback){
callback(list[selectedInt], selectedInt);
}
mouseDownTimeWindow = -1;
}
}
if(!Input.GetMouseButton(0) && mouseDownTimeWindow == 0) {
mouseDownTimeWindow = -1;
}
}
}
}
背景画像はこんな感じで
textures/list
textures/list_hover
textures/list_on
表示させる側のコードはこんな感じです
main.js
var listBox:ListBox;
function Start() {
listBox = null;
}
function OnGUI(){
if(!listBox){
var stringList:List.<System.Object> = new List.<System.Object>();
var item1 = new Dictionary.<String, System.Object>();
item1['name'] = '布の服';
item1['price'] = '80G';
stringList.Add(item1);
var item2 = new Dictionary.<String, System.Object>();
item2['name'] = '旅人の服';
item2['price'] = '100G';
stringList.Add(item2);
var item3 = new Dictionary.<String, System.Object>();
item3['name'] = '銅の剣';
item3['price'] = '120G';
stringList.Add(item3);
var item4 = new Dictionary.<String, System.Object>();
item4['name'] = '銅の盾';
item4['price'] = '70G';
stringList.Add(item4);
listBox = new ListBox(stringList, function(selected, index){
Debug.Log("Selected '" + selected + "' at " + index);
});
}
if (Event.current.type != EventType.keyDown) {
listBox.OnGUI();
}
}
darktablesさんのJSONプラグイン
MiniJSON.csと併用することでJSONを一覧表示することもできます。