mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-14 11:49:59 +01:00
BugFix Color dialog ends properly
Changed multithreading mechanism to use color value from color dialog, avoiding to rely on the testing of future value.
This commit is contained in:
@@ -591,33 +591,18 @@ void DialogToolkit::ErrorDialog(const char* message)
|
||||
// Color Picker Dialog common functions
|
||||
//
|
||||
|
||||
bool DialogToolkit::ColorPickerDialog::busy_ = false;
|
||||
|
||||
DialogToolkit::ColorPickerDialog::ColorPickerDialog()
|
||||
DialogToolkit::ColorPickerDialog::ColorPickerDialog(): busy_(false)
|
||||
{
|
||||
rgb_ = std::make_tuple(0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
bool DialogToolkit::ColorPickerDialog::closed()
|
||||
void DialogToolkit::ColorPickerDialog::openColorDialog( std::function<void (std::tuple<float, float, float>)> func )
|
||||
{
|
||||
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;
|
||||
}
|
||||
DialogToolkit::ColorPickerDialog::instance().busy_ = true;
|
||||
|
||||
std::tuple<float, float, float> openColorDialog( std::tuple<float, float, float> rgb)
|
||||
{
|
||||
// default return value to given value (so Cancel does nothing)
|
||||
std::tuple<float, float, float> ret = rgb;
|
||||
bool changed = false;
|
||||
std::tuple<float, float, float> rgb = DialogToolkit::ColorPickerDialog::instance().RGB();
|
||||
|
||||
#if USE_TINYFILEDIALOG
|
||||
|
||||
@@ -631,11 +616,12 @@ std::tuple<float, float, float> openColorDialog( std::tuple<float, float, float>
|
||||
if ( NULL != tinyfd_colorChooser("Choose or pick a color", NULL, prev_color, ret_color) )
|
||||
{
|
||||
ret = { (float) ret_color[0] / 255.f, (float) ret_color[1] / 255.f, (float) ret_color[2] / 255.f};
|
||||
changed = true;
|
||||
}
|
||||
|
||||
#else
|
||||
if (!gtk_init()) {
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
GtkWidget *dialog = gtk_color_chooser_dialog_new( "Choose or pick a color", NULL);
|
||||
@@ -662,7 +648,8 @@ std::tuple<float, float, float> openColorDialog( std::tuple<float, float, float>
|
||||
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};
|
||||
rgb = { color.red, color.green, color.blue};
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// remember position
|
||||
@@ -674,14 +661,16 @@ std::tuple<float, float, float> openColorDialog( std::tuple<float, float, float>
|
||||
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
// call the function with the selected color
|
||||
if (changed)
|
||||
func(rgb);
|
||||
|
||||
DialogToolkit::ColorPickerDialog::instance().busy_ = false;
|
||||
}
|
||||
|
||||
void DialogToolkit::ColorPickerDialog::open()
|
||||
void DialogToolkit::ColorPickerDialog::open(std::function<void(std::tuple<float, float, float>)> func)
|
||||
{
|
||||
if ( !DialogToolkit::ColorPickerDialog::busy_ && promises_.empty() ) {
|
||||
promises_.emplace_back( std::async(std::launch::async, openColorDialog, rgb_) );
|
||||
busy_ = true;
|
||||
}
|
||||
if (!busy_)
|
||||
// launch thread to get color from dialog
|
||||
std::thread( openColorDialog, func ).detach();
|
||||
}
|
||||
|
||||
|
||||
@@ -98,19 +98,30 @@ class ColorPickerDialog
|
||||
{
|
||||
protected:
|
||||
std::tuple<float, float, float> rgb_;
|
||||
std::vector< std::future< std::tuple<float, float, float> > > promises_;
|
||||
static bool busy_;
|
||||
std::atomic<bool> busy_;
|
||||
|
||||
// private function to open dialog
|
||||
static void openColorDialog( std::function<void(std::tuple<float, float, float>)> func);
|
||||
|
||||
// Private Constructor
|
||||
ColorPickerDialog();
|
||||
ColorPickerDialog(ColorPickerDialog const& copy) = delete;
|
||||
ColorPickerDialog& operator=(ColorPickerDialog const& copy) = delete;
|
||||
|
||||
public:
|
||||
ColorPickerDialog();
|
||||
|
||||
void open();
|
||||
bool closed();
|
||||
static ColorPickerDialog& instance()
|
||||
{
|
||||
// The only instance
|
||||
static ColorPickerDialog _instance;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void open( std::function<void(std::tuple<float, float, float>)> func);
|
||||
|
||||
inline bool busy() { return busy_; }
|
||||
inline void setRGB(std::tuple<float, float, float> rgb) { rgb_ = rgb; }
|
||||
inline std::tuple<float, float, float> RGB() const { return rgb_; }
|
||||
|
||||
static bool busy() { return busy_; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -424,9 +424,6 @@ void DisplaysView::adaptGridToWindow(int w)
|
||||
|
||||
void DisplaysView::draw()
|
||||
{
|
||||
// White ballance color button
|
||||
static DialogToolkit::ColorPickerDialog whitebalancedialog;
|
||||
|
||||
// draw all windows
|
||||
int i = 0;
|
||||
for (; i < Settings::application.num_output_windows; ++i) {
|
||||
@@ -626,14 +623,24 @@ void DisplaysView::draw()
|
||||
Settings::application.windows[1+current_window_].whitebalance.y,
|
||||
Settings::application.windows[1+current_window_].whitebalance.z, 1.f),
|
||||
ImGuiColorEditFlags_NoAlpha)) {
|
||||
if ( DialogToolkit::ColorPickerDialog::busy()) {
|
||||
if ( DialogToolkit::ColorPickerDialog::instance().busy()) {
|
||||
Log::Warning("Close previously openned color picker.");
|
||||
}
|
||||
else {
|
||||
whitebalancedialog.setRGB( std::make_tuple(Settings::application.windows[1+current_window_].whitebalance.x,
|
||||
// prepare the color picker to start with white balance color
|
||||
DialogToolkit::ColorPickerDialog::instance().setRGB( std::make_tuple(Settings::application.windows[1+current_window_].whitebalance.x,
|
||||
Settings::application.windows[1+current_window_].whitebalance.y,
|
||||
Settings::application.windows[1+current_window_].whitebalance.z) );
|
||||
whitebalancedialog.open();
|
||||
// declare function to be called
|
||||
int w = 1+current_window_;
|
||||
auto applyColor = [w](std::tuple<float, float, float> c) {
|
||||
Settings::application.windows[w].whitebalance.x = std::get<0>(c);
|
||||
Settings::application.windows[w].whitebalance.y = std::get<1>(c);
|
||||
Settings::application.windows[w].whitebalance.z = std::get<2>(c);
|
||||
};
|
||||
|
||||
// open dialog (starts a thread that will call the 'applyColor' function
|
||||
DialogToolkit::ColorPickerDialog::instance().open( applyColor );
|
||||
}
|
||||
}
|
||||
ImGui::PopFont();
|
||||
@@ -700,14 +707,6 @@ void DisplaysView::draw()
|
||||
}
|
||||
ImGui::PopFont();
|
||||
|
||||
// get picked color if dialog finished
|
||||
if (whitebalancedialog.closed()){
|
||||
std::tuple<float, float, float> c = whitebalancedialog.RGB();
|
||||
Settings::application.windows[1+current_window_].whitebalance.x = std::get<0>(c);
|
||||
Settings::application.windows[1+current_window_].whitebalance.y = std::get<1>(c);
|
||||
Settings::application.windows[1+current_window_].whitebalance.z = std::get<2>(c);
|
||||
}
|
||||
|
||||
// display popup menu
|
||||
if (show_window_menu_ && current_window_ > -1) {
|
||||
ImGui::OpenPopup( "DisplaysOutputContextMenu" );
|
||||
|
||||
@@ -1203,8 +1203,6 @@ void ImGuiVisitor::visit (AlphaFilter& f)
|
||||
|
||||
if ( m == AlphaFilter::ALPHA_CHROMAKEY || m == AlphaFilter::ALPHA_FILL)
|
||||
{
|
||||
static DialogToolkit::ColorPickerDialog colordialog;
|
||||
|
||||
// read color from filter
|
||||
float color[3] = {filter_parameters["Red"], filter_parameters["Green"], filter_parameters["Blue"]};
|
||||
|
||||
@@ -1227,12 +1225,30 @@ void ImGuiVisitor::visit (AlphaFilter& f)
|
||||
ImGui::SameLine(0, IMGUI_SAME_LINE);
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
if ( ImGui::Button( ICON_FA_EYE_DROPPER " Open selector", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ){
|
||||
if ( DialogToolkit::ColorPickerDialog::busy()) {
|
||||
if ( DialogToolkit::ColorPickerDialog::instance().busy()) {
|
||||
Log::Warning("Close previously openned color picker.");
|
||||
}
|
||||
else {
|
||||
colordialog.setRGB( std::make_tuple(color[0], color[1], color[2]) );
|
||||
colordialog.open();
|
||||
// prepare the color picker to start with filter's color
|
||||
DialogToolkit::ColorPickerDialog::instance().setRGB( std::make_tuple(color[0], color[1], color[2]) );
|
||||
|
||||
// declare function to be called
|
||||
std::string msg = oss.str();
|
||||
auto applyColor = [&f, msg]( std::tuple<float, float, float> c) {
|
||||
f.setProgramParameter("Red", std::get<0>(c));
|
||||
f.setProgramParameter("Green", std::get<1>(c));
|
||||
f.setProgramParameter("Blue", std::get<2>(c));
|
||||
char buf[1024];
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "%scolor #%02X%02X%02X",
|
||||
msg.c_str(),
|
||||
ImClamp((int)ceil(255.f * std::get<0>(c)),0,255),
|
||||
ImClamp((int)ceil(255.f * std::get<1>(c)),0,255),
|
||||
ImClamp((int)ceil(255.f * std::get<2>(c)),0,255));
|
||||
Action::manager().store(buf);
|
||||
};
|
||||
|
||||
// open dialog (starts a thread that will callthe 'applyColor' function
|
||||
DialogToolkit::ColorPickerDialog::instance().open( applyColor );
|
||||
}
|
||||
}
|
||||
ImGui::SameLine(0, IMGUI_SAME_LINE);
|
||||
@@ -1244,18 +1260,6 @@ void ImGuiVisitor::visit (AlphaFilter& f)
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
|
||||
// get picked color if dialog finished
|
||||
if (colordialog.closed()){
|
||||
std::tuple<float, float, float> c = colordialog.RGB();
|
||||
f.setProgramParameter("Red", std::get<0>(c));
|
||||
f.setProgramParameter("Green", std::get<1>(c));
|
||||
f.setProgramParameter("Blue", std::get<2>(c));
|
||||
char buf[64];
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp((int)ceil(255.f * std::get<0>(c)),0,255),
|
||||
ImClamp((int)ceil(255.f * std::get<1>(c)),0,255), ImClamp((int)ceil(255.f * std::get<2>(c)),0,255));
|
||||
oss << " Color " << buf;
|
||||
Action::manager().store(oss.str());
|
||||
}
|
||||
}
|
||||
// Luminance extra parameter
|
||||
else {
|
||||
|
||||
@@ -790,7 +790,7 @@ bool UserInterface::saveOrSaveAs(bool force_versioning)
|
||||
bool UserInterface::TryClose()
|
||||
{
|
||||
// cannot close if a file dialog is pending
|
||||
if (DialogToolkit::FileDialog::busy() || DialogToolkit::ColorPickerDialog::busy())
|
||||
if (DialogToolkit::FileDialog::busy() || DialogToolkit::ColorPickerDialog::instance().busy())
|
||||
return false;
|
||||
|
||||
// always stop all recordings and pending actions
|
||||
@@ -902,7 +902,7 @@ void UserInterface::NewFrame()
|
||||
}
|
||||
|
||||
// overlay to ensure file color dialog is closed after use
|
||||
if (DialogToolkit::ColorPickerDialog::busy()){
|
||||
if (DialogToolkit::ColorPickerDialog::instance().busy()){
|
||||
if (!ImGui::IsPopupOpen("##ColorBusy"))
|
||||
ImGui::OpenPopup("##ColorBusy");
|
||||
if (ImGui::BeginPopup("##ColorBusy")) {
|
||||
|
||||
Reference in New Issue
Block a user