diff --git a/src/DialogToolkit.cpp b/src/DialogToolkit.cpp index 4db508b..97db138 100644 --- a/src/DialogToolkit.cpp +++ b/src/DialogToolkit.cpp @@ -559,7 +559,6 @@ std::list selectImagesFileDialog(const std::string &label,const std // Set the default path gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), startpath.c_str() ); - // ensure front and centered gtk_window_set_keep_above( GTK_WINDOW(dialog), TRUE ); if (window_x > 0 && window_y > 0) @@ -622,3 +621,91 @@ void DialogToolkit::ErrorDialog(const char* message) } +// +// Color Picker Dialog common functions +// + +bool DialogToolkit::ColorPickerDialog::busy_ = false; + +DialogToolkit::ColorPickerDialog::ColorPickerDialog() +{ + rgb_ = std::make_tuple(0.f, 0.f, 0.f); +} + +bool DialogToolkit::ColorPickerDialog::closed() +{ + if ( !promises_.empty() ) { + // check that file dialog thread finished + if (promises_.back().wait_for(timeout) == std::future_status::ready ) { + // get the filename from this file dialog + rgb_ = promises_.back().get(); + // done with this file dialog + promises_.pop_back(); + busy_ = false; + return true; + } + } + return false; +} + +std::tuple openColorDialog( std::tuple rgb) +{ + // default return value to given value (so Cancel does nothing) + std::tuple ret = rgb; + +#if USE_TINYFILEDIALOG + +// TODO +// char rgb[3]; +// c_str hexColor = tinyfd_colorChooser("Choose or pick a color", "#FF0077", rgb, rgb); +// if (hexColor) { +// } + +#else + if (!gtk_init()) { + return ret; + } + + GtkWidget *dialog = gtk_color_chooser_dialog_new( "Choose or pick a color", NULL); + + // set initial color + GdkRGBA color; + color.red = std::get<0>(rgb); + color.green = std::get<1>(rgb); + color.blue = std::get<2>(rgb); + color.alpha = 1.f; + gtk_color_chooser_set_rgba( GTK_COLOR_CHOOSER(dialog), &color ); + + // prepare dialog + gtk_window_set_keep_above( GTK_WINDOW(dialog), TRUE ); + static int x = 0, y = 0; + if (x != 0) + gtk_window_move( GTK_WINDOW(dialog), x, y); + + // display and get color + if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_OK ) { + + gtk_color_chooser_get_rgba( GTK_COLOR_CHOOSER(dialog), &color ); + ret = { color.red, color.green, color.blue}; + } + + // remember position + gtk_window_get_position( GTK_WINDOW(dialog), &x, &y); + + // done + gtk_widget_destroy( dialog ); + wait_for_event(); + +#endif + + return ret; +} + +void DialogToolkit::ColorPickerDialog::open() +{ + if ( !busy_ && promises_.empty() ) { + promises_.emplace_back( std::async(std::launch::async, openColorDialog, rgb_) ); + busy_ = true; + } +} + diff --git a/src/DialogToolkit.h b/src/DialogToolkit.h index 659c1ba..22b6cc8 100644 --- a/src/DialogToolkit.h +++ b/src/DialogToolkit.h @@ -77,6 +77,27 @@ public: inline std::list images() const { return pathlist_; } }; + +class ColorPickerDialog +{ +protected: + std::tuple rgb_; + std::vector< std::future< std::tuple > > promises_; + static bool busy_; + +public: + ColorPickerDialog(); + + void open(); + bool closed(); + + inline void setRGB(std::tuple rgb) { rgb_ = rgb; } + inline std::tuple RGB() const { return rgb_; } + + static bool busy() { return busy_; } +}; + + } diff --git a/src/ImGuiVisitor.cpp b/src/ImGuiVisitor.cpp index b708995..80bda99 100644 --- a/src/ImGuiVisitor.cpp +++ b/src/ImGuiVisitor.cpp @@ -29,13 +29,11 @@ #include #include -#include "tinyxml2Toolkit.h" #include "imgui.h" #include "imgui_internal.h" #include "defines.h" -#include "Log.h" #include "Scene.h" #include "Primitives.h" #include "ImageShader.h" @@ -983,26 +981,31 @@ void ImGuiVisitor::visit (AlphaFilter& f) } if ( m == AlphaFilter::ALPHA_CHROMAKEY || m == AlphaFilter::ALPHA_FILL) - { - glm::vec4 color = glm::vec4(filter_parameters["Red"], filter_parameters["Green"], filter_parameters["Blue"], 1.f); - if (ImGuiToolkit::IconButton(13, 14)) { - color = glm::vec4(0.f, 0.8f, 0.f, 1.f); - f.setProgramParameter("Red", color.r); - f.setProgramParameter("Green", color.g); - f.setProgramParameter("Blue", color.b); - } + { + static DialogToolkit::ColorPickerDialog colordialog; + + // read color from filter + ImVec4 color = ImVec4(filter_parameters["Red"], filter_parameters["Green"], filter_parameters["Blue"], 1.f); + + // show color + ImGui::ColorButton("##colorchromakey", *(ImVec4*)&color ); + + // offer to pick color ImGui::SameLine(0, IMGUI_SAME_LINE); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - if ( ImGui::ColorEdit3("Color", glm::value_ptr(color), ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoOptions) ) - { - f.setProgramParameter("Red", color.r); - f.setProgramParameter("Green", color.g); - f.setProgramParameter("Blue", color.b); + if ( ImGui::Button( ICON_FA_EYE_DROPPER " Pick", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ){ + colordialog.setRGB( std::make_tuple(color.x, color.y, color.z) ); + colordialog.open(); } - if (ImGui::IsItemDeactivatedAfterEdit()) { - oss << AlphaFilter::operation_label[ f.operation() ]; - oss << " : " << "Color" << " " << color.r << " " << color.g << " " << color.b; - Action::manager().store(oss.str()); + ImGui::SameLine(0, IMGUI_SAME_LINE); + ImGui::Text("Color"); + + // get picked color if dialog finished + if (colordialog.closed()){ + std::tuple c = colordialog.RGB(); + f.setProgramParameter("Red", std::get<0>(c)); + f.setProgramParameter("Green", std::get<1>(c)); + f.setProgramParameter("Blue", std::get<2>(c)); } } diff --git a/src/UserInterfaceManager.cpp b/src/UserInterfaceManager.cpp index 575e0c3..e13b260 100644 --- a/src/UserInterfaceManager.cpp +++ b/src/UserInterfaceManager.cpp @@ -715,7 +715,7 @@ bool UserInterface::saveOrSaveAs(bool force_versioning) bool UserInterface::TryClose() { // cannot close if a file dialog is pending - if (DialogToolkit::FileDialog::busy()) + if (DialogToolkit::FileDialog::busy() || DialogToolkit::ColorPickerDialog::busy()) return false; // always stop all recordings