Move some System.err to Debugging.debugNote.
[SquirrelJME.git] / modules / midp-lcdui / src / main / java / cc / squirreljme / runtime / lcdui / scritchui / MenuActionTree.java
blob51b7452630fdd1522e986633df40c1dcfe53bdbe
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;
26 /**
27 * Menu action tree.
29 * @since 2024/07/21
31 @SquirrelJMEVendorApi
32 public final class MenuActionTree
34 /** Mapping of nodes to leafs, to keep track of natives. */
35 @SquirrelJMEVendorApi
36 private final List<MenuActionTreeLeaf> _mappings =
37 new ArrayList<>();
39 /**
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.
45 * @since 2024/07/30
47 public MenuActionTreeLeaf find(ScritchMenuKindBracket __kind)
48 throws NullPointerException
50 if (__kind == null)
51 throw new NullPointerException("NARG");
53 List<MenuActionTreeLeaf> mappings = this._mappings;
54 synchronized (this)
56 for (int i = 0, n = mappings.size(); i < n; i++)
58 MenuActionTreeLeaf leaf = mappings.get(i);
59 if (leaf._scritch == __kind)
60 return leaf;
64 // Not found
65 return null;
68 /**
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.
74 * @since 2024/07/21
76 @SquirrelJMEVendorApi
77 public final MenuActionTreeLeaf map(MenuActionNode __node)
78 throws NullPointerException
80 if (__node == null)
81 throw new NullPointerException("NARG");
83 List<MenuActionTreeLeaf> mappings = this._mappings;
84 synchronized (this)
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)
92 return check;
95 // Otherwise it needs creation
96 MenuActionTreeLeaf result = new MenuActionTreeLeaf(__node);
98 // Add to mapping set
99 mappings.add(result);
101 // And then use it
102 return result;
107 * Performs actual update of the menu tree.
109 * @param __context The base context root.
110 * @throws NullPointerException On null arguments.
111 * @since 2024/07/21
113 @SquirrelJMEVendorApi
114 @Async.Execute
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.
131 * @since 2024/07/21
133 @Async.Execute
134 private void __update(MenuActionNode __into, MenuActionHasParent... __add)
135 throws NullPointerException
137 if (__into == null)
138 throw new NullPointerException("NARG");
140 // Debug
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?
154 if (__add != null)
156 // Debug
157 Debugging.debugNote("Menu add children %d...",
158 __add.length);
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
180 menuApi.menuInsert(
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,
197 label);