]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/dialog.h
Rework how widget ownership works in Container
[libs/gltk.git] / source / dialog.h
index 0a9b0d88c9037c358ba50fa9eee8329239f08a9b..6209ab29c4fa42ebe00678ffb170a8b4b0206da4 100644 (file)
@@ -1,13 +1,7 @@
-/* $Id$
-
-This file is part of libmspgltk
-Copyright © 2010  Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
-
 #ifndef MSP_GLTK_DIALOG_H_
 #define MSP_GLTK_DIALOG_H_
 
+#include "mspgltk_api.h"
 #include "panel.h"
 
 namespace Msp {
@@ -17,31 +11,78 @@ 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 Dialog: public Panel
+class MSPGLTK_API Dialog: public Panel
 {
-private:
-       bool stale;
-
 public:
+       class MSPGLTK_API Loader: public DataFile::DerivedObjectLoader<Dialog, Panel::Loader>
+       {
+       public:
+               Loader(Dialog &, WidgetMap &);
+
+       private:
+               void action_button(const std::string &, int);
+       };
+
        sigc::signal<void, int> signal_response;
 
-       Dialog(const Resources &);
+       const char *get_class() const override { return "dialog"; }
 
        /** Adds an action button to the dialog.  Pressing the button will invoke
        response handlers and delete the dialog. */
        void add_button(Button &, int);
 
-       virtual void button_release(int, int, unsigned);
-       virtual void key_release(unsigned, unsigned);
+       void add_button(std::unique_ptr<Button>, int);
+
+       Button &add_button(const std::string &, int);
+
+       /** Sets the modality of the dialog.  When modal, the user can't navigate
+       away from the dialog. */
+       void set_modal(bool);
+
 protected:
+       void connect_button(Button &, int);
        void response(int);
 
        /** 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