123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- {
- FreePascal / Delphi bindings for ImGui
- Copyright (C) 2023 Coldzer0 <Coldzer0 [at] protonmail.ch>
- This program is free software: you can redistribute it and/or modify
- it under the terms of the MIT License.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- MIT License for more details.
- }
- {
- Code From https://github.com/dpethes/imgui-pas - Updated by Coldzer0
- Partial translation of imgui demo / ShowTestWindow
- While you're probably better off with the original version as it's way more extensive,
- this is good as
- * a test case for the bindings or
- * a quick guide if something isn't translated in a straightforward way
- }
- Unit TestWindow;
- {$IFDEF FPC}
- {$mode objfpc}{$H+}
- {$ENDIF}
- {$J+}
- Interface
- Uses
- Classes,
- SysUtils,
- PasImGui,
- PasImGui.Utils;
- Type
- { TTestWindow }
- TTestWindow = Class
- Private
- show_app_main_menu_bar: boolean;
- show_app_console: boolean;
- show_app_log: boolean;
- show_app_layout: boolean;
- show_app_property_editor: boolean;
- show_app_long_text: boolean;
- show_app_auto_resize: boolean;
- show_app_constrained_resize: boolean;
- show_app_fixed_overlay: boolean;
- show_app_manipulating_window_title: boolean;
- show_app_custom_rendering: boolean;
- show_app_style_editor: boolean;
- show_app_metrics: boolean;
- show_app_about: boolean;
- no_titlebar: boolean;
- no_resize: boolean;
- no_move: boolean;
- no_scrollbar: boolean;
- no_collapse: boolean;
- no_menu: boolean;
- Procedure Trees;
- Public
- Constructor Create;
- Procedure Show(Var p_open: boolean);
- End;
- Implementation
- Procedure ShowHelpMarker(Const desc: AnsiString);
- Begin
- ImGui.TextDisabled('(?)');
- If (ImGui.IsItemHovered()) Then
- Begin
- ImGui.BeginTooltip();
- ImGui.PushTextWrapPos(450.0);
- ImGui.TextUnformatted(desc);
- ImGui.PopTextWrapPos();
- ImGui.EndTooltip();
- End;
- End;
- { TTestWindow }
- Procedure TTestWindow.Trees;
- Const //static vars
- align_label_with_current_x_position: boolean = False;
- selection_mask: integer = 1 shl 2;
- // Dumb representation of what may be user-side selection state. You may carry selection state inside or outside your objects in whatever format you see fit.
- Var
- node_open: Boolean;
- node_clicked: Integer;
- i: Integer;
- node_flags: ImGuiTreeNodeFlags;
- Begin
- If (ImGui.TreeNode('Basic trees')) Then
- Begin
- For i := 0 To 4 Do
- If (ImGui.TreeNode({%H-}PImGuiID(i), 'Child %d', [i])) Then
- Begin
- ImGui.Text('blah blah');
- ImGui.SameLine();
- If (ImGui.SmallButton('print')) Then
- begin
- ImGui.LogText('Child ' + i.ToString + ' pressed');
- Imgui.LogFinish;
- end;
- ImGui.TreePop();
- End;
- ImGui.TreePop();
- End;
- If (ImGui.TreeNode('Advanced, with Selectable nodes')) Then
- Begin
- ShowHelpMarker('This is a more standard looking tree with selectable nodes.' + #10 +
- 'Click to select, CTRL+Click to toggle, click on arrows or double-click to open.');
- ImGui.Checkbox('Align label with current X position)',
- @align_label_with_current_x_position);
- ImGui.Text('Hello!');
- If (align_label_with_current_x_position) Then
- ImGui.Unindent(ImGui.GetTreeNodeToLabelSpacing());
- node_clicked := -1;
- // Temporary storage of what node we have clicked to process selection at the end of the loop. May be a pointer to your own node type, etc.
- ImGui.PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui.GetFontSize() * 3);
- // Increase spacing to differentiate leaves from expanded contents.
- For i := 0 To 5 Do
- Begin
- // Disable the default open on single-click behavior and pass in Selected flag according to our selection state.
- //ImGuiTreeNodeFlags node_flags := ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0);
- node_flags := ImGuiTreeNodeFlags_OpenOnArrow Or
- ImGuiTreeNodeFlags_OpenOnDoubleClick;
- If (selection_mask And (1 shl i)) > 0 Then
- node_flags := node_flags Or ImGuiTreeNodeFlags_Selected;
- If (i < 3) Then
- Begin
- // Node
- node_open := ImGui.TreeNodeEx({%H-}PImGuiID(i), node_flags,
- 'Selectable Node %d', [i]);
- If (ImGui.IsItemClicked()) Then
- node_clicked := i;
- If (node_open) Then
- Begin
- ImGui.Text('Blah blah' + #10 + 'Blah Blah');
- ImGui.TreePop();
- End;
- End
- Else
- Begin
- // Leaf: The only reason we have a TreeNode at all is to allow selection of the leaf. Otherwise we can use BulletText() or TreeAdvanceToLabelPos()+Text().
- node_flags := node_flags Or ImGuiTreeNodeFlags_Leaf Or
- ImGuiTreeNodeFlags_NoTreePushOnOpen;
- ImGui.TreeNodeEx({%H-}PImGuiID(i), node_flags, 'Selectable Leaf %d', [i]);
- If (ImGui.IsItemClicked()) Then
- node_clicked := i;
- End;
- End;
- If (node_clicked <> -1) Then
- Begin
- // Update selection state. Process outside of tree loop to avoid visual inconsistencies during the clicking-frame.
- If (ImGui.GetIO()^.KeyCtrl) Then
- selection_mask := selection_mask Xor (1 shl node_clicked) // CTRL+click to toggle
- Else
- //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, this commented bit preserve selection when clicking on item that is part of the selection
- selection_mask := (1 shl node_clicked); // Click to single-select
- End;
- ImGui.PopStyleVar();
- If (align_label_with_current_x_position) Then
- ImGui.Indent(ImGui.GetTreeNodeToLabelSpacing());
- ImGui.TreePop();
- End;
- ImGui.TreePop();
- End;
- Constructor TTestWindow.Create;
- Begin
- show_app_main_menu_bar := False;
- show_app_console := False;
- show_app_log := False;
- show_app_layout := False;
- show_app_property_editor := False;
- show_app_long_text := False;
- show_app_auto_resize := False;
- show_app_constrained_resize := False;
- show_app_fixed_overlay := False;
- show_app_manipulating_window_title := False;
- show_app_custom_rendering := False;
- show_app_style_editor := False;
- show_app_metrics := False;
- show_app_about := False;
- no_titlebar := False;
- no_resize := False;
- no_move := False;
- no_scrollbar := False;
- no_collapse := False;
- no_menu := False;
- End;
- Procedure TTestWindow.Show(Var p_open: boolean);
- Var
- io: PImGuiIO;
- window_flags: ImGuiWindowFlags;
- draw_list: PImDrawList;
- value_raw, value_with_lock_threshold, mouse_delta: ImVec2;
- Begin
- window_flags := ImGuiWindowFlags_None;
- // Demonstrate the various window flags. Typically you would just use the default.
- If (no_titlebar) Then window_flags := window_flags Or ImGuiWindowFlags_NoTitleBar;
- If (no_resize) Then window_flags := window_flags Or ImGuiWindowFlags_NoResize;
- If (no_move) Then window_flags := window_flags Or ImGuiWindowFlags_NoMove;
- If (no_scrollbar) Then window_flags := window_flags Or ImGuiWindowFlags_NoScrollbar;
- If (no_collapse) Then window_flags := window_flags Or ImGuiWindowFlags_NoCollapse;
- If (Not no_menu) Then window_flags := window_flags Or ImGuiWindowFlags_MenuBar;
- ImGui.SetNextWindowSize(ImVec2.New(550, 680), ImGuiCond_FirstUseEver);
- If Not ImGui.Begin_('ImGui Demo (FreePascal / Delphi version)', @p_open, window_flags) Then
- Begin
- // Early out if the window is collapsed, as an optimization.
- ImGui.End_;
- exit;
- End;
- //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); // 2/3 of the space for widget and 1/3 for labels
- ImGui.PushItemWidth(ImGui.GetWindowWidth() * 0.65);
- // Right align, keep 140 pixels for labels
- ImGui.Text('Dear ImGui says hello.');
- // Menu
- If (ImGui.BeginMenuBar()) Then
- Begin
- If (ImGui.BeginMenu('Menu')) Then
- Begin
- ImGui.MenuItem('Open');
- ImGui.MenuItem('Close');
- ImGui.EndMenu();
- End;
- If (ImGui.BeginMenu('Examples')) Then
- Begin
- ImGui.MenuItem('Main menu bar', nil, @show_app_main_menu_bar);
- ImGui.MenuItem('Console', nil, @show_app_console);
- ImGui.MenuItem('Log', nil, @show_app_log);
- ImGui.MenuItem('Simple layout', nil, @show_app_layout);
- ImGui.MenuItem('Property editor', nil, @show_app_property_editor);
- ImGui.MenuItem('Long text display', nil, @show_app_long_text);
- ImGui.MenuItem('Auto-resizing window', nil, @show_app_auto_resize);
- ImGui.MenuItem('Constrained-resizing window', nil,
- @show_app_constrained_resize);
- ImGui.MenuItem('Simple overlay', nil, @show_app_fixed_overlay);
- ImGui.MenuItem('Manipulating window title', nil,
- @show_app_manipulating_window_title);
- ImGui.MenuItem('Custom rendering', nil, @show_app_custom_rendering);
- ImGui.EndMenu();
- End;
- If (ImGui.BeginMenu('Help')) Then
- Begin
- ImGui.MenuItem('Metrics', nil, @show_app_metrics);
- ImGui.MenuItem('Style Editor', nil, @show_app_style_editor);
- ImGui.MenuItem('About ImGui', nil, @show_app_about);
- ImGui.EndMenu();
- End;
- ImGui.EndMenuBar();
- End;
- ImGui.Spacing();
- If ImGui.CollapsingHeader('Help') Then
- Begin
- ImGui.TextWrapped(
- 'This window is being created by the ShowTestWindow() function. Please refer to the code for programming reference.'
- + #10#10 +
- 'User Guide:');
- ImGui.ShowUserGuide();
- End;
- If ImGui.CollapsingHeader('Window options') Then
- Begin
- ImGui.Checkbox('No titlebar', @no_titlebar);
- ImGui.SameLine(150);
- ImGui.Checkbox('No resize', @no_resize);
- ImGui.Checkbox('No move', @no_move);
- ImGui.SameLine(150);
- ImGui.Checkbox('No scrollbar', @no_scrollbar);
- ImGui.SameLine(300);
- ImGui.Checkbox('No collapse', @no_collapse);
- ImGui.Checkbox('No menu', @no_menu);
- If ImGui.TreeNode('Style') Then
- Begin
- ImGui.ShowStyleEditor(Imgui.GetStyle());
- //this is useful to have, but doesn't need to be translated as an example
- ImGui.TreePop();
- End;
- If ImGui.TreeNode('Logging') Then
- Begin
- ImGui.TextWrapped(
- 'The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded. You can also call ImGui.LogText() to output directly to the log without a visual output.');
- ImGui.LogButtons();
- ImGui.TreePop();
- End;
- End;
- If ImGui.CollapsingHeader('Widgets') Then
- Begin
- If ImGui.TreeNode('Trees') Then
- Trees;
- End;
- If ImGui.CollapsingHeader('Keyboard, Mouse & Focus') Then
- Begin
- If ImGui.TreeNode('Dragging') Then
- Begin
- ImGui.TextWrapped(
- 'You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget.');
- ImGui.Button('Drag Me');
- If ImGui.IsItemActive() Then
- Begin
- io := ImGui.GetIO();
- // Draw a line between the button and the mouse cursor
- draw_list := ImGui.GetWindowDrawList();
- draw_list^.PushClipRectFullScreen;
- draw_list^.AddLine(io^.MouseClickedPos[0], io^.MousePos,
- ImGui.GetColorU32Vec(ImGui.GetStyle()^.Colors[ImGuiCol_DragDropTarget]),
- 4.0);
- draw_list^.PopClipRect;
- value_raw := ImGui.GetMouseDragDelta(ImGuiMouseButton_Left, 0.0);
- value_with_lock_threshold := ImGui.GetMouseDragDelta(ImGuiMouseButton_Left);
- mouse_delta := ImGui.GetIO()^.MouseDelta;
- ImGui.SameLine();
- ImGui.TextWrapped(
- 'Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f), MouseDelta (%.1f, %.1f)',
- [value_raw.x, value_raw.y, value_with_lock_threshold.x,
- value_with_lock_threshold.y, mouse_delta.x, mouse_delta.y]);
- End;
- ImGui.TreePop();
- End;
- End;
- ImGui.End_;
- End;
- End.
|