fix menubar behavior issue
no key_press and key_release after destroying caret under X11 missing some key_press events menu text color issue
This commit is contained in:
@@ -37,21 +37,25 @@ namespace nana
|
||||
::nana::color clr{ 0xaf, 0xc7, 0xe3 };
|
||||
graph.rectangle(r, false, clr);
|
||||
|
||||
auto right = r.right() - 1;
|
||||
auto bottom = r.bottom() - 1;
|
||||
graph.set_color(colors::white);
|
||||
graph.set_pixel(r.x, r.y);
|
||||
graph.set_pixel(r.x + r.width - 1, r.y);
|
||||
graph.set_pixel(r.x, r.y + r.height - 1);
|
||||
graph.set_pixel(r.x + r.width - 1, r.y + r.height - 1);
|
||||
graph.set_pixel(right, r.y);
|
||||
graph.set_pixel(r.x, bottom);
|
||||
graph.set_pixel(right, bottom);
|
||||
|
||||
--right;
|
||||
--bottom;
|
||||
graph.set_color(clr);
|
||||
graph.set_pixel(r.x + 1, r.y + 1);
|
||||
graph.set_pixel(r.x + r.width - 2, r.y + 1);
|
||||
graph.set_pixel(r.x + 1, r.y + r.height - 2);
|
||||
graph.set_pixel(r.x + r.width - 2, r.y + r.height - 2);
|
||||
graph.set_pixel(right, r.y + 1);
|
||||
graph.set_pixel(r.x + 1, bottom);
|
||||
graph.set_pixel(right, bottom);
|
||||
|
||||
nana::rectangle po_r(r);
|
||||
graph.rectangle(po_r.pare_off(1), false, { 0xEB, 0xF4, 0xFB });
|
||||
graph.gradual_rectangle(po_r.pare_off(1), { 0xDD, 0xEC, 0xFD }, { 0xC2, 0xDC, 0xFD }, true);
|
||||
graph.rectangle(po_r.pare_off(1), false, static_cast<color_rgb>(0xEBF4FB));
|
||||
graph.gradual_rectangle(po_r.pare_off(1), static_cast<color_rgb>(0xDDECFD), static_cast<color_rgb>(0xC2DCFD), true);
|
||||
}
|
||||
else
|
||||
graph.rectangle(r, true, colors::white);
|
||||
@@ -113,13 +117,8 @@ namespace nana
|
||||
class drawer_impl
|
||||
{
|
||||
public:
|
||||
typedef widget& widget_reference;
|
||||
typedef nana::paint::graphics& graph_reference;
|
||||
|
||||
drawer_impl()
|
||||
: widget_(nullptr), graph_(nullptr), image_pixels_(16),
|
||||
ignore_first_mouseup_(true), module_(nullptr)
|
||||
{}
|
||||
using widget_reference = widget&;
|
||||
using graph_reference = paint::graphics&;
|
||||
|
||||
void clear_state()
|
||||
{
|
||||
@@ -151,25 +150,19 @@ namespace nana
|
||||
{
|
||||
if(scrollbar_.empty()) return;
|
||||
|
||||
bool update = false;
|
||||
const auto before_change = state_.offset_y;
|
||||
if(upwards)
|
||||
{
|
||||
if(state_.offset_y)
|
||||
{
|
||||
if (before_change)
|
||||
--(state_.offset_y);
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if((state_.offset_y + module_->max_items) < module_->items.size())
|
||||
{
|
||||
if ((before_change + module_->max_items) < module_->items.size())
|
||||
++(state_.offset_y);
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(update)
|
||||
if(before_change != state_.offset_y)
|
||||
{
|
||||
draw();
|
||||
scrollbar_.value(state_.offset_y);
|
||||
@@ -323,8 +316,7 @@ namespace nana
|
||||
state_.renderer->image(_m_image_enabled(), image_pixels_);
|
||||
for(std::size_t i = state_.offset_y; i < items; ++i)
|
||||
{
|
||||
item_renderer::state_t state = item_renderer::StateNone;
|
||||
if(i == state_.index) state = item_renderer::StateHighlighted;
|
||||
auto state = (i != state_.index ? item_renderer::StateNone : item_renderer::StateHighlighted);
|
||||
|
||||
state_.renderer->render(*widget_, *graph_, item_r, module_->items[i].get(), state);
|
||||
item_r.y += item_pixels;
|
||||
@@ -384,20 +376,20 @@ namespace nana
|
||||
scrollbar_.close();
|
||||
}
|
||||
private:
|
||||
widget * widget_;
|
||||
nana::paint::graphics * graph_;
|
||||
unsigned image_pixels_; //Define the width pixels of the image area
|
||||
widget * widget_{nullptr};
|
||||
nana::paint::graphics * graph_{nullptr};
|
||||
unsigned image_pixels_{16}; //Define the width pixels of the image area
|
||||
|
||||
bool ignore_first_mouseup_;
|
||||
bool ignore_first_mouseup_{true};
|
||||
struct state_type
|
||||
{
|
||||
std::size_t offset_y;
|
||||
std::size_t index; //The index of the selected item.
|
||||
std::size_t offset_y{0};
|
||||
std::size_t index{npos}; //The index of the selected item.
|
||||
|
||||
item_renderer * const orig_renderer;
|
||||
item_renderer * renderer;
|
||||
|
||||
state_type(): offset_y(0), index(npos), orig_renderer(new def_item_renderer), renderer(orig_renderer){}
|
||||
state_type(): orig_renderer(new def_item_renderer), renderer(orig_renderer){}
|
||||
~state_type()
|
||||
{
|
||||
delete orig_renderer;
|
||||
@@ -405,7 +397,7 @@ namespace nana
|
||||
}state_;
|
||||
nana::scroll<true> scrollbar_;
|
||||
|
||||
const module_def* module_;
|
||||
const module_def* module_{nullptr};
|
||||
};
|
||||
|
||||
//class drawer_impl;
|
||||
|
||||
@@ -588,8 +588,6 @@ namespace nana
|
||||
|
||||
std::pair<std::size_t, std::size_t> _m_locate(dstream::linecontainer::iterator& i, std::size_t pos)
|
||||
{
|
||||
//std::pair<std::size_t, std::size_t> r; //deprecated
|
||||
|
||||
std::size_t n = i->data_ptr->text().length();
|
||||
while(pos >= n)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A Menu implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2009-2014 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2009-2015 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -151,7 +151,7 @@ namespace nana
|
||||
|
||||
void item_text(graph_reference graph, const nana::point& pos, const nana::string& text, unsigned text_pixels, const attr& at)
|
||||
{
|
||||
graph.set_color(at.enabled ? colors::black : colors::gray_border);
|
||||
graph.set_text_color(at.enabled ? colors::black : colors::gray_border);
|
||||
nana::paint::text_renderer tr(graph);
|
||||
tr.render(pos, text.c_str(), text.length(), text_pixels, true);
|
||||
}
|
||||
|
||||
@@ -58,16 +58,6 @@ namespace nana
|
||||
cont_.push_back(new item_type(text, shortkey));
|
||||
}
|
||||
|
||||
nana::menu* get_menu(std::size_t index) const
|
||||
{
|
||||
return (index < cont_.size() ? &(cont_[index]->menu_obj) : nullptr);
|
||||
}
|
||||
|
||||
const item_type& at(std::size_t index) const
|
||||
{
|
||||
return *cont_.at(index);
|
||||
}
|
||||
|
||||
std::size_t find(unsigned long shortkey) const
|
||||
{
|
||||
if(shortkey)
|
||||
@@ -98,19 +88,19 @@ namespace nana
|
||||
:handle_(wd), graph_(graph)
|
||||
{}
|
||||
|
||||
void item_renderer::background(const nana::point& pos, const nana::size& size, state_t state)
|
||||
void item_renderer::background(const nana::point& pos, const nana::size& size, state item_state)
|
||||
{
|
||||
auto bground = API::fgcolor(handle_);
|
||||
::nana::color border, body, corner;
|
||||
|
||||
switch(state)
|
||||
switch (item_state)
|
||||
{
|
||||
case item_renderer::state_highlight:
|
||||
case state::highlighted:
|
||||
border = colors::highlight;
|
||||
body.from_rgb(0xC0, 0xDD, 0xFC);
|
||||
corner = body.blend(bground, 0.5);
|
||||
break;
|
||||
case item_renderer::state_selected:
|
||||
case state::selected:
|
||||
border = colors::dark_border;
|
||||
body = colors::white;
|
||||
corner = body.blend(bground, 0.5);
|
||||
@@ -132,9 +122,9 @@ namespace nana
|
||||
graph_.rectangle(r.pare_off(1), true, body);
|
||||
}
|
||||
|
||||
void item_renderer::caption(int x, int y, const nana::string& text)
|
||||
void item_renderer::caption(const point& pos, const nana::string& text)
|
||||
{
|
||||
graph_.string({ x, y }, text, colors::black);
|
||||
graph_.string(pos, text, colors::black);
|
||||
}
|
||||
//end class item_renderer
|
||||
|
||||
@@ -150,22 +140,26 @@ namespace nana
|
||||
|
||||
nana::menu* trigger::push_back(const ::nana::string& text)
|
||||
{
|
||||
::nana::string::value_type shkey;
|
||||
::nana::char_t shkey;
|
||||
API::transform_shortkey_text(text, shkey, nullptr);
|
||||
|
||||
if(shkey)
|
||||
API::register_shortkey(widget_->handle(), shkey);
|
||||
|
||||
auto i = items_->cont().size();
|
||||
auto pos = items_->cont().size();
|
||||
items_->append(text, shkey);
|
||||
_m_draw();
|
||||
API::update_window(*widget_);
|
||||
return items_->get_menu(i);
|
||||
|
||||
return at(pos);
|
||||
}
|
||||
|
||||
nana::menu* trigger::at(std::size_t index) const
|
||||
nana::menu* trigger::at(std::size_t pos) const
|
||||
{
|
||||
return items_->get_menu(index);
|
||||
if (pos < items_->cont().size())
|
||||
return &(items_->cont()[pos]->menu_obj);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::size_t trigger::size() const
|
||||
@@ -222,22 +216,17 @@ namespace nana
|
||||
void trigger::mouse_down(graph_reference graph, const arg_mouse& arg)
|
||||
{
|
||||
state_.nullify_mouse = false;
|
||||
|
||||
state_.active = _m_item_by_pos(arg.pos);
|
||||
if(state_.menu_active == false)
|
||||
|
||||
if (npos != state_.active)
|
||||
{
|
||||
if(state_.active != npos)
|
||||
{
|
||||
if (!state_.menu_active)
|
||||
state_.menu_active = true;
|
||||
_m_popup_menu();
|
||||
}
|
||||
else
|
||||
_m_total_close(true);
|
||||
}
|
||||
else if(npos == state_.active)
|
||||
_m_total_close(true);
|
||||
else
|
||||
|
||||
_m_popup_menu();
|
||||
}
|
||||
else
|
||||
_m_total_close();
|
||||
|
||||
_m_draw();
|
||||
API::lazy_refresh();
|
||||
@@ -255,11 +244,10 @@ namespace nana
|
||||
else
|
||||
{
|
||||
state_.behavior = state_.behavior_none;
|
||||
_m_total_close(true);
|
||||
_m_total_close();
|
||||
_m_draw();
|
||||
API::lazy_refresh();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void trigger::focus(graph_reference, const arg_focus& arg)
|
||||
@@ -284,10 +272,10 @@ namespace nana
|
||||
switch(arg.key)
|
||||
{
|
||||
case keyboard::os_arrow_down:
|
||||
state_.menu->goto_next(true); break;
|
||||
case keyboard::backspace:
|
||||
case keyboard::os_arrow_up:
|
||||
state_.menu->goto_next(false); break;
|
||||
state_.menu->goto_next(keyboard::os_arrow_down == arg.key);
|
||||
break;
|
||||
case keyboard::os_arrow_right:
|
||||
if(state_.menu->goto_submen() == false)
|
||||
_m_move(false);
|
||||
@@ -305,19 +293,14 @@ namespace nana
|
||||
}
|
||||
break;
|
||||
case keyboard::enter:
|
||||
state_.delay_restore = true;
|
||||
state_.menu->pick();
|
||||
break;
|
||||
default:
|
||||
if(2 != state_.menu->send_shortkey(arg.key))
|
||||
if (2 != state_.menu->send_shortkey(arg.key))
|
||||
{
|
||||
if (state_.active != npos)
|
||||
{
|
||||
state_.delay_restore = true;
|
||||
_m_total_close(false);
|
||||
if (arg.key == 18) //ALT
|
||||
state_.behavior = state_.behavior_focus;
|
||||
}
|
||||
_m_total_close();
|
||||
if (arg.key == 18) //ALT
|
||||
state_.behavior = state_.behavior_focus;
|
||||
}
|
||||
else
|
||||
state_.menu->goto_submen();
|
||||
@@ -328,18 +311,15 @@ namespace nana
|
||||
switch(arg.key)
|
||||
{
|
||||
case keyboard::os_arrow_right:
|
||||
_m_move(false);
|
||||
break;
|
||||
case keyboard::backspace:
|
||||
case keyboard::os_arrow_left:
|
||||
_m_move(true);
|
||||
_m_move(keyboard::os_arrow_right != arg.key);
|
||||
break;
|
||||
case keyboard::escape:
|
||||
if(state_.behavior == state_.behavior_focus)
|
||||
{
|
||||
state_.active= npos;
|
||||
state_.behavior = state_.behavior_none;
|
||||
API::restore_menubar_taken_window();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,12 +349,6 @@ namespace nana
|
||||
_m_draw();
|
||||
API::lazy_refresh();
|
||||
}
|
||||
|
||||
if (state_.delay_restore)
|
||||
{
|
||||
API::restore_menubar_taken_window();
|
||||
state_.delay_restore = false;
|
||||
}
|
||||
}
|
||||
|
||||
void trigger::shortkey(graph_reference graph, const arg_keyboard& arg)
|
||||
@@ -430,33 +404,44 @@ namespace nana
|
||||
|
||||
bool trigger::_m_popup_menu()
|
||||
{
|
||||
if(state_.menu_active && (state_.menu != items_->get_menu(state_.active)))
|
||||
{
|
||||
std::size_t index = state_.active;
|
||||
_m_close_menu();
|
||||
state_.active = index;
|
||||
auto& items = items_->cont();
|
||||
|
||||
state_.menu = items_->get_menu(state_.active);
|
||||
if(state_.menu)
|
||||
auto pos = state_.active;
|
||||
if (pos >= items.size())
|
||||
return false;
|
||||
|
||||
if(state_.menu_active && (state_.menu != &(items[pos]->menu_obj)))
|
||||
{
|
||||
API::dev::delay_restore(true);
|
||||
_m_close_menu();
|
||||
API::dev::delay_restore(false);
|
||||
state_.active = pos;
|
||||
|
||||
auto & m = items[pos];
|
||||
state_.menu = &(m->menu_obj);
|
||||
state_.menu->destroy_answer([this]
|
||||
{
|
||||
const item_type &m = items_->at(state_.active);
|
||||
state_.menu->destroy_answer(std::bind(&trigger::_m_unload_menu_window, this));
|
||||
menu_accessor::popup(*state_.menu, widget_->handle(), m.pos.x, m.pos.y + m.size.height);
|
||||
return true;
|
||||
}
|
||||
state_.menu = nullptr;
|
||||
if (state_.passive_close)
|
||||
{
|
||||
_m_total_close();
|
||||
|
||||
_m_draw();
|
||||
API::update_window(widget_->handle());
|
||||
}
|
||||
});
|
||||
menu_accessor::popup(*state_.menu, *widget_, m->pos.x, m->pos.y + static_cast<int>(m->size.height));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void trigger::_m_total_close(bool try_restore)
|
||||
void trigger::_m_total_close()
|
||||
{
|
||||
_m_close_menu();
|
||||
state_.menu_active = false;
|
||||
state_.behavior = state_.behavior_none;
|
||||
|
||||
if (try_restore)
|
||||
API::restore_menubar_taken_window();
|
||||
|
||||
auto pos = API::cursor_position();
|
||||
API::calc_window_point(widget_->handle(), pos);
|
||||
state_.active = _m_item_by_pos(pos);
|
||||
@@ -475,18 +460,6 @@ namespace nana
|
||||
return false;
|
||||
}
|
||||
|
||||
void trigger::_m_unload_menu_window()
|
||||
{
|
||||
state_.menu = nullptr;
|
||||
if(state_.passive_close)
|
||||
{
|
||||
_m_total_close(false);
|
||||
|
||||
_m_draw();
|
||||
API::update_window(widget_->handle());
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t trigger::_m_item_by_pos(const ::nana::point& pos)
|
||||
{
|
||||
if((2 <= pos.x) && (2 <= pos.y) && (pos.y < 25))
|
||||
@@ -534,9 +507,9 @@ namespace nana
|
||||
for(auto i : items_->cont())
|
||||
{
|
||||
//Transform the text if it contains the hotkey character
|
||||
nana::string::value_type hotkey;
|
||||
nana::string::size_type hotkey_pos;
|
||||
nana::string text = API::transform_shortkey_text(i->text, hotkey, &hotkey_pos);
|
||||
::nana::char_t hotkey;
|
||||
::nana::string::size_type hotkey_pos;
|
||||
auto text = API::transform_shortkey_text(i->text, hotkey, &hotkey_pos);
|
||||
|
||||
nana::size text_s = graph_->text_extent_size(text);
|
||||
|
||||
@@ -545,10 +518,11 @@ namespace nana
|
||||
i->pos = item_pos;
|
||||
i->size = item_s;
|
||||
|
||||
item_renderer::state_t state = (index != state_.active ? ird.state_normal : (state_.menu_active ? ird.state_selected : ird.state_highlight));
|
||||
ird.background(item_pos, item_s, state);
|
||||
using state = item_renderer::state;
|
||||
state item_state = (index != state_.active ? state::normal : (state_.menu_active ? state::selected : state::highlighted));
|
||||
ird.background(item_pos, item_s, item_state);
|
||||
|
||||
if(state == ird.state_selected)
|
||||
if (state::selected == item_state)
|
||||
{
|
||||
int x = item_pos.x + item_s.width;
|
||||
int y1 = item_pos.y + 2, y2 = item_pos.y + item_s.height - 1;
|
||||
@@ -558,7 +532,7 @@ namespace nana
|
||||
|
||||
//Draw text, the text is transformed from orignal for hotkey character
|
||||
int text_top_off = (item_s.height - text_s.height) / 2;
|
||||
ird.caption(item_pos.x + 8, item_pos.y + text_top_off, text);
|
||||
ird.caption({ item_pos.x + 8, item_pos.y + text_top_off }, text);
|
||||
|
||||
if(hotkey)
|
||||
{
|
||||
@@ -584,8 +558,7 @@ namespace nana
|
||||
menu_active(false),
|
||||
passive_close(true),
|
||||
nullify_mouse(false),
|
||||
menu(nullptr),
|
||||
delay_restore(false)
|
||||
menu(nullptr)
|
||||
{}
|
||||
//end struct state_type
|
||||
//end class trigger
|
||||
|
||||
Reference in New Issue
Block a user