Rapicorn - Experimental UI Toolkit - Source Code
13.07.0
|
00001 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html 00002 #include <ui/serverapi.hh> 00003 // serverapi.hh includes widget.hh after WidgetIface declaration 00004 00005 #ifndef __RAPICORN_WIDGET_HH_ 00006 #define __RAPICORN_WIDGET_HH_ 00007 00008 #include <ui/events.hh> 00009 #include <ui/region.hh> 00010 #include <ui/commands.hh> 00011 #include <ui/heritage.hh> 00012 00013 namespace Rapicorn { 00014 00015 /* --- Widget structures and forward decls --- */ 00016 typedef Rect Allocation; 00017 class WidgetImpl; 00018 class AnchorInfo; 00019 class SizeGroup; 00020 class Adjustment; 00021 class ContainerImpl; 00022 class ResizeContainerImpl; 00023 class WindowImpl; 00024 class ViewportImpl; 00025 namespace Selector { class Selob; } 00026 00027 /* --- event handler --- */ 00028 class EventHandler : public virtual ReferenceCountable { 00029 typedef Aida::Signal<bool (const Event&), Aida::CollectorWhile0<bool>> EventSignal; 00030 protected: 00031 virtual bool handle_event (const Event &event); 00032 public: 00033 explicit EventHandler (); 00034 EventSignal sig_event; 00035 typedef enum { 00036 RESET_ALL 00037 } ResetMode; 00038 virtual void reset (ResetMode mode = RESET_ALL) = 0; 00039 }; 00040 00043 class WidgetImpl : public virtual WidgetIface, public virtual DataListContainer { 00044 friend class ClassDoctor; 00045 friend class ContainerImpl; 00046 friend class SizeGroup; 00047 uint64 flags_; // inlined for fast access 00048 ContainerImpl *parent_; // inlined for fast access 00049 const AnchorInfo *ainfo_; 00050 Heritage *heritage_; 00051 FactoryContext *factory_context_; 00052 Allocation allocation_; 00053 Requisition requisition_; 00054 Requisition inner_size_request (); // ungrouped size requisition 00055 void propagate_state (bool notify_changed); 00056 ContainerImpl** _parent_loc () { return &parent_; } 00057 void propagate_heritage (); 00058 void heritage (Heritage *heritage); 00059 void expose_internal (const Region ®ion); 00060 protected: 00061 const AnchorInfo* force_anchor_info () const; 00062 virtual void constructed (); 00063 /* flag handling */ 00064 bool change_flags_silently (uint64 mask, bool on); 00065 enum { 00066 ANCHORED = 1 << 0, 00067 VISIBLE = 1 << 1, 00068 SENSITIVE = 1 << 2, 00069 UNVIEWABLE = 1 << 3, 00070 PARENT_SENSITIVE = 1 << 4, 00071 PARENT_UNVIEWABLE = 1 << 5, 00072 PRELIGHT = 1 << 6, 00073 IMPRESSED = 1 << 7, 00074 HAS_DEFAULT = 1 << 8, 00075 FOCUS_CHAIN = 1 << 9, 00076 HSHRINK = 1 << 10, 00077 VSHRINK = 1 << 11, 00078 HEXPAND = 1 << 12, 00079 VEXPAND = 1 << 13, 00080 HSPREAD = 1 << 14, 00081 VSPREAD = 1 << 15, 00082 HSPREAD_CONTAINER = 1 << 16, 00083 VSPREAD_CONTAINER = 1 << 17, 00084 INVALID_REQUISITION = 1 << 18, 00085 INVALID_ALLOCATION = 1 << 19, 00086 INVALID_CONTENT = 1 << 20, 00087 }; 00088 void set_flag (uint64 flag, bool on = true); 00089 void unset_flag (uint64 flag) { set_flag (flag, false); } 00090 virtual Selector::Selob* pseudo_selector (Selector::Selob &selob, const String &ident, const String &arg, String &error) { return NULL; } 00091 // resizing, requisition and allocation 00092 virtual void size_request (Requisition &requisition) = 0; 00093 virtual void size_allocate (Allocation area, bool changed) = 0; 00094 virtual void invalidate_parent (); 00095 void clip_area (const Allocation *clip); 00096 bool tune_requisition (Requisition requisition); 00097 bool tune_requisition (double new_width, 00098 double new_height); 00099 /* signal methods */ 00100 virtual void do_invalidate (); 00101 virtual void do_changed (); 00102 /* idlers & timers */ 00103 uint exec_fast_repeater (const EventLoop::BoolSlot &sl); 00104 uint exec_slow_repeater (const EventLoop::BoolSlot &sl); 00105 uint exec_key_repeater (const EventLoop::BoolSlot &sl); 00106 bool remove_exec (uint exec_id); 00107 bool clear_exec (uint *exec_id); 00108 virtual void visual_update (); 00109 /* misc */ 00110 virtual ~WidgetImpl (); 00111 virtual void finalize (); 00112 virtual void set_parent (ContainerImpl *parent); 00113 virtual void hierarchy_changed (WidgetImpl *old_toplevel); 00114 virtual bool activate_widget (); 00115 virtual bool custom_command (const String &command_name, 00116 const StringSeq &command_args); 00117 void anchored (bool b) { set_flag (ANCHORED, b); } 00118 void notify_key_error (); 00119 public: 00120 explicit WidgetImpl (); 00121 virtual WindowImpl* as_window_impl () { return NULL; } 00122 virtual ContainerImpl* as_container_impl () { return NULL; } 00123 bool test_all_flags (uint64 mask) const { return (flags_ & mask) == mask; } 00124 bool test_any_flag (uint64 mask) const { return (flags_ & mask) != 0; } 00125 bool anchored () const { return test_all_flags (ANCHORED); } 00126 virtual bool visible () const { return test_all_flags (VISIBLE); } 00127 virtual void visible (bool b) { set_flag (VISIBLE, b); } 00128 bool ancestry_visible () const; 00129 virtual bool viewable () const; // visible() && !UNVIEWABLE && !PARENT_UNVIEWABLE 00130 bool drawable () const; // viewable() && clipped_allocation > 0 00131 virtual bool sensitive () const { return test_all_flags (SENSITIVE | PARENT_SENSITIVE); } 00132 virtual void sensitive (bool b) { set_flag (SENSITIVE, b); } 00133 bool insensitive () const { return !sensitive(); } 00134 void insensitive (bool b) { sensitive (!b); } 00135 bool key_sensitive () const; 00136 bool pointer_sensitive () const; 00137 bool prelight () const { return test_any_flag (PRELIGHT); } 00138 virtual void prelight (bool b) { set_flag (PRELIGHT, b); } 00139 bool ancestry_prelight () const; 00140 bool impressed () const { return test_any_flag (IMPRESSED); } 00141 virtual void impressed (bool b) { set_flag (IMPRESSED, b); } 00142 bool ancestry_impressed() const; 00143 bool has_default () const { return test_any_flag (HAS_DEFAULT); } 00144 bool grab_default () const; 00145 virtual bool can_focus () const; 00146 bool has_focus () const; 00147 bool grab_focus (); 00148 void unset_focus (); 00149 virtual bool move_focus (FocusDirType fdir); 00150 virtual bool activate (); 00151 virtual bool hexpand () const { return test_any_flag (HEXPAND | HSPREAD | HSPREAD_CONTAINER); } 00152 virtual void hexpand (bool b) { set_flag (HEXPAND, b); } 00153 virtual bool vexpand () const { return test_any_flag (VEXPAND | VSPREAD | VSPREAD_CONTAINER); } 00154 virtual void vexpand (bool b) { set_flag (VEXPAND, b); } 00155 virtual bool hspread () const { return test_any_flag (HSPREAD | HSPREAD_CONTAINER); } 00156 virtual void hspread (bool b) { set_flag (HSPREAD, b); } 00157 virtual bool vspread () const { return test_any_flag (VSPREAD | VSPREAD_CONTAINER); } 00158 virtual void vspread (bool b) { set_flag (VSPREAD, b); } 00159 virtual bool hshrink () const { return test_any_flag (HSHRINK); } 00160 virtual void hshrink (bool b) { set_flag (HSHRINK, b); } 00161 virtual bool vshrink () const { return test_any_flag (VSHRINK); } 00162 virtual void vshrink (bool b) { set_flag (VSHRINK, b); } 00163 virtual String name () const; 00164 virtual void name (const String &str); 00165 FactoryContext* factory_context () const; 00166 void factory_context (FactoryContext *fc); 00167 UserSource user_source () const; 00168 ColorSchemeType color_scheme () const; 00169 void color_scheme (ColorSchemeType cst); 00170 /* override requisition */ 00171 double width () const; 00172 void width (double w); 00173 double height () const; 00174 void height (double h); 00175 /* properties */ 00176 Property* lookup_property (const String &property_name); 00177 String get_property (const String &property_name); 00178 void set_property (const String &property_name, 00179 const String &value); 00180 bool try_set_property (const String &property_name, 00181 const String &value); 00182 const PropertyList& list_properties (); 00183 /* commands */ 00184 bool exec_command (const String &command_call_string); 00185 Command* lookup_command (const String &command_name); 00186 virtual const CommandList& list_commands (); 00187 /* parents */ 00188 ContainerImpl* parent () const { return parent_; } 00189 ContainerImpl* root () const; 00190 bool has_ancestor (const WidgetImpl &ancestor) const; 00191 WidgetImpl* common_ancestor (const WidgetImpl &other) const; 00192 WidgetImpl* common_ancestor (const WidgetImpl *other) const { return common_ancestor (*other); } 00193 const AnchorInfo* anchor_info () const { return RAPICORN_UNLIKELY (!anchored()) ? NULL : RAPICORN_LIKELY (ainfo_) ? ainfo_ : force_anchor_info(); } 00194 WindowImpl* get_window () const; 00195 ViewportImpl* get_viewport () const; 00196 ResizeContainerImpl* get_resize_container () const; 00197 /* cross links */ 00198 typedef std::function<void (WidgetImpl&)> WidgetSlot; 00199 size_t cross_link (WidgetImpl &link, const WidgetSlot &uncross); 00200 void cross_unlink (WidgetImpl &link, size_t link_id); 00201 void uncross_links (WidgetImpl &link); 00202 /* invalidation / changes */ 00203 void invalidate (uint64 mask = INVALID_REQUISITION | INVALID_ALLOCATION | INVALID_CONTENT); 00204 void invalidate_size () { invalidate (INVALID_REQUISITION | INVALID_ALLOCATION); } 00205 void changed (); 00206 void expose () { expose (allocation()); } 00207 void expose (const Rect &rect) { expose (Region (rect)); } 00208 void expose (const Region ®ion); 00209 void queue_visual_update (); 00210 void force_visual_update (); 00211 /* public signals */ 00212 Aida::Signal<void ()> sig_finalize; 00213 Aida::Signal<void ()> sig_changed; 00214 Aida::Signal<void ()> sig_invalidate; 00215 Aida::Signal<void (WidgetImpl *old)> sig_hierarchy_changed; 00216 /* event handling */ 00217 bool process_event (const Event &event); // widget coordinates relative 00218 bool process_screen_window_event (const Event &event); // screen_window coordinates relative 00219 /* coordinate handling */ 00220 protected: 00221 Affine affine_to_screen_window (); // widget => screen_window affine 00222 Affine affine_from_screen_window (); // screen_window => widget affine 00223 // rendering 00224 class RenderContext; 00225 virtual void render_widget (RenderContext &rcontext); 00226 virtual void render_recursive (RenderContext &rcontext); 00227 virtual void render (RenderContext &rcontext, const Rect &rect) = 0; 00228 const Region& rendering_region (RenderContext &rcontext) const; 00229 virtual cairo_t* cairo_context (RenderContext &rcontext, 00230 const Allocation &area = Allocation (-1, -1, 0, 0)); 00231 public: 00232 void render_into (cairo_t *cr, const Region ®ion); 00233 virtual bool point (Point p); // widget coordinates relative 00234 Point point_to_screen_window (Point widget_point); // widget coordinates relative 00235 Point point_from_screen_window (Point window_point); // screen_window coordinates relative 00236 virtual bool translate_from (const WidgetImpl &src_widget, 00237 const uint n_points, 00238 Point *points) const; 00239 bool translate_to (const uint n_points, 00240 Point *points, 00241 const WidgetImpl &target_widget) const; 00242 bool translate_from (const WidgetImpl &src_widget, 00243 const uint n_rects, 00244 Rect *rects) const; 00245 bool translate_to (const uint n_rects, 00246 Rect *rects, 00247 const WidgetImpl &target_widget) const; 00248 bool screen_window_point (Point p); // screen_window coordinates relative 00249 /* public size accessors */ 00250 Requisition requisition (); // effective size requisition 00251 void set_allocation (const Allocation &area, 00252 const Allocation *clip = NULL); // assign new allocation 00253 const Allocation& allocation () const { return allocation_; } // current allocation 00254 Allocation clipped_allocation () const; // clipped allocation 00255 const Allocation* clip_area () const; // widget clipping 00256 /* heritage / appearance */ 00257 StateType state () const; 00258 Heritage* heritage () const { return heritage_; } 00259 Color foreground () { return heritage()->foreground (state()); } 00260 Color background () { return heritage()->background (state()); } 00261 Color dark_color () { return heritage()->dark_color (state()); } 00262 Color dark_shadow () { return heritage()->dark_shadow (state()); } 00263 Color dark_glint () { return heritage()->dark_glint (state()); } 00264 Color light_color () { return heritage()->light_color (state()); } 00265 Color light_shadow () { return heritage()->light_shadow (state()); } 00266 Color light_glint () { return heritage()->light_glint (state()); } 00267 Color focus_color () { return heritage()->focus_color (state()); } 00268 /* debugging/testing */ 00269 virtual String test_dump (); 00270 String debug_dump (const String &flags = String()); 00271 protected: 00272 void make_test_dump (TestStream &tstream); 00273 virtual void dump_test_data (TestStream &tstream); 00274 virtual void dump_private_data (TestStream &tstream); 00275 /* convenience */ 00276 public: 00277 void find_adjustments (AdjustmentSourceType adjsrc1, 00278 Adjustment **adj1, 00279 AdjustmentSourceType adjsrc2 = ADJUSTMENT_SOURCE_NONE, 00280 Adjustment **adj2 = NULL, 00281 AdjustmentSourceType adjsrc3 = ADJUSTMENT_SOURCE_NONE, 00282 Adjustment **adj3 = NULL, 00283 AdjustmentSourceType adjsrc4 = ADJUSTMENT_SOURCE_NONE, 00284 Adjustment **adj4 = NULL); 00285 public: /* packing */ 00286 struct PackInfo { 00287 double hposition, hspan, vposition, vspan; 00288 uint left_spacing, right_spacing, bottom_spacing, top_spacing; 00289 double halign, hscale, valign, vscale; 00290 }; 00291 const PackInfo& pack_info () const { return const_cast<WidgetImpl*> (this)->pack_info (false); } 00292 double hposition () const { return pack_info ().hposition; } 00293 void hposition (double d); 00294 double hspan () const { return pack_info ().hspan; } 00295 void hspan (double d); 00296 double vposition () const { return pack_info ().vposition; } 00297 void vposition (double d); 00298 double vspan () const { return pack_info ().vspan; } 00299 void vspan (double d); 00300 int left_spacing () const { return pack_info ().left_spacing; } 00301 void left_spacing (int s); 00302 int right_spacing () const { return pack_info ().right_spacing; } 00303 void right_spacing (int s); 00304 int bottom_spacing () const { return pack_info ().bottom_spacing; } 00305 void bottom_spacing (int s); 00306 int top_spacing () const { return pack_info ().top_spacing; } 00307 void top_spacing (int s); 00308 double halign () const { return pack_info ().halign; } 00309 void halign (double f); 00310 double hscale () const { return pack_info ().hscale; } 00311 void hscale (double f); 00312 double valign () const { return pack_info ().valign; } 00313 void valign (double f); 00314 double vscale () const { return pack_info ().vscale; } 00315 void vscale (double f); 00316 double hanchor () const { return halign(); } // mirrors halign 00317 void hanchor (double a) { halign (a); } // mirrors halign 00318 double vanchor () const { return valign(); } // mirrors valign 00319 void vanchor (double a) { valign (a); } // mirrors valign 00320 private: 00321 void repack (const PackInfo &orig, const PackInfo &pnew); 00322 PackInfo& pack_info (bool create); 00323 public: 00324 virtual bool match_selector (const String &selector); 00325 virtual WidgetIface* query_selector (const String &selector); 00326 virtual WidgetSeq query_selector_all (const String &selector); 00327 virtual WidgetIface* query_selector_unique (const String &selector); 00328 template<class C> typename 00329 InterfaceMatch<C>::Result interface (const String &ident = String(), 00330 const std::nothrow_t &nt = dothrow) const; 00331 template<class C> typename 00332 InterfaceMatch<C>::Result parent_interface (const String &ident = String(), 00333 const std::nothrow_t &nt = dothrow) const; 00334 protected: 00335 virtual bool do_event (const Event &event); 00336 static ContainerImpl* container_cast (WidgetImpl *widget) { return widget ? widget->as_container_impl() : NULL; } 00337 static WindowImpl* window_cast (WidgetImpl *widget) { return widget ? widget->as_window_impl() : NULL; } 00338 private: 00339 void type_cast_error (const char *dest_type) RAPICORN_NORETURN; 00340 bool match_interface (bool wself, bool wparent, bool children, InterfaceMatcher &imatcher) const; 00341 }; 00342 inline bool operator== (const WidgetImpl &widget1, const WidgetImpl &widget2) { return &widget1 == &widget2; } 00343 inline bool operator!= (const WidgetImpl &widget1, const WidgetImpl &widget2) { return &widget1 != &widget2; } 00344 00345 // == WidgetIfaceVector == 00346 struct WidgetIfaceVector : public std::vector<WidgetIface*> { 00347 explicit WidgetIfaceVector (const WidgetSeq &widgetseq); 00348 /*ctor*/ WidgetIfaceVector () {} 00349 WidgetSeq to_widget_seq () const; 00350 }; 00351 00352 // == Implementations == 00353 template<class C> typename WidgetImpl::InterfaceMatch<C>::Result 00354 WidgetImpl::interface (const String &ident, 00355 const std::nothrow_t &nt) const 00356 { 00357 InterfaceMatch<C> interface_match (ident); 00358 match_interface (1, 0, 1, interface_match); 00359 return interface_match.result (&nt == &dothrow); 00360 } 00361 00362 template<class C> typename WidgetImpl::InterfaceMatch<C>::Result 00363 WidgetImpl::parent_interface (const String &ident, 00364 const std::nothrow_t &nt) const 00365 { 00366 InterfaceMatch<C> interface_match (ident); 00367 match_interface (0, 1, 0, interface_match); 00368 return interface_match.result (&nt == &dothrow); 00369 } 00370 00371 } // Rapicorn 00372 00373 #endif /* __RAPICORN_WIDGET_HH_ */