]> git.tdb.fi Git - libs/gltk.git/commitdiff
Refactor Dialog to separate the autodeletion functionality
authorMikko Rasa <tdb@tdb.fi>
Mon, 21 Aug 2023 14:34:08 +0000 (17:34 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 21 Aug 2023 14:37:21 +0000 (17:37 +0300)
The base Dialog class now only hides itself, allowing reusable dialogs.
There's a new AutoDialog class which can be used to create autodeleting
dialogs, ensuring that they're allocated in the correct way.

source/dialog.cpp
source/dialog.h

index 9f9fc20d15388f69ece201db0105265ddae7c74e..5e5e390e7cadadf91d3e5af4e978d4e3f333dc33 100644 (file)
@@ -24,37 +24,11 @@ void Dialog::set_modal(bool m)
                signal_ungrab_pointer.emit();
 }
 
-void Dialog::button_release(int x, int y, unsigned button)
-{
-       Panel::button_release(x, y, button);
-       check_stale();
-}
-
-bool Dialog::key_release(unsigned key, unsigned mod)
-{
-       bool result = Panel::key_release(key, mod);
-       check_stale();
-       return result;
-}
-
-bool Dialog::navigate(Navigation nav)
-{
-       bool result = Panel::navigate(nav);
-       check_stale();
-       return result;
-}
-
 void Dialog::response(int code)
 {
        on_response(code);
        signal_response.emit(code);
-       stale = true;
-}
-
-void Dialog::check_stale()
-{
-       if(stale)
-               delete this;
+       set_visible(false);
 }
 
 
index 6f3556586939eeabf882a3661d8063d41dcd8d03..cc5ed41d1cfa6a4d967b376a71114ec6f8636b59 100644 (file)
@@ -11,7 +11,7 @@ class Button;
 
 /**
 A Dialog is used for temporary interaction with the user.  When any of the
-Dialog's action buttons are clicked, it will emit a signal and delete itself.
+Dialog's action buttons are clicked, it will emit a signal and hide itself.
 */
 class MSPGLTK_API Dialog: public Panel
 {
@@ -27,10 +27,6 @@ public:
 
        sigc::signal<void, int> signal_response;
 
-private:
-       bool stale = false;
-
-public:
        const char *get_class() const override { return "dialog"; }
 
        /** Adds an action button to the dialog.  Pressing the button will invoke
@@ -41,17 +37,47 @@ public:
        away from the dialog. */
        void set_modal(bool);
 
-       void button_release(int, int, unsigned) override;
-       bool key_release(unsigned, unsigned) override;
-       bool navigate(Navigation) override;
 protected:
        void response(int);
-       void check_stale();
 
        /** Called when an action button is pressed. */
        virtual void on_response(int) { }
 };
 
+
+/**
+A dialog which automatically deletes itself after being responded to.
+*/
+template<typename D>
+class MSPGLTK_API AutoDialog: public D
+{
+private:
+       struct StaleChecker
+       {
+               AutoDialog *dialog;
+
+               StaleChecker(AutoDialog &d): dialog(&d) { }
+               ~StaleChecker() { if(dialog->stale) delete dialog; }
+       };
+
+       bool stale = false;
+
+       template<typename... Args>
+       AutoDialog(Args &&... args): D(std::forward<Args>(args)...) { }
+
+public:
+       // Ensure that AutoDialog is always created with new.
+       template<typename... Args>
+       static AutoDialog *create(Args &&... args) { return new AutoDialog(std::forward<Args>(args)...); }
+
+       void button_release(int x, int y, unsigned b) override { StaleChecker sc(*this); D::button_release(x, y, b); }
+       bool key_release(unsigned k, unsigned m) override { StaleChecker sc(*this); return D::key_release(k, m); }
+       bool navigate(Navigation n) override { StaleChecker sc(*this); return D::navigate(n); }
+
+protected:
+       void on_response(int c) override { D::on_response(c); stale = true; }
+};
+
 } // namespace GLtk
 } // namespace Msp