Merge branch 'hotfix-1.7' into develop
This commit is contained in:
@@ -336,6 +336,43 @@ namespace nana
|
||||
flags.action = act;
|
||||
}
|
||||
|
||||
|
||||
bool basic_window::try_lazy_update(bool try_refresh)
|
||||
{
|
||||
if (drawer.graphics.empty())
|
||||
return true;
|
||||
|
||||
if (!this->root_widget->other.attribute.root->lazy_update)
|
||||
return false;
|
||||
|
||||
if (nullptr == effect.bground)
|
||||
{
|
||||
if (try_refresh)
|
||||
{
|
||||
flags.refreshing = true;
|
||||
drawer.refresh();
|
||||
flags.refreshing = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i = this->root_widget->other.attribute.root->update_requesters.cbegin(); i != this->root_widget->other.attribute.root->update_requesters.cend();)
|
||||
{
|
||||
auto req = *i;
|
||||
//Avoid redundancy, don't insert the window if it or its ancestor window already exist in the container.
|
||||
if ((req == this) || req->is_ancestor_of(this))
|
||||
return true;
|
||||
|
||||
//If there is a window which is a child or child's child of the window, remove it.
|
||||
if (this->is_ancestor_of(req))
|
||||
i = this->root_widget->other.attribute.root->update_requesters.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
this->root_widget->other.attribute.root->update_requesters.push_back(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void basic_window::_m_init_pos_and_size(basic_window* parent, const rectangle& r)
|
||||
{
|
||||
pos_owner = pos_root = r.position();
|
||||
@@ -390,7 +427,6 @@ namespace nana
|
||||
flags.ignore_menubar_focus = false;
|
||||
flags.ignore_mouse_focus = false;
|
||||
flags.space_click_enabled = false;
|
||||
flags.ignore_child_mapping = false;
|
||||
|
||||
visible = false;
|
||||
|
||||
|
||||
@@ -641,13 +641,8 @@ namespace nana
|
||||
if (update_state::none == wd->other.upd_state)
|
||||
wd->other.upd_state = update_state::lazy;
|
||||
|
||||
auto ignore_mapping_value = wd->flags.ignore_child_mapping;
|
||||
wd->flags.ignore_child_mapping = true;
|
||||
|
||||
_m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal);
|
||||
|
||||
wd->flags.ignore_child_mapping = ignore_mapping_value;
|
||||
|
||||
bool good_wd = false;
|
||||
if(wd_manager().available(wd))
|
||||
{
|
||||
@@ -658,10 +653,7 @@ namespace nana
|
||||
wd_manager().do_lazy_refresh(wd, false, (event_code::resized == evt_code));
|
||||
}
|
||||
else
|
||||
{
|
||||
wd_manager().map_requester(wd);
|
||||
wd->other.upd_state = update_state::none;
|
||||
}
|
||||
|
||||
good_wd = true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <nana/system/platform.hpp>
|
||||
#include <nana/gui/detail/native_window_interface.hpp>
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
#include <nana/gui/detail/window_layout.hpp>
|
||||
#include <nana/gui/detail/element_store.hpp>
|
||||
#include "inner_fwd_implement.hpp"
|
||||
#include <errno.h>
|
||||
@@ -555,6 +556,27 @@ namespace detail
|
||||
context.is_alt_pressed = false;
|
||||
}
|
||||
|
||||
class window_proc_guard
|
||||
{
|
||||
public:
|
||||
window_proc_guard(detail::basic_window* wd) :
|
||||
root_wd_(wd)
|
||||
{
|
||||
root_wd_->other.attribute.root->lazy_update = true;
|
||||
}
|
||||
|
||||
~window_proc_guard()
|
||||
{
|
||||
if (!bedrock::instance().wd_manager().available(root_wd_))
|
||||
return;
|
||||
|
||||
root_wd_->other.attribute.root->lazy_update = false;
|
||||
root_wd_->other.attribute.root->update_requesters.clear();
|
||||
}
|
||||
private:
|
||||
detail::basic_window* const root_wd_;
|
||||
};
|
||||
|
||||
void window_proc_for_xevent(Display* /*display*/, XEvent& xevent)
|
||||
{
|
||||
typedef detail::bedrock::core_window_t core_window_t;
|
||||
@@ -569,10 +591,13 @@ namespace detail
|
||||
|
||||
if(root_runtime)
|
||||
{
|
||||
auto msgwnd = root_runtime->window;
|
||||
auto const root_wd = root_runtime->window;
|
||||
auto msgwnd = root_wd;
|
||||
window_proc_guard wp_guard{ root_wd };
|
||||
|
||||
auto& context = *brock.get_thread_context(msgwnd->thread_id);
|
||||
|
||||
auto pre_event_window = context.event_window;
|
||||
auto const pre_event_window = context.event_window;
|
||||
auto pressed_wd = root_runtime->condition.pressed;
|
||||
auto pressed_wd_space = root_runtime->condition.pressed_by_space;
|
||||
auto hovered_wd = root_runtime->condition.hovered;
|
||||
@@ -1190,6 +1215,15 @@ namespace detail
|
||||
}
|
||||
}
|
||||
|
||||
if (wd_manager.available(root_wd) && root_wd->other.attribute.root->update_requesters.size())
|
||||
{
|
||||
for (auto wd : root_wd->other.attribute.root->update_requesters)
|
||||
{
|
||||
window_layout::paint(wd, window_layout::paint_operation::have_refreshed, false);
|
||||
wd_manager.map(wd, true);
|
||||
}
|
||||
}
|
||||
|
||||
root_runtime = wd_manager.root_runtime(native_window);
|
||||
if(root_runtime)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <nana/gui.hpp>
|
||||
#include <nana/gui/detail/native_window_interface.hpp>
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
#include <nana/gui/detail/window_layout.hpp>
|
||||
#include <nana/gui/detail/element_store.hpp>
|
||||
#include <nana/gui/detail/color_schemes.hpp>
|
||||
#include "inner_fwd_implement.hpp"
|
||||
@@ -37,6 +38,7 @@
|
||||
|
||||
#include "bedrock_types.hpp"
|
||||
|
||||
|
||||
typedef void (CALLBACK *win_event_proc_t)(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime);
|
||||
|
||||
namespace nana
|
||||
@@ -738,6 +740,27 @@ namespace detail
|
||||
return static_cast<wchar_t>(vkey);
|
||||
}
|
||||
|
||||
class window_proc_guard
|
||||
{
|
||||
public:
|
||||
window_proc_guard(detail::basic_window* wd) :
|
||||
root_wd_(wd)
|
||||
{
|
||||
root_wd_->other.attribute.root->lazy_update = true;
|
||||
}
|
||||
|
||||
~window_proc_guard()
|
||||
{
|
||||
if (!bedrock::instance().wd_manager().available(root_wd_))
|
||||
return;
|
||||
|
||||
root_wd_->other.attribute.root->lazy_update = false;
|
||||
root_wd_->other.attribute.root->update_requesters.clear();
|
||||
}
|
||||
private:
|
||||
detail::basic_window* const root_wd_;
|
||||
};
|
||||
|
||||
LRESULT CALLBACK Bedrock_WIN32_WindowProc(HWND root_window, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LRESULT window_proc_value = 0;
|
||||
@@ -757,6 +780,7 @@ namespace detail
|
||||
bool def_window_proc = false;
|
||||
auto& context = *brock.get_thread_context();
|
||||
|
||||
auto const pre_event_window = context.event_window;
|
||||
auto pressed_wd = root_runtime->condition.pressed;
|
||||
auto pressed_wd_space = root_runtime->condition.pressed_by_space;
|
||||
auto hovered_wd = root_runtime->condition.hovered;
|
||||
@@ -766,7 +790,10 @@ namespace detail
|
||||
pmdec.raw_param.wparam = wParam;
|
||||
|
||||
internal_scope_guard lock;
|
||||
auto msgwnd = root_runtime->window;
|
||||
auto const root_wd = root_runtime->window;
|
||||
auto msgwnd = root_wd;
|
||||
|
||||
window_proc_guard wp_guard{ root_wd };
|
||||
|
||||
switch (message)
|
||||
{
|
||||
@@ -775,10 +802,7 @@ namespace detail
|
||||
{
|
||||
auto i = root_runtime->wpassoc->accel_commands.find(LOWORD(wParam));
|
||||
if (i != root_runtime->wpassoc->accel_commands.end())
|
||||
{
|
||||
auto fn = i->second;
|
||||
fn();
|
||||
}
|
||||
i->second();
|
||||
}
|
||||
break;
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
@@ -1092,7 +1116,9 @@ namespace detail
|
||||
//The focus window receives the message in Windows system, it should be redirected to the hovered window
|
||||
::POINT scr_pos{ pmdec.mouse.x, pmdec.mouse.y}; //Screen position
|
||||
auto pointer_wd = ::WindowFromPoint(scr_pos);
|
||||
if (pointer_wd == root_window)
|
||||
|
||||
//Ignore the message if the window is disabled.
|
||||
if ((pointer_wd == root_window) && ::IsWindowEnabled(root_window))
|
||||
{
|
||||
::ScreenToClient(pointer_wd, &scr_pos);
|
||||
auto scrolled_wd = wd_manager.find_window(reinterpret_cast<native_window_type>(pointer_wd), { scr_pos.x, scr_pos.y });
|
||||
@@ -1124,7 +1150,7 @@ namespace detail
|
||||
wd_manager.do_lazy_refresh(scrolled_wd, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (pointer_wd != root_window)
|
||||
{
|
||||
DWORD pid = 0;
|
||||
::GetWindowThreadProcessId(pointer_wd, &pid);
|
||||
@@ -1450,7 +1476,7 @@ namespace detail
|
||||
wd_manager.do_lazy_refresh(msgwnd, false);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
case WM_KEYUP:
|
||||
if(wParam != VK_MENU) //MUST NOT BE AN ALT
|
||||
{
|
||||
@@ -1551,13 +1577,28 @@ namespace detail
|
||||
def_window_proc = true;
|
||||
}
|
||||
|
||||
if (wd_manager.available(root_wd) && root_wd->other.attribute.root->update_requesters.size())
|
||||
{
|
||||
for (auto wd : root_wd->other.attribute.root->update_requesters)
|
||||
{
|
||||
window_layout::paint(wd, window_layout::paint_operation::have_refreshed, false);
|
||||
wd_manager.map(wd, true);
|
||||
}
|
||||
}
|
||||
|
||||
root_runtime = wd_manager.root_runtime(native_window);
|
||||
if(root_runtime)
|
||||
{
|
||||
context.event_window = pre_event_window;
|
||||
root_runtime->condition.pressed = pressed_wd;
|
||||
root_runtime->condition.hovered = hovered_wd;
|
||||
root_runtime->condition.pressed_by_space = pressed_wd_space;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto context = brock.get_thread_context();
|
||||
if(context) context->event_window = pre_event_window;
|
||||
}
|
||||
|
||||
if (!def_window_proc)
|
||||
return 0;
|
||||
|
||||
@@ -701,19 +701,40 @@ namespace detail
|
||||
return true;
|
||||
}
|
||||
|
||||
window_manager::core_window_t* window_manager::find_window(native_window_type root, const point& pos)
|
||||
window_manager::core_window_t* window_manager::find_window(native_window_type root, const point& pos, bool ignore_captured)
|
||||
{
|
||||
if (nullptr == root)
|
||||
return nullptr;
|
||||
|
||||
if((false == attr_.capture.ignore_children) || (nullptr == attr_.capture.window) || (attr_.capture.window->root != root))
|
||||
//Thread-Safe Required!
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
|
||||
if (ignore_captured || (nullptr == attr_.capture.window))
|
||||
{
|
||||
//Thread-Safe Required!
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
auto rrt = root_runtime(root);
|
||||
if (rrt && _m_effective(rrt->window, pos))
|
||||
return _m_find(rrt->window, pos);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (attr_.capture.ignore_children)
|
||||
return attr_.capture.window;
|
||||
|
||||
auto rrt = root_runtime(root);
|
||||
if (rrt && _m_effective(rrt->window, pos))
|
||||
{
|
||||
auto target = _m_find(rrt->window, pos);
|
||||
|
||||
auto p = target;
|
||||
while (p)
|
||||
{
|
||||
if (p == attr_.capture.window)
|
||||
return target;
|
||||
p = p->parent;
|
||||
}
|
||||
}
|
||||
|
||||
return attr_.capture.window;
|
||||
}
|
||||
|
||||
@@ -980,28 +1001,7 @@ namespace detail
|
||||
//Thread-Safe Required!
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
if (impl_->wd_register.available(wd) && !wd->is_draw_through())
|
||||
{
|
||||
auto parent = wd->parent;
|
||||
while (parent)
|
||||
{
|
||||
if(parent->flags.ignore_child_mapping || parent->flags.refreshing)
|
||||
{
|
||||
auto top = parent;
|
||||
while(parent->parent)
|
||||
{
|
||||
parent = parent->parent;
|
||||
if(parent->flags.ignore_child_mapping || parent->flags.refreshing)
|
||||
top = parent;
|
||||
}
|
||||
|
||||
top->other.mapping_requester.push_back(wd);
|
||||
return;
|
||||
}
|
||||
parent = parent->parent;
|
||||
}
|
||||
|
||||
bedrock::instance().flush_surface(wd, forced, update_area);
|
||||
}
|
||||
}
|
||||
|
||||
//update
|
||||
@@ -1028,8 +1028,11 @@ namespace detail
|
||||
{
|
||||
if (!wd->flags.refreshing)
|
||||
{
|
||||
window_layer::paint(wd, (redraw ? paint_operation::try_refresh : paint_operation::none), false);
|
||||
this->map(wd, forced, update_area);
|
||||
if (!wd->try_lazy_update(redraw))
|
||||
{
|
||||
window_layer::paint(wd, (redraw ? paint_operation::try_refresh : paint_operation::none), false);
|
||||
this->map(wd, forced, update_area);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (forced)
|
||||
@@ -1076,39 +1079,28 @@ namespace detail
|
||||
{
|
||||
if ((wd->other.upd_state == core_window_t::update_state::refreshed) || (wd->other.upd_state == core_window_t::update_state::request_refresh) || force_copy_to_screen)
|
||||
{
|
||||
window_layer::paint(wd, (wd->other.upd_state == core_window_t::update_state::request_refresh ? paint_operation::try_refresh : paint_operation::have_refreshed), refresh_tree);
|
||||
this->map(wd, force_copy_to_screen);
|
||||
if (!wd->try_lazy_update(wd->other.upd_state == core_window_t::update_state::request_refresh))
|
||||
{
|
||||
window_layer::paint(wd, (wd->other.upd_state == core_window_t::update_state::request_refresh ? paint_operation::try_refresh : paint_operation::have_refreshed), refresh_tree);
|
||||
this->map(wd, force_copy_to_screen);
|
||||
}
|
||||
}
|
||||
else if (effects::edge_nimbus::none != wd->effect.edge_nimbus)
|
||||
{
|
||||
//The window is still mapped because of edge nimbus effect.
|
||||
//Avoid duplicate copy if action state is not changed and the window is not focused.
|
||||
if (wd->flags.action != wd->flags.action_before)
|
||||
this->map(wd, true);
|
||||
{
|
||||
if (!wd->try_lazy_update(false))
|
||||
this->map(wd, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
window_layer::paint(wd, paint_operation::try_refresh, refresh_tree); //only refreshing if it has an invisible parent
|
||||
}
|
||||
|
||||
wd->other.upd_state = core_window_t::update_state::none;
|
||||
wd->other.mapping_requester.clear();
|
||||
}
|
||||
|
||||
void window_manager::map_requester(core_window_t* wd)
|
||||
{
|
||||
//Thread-Safe Required!
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
|
||||
if (false == impl_->wd_register.available(wd))
|
||||
return;
|
||||
|
||||
if (wd->visible_parents())
|
||||
{
|
||||
for(auto requestor : wd->other.mapping_requester)
|
||||
this->map(requestor, true);
|
||||
}
|
||||
|
||||
wd->other.mapping_requester.clear();
|
||||
}
|
||||
|
||||
bool window_manager::set_parent(core_window_t* wd, core_window_t* newpa)
|
||||
|
||||
@@ -1359,7 +1359,7 @@ namespace nana
|
||||
path.resize(len);
|
||||
|
||||
impl_->path = to_utf8(path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1589,7 +1589,7 @@ namespace nana
|
||||
};
|
||||
|
||||
folderbox::folderbox(window owner, const path_type& init_path, std::string title)
|
||||
: impl_(new implement{ owner, fs::canonical(init_path).make_preferred(), title, false})
|
||||
: impl_(new implement{ owner, fs::weakly_canonical(init_path).make_preferred(), title, false})
|
||||
{}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A Message Box Class
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -453,7 +453,20 @@ namespace nana
|
||||
default: break;
|
||||
}
|
||||
|
||||
auto bt = ::MessageBoxW(reinterpret_cast<HWND>(API::root(wd_)), to_wstring(sstream_.str()).c_str(), to_wstring(title_).c_str(), type);
|
||||
//Disables the owner window to prevent the owner window processing mouse wheel event
|
||||
//when the message box is showing and scroll the wheel on the owner window.
|
||||
auto native = reinterpret_cast<HWND>(API::root(wd_));
|
||||
BOOL enabled = FALSE;
|
||||
if (native)
|
||||
{
|
||||
enabled = ::IsWindowEnabled(native);
|
||||
if (enabled)
|
||||
::EnableWindow(native, FALSE);
|
||||
}
|
||||
auto bt = ::MessageBoxW(native, to_wstring(sstream_.str()).c_str(), to_wstring(title_).c_str(), type);
|
||||
|
||||
if (native && enabled)
|
||||
::EnableWindow(native, TRUE);
|
||||
|
||||
switch(bt)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* An Implementation of Place for Layout
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -630,7 +630,8 @@ namespace nana
|
||||
void collocate();
|
||||
|
||||
static division * search_div_name(division* start, const std::string&) noexcept;
|
||||
std::unique_ptr<division> scan_div(place_parts::tokenizer&);
|
||||
|
||||
std::unique_ptr<division> scan_div(place_parts::tokenizer&, bool implicitly_started, const std::string& ignore_duplicate = {});
|
||||
void check_unique(const division*) const;
|
||||
|
||||
//connect the field/dock with div object
|
||||
@@ -1987,7 +1988,7 @@ namespace nana
|
||||
|
||||
std::string::size_type tag_pos{ left ? div.find('<', bound.second + 2) : div.rfind('>', bound.first - 2) };
|
||||
if (div.npos == tag_pos)
|
||||
throw std::runtime_error("place report an issue if it throws");
|
||||
throw std::invalid_argument("please report an issue if it throws");
|
||||
|
||||
auto other_bound = get_field_boundary(div, tag_pos);
|
||||
|
||||
@@ -2706,7 +2707,9 @@ namespace nana
|
||||
throw std::invalid_argument("nana.place: the type of the " + std::string{pos_strs[pos]} +"th parameter for collapse should be integer.");
|
||||
}
|
||||
|
||||
auto place::implement::scan_div(place_parts::tokenizer& tknizer) -> std::unique_ptr<division>
|
||||
//implicitly_started indicates whether the field in div-text starts without < mark.
|
||||
//ignore_duplicate A field is allowed to have same name if its has an ancestor which name is same with ignore_duplicate.
|
||||
auto place::implement::scan_div(place_parts::tokenizer& tknizer, bool implicitly_started, const std::string& ignore_duplicate) -> std::unique_ptr<division>
|
||||
{
|
||||
using token = place_parts::tokenizer::token ;
|
||||
|
||||
@@ -2728,7 +2731,8 @@ namespace nana
|
||||
bool undisplayed = false;
|
||||
bool invisible = false;
|
||||
|
||||
for (token tk = tknizer.read(); (tk != token::eof && tk != token::div_end); tk = tknizer.read())
|
||||
token tk = token::eof;
|
||||
for (tk = tknizer.read(); (tk != token::eof && tk != token::div_end); tk = tknizer.read())
|
||||
{
|
||||
switch (tk)
|
||||
{
|
||||
@@ -2752,14 +2756,25 @@ namespace nana
|
||||
{
|
||||
auto splitter = new div_splitter(tknizer.number(), this);
|
||||
children.back()->div_next = splitter;
|
||||
|
||||
//Hides the splitter if its left leaf is undisplayed.
|
||||
if (!children.back()->display)
|
||||
splitter->display = false;
|
||||
|
||||
children.emplace_back(std::unique_ptr<division>{ splitter });
|
||||
}
|
||||
break;
|
||||
case token::div_start:
|
||||
{
|
||||
auto div = scan_div(tknizer);
|
||||
auto div = scan_div(tknizer, false, ignore_duplicate);
|
||||
if (!children.empty())
|
||||
{
|
||||
//Hides the splitter if its right leaf is undisplayed.
|
||||
if ((children.back()->kind_of_division == division::kind::splitter) && !div->display)
|
||||
children.back()->display = false;
|
||||
|
||||
children.back()->div_next = div.get();
|
||||
}
|
||||
|
||||
children.emplace_back(std::move(div));
|
||||
}
|
||||
@@ -2887,6 +2902,9 @@ namespace nana
|
||||
}
|
||||
}
|
||||
|
||||
if (implicitly_started && (tk == token::div_end))
|
||||
throw std::invalid_argument("nana.place: the div-text ends prematurely at " + std::to_string(tknizer.pos()));
|
||||
|
||||
field_gather * attached_field = nullptr;
|
||||
|
||||
//find the field with specified name.
|
||||
@@ -2897,7 +2915,30 @@ namespace nana
|
||||
attached_field = i->second;
|
||||
//the field is attached to a division, it means there is another division with same name.
|
||||
if (attached_field->attached)
|
||||
throw std::runtime_error("place, the name '" + name + "' is redefined.");
|
||||
{
|
||||
//The fields are allowed to have a same name. E.g.
|
||||
//place.div("A <B><C>");
|
||||
//place.modify("A", "<B>"); Here the same name B must be allowed, otherwise it throws runtime error.
|
||||
|
||||
bool allow_same_name = false;
|
||||
if (!ignore_duplicate.empty())
|
||||
{
|
||||
auto f = attached_field->attached->div_owner;
|
||||
while (f)
|
||||
{
|
||||
if (f->name == ignore_duplicate)
|
||||
{
|
||||
allow_same_name = true;
|
||||
break;
|
||||
}
|
||||
|
||||
f = f->div_owner;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allow_same_name)
|
||||
throw std::runtime_error("place, the name '" + name + "' is redefined.");
|
||||
}
|
||||
}
|
||||
|
||||
token unmatch = token::width;
|
||||
@@ -2977,7 +3018,16 @@ namespace nana
|
||||
//attach the field to the division
|
||||
div->field = attached_field;
|
||||
if (attached_field)
|
||||
{
|
||||
//Replaces the previous div with the new div which is allowed to have a same name.
|
||||
|
||||
//Detaches the field from the previous div.
|
||||
if (attached_field->attached)
|
||||
attached_field->attached->field = nullptr;
|
||||
|
||||
//Attaches new div
|
||||
attached_field->attached = div.get();
|
||||
}
|
||||
|
||||
if (children.size())
|
||||
{
|
||||
@@ -3194,7 +3244,7 @@ namespace nana
|
||||
{
|
||||
place_parts::tokenizer tknizer(div_text.c_str());
|
||||
impl_->disconnect();
|
||||
auto div = impl_->scan_div(tknizer);
|
||||
auto div = impl_->scan_div(tknizer, true);
|
||||
try
|
||||
{
|
||||
impl_->connect(div.get()); //throws if there is a redefined name of field.
|
||||
@@ -3263,7 +3313,7 @@ namespace nana
|
||||
try
|
||||
{
|
||||
place_parts::tokenizer tknizer(div_text);
|
||||
auto modified = impl_->scan_div(tknizer);
|
||||
auto modified = impl_->scan_div(tknizer, true, name);
|
||||
auto modified_ptr = modified.get();
|
||||
modified_ptr->name = name;
|
||||
|
||||
|
||||
@@ -1403,7 +1403,7 @@ namespace API
|
||||
::nana::point clipos{pos};
|
||||
interface_type::calc_window_point(wd, clipos);
|
||||
return reinterpret_cast<window>(
|
||||
restrict::wd_manager().find_window(wd, clipos));
|
||||
restrict::wd_manager().find_window(wd, clipos, true));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A Combox Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -676,7 +676,10 @@ namespace nana
|
||||
{
|
||||
auto * editor = drawer_->editor();
|
||||
editor->mouse_pressed(arg);
|
||||
drawer_->open_lister_if_push_button_positioned();
|
||||
|
||||
//Pops up the droplist only if left button is clicked
|
||||
if(arg.is_left_button())
|
||||
drawer_->open_lister_if_push_button_positioned();
|
||||
|
||||
drawer_->draw();
|
||||
if(editor->attr().editable)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* A Tabbar Implementation
|
||||
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -1291,7 +1291,8 @@ namespace nana
|
||||
|
||||
void trigger::mouse_down(graph_reference, const arg_mouse& arg)
|
||||
{
|
||||
if(layouter_->press())
|
||||
//Activates the tab only if left button is clicked.
|
||||
if(arg.is_left_button() && layouter_->press())
|
||||
{
|
||||
if(false == layouter_->active_by_trace(arg))
|
||||
layouter_->toolbox_answer(arg);
|
||||
@@ -1593,10 +1594,10 @@ namespace nana
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
void driver::mouse_down(graph_reference graph, const arg_mouse&)
|
||||
void driver::mouse_down(graph_reference graph, const arg_mouse& arg)
|
||||
{
|
||||
auto & indexes = model_->get_indexes();
|
||||
if ((indexes.hovered_pos == model_->npos) || (indexes.active_pos == indexes.hovered_pos))
|
||||
if ((indexes.hovered_pos == model_->npos) || (indexes.active_pos == indexes.hovered_pos) || !arg.is_left_button())
|
||||
return;
|
||||
|
||||
if (indexes.active_pos != indexes.hovered_pos)
|
||||
|
||||
@@ -963,6 +963,11 @@ namespace nana
|
||||
if(text_r.right() > visible_w_pixels())
|
||||
{
|
||||
node_state.tooltip = new tooltip_window(data.widget_ptr->handle(), text_r);
|
||||
|
||||
//PR#406 Error Flynn's contribution
|
||||
//fix: tooltip window doesn't have tree scheme & typeface
|
||||
API::dev::set_scheme(node_state.tooltip->handle(), API::dev::get_scheme(data.widget_ptr->handle()));
|
||||
node_state.tooltip->typeface(data.widget_ptr->typeface());
|
||||
|
||||
node_attribute node_attr;
|
||||
assign_node_attr(node_attr, node_state.pointed);
|
||||
|
||||
Reference in New Issue
Block a user