1010import com .ss .editor .ui .css .CssClasses ;
1111import com .ss .rlib .ui .util .FXUtils ;
1212import com .ss .rlib .util .array .Array ;
13+ import javafx .beans .value .ObservableValue ;
1314import javafx .collections .ObservableList ;
1415import javafx .scene .Node ;
1516import javafx .scene .control .ComboBox ;
@@ -66,6 +67,18 @@ public class PaintingComponentContainer extends ScrollPane {
6667 @ NotNull
6768 protected final ComboBox <PaintingComponent > componentBox ;
6869
70+ /**
71+ * The painted object.
72+ */
73+ @ Nullable
74+ private Object paintedObject ;
75+
76+ /**
77+ * The current component.
78+ */
79+ @ Nullable
80+ private PaintingComponent currentComponent ;
81+
6982 /**
7083 * The flag of showing this container.
7184 */
@@ -87,8 +100,14 @@ public PaintingComponentContainer(@NotNull final ModelChangeConsumer changeConsu
87100 .multiply (LABEL_PERCENT ));
88101
89102 componentBox = new ComboBox <>();
103+ componentBox .setCellFactory (PaintingComponentListCell ::new );
104+ componentBox .setButtonCell (new PaintingComponentListCell (null ));
105+ componentBox .setPromptText ("No tools" );
90106 componentBox .prefWidthProperty ().bind (horContainer .widthProperty ()
91107 .multiply (FIELD_PERCENT ));
108+ componentBox .getSelectionModel ()
109+ .selectedItemProperty ()
110+ .addListener (this ::activate );
92111
93112 final VBox resultContainer = new VBox ();
94113
@@ -104,6 +123,81 @@ public PaintingComponentContainer(@NotNull final ModelChangeConsumer changeConsu
104123 this .components = registry .createComponents (this );
105124 }
106125
126+ /**
127+ * Get the painted object.
128+ *
129+ * @return the painted object.
130+ */
131+ @ FxThread
132+ private @ Nullable Object getPaintedObject () {
133+ return paintedObject ;
134+ }
135+
136+ /**
137+ * Set the painted object.
138+ *
139+ * @param paintedObject the painted object.
140+ */
141+ @ FxThread
142+ private void setPaintedObject (@ Nullable final Object paintedObject ) {
143+ this .paintedObject = paintedObject ;
144+ }
145+
146+ /**
147+ * Get the current painting component.
148+ *
149+ * @return the current painting component.
150+ */
151+ @ FxThread
152+ private @ Nullable PaintingComponent getCurrentComponent () {
153+ return currentComponent ;
154+ }
155+
156+ /**
157+ * Set the current painting component.
158+ *
159+ * @param currentComponent the current painting component.
160+ */
161+ @ FxThread
162+ private void setCurrentComponent (@ Nullable final PaintingComponent currentComponent ) {
163+ this .currentComponent = currentComponent ;
164+ }
165+
166+ /**
167+ * Activate the selected painting component.
168+ *
169+ * @param observable the component box's property.
170+ * @param oldValue the previous component.
171+ * @param newValue the new component.
172+ */
173+ @ FxThread
174+ private void activate (@ NotNull final ObservableValue <? extends PaintingComponent > observable ,
175+ @ Nullable final PaintingComponent oldValue , @ Nullable final PaintingComponent newValue ) {
176+
177+ final ObservableList <Node > items = getContainer ()
178+ .getChildren ();
179+
180+ if (oldValue != null ) {
181+ oldValue .notifyHided ();
182+ oldValue .stopPainting ();
183+ items .remove (oldValue );
184+ }
185+
186+ final Object paintedObject = getPaintedObject ();
187+
188+ if (newValue != null ) {
189+ if (paintedObject != null ) {
190+ newValue .startPainting (paintedObject );
191+ }
192+ if (isShowed ()) {
193+ newValue .notifyShowed ();
194+ }
195+ items .add ((Node ) newValue );
196+ }
197+
198+ setCurrentComponent (newValue );
199+ }
200+
107201 /**
108202 * Get the container.
109203 *
@@ -125,33 +219,35 @@ public PaintingComponentContainer(@NotNull final ModelChangeConsumer changeConsu
125219 }
126220
127221 /**
128- * Show a painting component to process with the element .
222+ * Get the component box .
129223 *
130- * @param element the element to process .
224+ * @return the component box .
131225 */
132226 @ FxThread
133- public void showComponentFor (@ Nullable final Object element ) {
134-
135- final VBox container = getContainer ();
136- final ObservableList <Node > children = container .getChildren ();
137- children .stream ().filter (PaintingComponent .class ::isInstance )
138- .map (PaintingComponent .class ::cast )
139- .peek (PaintingComponent ::notifyHided )
140- .forEach (PaintingComponent ::stopProcessing );
141-
142- children .clear ();
143-
144- if (element == null ) return ;
227+ private @ NotNull ComboBox <PaintingComponent > getComponentBox () {
228+ return componentBox ;
229+ }
145230
146- final PaintingComponent processingComponent = getComponents ().search (element , PaintingComponent ::isSupport );
147- if (processingComponent == null ) return ;
231+ /**
232+ * Prepare painting components to work with the element
233+ *
234+ * @param element the element.
235+ */
236+ @ FxThread
237+ public void prepareFor (@ Nullable final Object element ) {
238+ setPaintedObject (element );
148239
149- children .add ((Node ) processingComponent );
240+ final ComboBox <PaintingComponent > componentBox = getComponentBox ();
241+ final ObservableList <PaintingComponent > items = componentBox .getItems ();
242+ items .clear ();
150243
151- processingComponent .startPainting (element );
244+ if (element != null ) {
245+ getComponents ().forEach (toCheck -> toCheck .isSupport (element ),
246+ toAdd -> items .add (toAdd ));
247+ }
152248
153- if (isShowed ()) {
154- processingComponent . notifyShowed ( );
249+ if (! items . isEmpty ()) {
250+ componentBox . getSelectionModel (). select ( 0 );
155251 }
156252 }
157253
@@ -161,12 +257,10 @@ public void showComponentFor(@Nullable final Object element) {
161257 @ FxThread
162258 public void notifyShowed () {
163259 setShowed (true );
164-
165- final VBox container = getContainer ();
166- final ObservableList <Node > children = container .getChildren ();
167- children .stream ().filter (PaintingComponent .class ::isInstance )
168- .map (PaintingComponent .class ::cast )
169- .forEach (PaintingComponent ::notifyShowed );
260+ final PaintingComponent currentComponent = getCurrentComponent ();
261+ if (currentComponent != null ) {
262+ currentComponent .notifyShowed ();
263+ }
170264 }
171265
172266 /**
@@ -175,12 +269,10 @@ public void notifyShowed() {
175269 @ FxThread
176270 public void notifyHided () {
177271 setShowed (false );
178-
179- final VBox container = getContainer ();
180- final ObservableList <Node > children = container .getChildren ();
181- children .stream ().filter (PaintingComponent .class ::isInstance )
182- .map (PaintingComponent .class ::cast )
183- .forEach (PaintingComponent ::notifyHided );
272+ final PaintingComponent currentComponent = getCurrentComponent ();
273+ if (currentComponent != null ) {
274+ currentComponent .notifyHided ();
275+ }
184276 }
185277
186278 /**
@@ -204,7 +296,7 @@ public void notifyHided() {
204296 }
205297
206298 /**
207- * Is showed boolean .
299+ * Return the showed state .
208300 *
209301 * @return true if this component is showed.
210302 */
@@ -214,7 +306,7 @@ protected boolean isShowed() {
214306 }
215307
216308 /**
217- * Sets showed.
309+ * Set the showed state .
218310 *
219311 * @param showed true if this component is showed.
220312 */
@@ -226,20 +318,14 @@ protected void setShowed(final boolean showed) {
226318 /**
227319 * Notify about changed property.
228320 *
229- * @param object the object
230- * @param propertyName the property name
321+ * @param object the object.
322+ * @param propertyName the property name.
231323 */
232324 @ FxThread
233325 public void notifyChangeProperty (@ NotNull final Object object , @ NotNull final String propertyName ) {
234-
235- final VBox container = getContainer ();
236- final ObservableList <Node > children = container .getChildren ();
237- if (children .isEmpty ()) {
238- return ;
326+ final PaintingComponent currentComponent = getCurrentComponent ();
327+ if (currentComponent != null ) {
328+ currentComponent .notifyChangeProperty (object , propertyName );
239329 }
240-
241- children .stream ().map (PaintingComponent .class ::cast )
242- .filter (component -> component .getPaintedObject () == object )
243- .forEach (c -> c .notifyChangeProperty (object , propertyName ));
244330 }
245331}
0 commit comments