Skip to content

Commit 41d9132

Browse files
committed
Fix indentation in right-click menu handler
Corrected indentation for the MouseRightClick event handler in IconPickerWidget.cs to improve code readability and maintain consistency. GameObject icon handling to use tags only , hidden tags Removed session-only custom icon storage and now rely solely on tags for persisting GameObject icons. Simplified icon retrieval and assignment logic to improve consistency and persistence across sessions. Remove CustomIconStorage class Deleted the CustomIconStorage static class, which provided session-only storage for custom icons keyed by GameObject reference. This may be part of a refactor or cleanup of unused code. Improve emoji search in IconPickerWidget Enhanced the emoji search functionality to allow searching by emoji names, not just the emoji character. This is achieved by building a reverse mapping from emoji characters to their searchable names using reflection, improving usability when searching for emojis by descriptive terms. Add Favorites category to IconPickerWidget Introduces a 'Favorites' category for both Material Icons and Emojis, updates category sidebar and icon mapping, and improves UI with a background for the content area. Also refines the Main icons list and adjusts search box placeholder text based on mode. Add reset icon functionality to GameObject header Implemented right-click context menu on the GameObject icon button with options to change the icon or reset it to default. Added logic to remove custom icons and related tags, update the UI, and provide a reset button in the icon color picker popup. Revamp icon picker UI and add color selection Refactored IconPickerWidget to improve layout, add a search box, and move mode buttons to a right sidebar. Introduced a color picker button for material icons, allowing users to select icon colors. Updated GameObjectHeader to handle live color updates from the icon picker and streamlined event handling for icon and color changes. back to normal icon when creating gameobject Replaced dynamic icon selection with static icons for game objects in both GameObjectHeader and GameObjectNode. This simplifies the UI by using a consistent icon representation regardless of children or components. Replace emoji-sequences.txt with emojis.json Removed the emoji-sequences.txt file and added emojis.json to update the emoji data source. This change likely transitions from a text-based Unicode emoji sequence format to a JSON format for improved parsing and integration.
1 parent 4949615 commit 41d9132

7 files changed

Lines changed: 424 additions & 1176 deletions

File tree

game/addons/tools/Code/Scene/GameObjectInspector/GameObjectHeader/CustomIconStorage.cs

Lines changed: 0 additions & 7 deletions
This file was deleted.

game/addons/tools/Code/Scene/GameObjectInspector/GameObjectHeader/GameObjectHeader.cs

Lines changed: 82 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ protected override void OnPaint()
8282
private Drag _drag;
8383

8484
public GameObjectIconButton( GameObjectHeader parent )
85-
: base( GetCurrentIcon( parent.Target ), null )
85+
: base( GetCurrentIcon( parent.Target ) ) // Load icon from tags
8686
{
8787
_parent = parent;
8888

@@ -100,9 +100,9 @@ public GameObjectIconButton( GameObjectHeader parent )
100100
private static string GetCurrentIcon( SerializedObject target )
101101
{
102102
var go = target.Targets.OfType<GameObject>().FirstOrDefault();
103-
if ( go is null ) return "folder";
103+
if ( go is null ) return "📦";
104104

105-
// Check for persistent icon tag first (saved with the scene)
105+
// Check for persistent icon tag (saved with the scene)
106106
var iconTag = go.Tags.FirstOrDefault( t => t.StartsWith( "icon_" ) );
107107
if ( iconTag is not null )
108108
{
@@ -111,14 +111,8 @@ private static string GetCurrentIcon( SerializedObject target )
111111
return decoded;
112112
}
113113

114-
// Fallback to session-only storage
115-
if ( CustomIconStorage.Icons.TryGetValue( go, out var customIcon ) )
116-
{
117-
return customIcon;
118-
}
119-
120-
// Default icon based on children and components
121-
return go.Children.Where( x => x.ShouldShowInHierarchy() ).Any() ? "📂" : (go.Components.Count > 0 ? "layers" : "📁");
114+
// Default icon
115+
return "📦";
122116
}
123117

124118
private static Color GetCurrentColor( SerializedObject target )
@@ -150,6 +144,19 @@ protected override void OnMousePress( MouseEvent e )
150144
base.OnMousePress( e );
151145
}
152146

147+
protected override void OnMouseRightClick( MouseEvent e )
148+
{
149+
base.OnMouseRightClick( e );
150+
151+
var menu = new Menu( this );
152+
menu.AddOption( "Change Icon...", "palette", OnIconClicked );
153+
menu.AddSeparator();
154+
menu.AddOption( "Reset to Default", "refresh", ResetToDefault );
155+
menu.OpenAtCursor();
156+
157+
e.Accepted = true;
158+
}
159+
153160
private void OnIconClicked()
154161
{
155162
var go = _parent.Target.Targets.OfType<GameObject>().FirstOrDefault();
@@ -162,7 +169,7 @@ private void OnIconClicked()
162169
{
163170
// Prepare new tag values
164171
var hasChildren = go.Children.Where( x => x.ShouldShowInHierarchy() ).Any();
165-
var defaultIcon = hasChildren ? "folder_open" : (go.Components.Count > 0 ? "layers" : "folder");
172+
var defaultIcon = "📦";
166173
string newIconTag = selectedIcon != defaultIcon ? IconTagEncoding.EncodeIconToTag( selectedIcon ) : null;
167174
string newColorTag = null;
168175
if ( selectedColor != Color.White )
@@ -174,17 +181,7 @@ private void OnIconClicked()
174181
var targets = _parent.Target.Targets.OfType<GameObject>().ToArray();
175182
foreach ( var targetGo in targets )
176183
{
177-
// Icon (store by Id)
178-
if ( selectedIcon == defaultIcon )
179-
{
180-
CustomIconStorage.Icons.Remove( targetGo );
181-
}
182-
else
183-
{
184-
CustomIconStorage.Icons[targetGo] = selectedIcon;
185-
}
186-
187-
// Color tag (keep using tags for color)
184+
// Remove existing color tag if needed
188185
var existingColorTag = targetGo.Tags.FirstOrDefault( t => t.StartsWith( "icon_color_" ) );
189186
if ( existingColorTag is not null )
190187
{
@@ -196,8 +193,8 @@ private void OnIconClicked()
196193
targetGo.Tags.Add( newColorTag );
197194
}
198195

199-
// Icon tag (persisted with the scene)
200-
var existingIconTag = targetGo.Tags.FirstOrDefault( t => t.StartsWith( "icon_" ) );
196+
// Remove existing icon tag if needed (but not color tags)
197+
var existingIconTag = targetGo.Tags.FirstOrDefault( t => t.StartsWith( "icon_" ) && !t.StartsWith( "icon_color_" ) );
201198
if ( existingIconTag is not null )
202199
{
203200
if ( newIconTag is null || existingIconTag != newIconTag )
@@ -229,6 +226,38 @@ private void OnIconClicked()
229226
} );
230227
}
231228

229+
private void ResetToDefault()
230+
{
231+
var targets = _parent.Target.Targets.OfType<GameObject>().ToArray();
232+
foreach ( var targetGo in targets )
233+
{
234+
// Remove all icon-related tags
235+
var iconTags = targetGo.Tags.Where( t => t.StartsWith( "icon_" ) || t.StartsWith( "icon_color_" ) ).ToList();
236+
foreach ( var tag in iconTags )
237+
{
238+
targetGo.Tags.Remove( tag );
239+
}
240+
}
241+
242+
// Update the tree view
243+
if ( SceneTreeWidget.Current?.TreeView is { } tv )
244+
{
245+
foreach ( var t in targets )
246+
{
247+
tv.Dirty( t );
248+
}
249+
tv.UpdateIfDirty();
250+
}
251+
252+
// Reset button to default state
253+
Icon = "📦";
254+
Foreground = Color.White;
255+
Update();
256+
257+
// Update the scene tree to reflect the change
258+
SceneTreeWidget.Current?.TreeView?.Update();
259+
}
260+
232261
protected override void OnDragStart()
233262
{
234263
base.OnDragStart();
@@ -296,39 +325,54 @@ public static void OpenPopup( Widget parent, string currentIcon, Color currentCo
296325
popup.Layout.Margin = 8;
297326
popup.Layout.Spacing = 8;
298327

299-
// Icon Picker
328+
// Track current color
329+
Color selectedColor = currentColor;
330+
331+
// Icon Picker with color button
300332
var iconPicker = popup.Layout.Add( new IconPickerWidget( popup ), 1 );
301333
iconPicker.Icon = currentIcon;
302-
303-
// Color Picker
304-
var colorPicker = popup.Layout.Add( new ColorPicker( popup ) );
305-
colorPicker.Value = currentColor;
306-
307-
// Live update when icon or color changes
308-
iconPicker.ValueChanged = ( v ) =>
334+
335+
// Update color when changed via the color button
336+
iconPicker.ColorChanged = ( c ) =>
309337
{
310-
onSelected?.Invoke( v, colorPicker.Value );
338+
selectedColor = c;
339+
onSelected?.Invoke( iconPicker.Icon, selectedColor );
311340
};
312341

313-
colorPicker.ValueChanged = ( c ) =>
342+
// Live update when icon changes
343+
iconPicker.ValueChanged = ( v ) =>
314344
{
315-
onSelected?.Invoke( iconPicker.Icon, c );
345+
onSelected?.Invoke( v, selectedColor );
316346
};
317347

318348
// Buttons
319349
var buttonRow = popup.Layout.AddRow();
320350
buttonRow.Spacing = 4;
321351

352+
var resetButton = buttonRow.Add( new Button( "Reset" ) );
353+
resetButton.Icon = "refresh";
354+
resetButton.Clicked += () =>
355+
{
356+
iconPicker.Icon = "📦";
357+
selectedColor = Color.White;
358+
onSelected?.Invoke( "📦", Color.White );
359+
};
360+
361+
buttonRow.AddStretchCell();
362+
322363
var cancelButton = buttonRow.Add( new Button( "Cancel" ) );
323364
cancelButton.Clicked += () => popup.Destroy();
324365

325366
var okButton = buttonRow.Add( new Button.Primary( "OK" ) );
326367
okButton.Clicked += () =>
327368
{
328-
onSelected?.Invoke( iconPicker.Icon, colorPicker.Value );
369+
onSelected?.Invoke( iconPicker.Icon, selectedColor );
329370
popup.Destroy();
330371
};
331372

332-
popup.OpenAtCursor();
373+
// Position with offset from cursor to avoid covering the icon
374+
popup.Position = Application.CursorPosition + new Vector2( 10, 10 );
375+
popup.Show();
376+
popup.ConstrainToScreen();
333377
}
334378
}

game/addons/tools/Code/Scene/GameObjectInspector/TagSetControlWidget.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ protected override void OnValueChanged()
6060
var isGameTags = tagset is GameTags;
6161
foreach ( var tag in tagset )
6262
{
63+
// Hide internal icon tags
64+
if ( tag.StartsWith( "icon_" ) || tag.StartsWith( "icon_color_" ) )
65+
continue;
66+
6367
if ( tagCounts.ContainsKey( tag ) )
6468
{
6569
tagCounts[tag]++;
@@ -78,6 +82,10 @@ protected override void OnValueChanged()
7882
{
7983
foreach ( var tag in gameset.TryGetAll( false ) )
8084
{
85+
// Hide internal icon tags
86+
if ( tag.StartsWith( "icon_" ) || tag.StartsWith( "icon_color_" ) )
87+
continue;
88+
8189
if ( !ownTags.Contains( tag ) )
8290
{
8391
ownTags.Add( tag );
@@ -93,13 +101,21 @@ protected override void OnValueChanged()
93101

94102
foreach ( var tag in tags )
95103
{
104+
// Hide internal icon tags
105+
if ( tag.StartsWith( "icon_" ) || tag.StartsWith( "icon_color_" ) )
106+
continue;
107+
96108
tagCounts[tag] = 1;
97109
}
98110

99111
if ( tags is GameTags gTags )
100112
{
101113
foreach ( var tag in gTags.TryGetAll( false ) )
102114
{
115+
// Hide internal icon tags
116+
if ( tag.StartsWith( "icon_" ) || tag.StartsWith( "icon_color_" ) )
117+
continue;
118+
103119
if ( !ownTags.Contains( tag ) )
104120
{
105121
ownTags.Add( tag );

game/addons/tools/Code/Scene/SceneTree/GameObjectNode.cs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,13 @@ public override int ValueHash
3434
hc.Add( Value.Active );
3535
hc.Add( Value.Tags ); // Include tags for custom icon and color changes
3636

37-
// Include custom icon (from session storage) so changes trigger a node update
38-
// Prefer persisted icon tag (saved with scene) so icons survive reloads
39-
var iconTag = Value.Tags.FirstOrDefault( t => t.StartsWith( "icon_" ) );
37+
// Include custom icon from tags so changes trigger a node update
38+
var iconTag = Value.Tags.FirstOrDefault( t => t.StartsWith( "icon_" ) && !t.StartsWith( "icon_color_" ) );
4039
if ( iconTag is not null )
4140
{
4241
var decoded = Editor.IconTagEncoding.DecodeIconFromTag( iconTag );
4342
if ( !string.IsNullOrEmpty( decoded ) ) hc.Add( decoded );
4443
}
45-
else if ( CustomIconStorage.Icons.TryGetValue( Value, out var sessionIcon ) )
46-
{
47-
hc.Add( sessionIcon );
48-
}
4944

5045
// Also include persisted color tag so color changes invalidate the node
5146
var colorTag = Value.Tags.FirstOrDefault( t => t.StartsWith( "icon_color_" ) );
@@ -92,7 +87,7 @@ public override void OnPaint( VirtualWidget item )
9287
if ( !Value.Active ) opacity *= 0.5f;
9388

9489
Color pen = Theme.TextControl;
95-
string icon = Value.Children.Where( x => x.ShouldShowInHierarchy() ).Any() ? "📂" : (Value.Components.Count > 0 ? "layers" : "📁");
90+
string icon = "layers";
9691
Color iconColor = Theme.TextControl.WithAlpha( 0.6f );
9792
Color overlayIconColor = iconColor;
9893

@@ -249,19 +244,12 @@ public override void OnPaint( VirtualWidget item )
249244
var iconSize = 16;
250245

251246
// Apply custom icon and color overrides (after all default conditions)
252-
253-
254-
// Prefer persisted icon tag (saved with scene)
255-
var iconTag = Value.Tags.FirstOrDefault( t => t.StartsWith( "icon_" ) );
247+
var iconTag = Value.Tags.FirstOrDefault( t => t.StartsWith( "icon_" ) && !t.StartsWith( "icon_color_" ) );
256248
if ( iconTag is not null )
257249
{
258250
var decoded = Editor.IconTagEncoding.DecodeIconFromTag( iconTag );
259251
if ( !string.IsNullOrEmpty( decoded ) ) icon = decoded;
260252
}
261-
else if ( CustomIconStorage.Icons.TryGetValue( Value, out var sessionIconValue ) )
262-
{
263-
icon = sessionIconValue;
264-
}
265253

266254
// Prefer persisted color tag (saved with scene)
267255
var colorTag = Value.Tags.FirstOrDefault( t => t.StartsWith( "icon_color_" ) );
@@ -329,17 +317,12 @@ public override void OnPaint( VirtualWidget item )
329317
else
330318
{
331319
Paint.Pen = Theme.Blue;
332-
Paint.DrawText( r, $"{connection.DisplayName}", TextFlag.LeftCenter );
333-
r.Left += 22;
334-
}
320+
Paint.DrawText( r, $"{connection.DisplayName}", TextFlag.LeftCenter );
321+
r.Left += 22;
322+
}
335323

336324

337325
}
338-
// Apply custom icon and color overrides (after all default conditions)
339-
if ( CustomIconStorage.Icons.TryGetValue( Value, out var customIcon ) )
340-
{
341-
icon = customIcon;
342-
}
343326
}
344327

345328
public override void OnRename( VirtualWidget item, string text, List<TreeNode> selection = null )

0 commit comments

Comments
 (0)