Merge branch 'develop' of https://github.com/besh81/nana into besh81-develop
This commit is contained in:
commit
44cbb18a50
@ -33,12 +33,53 @@ namespace nana
|
|||||||
{
|
{
|
||||||
namespace toolbar
|
namespace toolbar
|
||||||
{
|
{
|
||||||
struct item_proxy
|
enum class tool_type
|
||||||
{
|
{
|
||||||
nana::toolbar& widget;
|
button,
|
||||||
std::size_t button;
|
toggle
|
||||||
|
};
|
||||||
|
|
||||||
void enable(bool enable_state);
|
class item_proxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
item_proxy(::nana::toolbar*, std::size_t pos);
|
||||||
|
|
||||||
|
bool enable() const;
|
||||||
|
item_proxy& enable(bool enable_state);
|
||||||
|
|
||||||
|
item_proxy& tooltype(tool_type type); ///< Sets the tool style.
|
||||||
|
|
||||||
|
bool istoggle() const; ///< Returns true if the tool style is toggle.
|
||||||
|
bool toggle() const; ///< Gets the tool toggle state (only if tool style is toggle).
|
||||||
|
item_proxy& toggle(bool toggle_state); ///< Sets the tool toggle state (only if tool style is toggle).
|
||||||
|
std::string toggle_group() const; ///< Returns the toggle group associated with the tool (only if tool style is toggle).
|
||||||
|
item_proxy& toggle_group(const ::std::string& group); ///< Adds the tool to a toggle group (only if tool style is toggle).
|
||||||
|
|
||||||
|
item_proxy& textout(bool show); ///< Show/Hide the text inside the button
|
||||||
|
|
||||||
|
private:
|
||||||
|
nana::toolbar* const tb_;
|
||||||
|
std::size_t const pos_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct item_type
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
nana::paint::image image;
|
||||||
|
unsigned pixels{ 0 };
|
||||||
|
unsigned position{ 0 }; // last item position.
|
||||||
|
nana::size textsize;
|
||||||
|
bool enable{ true };
|
||||||
|
|
||||||
|
tool_type type{ tool_type::button };
|
||||||
|
bool toggle{ false };
|
||||||
|
std::string group;
|
||||||
|
|
||||||
|
bool textout{ false };
|
||||||
|
|
||||||
|
item_type(const std::string& text, const nana::paint::image& img, tool_type type)
|
||||||
|
:text(text), image(img), type(type)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct toolbar_events
|
struct toolbar_events
|
||||||
@ -49,7 +90,6 @@ namespace nana
|
|||||||
basic_event<arg_toolbar> leave; ///< The mouse leaves a control button.
|
basic_event<arg_toolbar> leave; ///< The mouse leaves a control button.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct item_type;
|
|
||||||
class item_container;
|
class item_container;
|
||||||
|
|
||||||
class drawer
|
class drawer
|
||||||
@ -90,6 +130,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using size_type = std::size_t; ///< A type to count the number of elements.
|
using size_type = std::size_t; ///< A type to count the number of elements.
|
||||||
|
using tool_type = drawerbase::toolbar::tool_type;
|
||||||
|
|
||||||
toolbar() = default;
|
toolbar() = default;
|
||||||
toolbar(window, bool visible, bool detached=false);
|
toolbar(window, bool visible, bool detached=false);
|
||||||
@ -102,6 +143,17 @@ namespace nana
|
|||||||
|
|
||||||
bool enable(size_type index) const;
|
bool enable(size_type index) const;
|
||||||
void enable(size_type index, bool enable_state);
|
void enable(size_type index, bool enable_state);
|
||||||
|
|
||||||
|
void tooltype(size_type index, tool_type type); ///< Sets the tool style.
|
||||||
|
|
||||||
|
bool istoggle(size_type index) const; ///< Returns true if the tool style is toggle.
|
||||||
|
bool toggle(size_type index) const; ///< Gets the tool toggle state (only if tool style is toggle).
|
||||||
|
void toggle(size_type index, bool toggle_state); ///< Sets the tool toggle state (only if tool style is toggle).
|
||||||
|
std::string toggle_group(size_type index) const; ///< Returns the toggle group associated with the tool (only if tool style is toggle).
|
||||||
|
void toggle_group(size_type index, const ::std::string& group); ///< Adds the tool to a toggle group (only if tool style is toggle).
|
||||||
|
|
||||||
|
void textout(size_type index, bool show); ///< Show/Hide the text inside the button
|
||||||
|
|
||||||
void scale(unsigned s); ///< Sets the scale of control button.
|
void scale(unsigned s); ///< Sets the scale of control button.
|
||||||
|
|
||||||
/// Enable to place buttons at right part. After calling it, every new button is right aligned.
|
/// Enable to place buttons at right part. After calling it, every new button is right aligned.
|
||||||
|
@ -27,26 +27,6 @@ namespace nana
|
|||||||
{
|
{
|
||||||
namespace toolbar
|
namespace toolbar
|
||||||
{
|
{
|
||||||
struct item_type
|
|
||||||
{
|
|
||||||
enum kind{ button, container};
|
|
||||||
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
|
|
||||||
std::string text;
|
|
||||||
nana::paint::image image;
|
|
||||||
unsigned pixels{0};
|
|
||||||
unsigned position{ 0 }; // last item position.
|
|
||||||
nana::size textsize;
|
|
||||||
bool enable{true};
|
|
||||||
|
|
||||||
kind type;
|
|
||||||
|
|
||||||
item_type(const std::string& text, const nana::paint::image& img, kind type)
|
|
||||||
:text(text), image(img), type(type)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
class item_container
|
class item_container
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -58,7 +38,7 @@ namespace nana
|
|||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(size_type pos, std::string text, const nana::paint::image& img, item_type::kind type)
|
void insert(size_type pos, std::string text, const nana::paint::image& img, tool_type type)
|
||||||
{
|
{
|
||||||
item_type* m = new item_type(std::move(text), img, type);
|
item_type* m = new item_type(std::move(text), img, type);
|
||||||
|
|
||||||
@ -70,12 +50,12 @@ namespace nana
|
|||||||
|
|
||||||
void push_back(const std::string& text, const nana::paint::image& img)
|
void push_back(const std::string& text, const nana::paint::image& img)
|
||||||
{
|
{
|
||||||
insert(cont_.size(), text, img, item_type::kind::button);
|
insert(cont_.size(), text, img, tool_type::button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void push_back(const std::string& text)
|
void push_back(const std::string& text)
|
||||||
{
|
{
|
||||||
insert(cont_.size(), text, nana::paint::image(), item_type::kind::button);
|
insert(cont_.size(), text, nana::paint::image(), tool_type::button);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Contributed by kmribti(pr#105)
|
//Contributed by kmribti(pr#105)
|
||||||
@ -126,6 +106,45 @@ namespace nana
|
|||||||
cont_.clear();
|
cont_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void update_toggle_group(item_type* item, bool toggle_state, bool clicked = true)
|
||||||
|
{
|
||||||
|
if(!item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(item->group.empty())
|
||||||
|
{
|
||||||
|
item->toggle = toggle_state;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// group rules:
|
||||||
|
// 1. inside a group only one item at the time is selected
|
||||||
|
// 2. inside a group one item must always be selected
|
||||||
|
// 3. a group with only one item IS NOT a group
|
||||||
|
|
||||||
|
bool is_group = false;
|
||||||
|
|
||||||
|
// look for other items inside the group
|
||||||
|
for(auto i : cont_)
|
||||||
|
{
|
||||||
|
if(i == item)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(i && i->group == item->group)
|
||||||
|
{
|
||||||
|
if(toggle_state == false && clicked == false) // needs to avoid to break rule no. 2
|
||||||
|
return;
|
||||||
|
|
||||||
|
is_group = true;
|
||||||
|
i->toggle = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item->toggle = is_group ? true : toggle_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
container_type cont_;
|
container_type cont_;
|
||||||
size_t right_{ npos };
|
size_t right_{ npos };
|
||||||
@ -137,8 +156,8 @@ namespace nana
|
|||||||
enum class state_t{normal, highlighted, selected};
|
enum class state_t{normal, highlighted, selected};
|
||||||
const static unsigned extra_size = 6;
|
const static unsigned extra_size = 6;
|
||||||
|
|
||||||
item_renderer(nana::paint::graphics& graph, bool textout, unsigned scale, const ::nana::color& bgcolor)
|
item_renderer(nana::paint::graphics& graph, unsigned scale, const ::nana::color& bgcolor, const ::nana::color& fgcolor)
|
||||||
:graph(graph), textout(textout), scale(scale), bgcolor(bgcolor)
|
:graph(graph), scale(scale), bgcolor(bgcolor), fgcolor(fgcolor)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void operator()(int x, int y, unsigned width, unsigned height, item_type& item, state_t state)
|
void operator()(int x, int y, unsigned width, unsigned height, item_type& item, state_t state)
|
||||||
@ -152,6 +171,13 @@ namespace nana
|
|||||||
if (state_t::highlighted == state || state_t::selected == state)
|
if (state_t::highlighted == state || state_t::selected == state)
|
||||||
graph.gradual_rectangle(background_r.pare_off(1), bgcolor, static_cast<color_rgb>(state_t::selected == state ? 0x99CCFF : 0xC0DDFC), true);
|
graph.gradual_rectangle(background_r.pare_off(1), bgcolor, static_cast<color_rgb>(state_t::selected == state ? 0x99CCFF : 0xC0DDFC), true);
|
||||||
}
|
}
|
||||||
|
else if (item.type == tool_type::toggle && item.toggle)
|
||||||
|
{
|
||||||
|
nana::rectangle background_r(x, y, width, height);
|
||||||
|
graph.rectangle(background_r, false, static_cast<color_rgb>(item.enable ? 0x3399FF : 0x999999));
|
||||||
|
|
||||||
|
graph.gradual_rectangle(background_r.pare_off(1), bgcolor, static_cast<color_rgb>(item.enable ? 0xC0DDFC : 0x969696), true);
|
||||||
|
}
|
||||||
|
|
||||||
if(!item.image.empty())
|
if(!item.image.empty())
|
||||||
{
|
{
|
||||||
@ -181,17 +207,17 @@ namespace nana
|
|||||||
width -= scale;
|
width -= scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(textout)
|
if(item.textout)
|
||||||
{
|
{
|
||||||
graph.string({ x + static_cast<int>(width - item.textsize.width) / 2, y + static_cast<int>(height - item.textsize.height) / 2 }, item.text);
|
graph.string({ x + static_cast<int>(width - item.textsize.width) / 2, y + static_cast<int>(height - item.textsize.height) / 2 }, item.text, fgcolor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nana::paint::graphics& graph;
|
nana::paint::graphics& graph;
|
||||||
bool textout;
|
|
||||||
unsigned scale;
|
unsigned scale;
|
||||||
::nana::color bgcolor;
|
::nana::color bgcolor;
|
||||||
|
::nana::color fgcolor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct drawer::drawer_impl_type
|
struct drawer::drawer_impl_type
|
||||||
@ -200,7 +226,6 @@ namespace nana
|
|||||||
paint::graphics* graph_ptr{ nullptr };
|
paint::graphics* graph_ptr{ nullptr };
|
||||||
|
|
||||||
unsigned scale{16};
|
unsigned scale{16};
|
||||||
bool textout{false};
|
|
||||||
size_type which{npos};
|
size_type which{npos};
|
||||||
item_renderer::state_t state{item_renderer::state_t::normal};
|
item_renderer::state_t state{item_renderer::state_t::normal};
|
||||||
|
|
||||||
@ -237,10 +262,11 @@ namespace nana
|
|||||||
int x = 2, y = 2;
|
int x = 2, y = 2;
|
||||||
|
|
||||||
auto bgcolor = API::bgcolor(widget_->handle());
|
auto bgcolor = API::bgcolor(widget_->handle());
|
||||||
|
auto fgcolor = API::fgcolor(widget_->handle());
|
||||||
graph.palette(true, bgcolor);
|
graph.palette(true, bgcolor);
|
||||||
graph.gradual_rectangle(rectangle{ graph.size() }, bgcolor.blend(colors::white, 0.1), bgcolor.blend(colors::black, 0.05), true);
|
graph.gradual_rectangle(rectangle{ graph.size() }, bgcolor.blend(colors::white, 0.1), bgcolor.blend(colors::black, 0.05), true);
|
||||||
|
|
||||||
item_renderer ir(graph, impl_->textout, impl_->scale, bgcolor);
|
item_renderer ir(graph, impl_->scale, bgcolor, fgcolor);
|
||||||
size_type index = 0;
|
size_type index = 0;
|
||||||
|
|
||||||
for (auto item : impl_->items.container())
|
for (auto item : impl_->items.container())
|
||||||
@ -378,6 +404,10 @@ namespace nana
|
|||||||
size_type which = _m_which(arg.pos, false);
|
size_type which = _m_which(arg.pos, false);
|
||||||
if(impl_->which == which)
|
if(impl_->which == which)
|
||||||
{
|
{
|
||||||
|
// update toggle state
|
||||||
|
auto m = impl_->items.at(impl_->which);
|
||||||
|
impl_->items.update_toggle_group(m, !m->toggle);
|
||||||
|
|
||||||
::nana::arg_toolbar arg{ *widget_, which };
|
::nana::arg_toolbar arg{ *widget_, which };
|
||||||
widget_->events().selected.emit(arg, widget_->handle());
|
widget_->events().selected.emit(arg, widget_->handle());
|
||||||
|
|
||||||
@ -419,19 +449,76 @@ namespace nana
|
|||||||
if (item->text.size())
|
if (item->text.size())
|
||||||
item->textsize = impl_->graph_ptr->text_extent_size(item->text);
|
item->textsize = impl_->graph_ptr->text_extent_size(item->text);
|
||||||
|
|
||||||
if (item->image.empty() == false)
|
if(item->image.empty())
|
||||||
|
{
|
||||||
|
if(item->textsize.width && item->textout)
|
||||||
|
item->pixels = item->textsize.width + 8;
|
||||||
|
else
|
||||||
item->pixels = impl_->scale + item_renderer::extra_size;
|
item->pixels = impl_->scale + item_renderer::extra_size;
|
||||||
|
}
|
||||||
if (item->textsize.width && impl_->textout)
|
else
|
||||||
|
{
|
||||||
|
item->pixels = impl_->scale + item_renderer::extra_size;
|
||||||
|
if(item->textsize.width && item->textout)
|
||||||
item->pixels += item->textsize.width + 8;
|
item->pixels += item->textsize.width + 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//class drawer
|
//class drawer
|
||||||
|
|
||||||
// Item Proxy
|
// Item Proxy
|
||||||
void item_proxy::enable(bool enable_state)
|
item_proxy::item_proxy(::nana::toolbar* t, std::size_t pos)
|
||||||
|
: tb_{ t }, pos_{ pos }
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool item_proxy::enable() const
|
||||||
{
|
{
|
||||||
widget.enable(button, enable_state);
|
return tb_->enable(pos_);
|
||||||
|
}
|
||||||
|
|
||||||
|
item_proxy& item_proxy::enable(bool enable_state)
|
||||||
|
{
|
||||||
|
tb_->enable(pos_, enable_state);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
item_proxy& item_proxy::tooltype(tool_type type)
|
||||||
|
{
|
||||||
|
tb_->tooltype(pos_, type);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool item_proxy::istoggle() const
|
||||||
|
{
|
||||||
|
return tb_->istoggle(pos_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool item_proxy::toggle() const
|
||||||
|
{
|
||||||
|
return tb_->toggle(pos_);
|
||||||
|
}
|
||||||
|
|
||||||
|
item_proxy& item_proxy::toggle(bool toggle_state)
|
||||||
|
{
|
||||||
|
tb_->toggle(pos_, toggle_state);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string item_proxy::toggle_group() const
|
||||||
|
{
|
||||||
|
return tb_->toggle_group(pos_);
|
||||||
|
}
|
||||||
|
|
||||||
|
item_proxy& item_proxy::textout(bool show)
|
||||||
|
{
|
||||||
|
tb_->textout(pos_, show);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
item_proxy& item_proxy::toggle_group(const ::std::string& group)
|
||||||
|
{
|
||||||
|
tb_->toggle_group(pos_, group);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
}//end namespace toolbar
|
}//end namespace toolbar
|
||||||
}//end namespace drawerbase
|
}//end namespace drawerbase
|
||||||
@ -465,14 +552,14 @@ namespace nana
|
|||||||
{
|
{
|
||||||
get_drawer_trigger().items().push_back(text, img);
|
get_drawer_trigger().items().push_back(text, img);
|
||||||
API::refresh_window(handle());
|
API::refresh_window(handle());
|
||||||
return {*this, get_drawer_trigger().items().size() - 1u};
|
return {this, get_drawer_trigger().items().size() - 1u};
|
||||||
}
|
}
|
||||||
|
|
||||||
drawerbase::toolbar::item_proxy toolbar::append(const std::string& text)
|
drawerbase::toolbar::item_proxy toolbar::append(const std::string& text)
|
||||||
{
|
{
|
||||||
get_drawer_trigger().items().push_back(text, {});
|
get_drawer_trigger().items().push_back(text, {});
|
||||||
API::refresh_window(this->handle());
|
API::refresh_window(this->handle());
|
||||||
return {*this, get_drawer_trigger().items().size() - 1u};
|
return {this, get_drawer_trigger().items().size() - 1u};
|
||||||
}
|
}
|
||||||
|
|
||||||
void toolbar::clear()
|
void toolbar::clear()
|
||||||
@ -507,6 +594,100 @@ namespace nana
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toolbar::tooltype(size_type index, tool_type type)
|
||||||
|
{
|
||||||
|
auto & items = get_drawer_trigger().items();
|
||||||
|
|
||||||
|
if(items.size() > index)
|
||||||
|
{
|
||||||
|
auto m = items.at(index);
|
||||||
|
if(m && m->type != type)
|
||||||
|
{
|
||||||
|
m->type = type;
|
||||||
|
API::refresh_window(this->handle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool toolbar::istoggle(size_type index) const
|
||||||
|
{
|
||||||
|
auto & items = get_drawer_trigger().items();
|
||||||
|
|
||||||
|
if(items.size() <= index)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto m = items.at(index);
|
||||||
|
return (m && m->type == tool_type::toggle);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool toolbar::toggle(size_type index) const
|
||||||
|
{
|
||||||
|
auto & items = get_drawer_trigger().items();
|
||||||
|
|
||||||
|
if(items.size() <= index)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto m = items.at(index);
|
||||||
|
return (m && m->toggle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toolbar::toggle(size_type index, bool toggle_state)
|
||||||
|
{
|
||||||
|
auto & items = get_drawer_trigger().items();
|
||||||
|
|
||||||
|
if(items.size() > index)
|
||||||
|
{
|
||||||
|
auto m = items.at(index);
|
||||||
|
if(m)
|
||||||
|
{
|
||||||
|
items.update_toggle_group(m, toggle_state, false);
|
||||||
|
|
||||||
|
API::refresh_window(this->handle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toolbar::toggle_group(size_type index) const
|
||||||
|
{
|
||||||
|
auto & items = get_drawer_trigger().items();
|
||||||
|
|
||||||
|
if(items.size() <= index)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
auto m = items.at(index);
|
||||||
|
return m ? m->group : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void toolbar::toggle_group(size_type index, const ::std::string& group)
|
||||||
|
{
|
||||||
|
auto & items = get_drawer_trigger().items();
|
||||||
|
|
||||||
|
if(items.size() > index)
|
||||||
|
{
|
||||||
|
auto m = items.at(index);
|
||||||
|
if(m && (m->group != group))
|
||||||
|
{
|
||||||
|
m->group = group;
|
||||||
|
API::refresh_window(this->handle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void toolbar::textout(size_type index, bool show)
|
||||||
|
{
|
||||||
|
auto & items = get_drawer_trigger().items();
|
||||||
|
|
||||||
|
if(items.size() > index)
|
||||||
|
{
|
||||||
|
auto m = items.at(index);
|
||||||
|
if(m && (m->textout != show))
|
||||||
|
{
|
||||||
|
m->textout = show;
|
||||||
|
API::refresh_window(this->handle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void toolbar::scale(unsigned s)
|
void toolbar::scale(unsigned s)
|
||||||
{
|
{
|
||||||
get_drawer_trigger().scale(s);
|
get_drawer_trigger().scale(s);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user