Rapicorn - Experimental UI Toolkit - Source Code  13.07.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
widget.hh
Go to the documentation of this file.
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 &region);
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 &region);
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 &region);
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_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines