]> git.tdb.fi Git - libs/gltk.git/blob - source/dialog.h
Rework how widget ownership works in Container
[libs/gltk.git] / source / dialog.h
1 #ifndef MSP_GLTK_DIALOG_H_
2 #define MSP_GLTK_DIALOG_H_
3
4 #include "mspgltk_api.h"
5 #include "panel.h"
6
7 namespace Msp {
8 namespace GLtk {
9
10 class Button;
11
12 /**
13 A Dialog is used for temporary interaction with the user.  When any of the
14 Dialog's action buttons are clicked, it will emit a signal and hide itself.
15 */
16 class MSPGLTK_API Dialog: public Panel
17 {
18 public:
19         class MSPGLTK_API Loader: public DataFile::DerivedObjectLoader<Dialog, Panel::Loader>
20         {
21         public:
22                 Loader(Dialog &, WidgetMap &);
23
24         private:
25                 void action_button(const std::string &, int);
26         };
27
28         sigc::signal<void, int> signal_response;
29
30         const char *get_class() const override { return "dialog"; }
31
32         /** Adds an action button to the dialog.  Pressing the button will invoke
33         response handlers and delete the dialog. */
34         void add_button(Button &, int);
35
36         void add_button(std::unique_ptr<Button>, int);
37
38         Button &add_button(const std::string &, int);
39
40         /** Sets the modality of the dialog.  When modal, the user can't navigate
41         away from the dialog. */
42         void set_modal(bool);
43
44 protected:
45         void connect_button(Button &, int);
46         void response(int);
47
48         /** Called when an action button is pressed. */
49         virtual void on_response(int) { }
50 };
51
52
53 /**
54 A dialog which automatically deletes itself after being responded to.
55 */
56 template<typename D>
57 class MSPGLTK_API AutoDialog: public D
58 {
59 private:
60         struct StaleChecker
61         {
62                 AutoDialog *dialog;
63
64                 StaleChecker(AutoDialog &d): dialog(&d) { }
65                 ~StaleChecker() { if(dialog->stale) delete dialog; }
66         };
67
68         bool stale = false;
69
70         template<typename... Args>
71         AutoDialog(Args &&... args): D(std::forward<Args>(args)...) { }
72
73 public:
74         // Ensure that AutoDialog is always created with new.
75         template<typename... Args>
76         static AutoDialog *create(Args &&... args) { return new AutoDialog(std::forward<Args>(args)...); }
77
78         void button_release(int x, int y, unsigned b) override { StaleChecker sc(*this); D::button_release(x, y, b); }
79         bool key_release(unsigned k, unsigned m) override { StaleChecker sc(*this); return D::key_release(k, m); }
80         bool navigate(Navigation n) override { StaleChecker sc(*this); return D::navigate(n); }
81
82 protected:
83         void on_response(int c) override { D::on_response(c); stale = true; }
84 };
85
86 } // namespace GLtk
87 } // namespace Msp
88
89 #endif