Merge branch 'feature-toolbar-proxy' of https://github.com/5cript/nana into 5cript-feature-toolbar-proxy

This commit is contained in:
Jinhao 2018-02-17 21:04:36 +08:00
commit 33afb37b1a
2 changed files with 618 additions and 604 deletions

View File

@ -1,108 +1,116 @@
/** /**
* A Toolbar Implementation * A Toolbar Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/widgets/toolbar.hpp * @file: nana/gui/widgets/toolbar.hpp
*/ */
#ifndef NANA_GUI_WIDGET_TOOLBAR_HPP #ifndef NANA_GUI_WIDGET_TOOLBAR_HPP
#define NANA_GUI_WIDGET_TOOLBAR_HPP #define NANA_GUI_WIDGET_TOOLBAR_HPP
#include <nana/push_ignore_diagnostic> #include <nana/push_ignore_diagnostic>
#include "widget.hpp" #include "widget.hpp"
namespace nana namespace nana
{ {
class toolbar; class toolbar;
struct arg_toolbar struct arg_toolbar
: public event_arg : public event_arg
{ {
toolbar& widget; toolbar& widget;
std::size_t button; std::size_t button;
arg_toolbar(toolbar&, std::size_t); arg_toolbar(toolbar&, std::size_t);
}; };
namespace drawerbase namespace drawerbase
{ {
namespace toolbar namespace toolbar
{ {
struct toolbar_events struct item_proxy
: public general_events {
{ nana::toolbar& widget;
basic_event<arg_toolbar> selected; ///< A mouse click on a control button. std::size_t button;
basic_event<arg_toolbar> enter; ///< The mouse enters a control button.
basic_event<arg_toolbar> leave; ///< The mouse leaves a control button. void enable(bool enable_state);
}; };
struct item_type; struct toolbar_events
class item_container; : public general_events
{
class drawer basic_event<arg_toolbar> selected; ///< A mouse click on a control button.
: public drawer_trigger basic_event<arg_toolbar> enter; ///< The mouse enters a control button.
{ basic_event<arg_toolbar> leave; ///< The mouse leaves a control button.
struct drawer_impl_type; };
public: struct item_type;
using size_type = std::size_t; class item_container;
drawer(); class drawer
~drawer(); : public drawer_trigger
{
item_container& items() const; struct drawer_impl_type;
void scale(unsigned);
private: public:
void refresh(graph_reference) override; using size_type = std::size_t;
void attached(widget_reference, graph_reference) override;
void detached() override; drawer();
void mouse_move(graph_reference, const arg_mouse&) override; ~drawer();
void mouse_leave(graph_reference, const arg_mouse&) override;
void mouse_down(graph_reference, const arg_mouse&) override; item_container& items() const;
void mouse_up(graph_reference, const arg_mouse&) override; void scale(unsigned);
private: private:
size_type _m_which(point, bool want_if_disabled) const; void refresh(graph_reference) override;
void _m_calc_pixels(item_type*, bool force); void attached(widget_reference, graph_reference) override;
private: void detached() override;
::nana::toolbar* widget_; void mouse_move(graph_reference, const arg_mouse&) override;
drawer_impl_type* impl_; void mouse_leave(graph_reference, const arg_mouse&) override;
}; void mouse_down(graph_reference, const arg_mouse&) override;
void mouse_up(graph_reference, const arg_mouse&) override;
}//end namespace toolbar private:
}//end namespace drawerbase size_type _m_which(point, bool want_if_disabled) const;
void _m_calc_pixels(item_type*, bool force);
/// Control bar that contains buttons for controlling private:
class toolbar ::nana::toolbar* widget_;
: public widget_object<category::widget_tag, drawerbase::toolbar::drawer, drawerbase::toolbar::toolbar_events> drawer_impl_type* impl_;
{ };
public:
using size_type = std::size_t; ///< A type to count the number of elements. }//end namespace toolbar
}//end namespace drawerbase
toolbar() = default;
toolbar(window, bool visible, bool detached=false); /// Control bar that contains buttons for controlling
toolbar(window, const rectangle& = rectangle(), bool visible = true, bool detached = false); class toolbar
: public widget_object<category::widget_tag, drawerbase::toolbar::drawer, drawerbase::toolbar::toolbar_events>
void separate(); ///< Adds a separator. {
void append(const ::std::string& text, const nana::paint::image& img); ///< Adds a control button. public:
void append(const ::std::string& text); ///< Adds a control button. using size_type = std::size_t; ///< A type to count the number of elements.
bool enable(size_type index) const;
void enable(size_type index, bool enable_state); toolbar() = default;
void scale(unsigned s); ///< Sets the scale of control button. toolbar(window, bool visible, bool detached=false);
toolbar(window, const rectangle& = rectangle(), bool visible = true, bool detached = false);
/// Enable to place buttons at right part. After calling it, every new button is right aligned.
void go_right(); void separate(); ///< Adds a separator.
drawerbase::toolbar::item_proxy append(const ::std::string& text, const nana::paint::image& img); ///< Adds a control button.
bool detached() { return detached_; }; drawerbase::toolbar::item_proxy append(const ::std::string& text); ///< Adds a control button.
bool enable(size_type index) const;
private: void enable(size_type index, bool enable_state);
bool detached_; void scale(unsigned s); ///< Sets the scale of control button.
};
}//end namespace nana /// Enable to place buttons at right part. After calling it, every new button is right aligned.
#include <nana/pop_ignore_diagnostic> void go_right();
#endif bool detached() { return detached_; };
private:
bool detached_;
};
}//end namespace nana
#include <nana/pop_ignore_diagnostic>
#endif

View File

@ -1,496 +1,502 @@
/* /*
* A Toolbar Implementation * A Toolbar Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/widgets/toolbar.cpp * @file: nana/gui/widgets/toolbar.cpp
* @contributors: * @contributors:
* kmribti(pr#105) * kmribti(pr#105)
*/ */
#include <nana/gui/widgets/toolbar.hpp> #include <nana/gui/widgets/toolbar.hpp>
#include <nana/gui/tooltip.hpp> #include <nana/gui/tooltip.hpp>
#include <vector> #include <vector>
namespace nana namespace nana
{ {
arg_toolbar::arg_toolbar(toolbar& tbar, std::size_t btn) arg_toolbar::arg_toolbar(toolbar& tbar, std::size_t btn)
: widget(tbar), button{btn} : widget(tbar), button{btn}
{} {}
namespace drawerbase namespace drawerbase
{ {
namespace toolbar namespace toolbar
{ {
struct item_type struct item_type
{ {
enum kind{ button, container}; enum kind{ button, container};
typedef std::size_t size_type; typedef std::size_t size_type;
std::string text; std::string text;
nana::paint::image image; nana::paint::image image;
unsigned pixels{0}; unsigned pixels{0};
unsigned position{ 0 }; // last item position. unsigned position{ 0 }; // last item position.
nana::size textsize; nana::size textsize;
bool enable{true}; bool enable{true};
kind type; kind type;
item_type(const std::string& text, const nana::paint::image& img, kind type) item_type(const std::string& text, const nana::paint::image& img, kind type)
:text(text), image(img), type(type) :text(text), image(img), type(type)
{} {}
}; };
class item_container
{
class item_container public:
{ using container_type = std::vector<item_type*>;
public: using size_type = container_type::size_type;
using container_type = std::vector<item_type*>;
using size_type = container_type::size_type; ~item_container()
{
~item_container() for(auto ptr : cont_)
{ delete ptr;
for(auto ptr : cont_) }
delete ptr;
} 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, item_type::kind type) item_type* m = new item_type(std::move(text), img, type);
{
item_type* m = new item_type(std::move(text), img, type); if(pos < cont_.size())
cont_.insert(cont_.begin() + pos, m);
if(pos < cont_.size()) else
cont_.insert(cont_.begin() + pos, m); cont_.push_back(m);
else }
cont_.push_back(m);
} 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, item_type::kind::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(), item_type::kind::button);
} //Contributed by kmribti(pr#105)
void go_right() noexcept
//Contributed by kmribti(pr#105) {
void go_right() noexcept right_ = cont_.size();
{ }
right_ = cont_.size();
} //Contributed by kmribti(pr#105)
size_t right() const noexcept
//Contributed by kmribti(pr#105) {
size_t right() const noexcept return right_;
{ }
return right_;
} void insert(size_type pos)
{
void insert(size_type pos) if(pos < cont_.size())
{ cont_.insert(cont_.begin() + pos, static_cast<item_type*>(nullptr)); //both works in C++0x and C++2003
if(pos < cont_.size()) else
cont_.insert(cont_.begin() + pos, static_cast<item_type*>(nullptr)); //both works in C++0x and C++2003 cont_.push_back(nullptr);
else }
cont_.push_back(nullptr);
} void separate()
{
void separate() cont_.push_back(nullptr);
{ }
cont_.push_back(nullptr);
} size_type size() const noexcept
{
size_type size() const noexcept return cont_.size();
{ }
return cont_.size();
} container_type& container() noexcept
{
container_type& container() noexcept return cont_;
{ }
return cont_;
} item_type * at(size_type pos)
{
item_type * at(size_type pos) return cont_.at(pos);
{ }
return cont_.at(pos); private:
} container_type cont_;
private: size_t right_{ npos };
container_type cont_; };
size_t right_{ npos };
}; class item_renderer
{
class item_renderer public:
{ enum class state_t{normal, highlighted, selected};
public: const static unsigned extra_size = 6;
enum class state_t{normal, highlighted, selected};
const static unsigned extra_size = 6; item_renderer(nana::paint::graphics& graph, bool textout, unsigned scale, const ::nana::color& bgcolor)
:graph(graph), textout(textout), scale(scale), bgcolor(bgcolor)
item_renderer(nana::paint::graphics& graph, bool textout, unsigned scale, const ::nana::color& bgcolor) {}
:graph(graph), textout(textout), scale(scale), bgcolor(bgcolor)
{} 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) //draw background
{ if (state != state_t::normal)
//draw background {
if (state != state_t::normal) nana::rectangle background_r(x, y, width, height);
{ graph.rectangle(background_r, false, static_cast<color_rgb>(0x3399FF));
nana::rectangle background_r(x, y, width, height);
graph.rectangle(background_r, false, static_cast<color_rgb>(0x3399FF)); 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);
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);
} if(!item.image.empty())
{
if(!item.image.empty()) auto imgsize = item.image.size();
{
auto imgsize = item.image.size(); if (imgsize.width > scale) imgsize.width = scale;
if (imgsize.height > scale) imgsize.height = scale;
if (imgsize.width > scale) imgsize.width = scale;
if (imgsize.height > scale) imgsize.height = scale; nana::point pos(
x + static_cast<int>(scale + extra_size - imgsize.width) / 2,
nana::point pos( y + static_cast<int>(height - imgsize.height) / 2);
x + static_cast<int>(scale + extra_size - imgsize.width) / 2,
y + static_cast<int>(height - imgsize.height) / 2); item.image.paste(::nana::rectangle{ imgsize }, graph, pos);
if(item.enable == false)
item.image.paste(::nana::rectangle{ imgsize }, graph, pos); {
if(item.enable == false) nana::paint::graphics gh(imgsize);
{ gh.bitblt(::nana::rectangle{ imgsize }, graph, pos);
nana::paint::graphics gh(imgsize); gh.rgb_to_wb();
gh.bitblt(::nana::rectangle{ imgsize }, graph, pos); gh.paste(graph, pos.x, pos.y);
gh.rgb_to_wb(); }
gh.paste(graph, pos.x, pos.y); else if (state == state_t::normal)
} {
else if (state == state_t::normal) graph.blend(nana::rectangle(pos, imgsize), ::nana::color(0xc0, 0xdd, 0xfc).blend(bgcolor, 0.5), 0.25);
{ }
graph.blend(nana::rectangle(pos, imgsize), ::nana::color(0xc0, 0xdd, 0xfc).blend(bgcolor, 0.5), 0.25);
} x += scale;
width -= scale;
x += scale; }
width -= scale;
} if(textout)
{
if(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); }
}
} protected:
nana::paint::graphics& graph;
protected: bool textout;
nana::paint::graphics& graph; unsigned scale;
bool textout; ::nana::color bgcolor;
unsigned scale; };
::nana::color bgcolor;
}; struct drawer::drawer_impl_type
{
struct drawer::drawer_impl_type event_handle event_size{ nullptr };
{ paint::graphics* graph_ptr{ nullptr };
event_handle event_size{ nullptr };
paint::graphics* graph_ptr{ nullptr }; unsigned scale{16};
bool textout{false};
unsigned scale{16}; size_type which{npos};
bool textout{false}; item_renderer::state_t state{item_renderer::state_t::normal};
size_type which{npos};
item_renderer::state_t state{item_renderer::state_t::normal}; item_container items;
::nana::tooltip tooltip;
item_container items; };
::nana::tooltip tooltip;
}; //class drawer
drawer::drawer()
//class drawer : impl_(new drawer_impl_type)
drawer::drawer() {
: impl_(new drawer_impl_type) }
{
} drawer::~drawer()
{
drawer::~drawer() delete impl_;
{ }
delete impl_;
} item_container& drawer::items() const
{
item_container& drawer::items() const return impl_->items;
{ }
return impl_->items;
} void drawer::scale(unsigned s)
{
void drawer::scale(unsigned s) impl_->scale = s;
{
impl_->scale = s; for(auto m : impl_->items.container())
_m_calc_pixels(m, true);
for(auto m : impl_->items.container()) }
_m_calc_pixels(m, true);
} void drawer::refresh(graph_reference graph)
{
void drawer::refresh(graph_reference graph) int x = 2, y = 2;
{
int x = 2, y = 2; auto bgcolor = API::bgcolor(widget_->handle());
graph.palette(true, bgcolor);
auto bgcolor = API::bgcolor(widget_->handle()); graph.gradual_rectangle(rectangle{ graph.size() }, bgcolor.blend(colors::white, 0.1), bgcolor.blend(colors::black, 0.05), true);
graph.palette(true, bgcolor);
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);
size_type index = 0;
item_renderer ir(graph, impl_->textout, impl_->scale, bgcolor);
size_type index = 0; for (auto item : impl_->items.container())
{
for (auto item : impl_->items.container()) if (item)
{ {
if (item) _m_calc_pixels(item, false);
{ item->position = x;
_m_calc_pixels(item, false); ir(x, y, item->pixels, impl_->scale + ir.extra_size, *item, (index == impl_->which ? impl_->state : item_renderer::state_t::normal));
item->position = x; x += item->pixels;
ir(x, y, item->pixels, impl_->scale + ir.extra_size, *item, (index == impl_->which ? impl_->state : item_renderer::state_t::normal)); }
x += item->pixels; else
} {
else x += 2;
{ graph.line({ x, y + 2 }, { x, y + static_cast<int>(impl_->scale + ir.extra_size) - 4 }, static_cast<color_rgb>(0x808080));
x += 2; x += 4;
graph.line({ x, y + 2 }, { x, y + static_cast<int>(impl_->scale + ir.extra_size) - 4 }, static_cast<color_rgb>(0x808080)); }
x += 4; ++index;
}
++index; //Reset the x position of items which are right aligned
//Contributed by kmribti(pr#105)
//Reset the x position of items which are right aligned if (index == impl_->items.right() && index < impl_->items.size())
//Contributed by kmribti(pr#105) {
if (index == impl_->items.right() && index < impl_->items.size()) unsigned total_x = 0;
{ for (size_t i = index; i < impl_->items.size(); i++) {
unsigned total_x = 0; if (impl_->items.at(i) == nullptr) {
for (size_t i = index; i < impl_->items.size(); i++) { total_x += 8; // we assume that separator has width = 8.
if (impl_->items.at(i) == nullptr) { }
total_x += 8; // we assume that separator has width = 8. else {
} _m_calc_pixels(impl_->items.at(i), false);
else { total_x += impl_->items.at(i)->pixels;
_m_calc_pixels(impl_->items.at(i), false); }
total_x += impl_->items.at(i)->pixels; }
}
} x = graph.size().width - total_x - 4;
}
x = graph.size().width - total_x - 4; }
} }
}
} void drawer::attached(widget_reference widget, graph_reference graph)
{
void drawer::attached(widget_reference widget, graph_reference graph) impl_->graph_ptr = &graph;
{
impl_->graph_ptr = &graph; widget_ = static_cast< ::nana::toolbar*>(&widget);
widget.caption("nana toolbar");
widget_ = static_cast< ::nana::toolbar*>(&widget);
widget.caption("nana toolbar"); if (widget_->detached()) return;
if (widget_->detached()) return; impl_->event_size = API::events(widget.parent()).resized.connect_unignorable([this](const arg_resized& arg)
{
impl_->event_size = API::events(widget.parent()).resized.connect_unignorable([this](const arg_resized& arg) auto wd = widget_->handle();
{ API::window_size(wd, nana::size(arg.width, widget_->size().height));
auto wd = widget_->handle(); API::update_window(wd);
API::window_size(wd, nana::size(arg.width, widget_->size().height)); });
API::update_window(wd); }
});
} void drawer::detached()
{
void drawer::detached() API::umake_event(impl_->event_size);
{ impl_->event_size = nullptr;
API::umake_event(impl_->event_size); impl_->graph_ptr = nullptr;
impl_->event_size = nullptr; }
impl_->graph_ptr = nullptr;
} void drawer::mouse_move(graph_reference graph, const arg_mouse& arg)
{
void drawer::mouse_move(graph_reference graph, const arg_mouse& arg) if (arg.left_button)
{ return;
if (arg.left_button)
return; size_type which = _m_which(arg.pos, true);
if(impl_->which != which)
size_type which = _m_which(arg.pos, true); {
if(impl_->which != which) auto & container = impl_->items.container();
{ if (impl_->which != npos && container.at(impl_->which)->enable)
auto & container = impl_->items.container(); {
if (impl_->which != npos && container.at(impl_->which)->enable) ::nana::arg_toolbar arg{ *widget_, impl_->which };
{ widget_->events().leave.emit(arg, widget_->handle());
::nana::arg_toolbar arg{ *widget_, impl_->which }; }
widget_->events().leave.emit(arg, widget_->handle());
} impl_->which = which;
if (which == npos || container.at(which)->enable)
impl_->which = which; {
if (which == npos || container.at(which)->enable) impl_->state = item_renderer::state_t::highlighted;
{
impl_->state = item_renderer::state_t::highlighted; refresh(graph);
API::dev::lazy_refresh();
refresh(graph);
API::dev::lazy_refresh(); if (impl_->state == item_renderer::state_t::highlighted)
{
if (impl_->state == item_renderer::state_t::highlighted) ::nana::arg_toolbar arg{ *widget_, which };
{ widget_->events().enter.emit(arg, widget_->handle());
::nana::arg_toolbar arg{ *widget_, which }; }
widget_->events().enter.emit(arg, widget_->handle()); }
}
} if(which != npos)
impl_->tooltip.show(widget_->handle(), nana::point(arg.pos.x, arg.pos.y + 20), (*(container.begin() + which))->text, 0);
if(which != npos) else
impl_->tooltip.show(widget_->handle(), nana::point(arg.pos.x, arg.pos.y + 20), (*(container.begin() + which))->text, 0); impl_->tooltip.close();
else }
impl_->tooltip.close(); }
}
} void drawer::mouse_leave(graph_reference graph, const arg_mouse&)
{
void drawer::mouse_leave(graph_reference graph, const arg_mouse&) if(impl_->which != npos)
{ {
if(impl_->which != npos) size_type which = impl_->which;
{
size_type which = impl_->which; impl_->which = npos;
refresh(graph);
impl_->which = npos; API::dev::lazy_refresh();
refresh(graph);
API::dev::lazy_refresh(); if (which != npos && impl_->items.at(which)->enable)
{
if (which != npos && impl_->items.at(which)->enable) ::nana::arg_toolbar arg{ *widget_, which };
{ widget_->events().leave.emit(arg, widget_->handle());
::nana::arg_toolbar arg{ *widget_, which }; }
widget_->events().leave.emit(arg, widget_->handle()); }
} impl_->tooltip.close();
} }
impl_->tooltip.close();
} void drawer::mouse_down(graph_reference graph, const arg_mouse&)
{
void drawer::mouse_down(graph_reference graph, const arg_mouse&) impl_->tooltip.close();
{ if(impl_->which != npos && (impl_->items.at(impl_->which)->enable))
impl_->tooltip.close(); {
if(impl_->which != npos && (impl_->items.at(impl_->which)->enable)) impl_->state = item_renderer::state_t::selected;
{ refresh(graph);
impl_->state = item_renderer::state_t::selected; API::dev::lazy_refresh();
refresh(graph); }
API::dev::lazy_refresh(); }
}
} void drawer::mouse_up(graph_reference graph, const arg_mouse& arg)
{
void drawer::mouse_up(graph_reference graph, const arg_mouse& arg) if(impl_->which != npos)
{ {
if(impl_->which != npos) size_type which = _m_which(arg.pos, false);
{ if(impl_->which == which)
size_type which = _m_which(arg.pos, false); {
if(impl_->which == which) ::nana::arg_toolbar arg{ *widget_, which };
{ widget_->events().selected.emit(arg, widget_->handle());
::nana::arg_toolbar arg{ *widget_, which };
widget_->events().selected.emit(arg, widget_->handle()); impl_->state = item_renderer::state_t::highlighted;
}
impl_->state = item_renderer::state_t::highlighted; else
} {
else impl_->which = which;
{ impl_->state = (which == npos ? item_renderer::state_t::normal : item_renderer::state_t::highlighted);
impl_->which = which; }
impl_->state = (which == npos ? item_renderer::state_t::normal : item_renderer::state_t::highlighted);
} refresh(graph);
API::dev::lazy_refresh();
refresh(graph); }
API::dev::lazy_refresh(); }
}
} drawer::size_type drawer::_m_which(point pos, bool want_if_disabled) const
{
drawer::size_type drawer::_m_which(point pos, bool want_if_disabled) const if (pos.x < 2 || pos.y < 2 || pos.y >= static_cast<int>(impl_->scale + item_renderer::extra_size + 2)) return npos;
{
if (pos.x < 2 || pos.y < 2 || pos.y >= static_cast<int>(impl_->scale + item_renderer::extra_size + 2)) return npos; pos.x -= 2;
pos.x -= 2; std::size_t index = 0;
for(auto m: impl_->items.container())
std::size_t index = 0; {
for(auto m: impl_->items.container()) unsigned x = static_cast<unsigned>(pos.x);
{ if (m && x >= m->position && x <= (m->position+m->pixels))
unsigned x = static_cast<unsigned>(pos.x); return (((!m) || (!m->enable && !want_if_disabled)) ? npos : index);
if (m && x >= m->position && x <= (m->position+m->pixels))
return (((!m) || (!m->enable && !want_if_disabled)) ? npos : index); ++index;
}
++index; return npos;
} }
return npos;
} void drawer::_m_calc_pixels(item_type* item, bool force)
{
void drawer::_m_calc_pixels(item_type* item, bool force) if (item && (force || (0 == item->pixels)))
{ {
if (item && (force || (0 == item->pixels))) if (item->text.size())
{ item->textsize = impl_->graph_ptr->text_extent_size(item->text);
if (item->text.size())
item->textsize = impl_->graph_ptr->text_extent_size(item->text); if (item->image.empty() == false)
item->pixels = impl_->scale + item_renderer::extra_size;
if (item->image.empty() == false)
item->pixels = impl_->scale + item_renderer::extra_size; if (item->textsize.width && impl_->textout)
item->pixels += item->textsize.width + 8;
if (item->textsize.width && impl_->textout) }
item->pixels += item->textsize.width + 8; }
} //class drawer
}
//class drawer // Item Proxy
}//end namespace toolbar void item_proxy::enable(bool enable_state)
}//end namespace drawerbase {
widget.enable(button, enable_state);
//class toolbar }
toolbar::toolbar(window wd, bool visible, bool detached) : }//end namespace toolbar
detached_(detached) }//end namespace drawerbase
{
create(wd, rectangle(), visible); //class toolbar
} toolbar::toolbar(window wd, bool visible, bool detached) :
detached_(detached)
toolbar::toolbar(window wd, const rectangle& r, bool visible, bool detached) : {
detached_(detached) create(wd, rectangle(), visible);
{ }
create(wd, r, visible);
} toolbar::toolbar(window wd, const rectangle& r, bool visible, bool detached) :
detached_(detached)
//Contributed by kmribti(pr#105) {
void toolbar::go_right() create(wd, r, visible);
{ }
get_drawer_trigger().items().go_right();
} //Contributed by kmribti(pr#105)
void toolbar::go_right()
void toolbar::separate() {
{ get_drawer_trigger().items().go_right();
get_drawer_trigger().items().separate(); }
API::refresh_window(handle());
} void toolbar::separate()
{
void toolbar::append(const std::string& text, const nana::paint::image& img) get_drawer_trigger().items().separate();
{ API::refresh_window(handle());
get_drawer_trigger().items().push_back(text, img); }
API::refresh_window(handle());
} drawerbase::toolbar::item_proxy toolbar::append(const std::string& text, const nana::paint::image& img)
{
void toolbar::append(const std::string& text) get_drawer_trigger().items().push_back(text, img);
{ API::refresh_window(handle());
get_drawer_trigger().items().push_back(text, {}); return {*this, get_drawer_trigger().items().size() - 1u};
API::refresh_window(this->handle()); }
}
drawerbase::toolbar::item_proxy toolbar::append(const std::string& text)
bool toolbar::enable(size_type pos) const {
{ get_drawer_trigger().items().push_back(text, {});
auto & items = get_drawer_trigger().items(); API::refresh_window(this->handle());
return {*this, get_drawer_trigger().items().size() - 1u};
if (items.size() <= pos) }
return false;
bool toolbar::enable(size_type pos) const
auto m = items.at(pos); {
return (m && m->enable); auto & items = get_drawer_trigger().items();
}
if (items.size() <= pos)
void toolbar::enable(size_type pos, bool eb) return false;
{
auto & items = get_drawer_trigger().items(); auto m = items.at(pos);
return (m && m->enable);
if (items.size() > pos) }
{
auto m = items.at(pos); void toolbar::enable(size_type pos, bool eb)
if (m && (m->enable != eb)) {
{ auto & items = get_drawer_trigger().items();
m->enable = eb;
API::refresh_window(this->handle()); if (items.size() > pos)
} {
} auto m = items.at(pos);
} if (m && (m->enable != eb))
{
void toolbar::scale(unsigned s) m->enable = eb;
{ API::refresh_window(this->handle());
get_drawer_trigger().scale(s); }
API::refresh_window(handle()); }
} }
//end class toolbar
}//end namespace nana void toolbar::scale(unsigned s)
{
get_drawer_trigger().scale(s);
API::refresh_window(handle());
}
//end class toolbar
}//end namespace nana