Dear ImGui is growing on me
In the past couple of months, I've been contributing to various projects for my Open Source class. C++ is the language I'm most comfortable with, and because of this, most of the projects I've contributed so far have been C++ projects. I've noticed a couple things in common with the C++ projects I've worked on:
- They use a build system like CMake
- They use a Dear ImGui, a C++ GUI library.
In a couple contributions I've made, I had the opportunity to work with Dear ImGui, such as refactoring and debugging. After these experiences, I wanted to challenge myself and try using Dear ImGui to add a feature to a project.
Raven, an Edit Decision List App
In my search for a Dear ImGui project, I found OpenTimelineIO/raven, timeline viewer for the OpenTimelineIO project. According to the OpenTimelineIO documentation, OpenTimelineIO is an interchange format for editorial cut information. These files have the .otio
extension. The project has a bunch of subprojects, like Raven, that support this format. I'm still getting familiar with all myself, but the Raven app reminds me of Garageband.
My task - Adding UI changes for disabled items.
Inside the Raven source code, there are objects like Clips (the green objects below) and Tracks the gray rectangles on the left-hand side) that have an enabled
flag used to toggle whether they are enabled or or disabled.
The enabled
flag would control a mute/unmute toggle for audio clips, and a hide/show toggle for video clips. My task is a feature request to add UI elements to support this feature:
- Color disabled Clips in a muted gray color to make its status obvious to users
- Add an "Enabled" checkbox that lets users modify a currently selected object's Enabled status.
There's also a stretch goal that would color entire disabled tracks with a ghosted/gray color.
My work
I took on this Issue as a way to get me more familiar with Dear ImGui. Previously I refactored and debugged ImGui code, but this time I have to add a new feature using Dear ImGui. The associated Issue pointed me in the right direction on where to look, so I knew where to start.
My first CMake build
Though past projects I've worked on have used CMake, I never had to build the project myself, as there was a GitHub Action that would build the project or my changes minor enough to not require building the project locally on my machine. This time would be different, so I installed CMake on my machine and followed Raven's README to install the project.
Building with CMake was a seamless process. Following the instructions built the development environment for me from scratch. In the past I didn't know much about C++ build systems. After using CMake for this Issue, I want to use it in my future C++ projects.
My first medium/large C++ codebase.
Opening the Visual Studio solution file CMake built for me showed me a large codebase. The solution file itself contains multiple projects, such as the Dear ImGui library, and other OpenTimelineIO subprojects.
This is the first large C++ codebase I've worked with (at least for my standards). Although the scope of my changes is restricted to the Raven project, I had to read through source code files in the other projects due to object inheritance. The Clip
and Track
classes for example, inherit from the Item
class, which contains the _enabled
variable I'm working with but is located in the opentimelineio
library. I had to do similar things to figure out how this project handles other features, such as coloring objects and checkboxes.
So far, I've been able to extend an Item rendering method, DrawItem()
, to color disabled items gray:
As well, I've added an "Enabled" checkbox toggle using the ImGui::Checkbox()
method:
GUI programming is challenging
If you look at my Pull Request, you'll see I've only added a few lines. Though my current changes appear small, I had to spend a lot of time to figure out the proper place to put these. In my experience, GUI programming can be a challenge, since there is code constantly running that renders the GUI. For example, if a checkbox is added in the wrong place in code, that checkbox may show up, but won't properly toggle a flag variable. Or if it does toggle a flag variable, the variable may re-toggle itself and the checkbox appears unchanged. As well, Gaps
are also their own class and, like Track
and Clip
inherit from the Item class:
Gaps never have to be disabled, so when making my changes I had to place the Checkbox such that it wouldn't appear for a Gap
.
Why do I have a Draft Pull Request?
My work isn't complete, due to how ImGui::Checkbox()
works. The prototype for this method is shown below:
The second formal parameter, the boolean pointer, is meant to be the flag variable that is toggled on/off by the checkbox. This is where the _enabled
flag variable should go. However, this is a private data member of the Item class (located in the opentimelineio project). The Item class has accessor methods, Item::enable()
and Item::set_enable()
, but after some experiment I wasn't able to use these methods to properly add a functioning checkbox.
Next plans
In my Draft Pull Request, I described my dilemma to the maintainers, and I plan to work with them to figure out another way. I'm hopeful that by working with them I'll learn something new about ImGui that I can share in the coming weeks.
Top comments (0)