nana/include/nana/gui/widgets/widget.hpp
cnjinhao 052d34a746 Added named colors from 4.3 Extended color keywords
::nana::colors::<named colors>
2014-12-29 06:20:18 +08:00

548 lines
13 KiB
C++

/*
* The fundamental widget class implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/widgets/widget.hpp
*/
#ifndef NANA_GUI_WIDGET_HPP
#define NANA_GUI_WIDGET_HPP
#include <nana/traits.hpp>
#include "../basis.hpp"
#include "../programming_interface.hpp"
#include <nana/internationalization.hpp>
#include <nana/gui/detail/drawer.hpp>
#include <nana/gui/layout_utility.hpp>
#include <functional>
namespace nana
{
class drawer_trigger;
/// Abstract class for defining the capacity interface.
class widget
: nana::noncopyable, nana::nonmovable
{
typedef void(*dummy_bool_type)(widget* (*)(const widget&));
public:
virtual ~widget() = default;
virtual window handle() const = 0; ///< Returns the handle of window, returns 0 if window is not created.
bool empty() const; ///< Determines whether the manipulator is handling a window.
void close();
window parent() const;
nana::string caption() const;
void caption(std::string utf8);
void caption(nana::string);
template<typename ...Args>
void i18n(std::string msgid, Args&&... args)
{
_m_caption(nana::internationalization().get(msgid, std::forward<Args>(args)...));
}
void i18n(i18n_eval);
void cursor(nana::cursor);
nana::cursor cursor() const; ///< Retrieves the shape of cursor
void typeface(const paint::font& font);
paint::font typeface() const;
bool enabled() const; ///< Determines whether the window is enabled for mouse and keyboard input.
void enabled(bool);
void enable_dropfiles(bool); ///< Enables/Disables a window to accept dropped files.
void focus();
bool focused() const;
void show(); ///< Sets the window visible.
void hide(); ///< Sets the window invisible.
bool visible() const;
nana::size size() const;
void size(const nana::size&);
point pos() const;
void move(int x, int y);
void move(const rectangle&);
void fgcolor(const nana::color&);
nana::color fgcolor() const;
void bgcolor(const nana::color&);
nana::color bgcolor() const;
general_events& events() const;
void umake_event(event_handle eh) const; ///< Deletes an event callback by a handle.
widget& register_shortkey(char_t); ///< Registers a shortkey. To remove a registered key, pass 0.
widget& take_active(bool activated, window take_if_not_activated);
widget& tooltip(const nana::string&);
operator dummy_bool_type() const;
operator window() const;
protected:
//protected members, a derived class must call this implementation if it overrides an implementation
virtual void _m_complete_creation();
virtual general_events& _m_get_general_events() const = 0;
virtual nana::string _m_caption() const;
virtual void _m_caption(nana::string&&);
virtual nana::cursor _m_cursor() const;
virtual void _m_cursor(nana::cursor);
virtual void _m_close();
virtual bool _m_enabled() const;
virtual void _m_enabled(bool);
virtual bool _m_show(bool);
virtual bool _m_visible() const;
virtual void _m_size(const nana::size&);
virtual void _m_move(int x, int y);
virtual void _m_move(const rectangle&);
virtual void _m_typeface(const nana::paint::font& font);
virtual nana::paint::font _m_typeface() const;
virtual void _m_fgcolor(const nana::color&);
virtual nana::color _m_fgcolor() const;
virtual void _m_bgcolor(const nana::color&);
virtual nana::color _m_bgcolor() const;
};
/// Base class of all the classes defined as a widget window. Defaultly a widget_tag
template<typename Category, typename DrawerTrigger, typename Events = ::nana::general_events, typename Scheme = ::nana::widget_colors>
class widget_object: public widget
{
protected:
typedef DrawerTrigger drawer_trigger_t;
public:
using scheme_type = Scheme;
widget_object()
: events_{ std::make_shared<Events>() },
scheme_{ API::dev::make_scheme<Scheme>() }
{}
~widget_object()
{
if(handle_)
API::close_window(handle_);
}
Events& events() const
{
return *events_;
}
bool create(window parent_wd, bool visible) ///< Creates a no-size (zero-size) widget. in a widget/root window specified by parent_wd.
{
return create(parent_wd, rectangle(), visible);
}
bool create(window parent_wd, const rectangle & r = {}, bool visible = true) ///< in a widget/root window specified by parent_wd.
{
if(parent_wd && this->empty())
{
handle_ = API::dev::create_widget(parent_wd, r, this);
API::dev::set_events(handle_, events_);
API::dev::set_scheme(handle_, scheme_.get());
API::dev::attach_signal(handle_, *this, &widget_object::signal);
API::dev::attach_drawer(*this, trigger_);
if(visible)
API::show_window(handle_, true);
this->_m_complete_creation();
}
return (this->empty() == false);
}
window handle() const override
{
return handle_;
}
widget_object& borderless(bool enable)
{
API::widget_borderless(handle_, enable);
return *this;
}
bool borderless() const
{
return API::widget_borderless(handle_);
}
scheme_type& scheme() const
{
return *scheme_;
}
protected:
DrawerTrigger& get_drawer_trigger()
{
return trigger_;
}
const DrawerTrigger& get_drawer_trigger() const
{
return trigger_;
}
private:
void signal(detail::signals::code code, const detail::signals& sig)
{
typedef detail::signals::code codes;
switch(code)
{
case codes::caption:
this->_m_caption(sig.info.caption);
break;
case codes::read_caption:
*sig.info.str = this->_m_caption();
break;
case codes::destroy:
handle_ = nullptr;
break;
default:
break;
}
}
general_events& _m_get_general_events() const
{
return *events_;
}
private:
window handle_{nullptr};
DrawerTrigger trigger_;
std::shared_ptr<Events> events_;
std::unique_ptr<scheme_type> scheme_;
};//end class widget_object
/// Base class of all the classes defined as a non-graphics-buffer widget window. The second template parameter DrawerTrigger is always ignored.\see nana::panel
template<typename DrawerTrigger, typename Events, typename Scheme>
class widget_object<category::lite_widget_tag, DrawerTrigger, Events, Scheme>: public widget
{
protected:
typedef DrawerTrigger drawer_trigger_t;
public:
using scheme_type = Scheme;
widget_object()
: events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() }
{}
~widget_object()
{
if(handle_)
API::close_window(handle_);
}
Events& events() const
{
return *events_;
}
bool create(window parent_wd, bool visible) ///< Creates a no-size (zero-size) widget. in a widget/root window specified by parent_wd.
{
return create(parent_wd, rectangle(), visible);
}
bool create(window parent_wd, const rectangle& r = rectangle(), bool visible = true) ///< in a widget/root window specified by parent_wd.
{
if(parent_wd && this->empty())
{
handle_ = API::dev::create_lite_widget(parent_wd, r, this);
API::dev::set_events(handle_, events_);
API::dev::set_scheme(handle_, scheme_.get());
if(visible)
API::show_window(handle_, true);
this->_m_complete_creation();
}
return (this->empty() == false);
}
window handle() const
{
return handle_;
}
scheme_type& scheme() const
{
return *scheme_;
}
private:
void signal(detail::signals::code code, const detail::signals& sig)
{
typedef detail::signals::code codes;
switch(code)
{
case codes::caption:
this->_m_caption(sig.info.caption);
break;
case codes::read_caption:
*sig.info.str = this->_m_caption();
break;
case codes::destroy:
handle_ = nullptr;
break;
default:
break;
}
}
general_events& _m_get_general_events() const
{
return *events_;
}
private:
window handle_{nullptr};
std::shared_ptr<Events> events_;
std::unique_ptr<scheme_type> scheme_;
};//end class widget_object
/// Base class of all the classes defined as a root window. \see nana::form
template<typename DrawerTrigger, typename Events, typename Scheme>
class widget_object<category::root_tag, DrawerTrigger, Events, Scheme>: public widget
{
protected:
typedef DrawerTrigger drawer_trigger_t;
public:
using scheme_type = Scheme;
widget_object()
{
handle_ = API::dev::create_window(nullptr, false, API::make_center(300, 150), appearance(), this);
_m_bind_and_attach();
}
widget_object(const rectangle& r, const appearance& apr = {})
{
handle_ = API::dev::create_window(nullptr, false, r, apr, this);
_m_bind_and_attach();
}
widget_object(window owner, bool nested, const rectangle& r = {}, const appearance& apr = {})
{
handle_ = API::dev::create_window(owner, nested, r, apr, this);
_m_bind_and_attach();
}
~widget_object()
{
if(handle_)
API::close_window(handle_);
}
Events& events() const
{
return *events_;
}
void activate()
{
API::activate_window(handle_);
}
window handle() const
{
return handle_;
}
native_window_type native_handle() const
{
return API::root(handle_);
}
void bring_top(bool activated)
{
API::bring_top(handle(), activated);
}
window owner() const
{
return API::get_owner_window(handle_);
}
void icon(const nana::paint::image& ico)
{
API::window_icon(handle_, ico);
}
void restore()
{
API::restore_window(handle_);
}
void zoom(bool ask_for_max)
{
API::zoom_window(handle_, ask_for_max);
}
bool is_zoomed(bool check_maximized) const
{
return API::is_window_zoomed(handle_, check_maximized);
}
widget_object& z_order(window wd_after, z_order_action action_if_no_wd_after)
{
API::set_window_z_order(handle_, wd_after, action_if_no_wd_after);
return *this;
}
scheme_type& scheme() const
{
return *scheme_;
}
protected:
DrawerTrigger& get_drawer_trigger()
{
return trigger_;
}
const DrawerTrigger& get_drawer_trigger() const
{
return trigger_;
}
private:
void signal(detail::signals::code code, const detail::signals& sig)
{
typedef detail::signals::code codes;
switch(code)
{
case codes::caption:
this->_m_caption(sig.info.caption);
break;
case codes::read_caption:
*sig.info.str = this->_m_caption();
break;
case codes::destroy:
handle_ = nullptr;
break;
default:
break;
}
}
void _m_bind_and_attach()
{
events_ = std::make_shared<Events>();
API::dev::set_events(handle_, events_);
scheme_ = API::dev::make_scheme<scheme_type>();
API::dev::set_scheme(handle_, scheme_.get());
API::dev::attach_signal(handle_, *this, &widget_object::signal);
API::dev::attach_drawer(*this, trigger_);
}
general_events& _m_get_general_events() const
{
return *events_;
}
private:
window handle_;
DrawerTrigger trigger_;
std::shared_ptr<Events> events_;
std::unique_ptr<scheme_type> scheme_;
};//end class widget_object<root_tag>
/// Base class of all the classes defined as a frame window. \see nana::frame
template<typename Drawer, typename Events, typename Scheme>
class widget_object<category::frame_tag, Drawer, Events, Scheme>: public widget{};
/// Especialization. Base class of all the classes defined as a frame window. \see nana::frame
template<typename Events, typename Scheme>
class widget_object<category::frame_tag, int, Events, Scheme>: public widget
{
protected:
typedef int drawer_trigger_t;
public:
using scheme_type = Scheme;
widget_object()
: events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() }
{}
~widget_object()
{
if(handle_)
API::close_window(handle_);
}
Events& events() const
{
return *events_;
}
bool create(window parent_wd, bool visible) ///< Creates a no-size (zero-size) widget. in a widget/root window specified by parent_wd.
{
return create(parent_wd, rectangle(), visible);
}
/// Creates in a widget/root window specified by parent_wd.
bool create(window parent_wd, const rectangle& r = rectangle(), bool visible = true)
{
if(parent_wd && this->empty())
{
handle_ = API::dev::create_frame(parent_wd, r, this);
API::dev::set_events(handle_, events_);
API::dev::set_scheme(handle_, scheme_.get());
API::dev::attach_signal(handle_, *this, &widget_object::signal);
API::show_window(handle_, visible);
this->_m_complete_creation();
}
return (this->empty() == false);
}
window handle() const
{
return handle_;
}
scheme_type& scheme() const
{
return *scheme_;
}
private:
virtual drawer_trigger* get_drawer_trigger()
{
return nullptr;
}
void signal(detail::signals::code code, const detail::signals& sig)
{
typedef detail::signals::code codes;
switch(code)
{
case codes::caption:
this->_m_caption(sig.info.caption);
break;
case codes::read_caption:
*sig.info.str = this->_m_caption();
break;
case codes::destroy:
handle_ = nullptr;
break;
default:
break;
}
}
general_events& _m_get_general_events() const
{
return *events_;
}
private:
window handle_{nullptr};
std::shared_ptr<Events> events_;
std::unique_ptr<scheme_type> scheme_;
};//end class widget_object<category::frame_tag>
}//end namespace nana
#endif