Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demo code markers (imgui_demo.cpp) #3689

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Conversation

pthom
Copy link
Contributor

@pthom pthom commented Jan 2, 2021

Hello,

This PR adds some "DemoCode" markers inside imgui_demo.cpp. They are used by imgui manual.

Basically, DemoCode and DemoCode_ are two macros that can optionally add a "Code" button like this
image
(DemoCode_ with an underscore will call ImGui::SameLine() first and align to the right).

By default, they will do nothing, unless gImGuiDemoCallback is not null. gImGuiDemoCallback is an optional callback, which is defined like this:

typedef void (*ImGuiDemoCallback)(int line_number, const char* demo_title);
ImGuiDemoCallback gImGuiDemoCallback = NULL;

For example, imgui manual uses it like this:

// Redefinition of ImGuiDemoCallback, as defined in imgui_demo.cpp
typedef void (*ImGuiDemoCallback)(int line_number, const char* demo_title);
extern ImGuiDemoCallback gImGuiDemoCallback;
 
....
gImGuiDemoCallback = implImGuiDemoCallbackDemoCallback;

As an example, the following extract from imgui_demo.cpp:

    DemoCode("Widgets");
    if (ImGui::TreeNode("Basic"))
    {
        DemoCode("Widgets/Basic");

        DemoCode_("Widgets/Basic/Button");
        static int clicked = 0;
        if (ImGui::Button("Button"))
            clicked++;
        if (clicked & 1)
        {
            ImGui::SameLine();
            ImGui::Text("Thanks for clicking me!");
        }

        DemoCode_("Widgets/Basic/Checkbox");
        static bool check = true;
        ImGui::Checkbox("checkbox", &check);

        DemoCode_("Widgets/Basic/RadioButton");
        static int e = 0;
        ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine();

Can then be parsed into a hierarchical table of contents like this:

image

(Side note: in the imgui manual code, the number of "/" denotes the title hierarchy level).

And will display buttons like this (if gImGuiDemoCallback is not null):
image


Feel free to close this PR if you think it is not appropriate, since it concern an aside project (imgui manual).

I suspect that the fact that imgui manual's in itself is not using orthodox C++ can be an issue for you; and that it might be the reason why you did not comment any further on it (and I can totally understand this :-).

However the modifications in imgui_demo.cpp are agnostic to the way the callbacks are made (so that another GUI could be built around them).

Also, IMHO the "DemoCode" markers can help navigate in the imgui_demo.cpp file. For example, below, the code below at line 3782 becomes clearer if we add a DemoCode marker that summarize the hierarchical context of what we are reading.

    if (ImGui::TreeNode("Padding"))
    {
        DemoCode("Tables & Columns/Padding");

@pthom pthom changed the title Demo code Demo code markers (imgui_demo.cpp) Jan 2, 2021
@ocornut
Copy link
Owner

ocornut commented Jan 11, 2021

Thank you for the update Pascal!

Feel free to close this PR if you think it is not appropriate, since it concern an aside project (imgui manual).
I suspect that the fact that imgui manual's in itself is not using orthodox C++ can be an issue for you; and that it might be the reason why you did not comment any further on it (and I can totally understand this :-).

I'm mostly generally overwhelmed by amount of tasks in-flight so didn't give any time to your idea yet. I'm generally favorable to it but you are right that the C++ use in imgui_manual was off-putting for dear imgui codebase and didn't help moving it nearer the top of the pile :) As a general rule of thumb, if I feel a proposal needs too much polish work on my side it's likely to move lower in the pile.

Some feedback:

  • I feel it might be adequate it to make the macros upper-case there, they'll more self-explicit as code markers.
  • The button identifier doesn't matter so you could use ("Code##%d", __LINE__) instead, of simply PushID(__LINE); Button(); PopID(); to avoid the printf.
  • There are hard-coded size contents in the code (the 70 seems that it should be CalcTextSize("Code").x + style.FramePadding.x * 2.0f and the 25.0f I don't know).
  • I would go all in and include FILE in the macros to potentially allow this to be used in other code.
  • Various glitches are visible with elements being offsets, e.g.
    image
  • Positioning could be improved for cases where there is no space:
    image
    Instead of using ImGui::SameLine(ImGui::GetWindowSize().x - 70.f); it could be something like Max(GetCursorPos().x, GetWindowContentRegionMax() - button_width) where button_width == CalcTextSize("Code").x + style.FramePadding.x * 2.0f.
  • The arbitrary naming of DemoCode() vs DemoCode_() is a little odd to expose to the end-user and generally the output with those empty lines seems to odd to me, why not trying to have everything on existing lines instead of using empty lines?
  • **Generally if you replace the first test with if (ImGui::GetIO().KeyShift && gImGuiDemoCallback) and use a key modifier to toggle visibility I think we should aim to have other items not move.

One good aspect of this is that we could later aim to implement a basic dependency-free version of your solution in imgui_demo., probably less polished, with less fancy text editor.

@ocornut
Copy link
Owner

ocornut commented Jan 11, 2021

As a quick experiment here's what I tried:

static void _ShowDemoCallbackButton(int line_number, const char* demo_title, bool before_widgets)
{
    //if (!gImGuiDemoCallback)
    //    return;

    ImVec2 backup_cursor = ImGui::GetCursorPos();
    if (!before_widgets)
    {
        ImGui::SetItemAllowOverlap();
        ImGui::SameLine();
    }

    float x = ImGui::GetContentRegionMax().x - ImGui::CalcTextSize(">").x - ImGui::GetStyle().ItemSpacing.x;
    if (x <= ImGui::GetCursorPosX())
    {
        //ImGui::SetCursorPos(backup_cursor); // Hide when there's no room, less ugly?
        //return;
    }
    else
    {
        ImGui::SetCursorPosX(x);
    }

    ImGui::PushID(line_number);
    if (ImGui::SmallButton(">"))
    {
        if (gImGuiDemoCallback)
            gImGuiDemoCallback(line_number, demo_title);
    }
    ImGui::PopID();
    if (ImGui::IsItemHovered())
        ImGui::SetTooltip("Code for section '%s' at line %d", demo_title, line_number);

    if (before_widgets)
        ImGui::SetCursorPos(backup_cursor);
}

#define DEMO_MARKER(demo_title)         _ShowDemoCallbackButton(__LINE__, demo_title, false)    // Submit button from after item/line submission
#define DEMO_MARKER_BOL(demo_title)     _ShowDemoCallbackButton(__LINE__, demo_title, true)     // Submit button from before item/line submission

image

Still doesn't look super great with lots of widgets though.

@ocornut
Copy link
Owner

ocornut commented Jan 11, 2021

Here's a completely different idea:

  • We make the marker record the current position ImGui::GetCursorScreenPos() + current ClipRect.
  • We always call the marker function at the top of a block. So essentially the marker would implicitly define zones assumed to be rectangles.
  • The marker macro doesn't display anything.
  • Move all markers before containers

Now we have zones:

image

From there, the documentation window (in imgui_manual or can be prototyped in imgui_demo) can use those rectangle for picking a section. E.g. has an always visible "CODE LOOKUP" button which use the position of markers and position of mouse to highlight the current section and allow picking from one. e.g. using similar visuals as RenderRectFilledWithHole() to dim other parts of the screen.

Hacky experiment above:

static void _ShowDemoCallbackButton(int line_number, const char* demo_title, bool before_widgets)
{
    struct Marker
    {
        ImVec2 Min;
        ImVec2 Max;
        ImVec2 ClipMin;
        ImVec2 ClipMax;
        char   Desc[256];
    };

    static Marker marker;

    ImVec2 curr_pos = ImGui::GetCursorScreenPos();

    // Display previous marker
    marker.Max.x = ImGui::GetWindowPos().x + ImGui::GetContentRegionMax().x;
    marker.Max.y = curr_pos.y;
    ImGui::GetForegroundDrawList()->AddRect(marker.Min, marker.Max, IM_COL32(255, 255, 0, 255));
    ImGui::GetForegroundDrawList()->AddText(marker.Min, IM_COL32(255, 255, 0, 255), marker.Desc);

    // Register new marker
    marker.Min = marker.Max = curr_pos;
    marker.ClipMin = ImGui::GetWindowDrawList()->GetClipRectMin();
    marker.ClipMax = ImGui::GetWindowDrawList()->GetClipRectMin();
    strncpy(marker.Desc, demo_title, IM_ARRAYSIZE(marker.Desc));
    marker.Desc[IM_ARRAYSIZE(marker.Desc) - 1] = 0;
}

@pthom
Copy link
Contributor Author

pthom commented Jan 12, 2021

Thanks a lot for your answers and suggestions Omar. I will have look at them and come back to you in a few days.

@pthom
Copy link
Contributor Author

pthom commented Jan 22, 2021

Hello Omar,

Many thanks for your suggestions. I added some more commits, and I think we are onto something interesting!
If you are in hurry, just look at the demo just below, and read the details later.

Demo


Details

Possible use of the DEMO_MARKER outside of imgui manual:

You wrote:

One good aspect of this is that we could later aim to implement a basic dependency-free version of your solution in imgui_demo., probably less polished, with less fancy text editor.

Well, my opinion is that the DEMO_MARKER macro can also be useful inside imgui even without the manual, and even without a side editor, since the tooltip show the exact location of the corresponding code in imgui_demo.cpp:
image

Only show code button if zone is hovered

As you can see, only one "Code" button is shown at a time. This is much less ugly.
This button is only shown if the mouse is inside the window, and it is hovering the demo ZoneBoundings.

In order to do this, I iterated on your "markers" idea, and I added a class DemoZonesRegistry, which can be summarized as below:

class DemoZonesRegistry
{
private:
    struct ZoneBoundings
    {
        int SourceLineNumber; // Source code location
        float MinY, MaxY;     // Location of this zone inside its parent window
    };
public:
    DemoZonesRegistry();
    bool DemoZone(int line_number);  // starts a demo zone, and returns true if the button shall be shown
private:
    ImVector<ZoneBoundings> AllZonesBoundings; // Holds all demo zone boundings
}

DemoCode -> DEMO_MARKER

The macro is now in upper case. Also I reviewed all the calls to this macro in order to make them more coherent.

We now have two macros:

  • DEMO_MARKER will put the button to the right of the next widget
  • DEMO_MARKER_BLANK_LINE will put the button to the right of a blank line

Most calls (>95%) are now using DEMO_MARKER. The only cases where there is a blank line are:

  • inside menus (because there might be a check or submenu to the right of the next widget)
  • immediately after ImGui::Begin() calls

Misc

  • added FILE in the macros to potentially allow this to be used in other code
  • Removed hard-coded size constraints
  • Corrected positioning glitches
  • Improved for cases where there is no space: the code button will not appear when there is not enough space to the right

@pthom
Copy link
Contributor Author

pthom commented Jan 22, 2021

@pthom
Copy link
Contributor Author

pthom commented Jan 23, 2021

I added a param hovering_zone_onlyto the callback, so that the GUI can react to the user only hovering a given zone, like so:

typedef void (*ImGuiDemoCallback)(const char* file, int line_number, const char* demo_title, bool hovering_zone_only);

I you now look at the manual, you will see that the TOC on the right now follows the mouse position in the demo (if "Follow Demo" is checked).

@pthom
Copy link
Contributor Author

pthom commented Jan 24, 2021

And then, we could suppress the code button and use the "Ctrl-Shift" modifier to display a tooltip, that would work even outside the manual.

See below:

image

(However, note that if no indication is shown in the demo itself, the user might not now whether there is an actual DEMO_MARKER tag for the widget he is looking at).


There could also be an alternative way to show them :
image


I did not yet push a change that suppresses the code button, or one that uses the "{?}", as I prefer to wait for your opinion

@ocornut
Copy link
Owner

ocornut commented Jan 25, 2021

Well, my opinion is that the DEMO_MARKER macro can also be useful inside imgui even without the manual, and even without a side editor, since the tooltip show the exact location of the corresponding code in imgui_demo.cpp:

This is a really good point! Makes this even more attractive to merge in existing demo even without a text editor in demo.

  • If I try your demo, the demo marker seems to be stealing inputs while grabbing a dock node separator.
  • The visible overlap when resizing a window small is a little ugly
  • The discrepancy between the fact this is checking entire zones, not widgets, can be confusing when hovering around. So when you hover to the right-side of a tree-node, the tree-node don't react but the help marker changes...

The last paragraph of my previous feedback post suggested flipping things around and have a modal "Help" tool to avoid those issues, I should have been clearer about that. Say you have 1 "Help/Code Lookup" button in a window, when activated it would: hold on active id (which prevent hovering other stuff, to reduce noise) + and highlight the zone by e.g. dimming the rest of the screen using 8 transparent rectangle + display tooltip and maybe clicking activate the callback action if any. It's using the exact same underlying data but picking is explicit and modal and because of that the interactions can be designed differently.

@ocornut
Copy link
Owner

ocornut commented Jan 25, 2021

Addendum: it's not 100% ideal because it requires activation from the user, and a button needs to be placed in more location (especially menus/popups), but might provide a better user experience ihmo.

@pthom
Copy link
Contributor Author

pthom commented Jan 25, 2021

I did some experiments; and I would like to explore a bit further with you concerning the different possibilities.

Say you have 1 "Help/Code Lookup" button in a window, when activated it would hold on active id (which prevent hovering other stuff, to reduce noise)

I'm not sure I understood your idea, since the active id would be deduced from the zone hovered by the mouse;
and this id would be lost as soon as we move the mouse to the button.

May be a combination of two keyboard shortcuts (activate highlighting for the current zone / deactivate highlighting) could work, but I'm afraid it would not be user friendly. So, I guess I did not understand your idea.

  • highlight the zone by e.g. dimming the rest of the screen using 8 transparent rectangle

I tried this, and I'm afraid that the discrepancy you noted ("this is checking entire zones, not widgets and can be confusing")
might get even worse.


Anyhow, I did a video since it is a lot easier to explain with live demonstrations.
It is 2 minutes long, and it explores 4 different possibilities:

  • No indication whatsoever
  • Demo Label {?} with tooltip
  • Global keyboard shortcut (e.g Ctrl-Shift)
  • Highlight with or without tooltip as a global option (I could not find a way to implement your "modal idea")

Can you have a look at it ( https://traineq.org/imgui_demo_alternatives.mp4 ) and tell me what you think?

Thanks!

@ocornut
Copy link
Owner

ocornut commented Jan 26, 2021

Thanks for the detailed video and investigating those ideas further.

Have a look at Tools > Metrics/Debugger > Tools > Item Picker for the type of interaction I was thinking.
It could be bound on a button called e.g. "Code Picker.." and also bound on a keyboard shortcut. Maybe that button can be on a floating window which you can enable in the demo, and then once you enable this floating window it's always visible.

The tool modal in the sense that once you enable it, it stays open until clicking or pressing space.

When the tool activated, if if make it steals the active id using SetActiveID(GetID("code picker")) unless clicked or escaped, then items in the window won't react to hovering or clicking, which seems desirable. This also helps focusing on the fact that we are targeting rectangular zones, not specific items (e.g. not a tree node). The only problem is that SetActiveID() is not a public API but we can find a way to solve this (for now ok to test with imgui_internal.h. As a super quick hack, if you use ButtonEx()withImGuiButtonFlags_PressedOnClickReleaseAnywhere` it will steal the active id but the interaction will require holding mouse button, and dragging to target zone (whereas we want the interaction to be "click once to activate tool", "click on zone"). But that's simpler to try very quickly. (Btw while writing this I noticed that "Item Picker" doesn't use that, I think it should).

For the dimming overlay, if you use GetForegroundDrawList() instead of GetWindowDrawList() you can cover the whole screen, may be nicer if the overlay is subtle (but probably not ok if code panel update while just moving mouse). Or maybe we can display all zones at all time with a subtle color (and then use the window drawlist) and display the hovered one more prominently. I think it is ok to put an emphases on zone especially if clicking item is disabled.

@pthom
Copy link
Contributor Author

pthom commented Jan 28, 2021

Hello Omar,

A quick update on the status.
As there are quite some details, I made a video that tries to summarize them :

https://traineq.org/imgui_demo_edit.mp4 (ignore the part about SetActiveID(), I have solved the issue)

Below is an abstract of the video:


Simple fixes:

  • No more button: I completely removed the code button that were appearing on the right
  • Dim full viewport: the full screen/viewport is now dimmed

Work inside imgui_demo with a code editor/viewer:

I would like to preview what a code editor might render on the demo itself; so I added a quick and dirty code viewer inside imgui_demo.cpp. Consider it as a draft that can be removed or disabled later, if you wish.

Note: as there is no way to embed resources inside the build; this code window will read the code via a simple call to fopen(__FILE__, "r"). I know, this is dirty; however if the file is not found after deployment, it will handle this gracefully.

Decide between several ways to pinpoint a demo code location

As of now, there are several ways to pinpoint the code location:

  • using the "Ctrl-Shift" hotkey
  • using the "Help/Code Lookup" picker button with SetActiveID
  • using the "Help/Code Lookup" picker button without SetActiveID + right-click to stop picking (see video in the next comment)
  • using the follow mode

The problem is that these modes are sometimes inconsistent. Your opinion will greatly interest me.

Issue with SetActiveID

I had an issue, which I solved using the following flag: ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)

Note: when using the existing "Metrics/Item Picker" , items are still updated when hovered on my side.


Note concerning the CI / build mode "without C++ runtime": are delete operator forbidden in the CI ?

The CI was failing on my code in the mode "without C++ runtime with an error that says
"Undefined symbol operator delete(void*, std::align_val_t)"
See for example:
https://github.com/ocornut/imgui/pull/3689/checks?check_run_id=1787291104

I "corrected" the CI by removing the destructor of DemoMarkersCodeWindow; but there is now a leak.

It seems strange, since for example ExampleAppConsole does have a destructor.

@pthom
Copy link
Contributor Author

pthom commented Jan 29, 2021

Another idea concerning the "Help/Code Lookup" button: instead of grabbing the ActiveID, it could let the user navigate the trees and menus, and require the user to right click to exit the picking mode. IMHO, this is quite usable.

See a demo here: http://traineq.org/imgui_demo_edit2.mp4

@ocornut
Copy link
Owner

ocornut commented Feb 1, 2021

Thank you, will look at the update whenever I have time.

Use IM_NEW/IM_DELETE to fix your allocation problem.

(As a minor suggestion, The PR has 58 commits it may be good to squash it in 1 or a few "milestones" commits e.g. 3-4)

@pthom
Copy link
Contributor Author

pthom commented Feb 1, 2021

Thanks for the suggestion about IM_DELETE.

I squashed all the commits into one, and added some documentation.

@pthom
Copy link
Contributor Author

pthom commented Feb 22, 2021

Hello Omar,

I squashed & rebased the code onto the latest commit of the docking branch.

I know that you are extremely busy, so take your time and review this whenever you want.

There are two decisions that still need to be made, but I tried to make it easier to decide by providing two temporary flags (that can easily be removed once the decisions are made).

If you look at imgui_demo.cpp, line 179 you will see the flags: DEMOMARKER_RIGHTCLICK and DEMOMARKER_SHOWCODEWINDOW.

These flags correspond to the following choices:

  • shall the "Help/Code Lookup" mode be exited via a right click, or shall it "grab the active id" ?
  • shall we keep with the basic imgui_demo.cpp code viewer that I added?

Concerning the right click, my opinion is that it is more usable (see previous video here: http://traineq.org/imgui_demo_edit2.mp4); so I enabled it in the defaults flag config.

@pthom
Copy link
Contributor Author

pthom commented Feb 24, 2021

Hello,

I did some more work on the manual inside imgui_demo.cpp.

Note: I added two new commits to this PR: one that embeds imgui_demo.cpp into the emscripten builds and one that adds a DemoMarkerTools namespace

However, I would need some additional input in order to be able to continue.
In order to make the decisions easy, this message will provide interactive links to demonstrations that showcase the different possibilities.

  1. Question 1: Do we want to grab the active ID when clicking the "Help/Code lookup" button.

    In that case, tree and menus cannot be opened. The user is forced to open them before using this button.
    IMHO, this is not very usable.

    Interactive demo here: Left click / No Code Viewer

  2. Question 2: Do we prefer to not grab the active ID when clicking the "Help/Code lookup" button and require the user to right-click

    IMHO, this is more usable, since the user can then navigate to wherever he wants (even inside menus), and see the corresponding code location.

    Interactive demo here: Right click / No code viewer

  3. Question 3: Do we want to include a low tech code viewer?

    imgui_demo.cpp can provide a basic CodeViewer that would read the code via a simple call to fopen(__FILE__, "r")

    This way, it is possible to display the corresponding code when using the "Help/Code Lookup" button.
    Of course, this will work only if the imgui_demo.cpp is still available at the same location as when compiling.

    Interactive demo here: Right Click / Code viewer

    But, as the demo shows, this could also work with emscripten: this commit enable to embed imgui_demo.cpp code into emscripten, like this:

    source ./emsdk_env.sh
    USE_FILE_SYSTEM=1 make -C examples/example_emscripten_opengl3
    make -C examples/example_emscripten_opengl3 serve
  1. Question 4: Do we want to include more functionality in this code viewer? Search and link to github?

    This can provide a more pleasant experience.

    Interactive demo here: Right click / Code Viewer with Search & github button

Below is a screenshot that shows the code viewer + search + github button:
image

However, things then get a little more complex, since this requires to add some more code to imgui_demo.cpp (mosty in order to parse the tags and to open the hyperlinks).

I did not include those modifications (i.e related to Question 4) into the original DemoCode branch (which is the subject of this PR), but I added them into a new branch (named DemoCodeSearch).
This adds mainly two commits:

  • Parsing
    (this commit parses imgui_demo.cpp's DEMO_MARKER tags, and adds a search filter)
  • BrowseToUrl
    (this commit adds a BrowseToUrl() function and thus requires some platform dependent calls)

@pthom
Copy link
Contributor Author

pthom commented Mar 21, 2021

Hello,

Just a quick update: I updated the code to solve the conflicts originating from the latest commits to the docking branch.

Also, in order to make the process easier for you, I put everything in this branch, and I took the decisions that, IMHO, were the most user friendly, i.e "use a right click", "include a code viewer", and provide a "Open Github" button.

So, we now have four commits, listed below in chronological order:

  • 872c7ab : imgui_demo.cpp: Add DEMO_MARKERS and DemoCodeWindow
  • 823765a : embed imgui_demo.cpp code into emscripten builds
  • d373f3f : imgui_demo.cpp/Code viewer: Parse DemoMarkers tags / add demo search
  • 8ccdea8 : imgui_demo.cpp: add BrowseToUrl (called from Code viewer)

Live demo here

@pthom
Copy link
Contributor Author

pthom commented Jan 7, 2023

@ocornut

Hello Omar, and happy new year!

I just released a new version of the online manual, it uses the new born v1.89.2.

https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html

You should see that font rendering is now much more crisp.

If you have a few minutes, you might take a look at a theme tweak utility I provide:

image

(available at https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/imgui_theme.h )

Cheers, and happy new year again!

pthom added 6 commits May 30, 2023 13:55
ImGuiDemoMarker_GuiToggle Display a "Code Lookup" checkbox that
toggles interactive code browsing
ImGuiDemoMarkerCallback_Default is the default callback
used by IMGUI_DEMO_MARKER, but this can be overriden via
GImGuiDemoMarkerCallback

ImGuiDemoMarkerHighlightZone() is able to graphically highlight
a *hovered* section of the demo (it keeps track of the graphical
location of each section).
ImGuiDemoMarkerCodeViewer is the external API which enables
to display a basic code viewer when hovering demos that
are marked with IMGUI_DEMO_MARKER.
This code viewer is also able to parse the IMGUI_DEMO_MARKERS calls
inside imgui_demo.cpp in order to also provide a searchable index.
Emscripten allows preloading a file or folder to be accessible at runtime.
Since the code viewer provided by ImGui::ShowDemoWindow() reads imgui_demo.cpp,
we embed it in the build.

In order to build the emscripten example and see the code viewer, run:

    USE_FILE_SYSTEM=1 make -C examples/example_emscripten_opengl3
    make -C examples/example_emscripten_opengl3 serve

Then, browse to http://localhost:8000
BrowseToUrl() is a platform dependent utility to open an url in a browser.
@pthom
Copy link
Contributor Author

pthom commented May 30, 2023

Bonjour Omar,

I just updated the online demo to use v1.89.6 WIP. No pressure, this is just FYI ;-)

@pthom pthom force-pushed the DemoCode branch 7 times, most recently from 72dc90e to 9b0d77a Compare December 6, 2023 09:30
Can be used to set the demo window position from an external file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants