1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // Multi-Phasic Applications: SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.runtime
.lcdui
.scritchui
;
12 import cc
.squirreljme
.jvm
.mle
.scritchui
.ScritchInterface
;
13 import cc
.squirreljme
.jvm
.mle
.scritchui
.ScritchLabelInterface
;
14 import cc
.squirreljme
.jvm
.mle
.scritchui
.ScritchMenuInterface
;
15 import cc
.squirreljme
.jvm
.mle
.scritchui
.brackets
.ScritchMenuHasChildrenBracket
;
16 import cc
.squirreljme
.jvm
.mle
.scritchui
.brackets
.ScritchMenuHasLabelBracket
;
17 import cc
.squirreljme
.jvm
.mle
.scritchui
.brackets
.ScritchMenuHasParentBracket
;
18 import cc
.squirreljme
.jvm
.mle
.scritchui
.brackets
.ScritchMenuKindBracket
;
19 import cc
.squirreljme
.runtime
.cldc
.annotation
.SquirrelJMEVendorApi
;
20 import cc
.squirreljme
.runtime
.cldc
.debug
.Debugging
;
21 import java
.util
.ArrayList
;
22 import java
.util
.Arrays
;
23 import java
.util
.List
;
24 import org
.jetbrains
.annotations
.Async
;
32 public final class MenuActionTree
34 /** Mapping of nodes to leafs, to keep track of natives. */
36 private final List
<MenuActionTreeLeaf
> _mappings
=
40 * Finds the given item.
42 * @param __kind The menu kind.
43 * @return The leaf for the given item, or {@code null} if not found.
44 * @throws NullPointerException On null arguments.
47 public MenuActionTreeLeaf
find(ScritchMenuKindBracket __kind
)
48 throws NullPointerException
51 throw new NullPointerException("NARG");
53 List
<MenuActionTreeLeaf
> mappings
= this._mappings
;
56 for (int i
= 0, n
= mappings
.size(); i
< n
; i
++)
58 MenuActionTreeLeaf leaf
= mappings
.get(i
);
59 if (leaf
._scritch
== __kind
)
69 * Returns the mapping for a given node.
71 * @param __node The node to get for.
72 * @return The resultant mapping.
73 * @throws NullPointerException On null arguments.
77 public final MenuActionTreeLeaf
map(MenuActionNode __node
)
78 throws NullPointerException
81 throw new NullPointerException("NARG");
83 List
<MenuActionTreeLeaf
> mappings
= this._mappings
;
86 // Find the mapping node
87 int n
= mappings
.size();
88 for (int i
= 0; i
< n
; i
++)
90 MenuActionTreeLeaf check
= mappings
.get(i
);
91 if (check
._node
== __node
)
95 // Otherwise it needs creation
96 MenuActionTreeLeaf result
= new MenuActionTreeLeaf(__node
);
107 * Performs actual update of the menu tree.
109 * @param __context The base context root.
110 * @throws NullPointerException On null arguments.
113 @SquirrelJMEVendorApi
115 public void update(MenuActionNode __context
)
116 throws NullPointerException
118 if (__context
== null)
119 throw new NullPointerException("NARG");
121 // Internal recursive logic setup
122 this.__update(__context
, __context
.children());
126 * Adds the given children to this given node.
128 * @param __into The node to write into.
129 * @param __add The children to add.
130 * @throws NullPointerException On null arguments.
134 private void __update(MenuActionNode __into
, MenuActionHasParent
... __add
)
135 throws NullPointerException
138 throw new NullPointerException("NARG");
141 Debugging
.debugNote("Menu __update(%s, %s)",
142 __into
.owner(), (__add
== null ?
null : Arrays
.asList(__add
)));
144 // API for accessing menus
145 ScritchInterface scritchApi
= DisplayManager
.instance().scritch();
146 ScritchLabelInterface labelApi
= scritchApi
.label();
147 ScritchMenuInterface menuApi
= scritchApi
.menu();
149 // Map ourself into a node
150 MenuActionTreeLeaf into
= this.map(__into
);
151 ScritchMenuKindBracket scritch
= into
._scritch
;
153 // Children need to be added?
157 Debugging
.debugNote("Menu add children %d...",
160 // Clear everything from the menu beforehand
161 menuApi
.menuRemoveAll((ScritchMenuHasChildrenBracket
)scritch
);
163 // Map all menu nodes to leaves first, so that they have created
164 // ScritchUI objects as required... if applicable
165 int n
= __add
.length
;
166 MenuActionTreeLeaf
[] leaves
= new MenuActionTreeLeaf
[n
];
167 for (int i
= 0; i
< n
; i
++)
168 leaves
[i
] = this.map(((MenuActionNodeOnly
)__add
[i
])._menuNode
);
170 // Setup leaves first
171 for (int i
= 0; i
< n
; i
++)
173 MenuActionTreeLeaf leaf
= leaves
[i
];
174 MenuActionNode leafNode
= leaf
._node
;
176 // Recursive update of child
177 this.__update(leafNode
, leafNode
.childrenOptional());
179 // Add leaf node widget to our own widget
181 (ScritchMenuHasChildrenBracket
)scritch
, i
,
182 (ScritchMenuHasParentBracket
)leaf
._scritch
);
186 // Set text label for this item?
187 if (scritch
instanceof ScritchMenuHasLabelBracket
)
189 MenuAction action
= into
._node
.owner(MenuAction
.class);
191 // Set the preferred label to use
192 String label
= action
._longLabel
.get();
193 if (label
== null || label
.isEmpty())
194 label
= action
._shortLabel
.get();
196 labelApi
.labelSetString((ScritchMenuHasLabelBracket
)scritch
,