Skip to content

mfkiwl/imgui_gradient

 
 

Repository files navigation

imgui_gradient

Dear ImGui extension that adds a gradient widget.

Animation

Table of Contents

Compatibility

This library is tested and compiles with C++11 on:

  • Windows
    • Clang
    • MSVC
  • Linux
    • Clang
    • GCC
  • MacOS
    • Clang

Basic usage

The whole state of the widget is stored in a ImGG::GradientWidget variable. You need to create and store one in order to have access to a gradient. You can then use the widget() method to render the ImGui widget:

ImGG::GradientWidget gradient_widget{};
gradient_widget.widget("My Gradient");

In order to access the gradient data (without the GUI state), you can get the ImGG::Gradient with gradient_widget.gradient().

Tutorial

Including

To add this library to your project, simply add these three lines to your CMakeLists.txt and replace folder/containing/imgui with the path to the parent folder containing imgui:

add_subdirectory(path/to/imgui_gradient)
target_include_directories(imgui_gradient PRIVATE folder/containing/imgui)
target_link_libraries(${PROJECT_NAME} PRIVATE imgui_gradient::imgui_gradient)

Then include it as:

#include <imgui_gradient/imgui_gradient.hpp>

Sampling the gradient

const ColorRGBA color = widget.gradient().at({0.5f});

Note that you should use values between 0.f and 1.f when sampling the gradient. If you know you are gonna use values outside that range, specify a WrapMode to indicate how the values should be mapped back to the [0, 1] range:

const ColorRGBA color = widget.gradient().at({0.5f, WrapMode::Clamp});

Our wrap modes mimic the OpenGL ones:

  • ImGG::WrapMode::Clamp: If the value is bigger than 1, maps it to 1. If it smaller than 0, maps it to 0.
  • ImGG::WrapMode::Repeat: Maps the number line to a bunch of copies of [0, 1] stuck together. Conceptually equivalent to adding or subtracting 1 to the position until it is in the [0, 1] range.
  • ImGG::WrapMode::MirrorRepeat: Like ImGG::WrapMode::Repeat except that every other range is flipped.

To create a widget for the wrap mode, you can use:

ImGG::wrap_mode_widget("Wrap Mode", &wrap_mode);

Interpolation

Controls how the colors are interpolated between two marks.

  • ImGG::Interpolation::Linear: Linear interpolation.
  • ImGG::Interpolation::Constant: Constant color between two marks (uses the color of the mark on the right).

To create a widget that changes the interpolation mode, use:

ImGG::interpolation_mode_widget("Interpolation Mode", &widget.gradient().interpolation_mode());

Settings

The ImGG::GradientWidget::widget() method can also take settings that control its behaviour:

ImGG::Settings settings{};

settings.gradient_width = 500.f;
settings.gradient_height = 40.f;
settings.horizontal_margin = 10.f;

/// Distance under the gradient bar to delete a mark by dragging it down.
/// This behaviour can also be disabled with the Flag::NoDragDowntoDelete.
settings.distance_to_delete_mark_by_dragging_down = 80.f;

settings.flags = ImGG::Flag::None;

settings.color_edit_flags = ImGuiColorEditFlags_None;

/// Controls how the new mark color is chosen.
/// If true, the new mark color will be a random color,
/// otherwise it will be the one that the gradient already has at the new mark position.
settings.should_use_a_random_color_for_the_new_marks = false;

gradient_widget.widget("My Gradient", settings);

Here are all the available flags:

  • ImGG::Flag::None: All options are enabled.
  • ImGG::Flag::NoTooltip: No tooltip when hovering a widget.
  • ImGG::Flag::NoResetButton: No button to reset the gradient to its default value.
  • ImGG::Flag::NoLabel: No name for the widget.
  • ImGG::Flag::NoAddButton: No "+" button to add a mark.
  • ImGG::Flag::NoRemoveButton: No "-" button to remove a mark.
  • ImGG::Flag::NoPositionSlider: No slider widget to chose a precise position for the selected mark.
  • ImGG::Flag::NoColorEdit: No color edit widget for the selected mark.
  • ImGG::Flag::NoDragDownToDelete: Don't delete a mark when dragging it down.
  • ImGG::Flag::NoBorder: No border around the gradient widget.
  • ImGG::Flag::NoAddAndRemoveButtons: No "+" and "-" buttons.
  • ImGG::Flag::NoMarkOptions: No widgets for the selected mark.

Color randomization

Settings::should_use_a_random_color_for_the_new_marks allows you to randomize the colors of the marks. To create a widget for that setting you can use:

ImGG::random_mode_widget("Use a random color for the new marks", &settings.should_use_a_random_color_for_the_new_marks);

By default we use our own internal std::default_random_engine, but you can provide your own rng function that we will use instead. It can be any function that returns a number between 0.f and 1.f.

const auto your_custom_rng = []() {
    static auto rng          = std::default_random_engine{std::random_device{}()};
    static auto distribution = std::uniform_real_distribution<float>{0.f, 1.f};
    return distribution(rng);
};
gradient_widget.widget("My Gradient", your_custom_rng, settings);

NB: If all calls to gradient_widget.widget(...) provide a rng function, we will not create our std::default_random_engine at all.

For maintainers

Running the tests

Simply use "tests/CMakeLists.txt" to generate a project, then run it.
If you are using VSCode and the CMake extension, this project already contains a .vscode/settings.json that will use the right CMakeLists.txt automatically.

About

Dear ImGui extension that adds a gradient widget

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • C++ 93.7%
  • CMake 4.2%
  • Python 2.1%