Stretching myself thin with Dear ImGui projects
Published: 2023-11-28 04:47:12

### 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:
1. They use a build system like [CMake](https://cmake.org/)
2. They use a [Dear ImGui](https://github.com/ocornut/imgui), a C++ GUI library.

In a couple contributions I've made, I had the opportunity to work with Dear ImGui, such as [refactoring](https://dev.to/rjwignar/delving-deeper-in-a-project-1-more-refactoring-with-git-grep-g1) and [debugging](https://dev.to/rjwignar/hacktoberfest-2-primedkeys-imgui-bugfix-3d2p). 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](https://github.com/OpenTimelineIO/raven), timeline viewer for the [OpenTimelineIO project](https://github.com/OpenTimelineIO). 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.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ixm82pc8p7h9fgnc87k.png)

The `enabled` flag would control a mute/unmute toggle for audio clips, and a hide/show toggle for video clips. My [task](https://github.com/OpenTimelineIO/raven/issues/19) 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](https://github.com/OpenTimelineIO/raven#building-macos-windows-linux) 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. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfngcujz9tuglqyuqhfu.png)

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:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/alyxeikkntbeean23t0t.png)

As well, I've added an "Enabled" checkbox toggle using the `ImGui::Checkbox()` method:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ntkb6sywg92wouzwq8yo.png)


### GUI programming is challenging
If you look at my [Pull Request](https://github.com/OpenTimelineIO/raven/pull/27), 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:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cihavfac5x8mq68p3v9w.png)

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:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/95l9dt6686ga8u9wwh0n.png)

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.