refactor functions
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Implementations of Inner Forward Declaration
|
* Implementations of Inner Forward Declaration
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2015 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
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
#include "../../paint/graphics.hpp"
|
#include "../../paint/graphics.hpp"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace nana{
|
namespace nana{
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -62,12 +61,15 @@ namespace nana{
|
|||||||
void umake(window wd)
|
void umake(window wd)
|
||||||
{
|
{
|
||||||
if (wd == nullptr) return;
|
if (wd == nullptr) return;
|
||||||
auto i = std::find_if(keybase_.begin(), keybase_.end(), [wd](const item_type& m){
|
|
||||||
return (m.handle == wd);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (i != keybase_.end())
|
for (auto i = keybase_.begin(), end = keybase_.end(); i != end; ++i)
|
||||||
|
{
|
||||||
|
if (i->handle == wd)
|
||||||
|
{
|
||||||
keybase_.erase(i);
|
keybase_.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned long> keys(window wd) const
|
std::vector<unsigned long> keys(window wd) const
|
||||||
|
|||||||
@@ -139,16 +139,16 @@ namespace nana
|
|||||||
void clear(); ///< Erases all of the items.
|
void clear(); ///< Erases all of the items.
|
||||||
/// Closes the menu. It does not destroy the menu; just close the window for the menu.
|
/// Closes the menu. It does not destroy the menu; just close the window for the menu.
|
||||||
void close();
|
void close();
|
||||||
void image(std::size_t index, const paint::image& icon);
|
void image(std::size_t pos, const paint::image& icon);
|
||||||
void check_style(std::size_t index, checks);
|
void check_style(std::size_t pos, checks);
|
||||||
void checked(std::size_t index, bool);
|
void checked(std::size_t pos, bool);
|
||||||
bool checked(std::size_t index) const;
|
bool checked(std::size_t pos) const;
|
||||||
void enabled(std::size_t index, bool);///< Enables or disables the mouse or keyboard input for the item.
|
void enabled(std::size_t pos, bool);///< Enables or disables the mouse or keyboard input for the item.
|
||||||
bool enabled(std::size_t index) const;
|
bool enabled(std::size_t pos) const;
|
||||||
void erase(std::size_t index); ///< Removes the item
|
void erase(std::size_t pos); ///< Removes the item
|
||||||
bool link(std::size_t index, menu& menu_obj);///< Link a menu to the item as a sub menu.
|
bool link(std::size_t pos, menu& menu_obj);///< Link a menu to the item as a sub menu.
|
||||||
menu * link(std::size_t index); ///< Retrieves a linked sub menu of the item.
|
menu * link(std::size_t pos); ///< Retrieves a linked sub menu of the item.
|
||||||
menu *create_sub_menu(std::size_t index);
|
menu *create_sub_menu(std::size_t pos);
|
||||||
void popup(window owner, int x, int y); ///< Popup the menu at the owner window.
|
void popup(window owner, int x, int y); ///< Popup the menu at the owner window.
|
||||||
void popup_await(window owner, int x, int y);
|
void popup_await(window owner, int x, int y);
|
||||||
void answerer(std::size_t index, const event_fn_t&); ///< Modify answerer of the specified item.
|
void answerer(std::size_t index, const event_fn_t&); ///< Modify answerer of the specified item.
|
||||||
@@ -171,7 +171,6 @@ namespace nana
|
|||||||
const pat::cloneable<renderer_interface>& renderer() const;
|
const pat::cloneable<renderer_interface>& renderer() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _m_destroy_menu_window();
|
|
||||||
void _m_popup(window, int x, int y, bool called_by_menubar);
|
void _m_popup(window, int x, int y, bool called_by_menubar);
|
||||||
private:
|
private:
|
||||||
implement * impl_;
|
implement * impl_;
|
||||||
|
|||||||
@@ -21,8 +21,6 @@
|
|||||||
#include <nana/detail/linux_X11/platform_spec.hpp>
|
#include <nana/detail/linux_X11/platform_spec.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
typedef detail::edge_nimbus_renderer<detail::bedrock::core_window_t> edge_nimbus_renderer_t;
|
typedef detail::edge_nimbus_renderer<detail::bedrock::core_window_t> edge_nimbus_renderer_t;
|
||||||
@@ -351,11 +349,12 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if(p)
|
if(p)
|
||||||
{
|
{
|
||||||
auto i = std::find(dynamic_drawing_objects_.begin(), dynamic_drawing_objects_.end(), p);
|
for (auto i = dynamic_drawing_objects_.begin(); i != dynamic_drawing_objects_.end(); ++i)
|
||||||
if (i != dynamic_drawing_objects_.end())
|
if (*i == p)
|
||||||
{
|
{
|
||||||
delete (*i);
|
delete (*i);
|
||||||
dynamic_drawing_objects_.erase(i);
|
dynamic_drawing_objects_.erase(i);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -556,6 +556,7 @@ namespace nana{
|
|||||||
{
|
{
|
||||||
::EnableWindow(native_wd, true);
|
::EnableWindow(native_wd, true);
|
||||||
::SetActiveWindow(native_wd);
|
::SetActiveWindow(native_wd);
|
||||||
|
::SetForegroundWindow(native_wd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
::PostMessage(native_wd, nana::detail::messages::async_activate, 0, 0);
|
::PostMessage(native_wd, nana::detail::messages::async_activate, 0, 0);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* An Implementation of Place for Layout
|
* An Implementation of Place for Layout
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2015 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
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#include <nana/system/platform.hpp>
|
#include <nana/system/platform.hpp>
|
||||||
#include <nana/gui/detail/native_window_interface.hpp>
|
#include <nana/gui/detail/native_window_interface.hpp>
|
||||||
#include <nana/gui/widgets/widget.hpp>
|
#include <nana/gui/widgets/widget.hpp>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@@ -54,7 +53,7 @@ namespace API
|
|||||||
if (!restrict::window_manager.available(reinterpret_cast<restrict::core_window_t*>(wd)))
|
if (!restrict::window_manager.available(reinterpret_cast<restrict::core_window_t*>(wd)))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return reinterpret_cast<restrict::core_window_t*>(wd)->together.attached_events;
|
return reinterpret_cast<restrict::core_window_t*>(wd)->together.events_ptr.get();
|
||||||
}
|
}
|
||||||
}//end namespace detail
|
}//end namespace detail
|
||||||
|
|
||||||
@@ -265,10 +264,22 @@ namespace API
|
|||||||
if((wd->thread_id == tid) && (wd->root != root))
|
if((wd->thread_id == tid) && (wd->root != root))
|
||||||
{
|
{
|
||||||
root = wd->root;
|
root = wd->root;
|
||||||
if(roots.cend() == std::find(roots.cbegin(), roots.cend(), root))
|
for (auto i = roots.cbegin(); i != roots.cend(); ++i)
|
||||||
|
{
|
||||||
|
if (*i == root)
|
||||||
|
{
|
||||||
|
root = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!root)
|
||||||
|
{
|
||||||
|
root = wd->root;
|
||||||
roots.push_back(root);
|
roots.push_back(root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(auto i : roots)
|
for(auto i : roots)
|
||||||
restrict::interface_type::close_window(i);
|
restrict::interface_type::close_window(i);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace nana
|
|||||||
sz.width -= 30;
|
sz.width -= 30;
|
||||||
sz.height -= 2;
|
sz.height -= 2;
|
||||||
graph.rectangle(false, colors::gray_border);
|
graph.rectangle(false, colors::gray_border);
|
||||||
graph.rectangle({ 1, 1, 28, sz.height }, true, { 0xf6, 0xf6, 0xf6 });
|
graph.rectangle({ 1, 1, 28, sz.height }, true, static_cast<color_rgb>(0xf6f6f6));
|
||||||
graph.rectangle({ 29, 1, sz.width, sz.height }, true, colors::white);
|
graph.rectangle({ 29, 1, sz.width, sz.height }, true, colors::white);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,17 +122,17 @@ namespace nana
|
|||||||
nana::point(r.x + r.width - 1, r.y + r.height - 1)
|
nana::point(r.x + r.width - 1, r.y + r.height - 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
graph.set_color({0xc0, 0xdd, 0xfc});
|
graph.set_color(static_cast<color_rgb>(0xc0ddfc));
|
||||||
for(int i = 0; i < 4; ++i)
|
for(int i = 0; i < 4; ++i)
|
||||||
graph.set_pixel(points[i].x, points[i].y);
|
graph.set_pixel(points[i].x, points[i].y);
|
||||||
|
|
||||||
if(at.enabled)
|
if(at.enabled)
|
||||||
graph.gradual_rectangle(nana::rectangle(r).pare_off(1), { 0xE8, 0xF0, 0xF4 }, { 0xDB,0xEC,0xF4 }, true);
|
graph.gradual_rectangle(nana::rectangle(r).pare_off(1), static_cast<color_rgb>(0xE8F0F4), static_cast<color_rgb>(0xDBECF4), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(at.checked && (checks::none != at.check_style))
|
if(at.checked && (checks::none != at.check_style))
|
||||||
{
|
{
|
||||||
graph.rectangle(r, false, { 0xCD, 0xD3, 0xE6 });
|
graph.rectangle(r, false, static_cast<color_rgb>(0xCDD3E6));
|
||||||
|
|
||||||
::nana::color clr(0xE6, 0xEF, 0xF4);
|
::nana::color clr(0xE6, 0xEF, 0xF4);
|
||||||
graph.rectangle(nana::rectangle(r).pare_off(1), true, clr);
|
graph.rectangle(nana::rectangle(r).pare_off(1), true, clr);
|
||||||
@@ -363,59 +363,58 @@ namespace nana
|
|||||||
bool goto_next(bool forword)
|
bool goto_next(bool forword)
|
||||||
{
|
{
|
||||||
state_.nullify_mouse = true;
|
state_.nullify_mouse = true;
|
||||||
if(menu_->items.size())
|
if (menu_->items.empty())
|
||||||
{
|
return false;
|
||||||
std::size_t index = state_.active;
|
|
||||||
|
auto pos = state_.active;
|
||||||
|
const auto lastpos = menu_->items.size() - 1;
|
||||||
|
|
||||||
bool end = false;
|
bool end = false;
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(forword)
|
if(forword)
|
||||||
{
|
{
|
||||||
if(index == menu_->items.size() - 1)
|
if(pos == lastpos)
|
||||||
{
|
{
|
||||||
if(end == false)
|
if (end)
|
||||||
{
|
{
|
||||||
end = true;
|
pos = npos;
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
index = npos;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(index == 0 || index == npos)
|
|
||||||
{
|
|
||||||
if(end == false)
|
|
||||||
{
|
|
||||||
end = true;
|
|
||||||
index = menu_->items.size() - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
--index;
|
|
||||||
}
|
|
||||||
if(menu_->items.at(index).flags.splitter == false)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index != npos && index != state_.active)
|
end = true;
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
state_.active = index;
|
if(pos == 0 || pos == npos)
|
||||||
|
{
|
||||||
|
if (end)
|
||||||
|
break;
|
||||||
|
|
||||||
|
end = true;
|
||||||
|
pos = lastpos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
--pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! menu_->items.at(pos).flags.splitter)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pos != npos && pos != state_.active)
|
||||||
|
{
|
||||||
|
state_.active = pos;
|
||||||
state_.sub_window = false;
|
state_.sub_window = false;
|
||||||
|
|
||||||
draw();
|
draw();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,8 +485,12 @@ namespace nana
|
|||||||
std::size_t index = 0;
|
std::size_t index = 0;
|
||||||
for(auto & m : menu_->items)
|
for(auto & m : menu_->items)
|
||||||
{
|
{
|
||||||
if(std::tolower(m.hotkey) == key)
|
if (std::tolower(m.hotkey) != key)
|
||||||
{
|
{
|
||||||
|
++index;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(!m.flags.splitter)
|
if(!m.flags.splitter)
|
||||||
{
|
{
|
||||||
if(m.sub_menu)
|
if(m.sub_menu)
|
||||||
@@ -509,8 +512,6 @@ namespace nana
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++index;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,12 +530,19 @@ namespace nana
|
|||||||
|
|
||||||
int text_top_off = (item_h_px - graph_->text_extent_size(STR("jh({[")).height) / 2;
|
int text_top_off = (item_h_px - graph_->text_extent_size(STR("jh({[")).height) / 2;
|
||||||
|
|
||||||
std::size_t index = 0;
|
std::size_t pos = 0;
|
||||||
for(auto & m : menu_->items)
|
for(auto & m : menu_->items)
|
||||||
{
|
{
|
||||||
if(false == m.flags.splitter)
|
if(m.flags.splitter)
|
||||||
{
|
{
|
||||||
renderer_interface::attr attr = _m_make_renderer_attr(index == state_.active, m);
|
graph_->set_color(colors::gray_border);
|
||||||
|
graph_->line({ item_r.x + 40, item_r.y }, { static_cast<int>(graph_->width()) - 1, item_r.y });
|
||||||
|
item_r.y += 2;
|
||||||
|
++pos;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer_interface::attr attr = _m_make_renderer_attr(pos == state_.active, m);
|
||||||
//Draw item background
|
//Draw item background
|
||||||
renderer->item(*graph_, item_r, attr);
|
renderer->item(*graph_, item_r, attr);
|
||||||
|
|
||||||
@@ -567,15 +575,8 @@ namespace nana
|
|||||||
renderer->sub_arrow(*graph_, nana::point(graph_->width() - 20, item_r.y), item_h_px, attr);
|
renderer->sub_arrow(*graph_, nana::point(graph_->width() - 20, item_r.y), item_h_px, attr);
|
||||||
|
|
||||||
item_r.y += item_r.height + 1;
|
item_r.y += item_r.height + 1;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
graph_->set_color(colors::gray_border);
|
|
||||||
graph_->line({ item_r.x + 40, item_r.y }, { static_cast<int>(graph_->width()) - 1, item_r.y });
|
|
||||||
item_r.y += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
++index;
|
++pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
@@ -592,9 +593,9 @@ namespace nana
|
|||||||
std::size_t _m_get_index_by_pos(int x, int y) const
|
std::size_t _m_get_index_by_pos(int x, int y) const
|
||||||
{
|
{
|
||||||
if( (x < static_cast<int>(detail_.border.x)) ||
|
if( (x < static_cast<int>(detail_.border.x)) ||
|
||||||
(x > static_cast<int>(graph_->width() - detail_.border.x)) ||
|
(x > static_cast<int>(graph_->width()) - static_cast<int>(detail_.border.x)) ||
|
||||||
(y < static_cast<int>(detail_.border.y)) ||
|
(y < static_cast<int>(detail_.border.y)) ||
|
||||||
(y > static_cast<int>(graph_->height() - detail_.border.y)))
|
(y > static_cast<int>(graph_->height()) - static_cast<int>(detail_.border.y)))
|
||||||
return npos;
|
return npos;
|
||||||
|
|
||||||
int pos = detail_.border.y;
|
int pos = detail_.border.y;
|
||||||
@@ -662,11 +663,11 @@ namespace nana
|
|||||||
auto scr_area = screen().from_point(detail_.monitor_pos).workarea();
|
auto scr_area = screen().from_point(detail_.monitor_pos).workarea();
|
||||||
|
|
||||||
if(pos.x + static_cast<int>(size.width) > scr_area.right())
|
if(pos.x + static_cast<int>(size.width) > scr_area.right())
|
||||||
pos.x = static_cast<int>(scr_area.x + scr_area.width - size.width);
|
pos.x = scr_area.right() - static_cast<int>(size.width);
|
||||||
if(pos.x < scr_area.x) pos.x = scr_area.x;
|
if(pos.x < scr_area.x) pos.x = scr_area.x;
|
||||||
|
|
||||||
if(pos.y + static_cast<int>(size.height) > scr_area.bottom())
|
if(pos.y + static_cast<int>(size.height) > scr_area.bottom())
|
||||||
pos.y = static_cast<int>(scr_area.y + scr_area.height - size.height);
|
pos.y = scr_area.bottom() - static_cast<int>(size.height);
|
||||||
if(pos.y < scr_area.y) pos.y = scr_area.y;
|
if(pos.y < scr_area.y) pos.y = scr_area.y;
|
||||||
|
|
||||||
auto owner = API::get_owner_window(*widget_);
|
auto owner = API::get_owner_window(*widget_);
|
||||||
@@ -705,7 +706,7 @@ namespace nana
|
|||||||
|
|
||||||
menu_window(window wd, const point& pos, renderer_interface * rdptr)
|
menu_window(window wd, const point& pos, renderer_interface * rdptr)
|
||||||
: base_type(wd, false, rectangle(pos, nana::size(2, 2)), appear::bald<appear::floating>()),
|
: base_type(wd, false, rectangle(pos, nana::size(2, 2)), appear::bald<appear::floating>()),
|
||||||
want_focus_(nullptr == wd),
|
want_focus_(nullptr == wd || (API::focus_window() != wd)),
|
||||||
event_focus_(nullptr)
|
event_focus_(nullptr)
|
||||||
{
|
{
|
||||||
caption(STR("nana menu window"));
|
caption(STR("nana menu window"));
|
||||||
@@ -729,11 +730,6 @@ namespace nana
|
|||||||
API::activate_window(this->parent());
|
API::activate_window(this->parent());
|
||||||
API::take_active(this->handle(), false, nullptr);
|
API::take_active(this->handle(), false, nullptr);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
activate();
|
|
||||||
focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(submenu_.parent == nullptr)
|
if(submenu_.parent == nullptr)
|
||||||
{
|
{
|
||||||
@@ -753,14 +749,6 @@ namespace nana
|
|||||||
pick();
|
pick();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (want_focus_)
|
|
||||||
{
|
|
||||||
event_focus_ = events().focus.connect_unignorable([this](const arg_focus& arg)
|
|
||||||
{
|
|
||||||
_m_focus_changed(arg);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_.interval(100);
|
timer_.interval(100);
|
||||||
timer_.elapse([this]{
|
timer_.elapse([this]{
|
||||||
this->_m_check_repeatly();
|
this->_m_check_repeatly();
|
||||||
@@ -768,6 +756,30 @@ namespace nana
|
|||||||
timer_.start();
|
timer_.start();
|
||||||
|
|
||||||
show();
|
show();
|
||||||
|
|
||||||
|
if (want_focus_)
|
||||||
|
{
|
||||||
|
event_focus_ = events().focus.connect_unignorable([this](const arg_focus& arg)
|
||||||
|
{
|
||||||
|
//when the focus of the menu window is losing, close the menu.
|
||||||
|
//But here is not every menu window may have focus event installed,
|
||||||
|
//It is only installed when the owner of window is the desktop window.
|
||||||
|
|
||||||
|
if (false == arg.getting && (arg.receiver != API::root(*this)))
|
||||||
|
{
|
||||||
|
for (auto child = submenu_.child; child; child = child->submenu_.child)
|
||||||
|
{
|
||||||
|
if (API::root(child->handle()) == arg.receiver)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_m_close_all();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
focus();
|
||||||
|
activate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void goto_next(bool forward)
|
void goto_next(bool forward)
|
||||||
@@ -783,27 +795,16 @@ namespace nana
|
|||||||
API::update_window(object->handle());
|
API::update_window(object->handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool goto_submenu()
|
bool submenu(bool enter)
|
||||||
{
|
{
|
||||||
menu_window * object = this;
|
menu_window * object = this;
|
||||||
while(object->submenu_.child)
|
while (object->submenu_.child)
|
||||||
object = object->submenu_.child;
|
object = object->submenu_.child;
|
||||||
|
|
||||||
state_.auto_popup_submenu = false;
|
state_.auto_popup_submenu = false;
|
||||||
|
|
||||||
nana::point pos;
|
if (enter)
|
||||||
menu_type * sbm = object->get_drawer_trigger().retrive_sub_menu(pos, 0);
|
|
||||||
return object->_m_show_submenu(sbm, pos, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool exit_submenu()
|
|
||||||
{
|
{
|
||||||
menu_window * object =this;
|
|
||||||
while(object->submenu_.child)
|
|
||||||
object = object->submenu_.child;
|
|
||||||
|
|
||||||
state_.auto_popup_submenu = false;
|
|
||||||
|
|
||||||
if (object->submenu_.parent)
|
if (object->submenu_.parent)
|
||||||
{
|
{
|
||||||
auto & sub = object->submenu_.parent->submenu_;
|
auto & sub = object->submenu_.parent->submenu_;
|
||||||
@@ -816,6 +817,11 @@ namespace nana
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nana::point pos;
|
||||||
|
menu_type * sbm = object->get_drawer_trigger().retrive_sub_menu(pos, 0);
|
||||||
|
return object->_m_show_submenu(sbm, pos, true);
|
||||||
|
}
|
||||||
|
|
||||||
int send_shortkey(nana::char_t key)
|
int send_shortkey(nana::char_t key)
|
||||||
{
|
{
|
||||||
menu_window * object = this;
|
menu_window * object = this;
|
||||||
@@ -832,11 +838,10 @@ namespace nana
|
|||||||
object = object->submenu_.child;
|
object = object->submenu_.child;
|
||||||
|
|
||||||
auto active = object->get_drawer_trigger().active();
|
auto active = object->get_drawer_trigger().active();
|
||||||
if (active != npos)
|
|
||||||
{
|
|
||||||
auto * menu = object->get_drawer_trigger().data();
|
auto * menu = object->get_drawer_trigger().data();
|
||||||
if (menu)
|
if ((npos == active) || !menu)
|
||||||
{
|
return;
|
||||||
|
|
||||||
menu_item_type & item = menu->items.at(active);
|
menu_item_type & item = menu->items.at(active);
|
||||||
if (item.flags.splitter == false && item.sub_menu == nullptr)
|
if (item.flags.splitter == false && item.sub_menu == nullptr)
|
||||||
{
|
{
|
||||||
@@ -850,24 +855,17 @@ namespace nana
|
|||||||
}
|
}
|
||||||
else if (checks::option == item.style)
|
else if (checks::option == item.style)
|
||||||
{
|
{
|
||||||
if (active > 0)
|
//Forward Looks for a splitter
|
||||||
|
auto pos = active;
|
||||||
|
while (pos)
|
||||||
{
|
{
|
||||||
//clear the checked state in front of active if it is check_option.
|
if (menu->items.at(--pos).flags.splitter)
|
||||||
auto i = active;
|
break;
|
||||||
do
|
|
||||||
{
|
|
||||||
--i;
|
|
||||||
menu_item_type & im = menu->items.at(i);
|
|
||||||
if (im.flags.splitter) break;
|
|
||||||
|
|
||||||
if (checks::option == im.style && im.flags.checked)
|
|
||||||
im.flags.checked = false;
|
|
||||||
} while (i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = active + 1; i < menu->items.size(); ++i)
|
for (; pos < menu->items.size(); ++pos)
|
||||||
{
|
{
|
||||||
menu_item_type & im = menu->items.at(i);
|
menu_item_type & im = menu->items.at(pos);
|
||||||
if (im.flags.splitter) break;
|
if (im.flags.splitter) break;
|
||||||
|
|
||||||
if ((checks::option == im.style) && im.flags.checked)
|
if ((checks::option == im.style) && im.flags.checked)
|
||||||
@@ -889,8 +887,6 @@ namespace nana
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
//_m_destroy just destroys the children windows.
|
//_m_destroy just destroys the children windows.
|
||||||
//The all window including parent windows want to be closed by calling the _m_close_all() instead of close()
|
//The all window including parent windows want to be closed by calling the _m_close_all() instead of close()
|
||||||
@@ -943,50 +939,29 @@ namespace nana
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//when the focus of the menu window is losing, close the menu.
|
|
||||||
//But here is not every menu window may have focus event installed,
|
|
||||||
//It is only installed when the owner of window is the desktop window.
|
|
||||||
void _m_focus_changed(const arg_focus& arg)
|
|
||||||
{
|
|
||||||
if (false == arg.getting)
|
|
||||||
{
|
|
||||||
for (auto child = submenu_.child; child; child = child->submenu_.child)
|
|
||||||
{
|
|
||||||
if (API::root(child->handle()) == arg.receiver)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_m_close_all();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _m_key_down(const arg_keyboard& arg)
|
void _m_key_down(const arg_keyboard& arg)
|
||||||
{
|
{
|
||||||
switch(arg.key)
|
switch(arg.key)
|
||||||
{
|
{
|
||||||
case keyboard::os_arrow_up:
|
case keyboard::os_arrow_up:
|
||||||
this->goto_next(false);
|
|
||||||
break;
|
|
||||||
case keyboard::os_arrow_down:
|
case keyboard::os_arrow_down:
|
||||||
this->goto_next(true);
|
this->goto_next(keyboard::os_arrow_down == arg.key);
|
||||||
break;
|
break;
|
||||||
case keyboard::os_arrow_left:
|
case keyboard::os_arrow_left:
|
||||||
this->exit_submenu();
|
|
||||||
break;
|
|
||||||
case keyboard::os_arrow_right:
|
case keyboard::os_arrow_right:
|
||||||
this->goto_submenu();
|
this->submenu(keyboard::os_arrow_right == arg.key);
|
||||||
break;
|
break;
|
||||||
case keyboard::enter:
|
case keyboard::enter:
|
||||||
this->pick();
|
this->pick();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(2 != send_shortkey(arg.key))
|
if (2 != send_shortkey(arg.key))
|
||||||
{
|
{
|
||||||
if(API::empty_window(*this) == false)
|
if (API::empty_window(*this) == false)
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
goto_submenu();
|
this->submenu(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1165,7 +1140,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if(impl_->mbuilder.set_sub_menu(index, menu_obj.impl_->mbuilder.data()))
|
if(impl_->mbuilder.set_sub_menu(index, menu_obj.impl_->mbuilder.data()))
|
||||||
{
|
{
|
||||||
implement::info& minfo = impl_->sub_container[index];
|
auto& minfo = impl_->sub_container[index];
|
||||||
minfo.handle = &menu_obj;
|
minfo.handle = &menu_obj;
|
||||||
minfo.kill = false;
|
minfo.kill = false;
|
||||||
return true;
|
return true;
|
||||||
@@ -1184,9 +1159,10 @@ namespace nana
|
|||||||
menu *menu::create_sub_menu(std::size_t index)
|
menu *menu::create_sub_menu(std::size_t index)
|
||||||
{
|
{
|
||||||
menu * sub = new menu;
|
menu * sub = new menu;
|
||||||
if(link(index, *sub))
|
|
||||||
|
if (this->link(index, *sub))
|
||||||
{
|
{
|
||||||
implement::info& minfo = impl_->sub_container[index];
|
auto& minfo = impl_->sub_container[index];
|
||||||
minfo.handle = sub;
|
minfo.handle = sub;
|
||||||
minfo.kill = true;
|
minfo.kill = true;
|
||||||
return sub;
|
return sub;
|
||||||
@@ -1255,12 +1231,12 @@ namespace nana
|
|||||||
|
|
||||||
bool menu::goto_submen()
|
bool menu::goto_submen()
|
||||||
{
|
{
|
||||||
return (impl_->uiobj ? impl_->uiobj->goto_submenu() : false);
|
return (impl_->uiobj ? impl_->uiobj->submenu(true) : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool menu::exit_submenu()
|
bool menu::exit_submenu()
|
||||||
{
|
{
|
||||||
return (impl_->uiobj ? impl_->uiobj->exit_submenu() : false);
|
return (impl_->uiobj ? impl_->uiobj->submenu(false) : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t menu::size() const
|
std::size_t menu::size() const
|
||||||
@@ -1311,21 +1287,17 @@ namespace nana
|
|||||||
impl_->mbuilder.renderer(rd);
|
impl_->mbuilder.renderer(rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu::_m_destroy_menu_window()
|
|
||||||
{
|
|
||||||
impl_->uiobj = nullptr;
|
|
||||||
if(impl_->destroy_answer)
|
|
||||||
impl_->destroy_answer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void menu::_m_popup(window wd, int x, int y, bool called_by_menubar)
|
void menu::_m_popup(window wd, int x, int y, bool called_by_menubar)
|
||||||
{
|
{
|
||||||
if (impl_->mbuilder.data().items.size())
|
if (impl_->mbuilder.data().items.size())
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
|
|
||||||
impl_->uiobj = &(form_loader<drawerbase::menu::menu_window, false>()(wd, point(x, y), &(*impl_->mbuilder.renderer())));
|
impl_->uiobj = &(form_loader<drawerbase::menu::menu_window, false>()(wd, point(x, y), &(*impl_->mbuilder.renderer())));
|
||||||
impl_->uiobj->events().destroy.connect_unignorable([this]{
|
impl_->uiobj->events().destroy.connect_unignorable([this]{
|
||||||
_m_destroy_menu_window();
|
impl_->uiobj = nullptr;
|
||||||
|
if (impl_->destroy_answer)
|
||||||
|
impl_->destroy_answer();
|
||||||
});
|
});
|
||||||
impl_->uiobj->popup(impl_->mbuilder.data(), called_by_menubar);
|
impl_->uiobj->popup(impl_->mbuilder.data(), called_by_menubar);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user