fix crash which occurs after calling widget::tooltip("")(#331)

This commit is contained in:
Jinhao 2018-08-25 06:06:57 +08:00
parent 74f060acbc
commit c440613d90
2 changed files with 41 additions and 32 deletions

View File

@ -1,6 +1,6 @@
/* /*
* A Tooltip Implementation * A Tooltip Implementation
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2018 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

View File

@ -1,7 +1,7 @@
/* /*
* A Tooltip Implementation * A Tooltip 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-2018 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
@ -15,6 +15,7 @@
#include <nana/gui/timer.hpp> #include <nana/gui/timer.hpp>
#include <nana/gui/screen.hpp> #include <nana/gui/screen.hpp>
#include <memory> #include <memory>
#include <map>
namespace nana namespace nana
{ {
@ -157,7 +158,14 @@ namespace nana
class controller class controller
{ {
typedef std::pair<window, std::string> pair_t; struct tip_value
{
std::string text;
event_handle evt_msenter;
event_handle evt_msleave;
event_handle evt_msdown;
event_handle evt_destroy;
};
typedef std::function<void(tooltip_interface*)> deleter_type; typedef std::function<void(tooltip_interface*)> deleter_type;
@ -207,7 +215,7 @@ namespace nana
if (str.empty()) if (str.empty())
_m_untip(wd); _m_untip(wd);
else else
_m_get(wd).second = str; _m_get(wd).text = str;
} }
void show(const std::string& text, const point* pos, std::size_t duration) void show(const std::string& text, const point* pos, std::size_t duration)
@ -236,35 +244,35 @@ namespace nana
window_.reset(); window_.reset();
//Destroy the tooltip controller when there are not tooltips. //Destroy the tooltip controller when there are not tooltips.
if (cont_.empty()) if (table_.empty())
instance(true); instance(true);
} }
private: private:
void _m_untip(window wd) void _m_untip(window wd)
{ {
for (auto i = cont_.begin(); i != cont_.end(); ++i) auto i = table_.find(wd);
if(i != table_.end())
{ {
if (i->first == wd) API::umake_event(i->second.evt_msdown);
{ API::umake_event(i->second.evt_msenter);
cont_.erase(i); API::umake_event(i->second.evt_msleave);
API::umake_event(i->second.evt_destroy);
if (cont_.empty()) table_.erase(i);
{ }
window_.reset();
instance(true); if (table_.empty())
} {
return; window_.reset();
} instance(true);
} }
} }
private: private:
pair_t& _m_get(window wd) tip_value& _m_get(window wd)
{ {
for (auto & pr : cont_) auto i = table_.find(wd);
{ if (i != table_.end())
if (pr.first == wd) return i->second;
return pr;
}
auto & events = API::events(wd); auto & events = API::events(wd);
@ -272,28 +280,29 @@ namespace nana
{ {
if (event_code::mouse_enter == arg.evt_code) if (event_code::mouse_enter == arg.evt_code)
{ {
auto & pr = _m_get(arg.window_handle); auto & value = _m_get(arg.window_handle);
if (pr.second.size()) if (value.text.size())
this->show(pr.second, nullptr, 0); this->show(value.text, nullptr, 0);
} }
else else
this->close(); this->close();
}; };
events.mouse_enter.connect(mouse_fn); auto & value = table_[wd];
events.mouse_leave.connect(mouse_fn);
events.mouse_down.connect(mouse_fn);
events.destroy.connect([this](const arg_destroy& arg){ value.evt_msenter = events.mouse_enter.connect(mouse_fn);
value.evt_msleave = events.mouse_leave.connect(mouse_fn);
value.evt_msdown = events.mouse_down.connect(mouse_fn);
value.evt_destroy = events.destroy.connect([this](const arg_destroy& arg){
_m_untip(arg.window_handle); _m_untip(arg.window_handle);
}); });
cont_.emplace_back(wd, std::string()); return value;
return cont_.back();
} }
private: private:
std::unique_ptr<tooltip_interface, deleter_type> window_; std::unique_ptr<tooltip_interface, deleter_type> window_;
std::vector<pair_t> cont_; std::map<window, tip_value> table_;
}; };
}//namespace tooltip }//namespace tooltip
}//namespace drawerbase }//namespace drawerbase