Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
w-link.hpp
Go to the documentation of this file.
1/*
2 W-LINK.hpp - smart-link to GTK widget
3
4 Copyright (C)
5 2018, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
48#ifndef STAGE_MODEL_W_LINK_H
49#define STAGE_MODEL_W_LINK_H
50
51
52#include "lib/error.hpp"
53#include "lib/format-string.hpp"
54
55#include <type_traits>
56#include <sigc++/trackable.h>
57
58
59namespace stage {
60namespace model {
61
62 namespace error = lumiera::error;
63 using error::LUMIERA_ERROR_BOTTOM_VALUE;
64
65 using util::_Fmt;
66
67
78 template<class TAR>
79 class WLink
80 {
81
82 TAR* widget_;
83
84
85 public:
87 {
88 try {
89 this->clear();
90 }
91 ERROR_LOG_AND_IGNORE (stage, "Detaching managed WLink from Widget")
92 }
93 WLink() noexcept
94 : widget_{nullptr}
95 { }
96
97 explicit
98 WLink (TAR& targetWidget)
99 : widget_{attachTo (targetWidget)}
100 { }
101
102 WLink (WLink const& r)
103 : widget_{r.widget_? attachTo(*r.widget_) : nullptr}
104 { }
105
106 WLink (WLink && rr)
107 : widget_{rr.widget_? attachTo(*rr.widget_) : nullptr}
108 {
109 rr.clear();
110 }
111
112 WLink&
114 {
115 swap (*this, other);
116 return *this;
117 }
118
127 friend void
128 swap (WLink& l, WLink& r)
129 {
130 TAR* tl = l.widget_;
131 TAR* tr = r.widget_;
132 if (tl == tr) return;
133 r.clear();
134 l.clear();
135 if (tr) l.widget_ = l.attachTo (*tr);
136 if (tl) r.widget_ = r.attachTo (*tl);
137 }
138
139
140 explicit
141 operator bool() const
142 {
143 return bool(widget_);
144 }
145
146 TAR&
148 {
150 return *widget_;
151 }
152
153 TAR*
155 {
157 return widget_;
158 }
159
160
161 bool isValid() const { return bool{*this}; }
162 bool isActive() const { return bool{*this}; }
163
164
169 void
171 {
172 if (widget_)
173 widget_->remove_destroy_notify_callback (&widget_);
174 widget_ = nullptr;
175 }
176
183 void
184 connect (TAR& otherTarget)
185 {
186 if (widget_ == &otherTarget) return;
187 clear();
188 widget_ = attachTo (otherTarget);
189 }
190
191 private:
192 void
194 {
195 if (not widget_)
196 throw error::State ("zombie widget encountered"
197 , LERR_(BOTTOM_VALUE));
198 }
199
204 TAR*
205 attachTo (TAR& target)
206 {
207 static_assert (std::is_base_of<sigc::trackable, TAR>()
208 ,"target type required to be sigc::trackable");
209
210 try {
211 target.add_destroy_notify_callback (&widget_
212 ,[](void* p)
213 {
214 TAR* & widgetPtr = *static_cast<TAR**>(p);
215 ASSERT (widgetPtr);
216 widgetPtr = nullptr;
217 return p;
218 });
219 return &target;
220 }
221 catch (std::exception& problem)
222 {
223 throw error::External (problem, _Fmt{"WLink could not attach to %s. Problem is %s"} % target % problem);
224 }
225 catch (...)
226 {
227 ERROR (stage, "Unknown exception while attaching WLink");
228 throw error::External (_Fmt{"WLink could not attach to %s due to unidentified Problems"} % target);
229 }
230 }
231 };
232
233
234}} // namespace stage::model
235#endif /*STAGE_MODEL_W_LINK_H*/
A front-end for using printf-style formatting.
Lumiera error handling (C++ interface).
#define ERROR_LOG_AND_IGNORE(_FLAG_, _OP_DESCR_)
convenience shortcut for a sequence of catch blocks just logging and consuming an error.
Definition error.hpp:267
#define LERR_(_NAME_)
Definition error.hpp:45
Front-end for printf-style string template interpolation.
LumieraError< LERR_(STATE)> State
Definition error.hpp:209
LumieraError< LERR_(EXTERNAL)> External
Definition error.hpp:213
Lumiera GTK UI implementation root.
Definition guifacade.cpp:37