#pragma once #include #include #include #include #include "button.h" #include "view.h" #include "control.h" #include "lib_begin.h" using cgv::base::base_ptr; template ::value> struct enum_aware_type_name : public cgv::type::info::type_name { }; template struct enum_aware_type_name { static const char* get_name() { return "enum"; } }; namespace cgv { namespace gui { class CGV_API gui_group; class CGV_API provider; /// ref counted pointer to a %gui %group typedef data::ref_ptr gui_group_ptr; /// ref counted pointer to const %gui %group typedef data::ref_ptr const_gui_group_ptr; /// %gui independent group class which is a container for %gui elements class CGV_API gui_group : public cgv::base::group, public cgv::base::registration_listener { protected: friend class provider; /// managed objects can be add to the group such that std::vector managed_objects; /// access to protected provider method static void set_provider_parent(provider* p, gui_group_ptr g); /// %driver specific handle for the group gui element managing the gui built in the provider static gui_group_ptr get_provider_parent(const provider* p); /// interface of adding an object void register_object(cgv::base::base_ptr object, const std::string& options); /// void unregister_object(cgv::base::base_ptr object, const std::string& options); public: /// construct from name gui_group(const std::string& name = ""); /// overload to return the %type name of this object std::string get_type_name() const; /**@name managed objects */ //@{ //! add the passed object as an managed object. /*! This will simply add a reference counted pointer to the object into a list of managed elements. This pointer is released whenever the gui group is destroyed or when the gui is recreated. This functionality can be used by gui_creators to manage objects that are not managed by the user of the gui library. An example usage can be found in the bit_field_controler found in the plugin plugins/cg_ext. */ void add_managed_objects(cgv::base::base_ptr object); /// release all managed objects void release_all_managed_objects(); /// release a specific managed object void release_managed_objects(cgv::base::base_ptr object); /// check whether an object is managed by this gui group bool is_managed_object(cgv::base::base_ptr object); //@/ /**@name selection of children */ //@{ /// return whether several children of the group can be selected at the same time virtual bool multiple_selection() const; //! select the ci-th child of the group. /*! If multiple_selection() returns true, the \c exclusive flag can be used to unselect all other previously selected children except the newly selected one. Typically, an exclusively selected child will gain input focus. */ virtual void select_child(unsigned ci, bool exclusive = false); /// same as version with child index virtual void select_child(base_ptr ci, bool exclusive = false); //! unselect the ci-th child. /*! If no multiple_selection is allowed, unselection can fail if the group does not support an empty selection.*/ virtual bool unselect_child(unsigned ci); /// same as version with child index virtual bool unselect_child(base_ptr ci); //! return the index of the currently selected child. /*! In case of multiple_selection, this function returns the index of the first selected child. In this case it can also happen that the returned index is -1 if no child is selected. */ virtual int get_selected_child_index() const; //! return the currently selected child. /*! In case of multiple_selection, this function returns the first selected child. In this case it can also happen that the returned base_ptr is empty if no child is selected. */ virtual base_ptr get_selected_child() const; /// return whether the given child is selected virtual bool is_selected(base_ptr c) const; //! return whether the given child is selected. /*! the implementation simply calls the virtual variant with get_child(ci). */ bool is_selected(unsigned ci) const; //! This signal is emitted for every change of the selection of a child. /*! The first argument is simply the pointer to the child whose selection state has been changed. The second argument is the new selection state. */ cgv::signal::signal on_selection_change; //@} /**@name opening and closing of child groups*/ //@{ /// returns whether open and close of sub groups is allowed virtual bool can_open_and_close() const; /// return whether the given child is open virtual bool is_open_child_group(gui_group_ptr g) const; /// return whether the ci-th child is an open gui group bool is_open_child_group(unsigned ci) const; /// try to open given child group and return whether this was successful virtual bool open_child_group(gui_group_ptr g); /// try to close given child group and return whether this was successful virtual bool close_child_group(gui_group_ptr g); //! this signal is emitted, when a child group is opened or closed /*! The first argument specifies the group and the second whether it has been opened. */ cgv::signal::signal on_open_state_change; //@} /**@name adding new elements to the group */ //@{ /// send pure alignment information virtual void align(const std::string& _align); /// add a new group to the given parent group virtual gui_group_ptr add_group(const std::string& label, const std::string& group_type, const std::string& options, const std::string& align); /// add a newly created decorator to the group virtual base_ptr add_decorator(const std::string& label, const std::string& decorator_type, const std::string& options, const std::string& align); /// add a newly created button to the group virtual button_ptr add_button(const std::string& label, const std::string& options, const std::string& align); /// add a newly created view to the group virtual view_ptr add_view_void(const std::string& label, const void* value_ptr, const std::string& value_type, const std::string& gui_type, const std::string& options, const std::string& align); /// add a newly created control to the group virtual control_ptr add_control_void(const std::string& label, void* value_ptr, abst_control_provider* acp, const std::string& value_type, const std::string& gui_type, const std::string& options, const std::string& align, void* user_data); /// add a newly created view to the group for the given value with the given %gui %type, init and align options template inline data::ref_ptr > add_view(const std::string& label, const T& value, const std::string& gui_type = "", const std::string& options = "", const std::string& align = "\n") { view_ptr vp = add_view_void(label, &value, enum_aware_type_name::get_name(), gui_type, options, align); return vp.up_cast >(); } /// add a newly created control to the group for the given value with the given %gui %type, init and align options template inline data::ref_ptr > add_control(const std::string& label, T& value, const std::string& gui_type = "", const std::string& options = "", const std::string& align = "\n") { control_ptr cp = add_control_void(label, &value, 0, enum_aware_type_name::get_name(), gui_type, options, align, 0); return cp.up_cast >(); } /// add a newly created control to the group which is controlled by a control_provider template inline data::ref_ptr > add_control(const std::string& label, control_provider* provider, const std::string& gui_type = "", const std::string& options = "", const std::string& align = "\n", void* user_data = 0) { control_ptr cp = add_control_void(label, 0, provider, enum_aware_type_name::get_name(), gui_type, options, align, user_data); return cp.up_cast >(); } //@} /**@name finding elements in the group*/ //@{ /// find a gui element by name, return empty pointer if not found base_ptr find_element(const std::string& name); /// find a view in the group based on a const void pointer view_ptr find_view_void(const void* value_ptr, int* idx_ptr); /// find a control in the group based on a const void pointer control_ptr find_control_void(void* value_ptr, int* idx_ptr); //! find the next view of the given value in the current group. /*! If the index pointer is given, start at the index to which the pointer points and set this index to the index of the child index of the found view */ template inline data::ref_ptr > find_view(const T& value, int* idx_ptr=0) { view_ptr vp = find_view_void(&value,idx_ptr); return vp.up_cast >(); } //! find the next control of the given value in the current group. /*! If the index pointer is given, start at the index to which the pointer points and set this index to the index of the child index of the found control */ template inline data::ref_ptr > find_control(T& value, int* idx_ptr=0) { control_ptr cp = find_control_void(&value,idx_ptr); return cp.up_cast >(); } //@} }; #if _MSC_VER >= 1400 CGV_TEMPLATE template class CGV_API data::ref_ptr; CGV_TEMPLATE template class CGV_API data::ref_ptr; #endif } } #include