Skip to content

Commit 2a195ed

Browse files
committed
Implement feature to toggle between menu and tree UI for item details
1 parent 3d18a2d commit 2a195ed

File tree

4 files changed

+127
-47
lines changed

4 files changed

+127
-47
lines changed

source/app.jai

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,6 @@ Selected :: #bake_arguments EntitiesIterator(entity_filter=#code !it.is_selected
294294

295295
// :UserConfig hotload changes to this file
296296
User_Settings :: struct {
297-
item_details_uses_menu := true;
298-
299297
item_list_max_size_before_scroll_px := 300.;
300298
annotation_list_max_size_before_scroll_px := 400.;
301299

source/changelog.jai

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ PRIZM_VERSION_BACKLOGGED :: Version.{"WIP", "WIP", #string DONE
1212
* New Feature: Attributes TODO Add a feature flag for enabling this
1313
1414
* Attributes are complementary to annotations but are intended to be dense (every mesh element will have a value) overlays of typed data associated with mesh elements (vertex/face/edge/halfedges...). Currently string, float, Vector3, Matrix3 types are supported. The concept of annotations has been refined to be a sparse overlay of string data attached mesh elements which are addressable via the .obj format e.g., vertices via lines starting with the 'v' directive, and faces via lines starting with the 'f' directive
15+
* TODO Implement some checks on the version numbers e.g., no duplicate numbers, no non-monotonic dates
1516
* TODO Added a new preset shape prism_obj_format_reference.obj which functions as a demo of how the semantic obj comments in Prism will work. This shape is also available via the Preset button.
1617
* Multiple attributes are supported, and each will have its own tab in the item context menu
1718
* TODO Added a preset example to demonstrate the new annotation functionality
@@ -33,6 +34,14 @@ PRIZM_VERSION_0_10_0 :: Version.{"0.10.0", "WIP", #string DONE
3334
* Removed the useless solid color option for triangle rendering, it will be replaced with gbuffer albedo visualization
3435
DONE};
3536

37+
PRIZM_VERSION_0_9_3 :: Version.{"0.9.3", "17 April 2024", #string DONE
38+
39+
* Clicking with LMB on a "Details" section heading now toggles between the following:
40+
1. Displaying section options in a popup menu. This is useful if you want the options is visible only while you're editing them
41+
2. Displaying section options inline with the "Details" section. This is useful if you want the options always visible
42+
* Removed the now unused "File > Preferences > Item List > Item Details Section Uses Menus" which is superceeded by the above feature
43+
DONE};
44+
3645
PRIZM_VERSION_0_9_2 :: Version.{"0.9.2", "31 March 2024", #string DONE
3746
3847
* Fixed some memory leaks
@@ -657,6 +666,7 @@ DONE
657666
init_changelog :: () {
658667
//array_add(*changelog, PRIZM_VERSION_BACKLOGGED);
659668
//array_add(*changelog, PRIZM_VERSION_0_10_0);
669+
array_add(*changelog, PRIZM_VERSION_0_9_3);
660670
array_add(*changelog, PRIZM_VERSION_0_9_2);
661671
array_add(*changelog, PRIZM_VERSION_0_9_1);
662672
array_add(*changelog, PRIZM_VERSION_0_9_0);

source/ui.jai

Lines changed: 115 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,6 @@ DONE);
11811181
show_tooltip("Used to handle invalid .obj files:\nInvalid `f` directive references (missing points) use this position\nInvalid point components (inf/nan) get the corresponding component value");
11821182
ImGui.Checkbox(imgui_label(tprint("Disable reload via % when file unchanged", to_string(cast(u32) Special_Key_Code.F5, pad_unmodified=false))), *app.settings.disable_reload_key_if_file_unchanged); // @Volatile Sync with :ReloadItemsKey
11831183
ImGui.Checkbox("Show Header Annotation Tooltips", *app.settings.show_header_annotation_tooltips);
1184-
ImGui.Checkbox("Item Details Section Uses Menus", *app.settings.item_details_uses_menu);
11851184
}
11861185

11871186
if ImGui.BeginMenu("Advanced") {
@@ -1227,18 +1226,87 @@ show_details_ui :: () {
12271226
}
12281227
}
12291228

1230-
begin_item_details_section :: (label : *u8) -> bool {
1231-
if app.settings.item_details_uses_menu {
1232-
return ImGui.BeginMenu(label);
1229+
1230+
Details_Section_Info :: struct {
1231+
Mode :: enum { NONE; MENU; TREE; }
1232+
begin_mode : Mode = .MENU;
1233+
end_mode : Mode = .MENU;
1234+
}
1235+
1236+
item_details_section_info : Table(*u8, Details_Section_Info);
1237+
1238+
ConfigureItemDetailsSection :: () #expand {
1239+
if #complete `section_mode == {
1240+
case .NONE;
1241+
// Do nothing
1242+
case .MENU;
1243+
// @TODO This does not work, we probably need to call this function before BeginMenu
1244+
//ImGui.PushStyleColor(xx ImGui.Col.PopupBg, ImGui.GetStyle().Colors[ImGui.Col.WindowBg]);
1245+
case .TREE;
1246+
begin_box_section();
1247+
}
1248+
1249+
`defer if #complete `section_mode == {
1250+
case .NONE;
1251+
// Do nothing
1252+
case .MENU;
1253+
//ImGui.PopStyleColor();
1254+
case .TREE;
1255+
end_box_section();
12331256
}
1234-
return ImGui.TreeNodeEx(label, ImGui.TreeNodeFlags.SpanAvailWidth);
12351257
}
12361258

1237-
end_item_details_section :: () {
1238-
if app.settings.item_details_uses_menu {
1239-
ImGui.EndMenu();
1240-
} else {
1259+
begin_item_details_section :: (label : *u8) -> bool, Details_Section_Info.Mode {
1260+
info, newly_added := find_or_add(*item_details_section_info, label);
1261+
1262+
if #complete info.begin_mode == {
1263+
case .NONE;
1264+
1265+
// Only expect NONE in for end_mode (when there is no ImGui ending function to call)
1266+
assert(false);
1267+
1268+
case .TREE;
1269+
1270+
ImGui.SetNextItemOpen(true);
1271+
do_tree := ImGui.TreeNodeEx(label, ImGui.TreeNodeFlags.SpanAvailWidth);
1272+
1273+
info.end_mode = .TREE; // This frame close the tree
1274+
if ImGui.IsItemClicked(.Left) {
1275+
info.begin_mode = .MENU; // Next frame show a menu
1276+
}
1277+
1278+
return do_tree, .TREE;
1279+
1280+
case .MENU;
1281+
do_menu := ImGui.BeginMenu(label);
1282+
1283+
info.end_mode = .MENU; // This frame close the menu
1284+
if ImGui.IsItemClicked(.Left) {
1285+
info.begin_mode = .TREE; // Next frame show a tree
1286+
}
1287+
1288+
if do_menu {
1289+
}
1290+
1291+
return do_menu, .MENU;
1292+
}
1293+
1294+
assert(false); // Unreachable
1295+
return false, .NONE;
1296+
}
1297+
1298+
end_item_details_section :: (label : *u8) {
1299+
info, newly_added := find_or_add(*item_details_section_info, label);
1300+
1301+
if #complete info.end_mode == {
1302+
case .NONE;
1303+
// No ending function to call
1304+
1305+
case .TREE;
12411306
ImGui.TreePop();
1307+
1308+
case .MENU;
1309+
ImGui.EndMenu();
12421310
}
12431311
}
12441312

@@ -1302,10 +1370,10 @@ show_details_pane_ui_for_item_selection :: () {
13021370

13031371
show_item_selection_ui :: () {
13041372

1305-
if begin_item_details_section("Selection") {
1306-
defer end_item_details_section();
1307-
if !app.settings.item_details_uses_menu begin_box_section();
1308-
defer if !app.settings.item_details_uses_menu end_box_section();
1373+
do_section, section_mode := begin_item_details_section("Selection");
1374+
if do_section {
1375+
defer end_item_details_section("Selection");
1376+
ConfigureItemDetailsSection();
13091377

13101378
for :Selected entity : app.entities {
13111379

@@ -2221,10 +2289,12 @@ display_info_ui :: (display_info : *Display_Info, aabb : AxisBox3, entity_index
22212289
}
22222290

22232291
display_information :: (entity : *Entity) {
2224-
if begin_item_details_section("Information") {
2225-
defer end_item_details_section();
2292+
2293+
do_section, section_mode := begin_item_details_section("Information");
2294+
if do_section {
2295+
defer end_item_details_section("Information");
22262296
table_flags : ImGui.TableFlags;
2227-
if !app.settings.item_details_uses_menu table_flags |= .BordersOuter;
2297+
if section_mode == .TREE table_flags |= .BordersOuter;
22282298

22292299
ImGui.BeginTable("##InformationTable", 2, flags=table_flags);
22302300
defer ImGui.EndTable();
@@ -2262,10 +2332,10 @@ display_information :: (entity : *Entity) {
22622332
}
22632333

22642334
display_transform :: (entity : *Entity) {
2265-
if begin_item_details_section("Transform") {
2266-
defer end_item_details_section();
2267-
if !app.settings.item_details_uses_menu begin_box_section();
2268-
defer if !app.settings.item_details_uses_menu end_box_section();
2335+
do_section, section_mode := begin_item_details_section("Transform");
2336+
if do_section {
2337+
defer end_item_details_section("Transform");
2338+
ConfigureItemDetailsSection();
22692339

22702340
ImGui.TableNextColumn();
22712341

@@ -2537,16 +2607,16 @@ show_rendering_triangles_ui :: (display_info : *Display_Info, entity_index : int
25372607
if valid_geometry_index(entity_index) && app.entities[entity_index].mesh.triangles.count == 0 {
25382608
ImGui.BeginDisabled();
25392609
if begin_item_details_section("Triangles (none)") {
2540-
defer end_item_details_section();
2610+
defer end_item_details_section("Triangles (none)");
25412611
}
25422612
ImGui.EndDisabled();
25432613
return;
25442614
}
25452615

2546-
if begin_item_details_section("Triangles") {
2547-
defer end_item_details_section();
2548-
if !app.settings.item_details_uses_menu begin_box_section();
2549-
defer if !app.settings.item_details_uses_menu end_box_section();
2616+
do_section, section_mode := begin_item_details_section("Triangles");
2617+
if do_section {
2618+
defer end_item_details_section("Triangles");
2619+
ConfigureItemDetailsSection();
25502620

25512621
ImGui.TableNextColumn();
25522622
ImGui.Text(
@@ -2613,16 +2683,16 @@ show_rendering_segments_ui :: (display_info : *Display_Info, entity_index : int
26132683
if valid_geometry_index(entity_index) && app.entities[entity_index].mesh.segments.count == 0 {
26142684
ImGui.BeginDisabled();
26152685
if begin_item_details_section("Segments (none)") {
2616-
defer end_item_details_section();
2686+
defer end_item_details_section("Segments (none)");
26172687
}
26182688
ImGui.EndDisabled();
26192689
return;
26202690
}
26212691

2622-
if begin_item_details_section("Segments") {
2623-
defer end_item_details_section();
2624-
if !app.settings.item_details_uses_menu begin_box_section();
2625-
defer if !app.settings.item_details_uses_menu end_box_section();
2692+
do_section, section_mode := begin_item_details_section("Segments");
2693+
if do_section {
2694+
defer end_item_details_section("Segments");
2695+
ConfigureItemDetailsSection();
26262696

26272697
ImGui.TableNextColumn();
26282698
ImGui.Text(
@@ -2656,16 +2726,16 @@ show_rendering_points_ui :: (display_info : *Display_Info, entity_index : int =
26562726
if valid_geometry_index(entity_index) && app.entities[entity_index].mesh.points.count == 0 {
26572727
ImGui.BeginDisabled();
26582728
if begin_item_details_section("Points (none)") {
2659-
defer end_item_details_section();
2729+
defer end_item_details_section("Points (none)");
26602730
}
26612731
ImGui.EndDisabled();
26622732
return;
26632733
}
26642734

2665-
if begin_item_details_section("Points") {
2666-
defer end_item_details_section();
2667-
if !app.settings.item_details_uses_menu begin_box_section();
2668-
defer if !app.settings.item_details_uses_menu end_box_section();
2735+
do_section, section_mode := begin_item_details_section("Points");
2736+
if do_section {
2737+
defer end_item_details_section("Points");
2738+
ConfigureItemDetailsSection();
26692739

26702740
ImGui.TableNextColumn();
26712741
ImGui.Text(
@@ -2700,16 +2770,16 @@ show_rendering_positions_ui :: (display_info : *Display_Info, entity_index : int
27002770
if valid_geometry_index(entity_index) && app.entities[entity_index].mesh.positions.count == 0 {
27012771
ImGui.BeginDisabled();
27022772
if begin_item_details_section("Vertices (none)") {
2703-
defer end_item_details_section();
2773+
defer end_item_details_section("Vertices (none)");
27042774
}
27052775
ImGui.EndDisabled();
27062776
return;
27072777
}
27082778

2709-
if begin_item_details_section("Vertices") {
2710-
defer end_item_details_section();
2711-
if !app.settings.item_details_uses_menu begin_box_section();
2712-
defer if !app.settings.item_details_uses_menu end_box_section();
2779+
do_section, section_mode := begin_item_details_section("Vertices");
2780+
if do_section {
2781+
defer end_item_details_section("Vertices");
2782+
ConfigureItemDetailsSection();
27132783

27142784
ImGui.TableNextColumn();
27152785
ImGui.Text(
@@ -2751,10 +2821,12 @@ show_rendering_positions_ui :: (display_info : *Display_Info, entity_index : int
27512821

27522822
show_clipping_ui :: (using display_info : *Display_Info, aabb : AxisBox3) {
27532823

2754-
if begin_item_details_section("Clipping") {
2755-
defer end_item_details_section();
2824+
do_section, section_mode := begin_item_details_section("Clipping");
2825+
if do_section {
2826+
defer end_item_details_section("Clipping");
2827+
27562828
table_flags : ImGui.TableFlags;
2757-
if !app.settings.item_details_uses_menu {
2829+
if section_mode == .TREE {
27582830
table_flags |= .BordersOuter; // | .RowBg; // .SizingFixedFit
27592831
}
27602832

source/ui_utils.jai

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ imgui_label2 :: (label : string, ptr : *void = null) -> string {
7373
return tprint("%##%", label, ptr);
7474
}
7575

76-
begin_box_section :: () {
77-
table_flags := ImGui.TableFlags.BordersOuter;
76+
begin_box_section :: (extra_flags := ImGui.TableFlags.None) {
77+
table_flags := ImGui.TableFlags.BordersOuter | extra_flags;
7878
// .NoHostExtendX; // Can be useful
7979
ImGui.BeginTable("", 1, flags=table_flags);
8080
}

0 commit comments

Comments
 (0)