coe refine
This commit is contained in:
parent
606087f962
commit
970412a3db
@ -1,295 +0,0 @@
|
|||||||
/*
|
|
||||||
* Handle Manager Implementation
|
|
||||||
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
|
|
||||||
*
|
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
*
|
|
||||||
* @file: nana/gui/detail/handle_manager.hpp
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* this manages all the window handles
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NANA_GUI_DETAIL_HANDLE_MANAGER_HPP
|
|
||||||
#define NANA_GUI_DETAIL_HANDLE_MANAGER_HPP
|
|
||||||
|
|
||||||
#include <nana/traits.hpp>
|
|
||||||
#include <nana/config.hpp>
|
|
||||||
#if defined(STD_THREAD_NOT_SUPPORTED)
|
|
||||||
#include <nana/std_mutex.hpp>
|
|
||||||
#else
|
|
||||||
#include <mutex>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <iterator>
|
|
||||||
#include <nana/push_ignore_diagnostic>
|
|
||||||
|
|
||||||
|
|
||||||
namespace nana
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template<typename Key, typename Value, std::size_t CacheSize>
|
|
||||||
class cache
|
|
||||||
: noncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef Key key_type;
|
|
||||||
typedef Value value_type;
|
|
||||||
typedef std::pair<key_type, value_type> pair_type;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
|
|
||||||
cache()
|
|
||||||
:addr_(reinterpret_cast<pair_type*>(::operator new(sizeof(pair_type) * CacheSize)))
|
|
||||||
{
|
|
||||||
for(std::size_t i = 0; i < CacheSize; ++i)
|
|
||||||
{
|
|
||||||
bitmap_[i] = 0;
|
|
||||||
seq_[i] = nana::npos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~cache()
|
|
||||||
{
|
|
||||||
for(std::size_t i = 0; i < CacheSize; ++i)
|
|
||||||
{
|
|
||||||
if(bitmap_[i])
|
|
||||||
addr_[i].~pair_type();
|
|
||||||
}
|
|
||||||
|
|
||||||
::operator delete(addr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool insert(key_type k, value_type v)
|
|
||||||
{
|
|
||||||
size_type pos = _m_find_key(k);
|
|
||||||
if(pos != nana::npos)
|
|
||||||
{
|
|
||||||
addr_[pos].second = v;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//No key exists
|
|
||||||
pos = _m_find_pos();
|
|
||||||
|
|
||||||
if(pos == nana::npos)
|
|
||||||
{ //No room, and remove the last pair
|
|
||||||
pos = seq_[CacheSize - 1];
|
|
||||||
(addr_ + pos)->~pair_type();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(seq_[0] != nana::npos)
|
|
||||||
{//Need to move
|
|
||||||
for(int i = CacheSize - 1; i > 0; --i)
|
|
||||||
seq_[i] = seq_[i - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_[0] = pos;
|
|
||||||
|
|
||||||
new (addr_ + pos) pair_type(k, v);
|
|
||||||
bitmap_[pos] = 1;
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type * get(key_type k)
|
|
||||||
{
|
|
||||||
size_type pos = _m_find_key(k);
|
|
||||||
if(pos != nana::npos)
|
|
||||||
return &(addr_[pos].second);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
size_type _m_find_key(key_type k) const
|
|
||||||
{
|
|
||||||
for(std::size_t i = 0; i < CacheSize; ++i)
|
|
||||||
{
|
|
||||||
if(bitmap_[i] && (addr_[i].first == k))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return nana::npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type _m_find_pos() const
|
|
||||||
{
|
|
||||||
for(std::size_t i = 0; i < CacheSize; ++i)
|
|
||||||
{
|
|
||||||
if(bitmap_[i] == 0)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return nana::npos;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
char bitmap_[CacheSize];
|
|
||||||
size_type seq_[CacheSize];
|
|
||||||
pair_type * addr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//handle_manager
|
|
||||||
//@brief
|
|
||||||
// handle_manager maintains handles of a type. removing a handle dose not destroy it,
|
|
||||||
// it will be inserted to a trash queue for deleting at a safe time.
|
|
||||||
// For efficiency, this class is not a thread-safe.
|
|
||||||
template<typename HandleType, typename Condition, typename Deleter>
|
|
||||||
class handle_manager
|
|
||||||
: nana::noncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef HandleType handle_type;
|
|
||||||
typedef Condition cond_type;
|
|
||||||
typedef Deleter deleter_type;
|
|
||||||
typedef std::map<handle_type, unsigned> handle_map_t;
|
|
||||||
typedef std::pair<handle_type, unsigned> holder_pair;
|
|
||||||
|
|
||||||
~handle_manager()
|
|
||||||
{
|
|
||||||
delete_trash(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void insert(handle_type handle, unsigned tid)
|
|
||||||
{
|
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
|
||||||
|
|
||||||
holder_[handle] = tid;
|
|
||||||
|
|
||||||
is_queue<std::is_same<cond_type, nana::null_type>::value, std::vector<handle_type> >::insert(handle, queue_);
|
|
||||||
cacher_.insert(handle, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(const handle_type handle)
|
|
||||||
{
|
|
||||||
remove(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove(const handle_type handle)
|
|
||||||
{
|
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
|
||||||
|
|
||||||
auto i = static_cast<const handle_map_t&>(holder_).find(handle);
|
|
||||||
if(holder_.cend() != i)
|
|
||||||
{
|
|
||||||
is_queue<std::is_same<cond_type, nana::null_type>::value, std::vector<handle_type> >::erase(handle, queue_);
|
|
||||||
cacher_.insert(handle, false);
|
|
||||||
trash_.push_back(*i);
|
|
||||||
holder_.erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void delete_trash(unsigned tid)
|
|
||||||
{
|
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
|
||||||
|
|
||||||
if(trash_.size())
|
|
||||||
{
|
|
||||||
deleter_type del_functor;
|
|
||||||
if(tid == 0)
|
|
||||||
{
|
|
||||||
for(auto & m : trash_)
|
|
||||||
del_functor(m.first);
|
|
||||||
trash_.clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(auto i = trash_.begin(), end = trash_.end(); i != end;)
|
|
||||||
{
|
|
||||||
if(tid == i->second)
|
|
||||||
{
|
|
||||||
del_functor(i->first);
|
|
||||||
i = trash_.erase(i);
|
|
||||||
end = trash_.end();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_type last() const
|
|
||||||
{
|
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
|
||||||
if(queue_.size())
|
|
||||||
return queue_.back();
|
|
||||||
return handle_type();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t size() const
|
|
||||||
{
|
|
||||||
return holder_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_type get(unsigned index) const
|
|
||||||
{
|
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
|
||||||
if(index < queue_.size())
|
|
||||||
return queue_[index];
|
|
||||||
return handle_type();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool available(const handle_type handle) const
|
|
||||||
{
|
|
||||||
if (nullptr == handle)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
|
||||||
bool * v = cacher_.get(handle);
|
|
||||||
if(v) return *v;
|
|
||||||
return cacher_.insert(handle, (holder_.count(handle) != 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void all(std::vector<handle_type> & v) const
|
|
||||||
{
|
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
|
||||||
std::copy(queue_.cbegin(), queue_.cend(), std::back_inserter(v));
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
|
|
||||||
template<bool IsQueueOperation, typename Container>
|
|
||||||
struct is_queue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static void insert(handle_type handle, Container& queue)
|
|
||||||
{
|
|
||||||
if(cond_type::is_queue(handle))
|
|
||||||
queue.push_back(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void erase(handle_type handle, Container& queue)
|
|
||||||
{
|
|
||||||
if(cond_type::is_queue(handle))
|
|
||||||
{
|
|
||||||
for (auto i = queue.begin(); i != queue.end(); ++i)
|
|
||||||
{
|
|
||||||
if (handle == *i)
|
|
||||||
{
|
|
||||||
queue.erase(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Container>
|
|
||||||
struct is_queue<true, Container>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static void insert(handle_type handle, Container& queue){}
|
|
||||||
static void erase(handle_type handle, Container& queue){}
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable std::recursive_mutex mutex_;
|
|
||||||
mutable cache<const handle_type, bool, 5> cacher_;
|
|
||||||
handle_map_t holder_;
|
|
||||||
std::vector<handle_type> queue_;
|
|
||||||
std::vector<holder_pair> trash_;
|
|
||||||
};//end class handle_manager
|
|
||||||
}//end namespace detail
|
|
||||||
}// end namespace nana
|
|
||||||
#include <nana/pop_ignore_diagnostic>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Window Manager Implementation
|
* Window Manager 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-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
|
||||||
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include <nana/push_ignore_diagnostic>
|
#include <nana/push_ignore_diagnostic>
|
||||||
|
|
||||||
#include "window_layout.hpp"
|
|
||||||
#include "event_code.hpp"
|
#include "event_code.hpp"
|
||||||
#include "inner_fwd.hpp"
|
#include "inner_fwd.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -31,6 +30,7 @@ namespace nana
|
|||||||
namespace paint
|
namespace paint
|
||||||
{
|
{
|
||||||
class image;
|
class image;
|
||||||
|
class graphics;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,12 +68,10 @@ namespace detail
|
|||||||
using mutex_type = revertible_mutex;
|
using mutex_type = revertible_mutex;
|
||||||
|
|
||||||
using core_window_t = basic_window;
|
using core_window_t = basic_window;
|
||||||
using window_layer = window_layout;
|
|
||||||
|
|
||||||
window_manager();
|
window_manager();
|
||||||
~window_manager();
|
~window_manager();
|
||||||
|
|
||||||
static bool is_queue(core_window_t*);
|
|
||||||
std::size_t number_of_core_window() const;
|
std::size_t number_of_core_window() const;
|
||||||
mutex_type & internal_lock() const;
|
mutex_type & internal_lock() const;
|
||||||
void all_handles(std::vector<core_window_t*>&) const;
|
void all_handles(std::vector<core_window_t*>&) const;
|
||||||
@ -103,12 +101,11 @@ namespace detail
|
|||||||
// Deletes a window whose category type is a root type or a frame type.
|
// Deletes a window whose category type is a root type or a frame type.
|
||||||
void destroy_handle(core_window_t*);
|
void destroy_handle(core_window_t*);
|
||||||
|
|
||||||
void default_icon(const paint::image& _small_icon, const paint::image& big_icon);
|
|
||||||
void icon(core_window_t*, const paint::image& small_icon, const paint::image& big_icon);
|
void icon(core_window_t*, const paint::image& small_icon, const paint::image& big_icon);
|
||||||
|
|
||||||
bool show(core_window_t* wd, bool visible);
|
bool show(core_window_t* wd, bool visible);
|
||||||
|
|
||||||
core_window_t* find_window(native_window_type root, int x, int y);
|
core_window_t* find_window(native_window_type root, const point& pos);
|
||||||
|
|
||||||
//move the wnd and its all children window, x and y is a relatively coordinate for wnd's parent window
|
//move the wnd and its all children window, x and y is a relatively coordinate for wnd's parent window
|
||||||
bool move(core_window_t*, int x, int y, bool passive);
|
bool move(core_window_t*, int x, int y, bool passive);
|
||||||
|
|||||||
@ -25,7 +25,6 @@ namespace detail
|
|||||||
void free_fade_table(const unsigned char*);
|
void free_fade_table(const unsigned char*);
|
||||||
|
|
||||||
//color = bgcolor * fade_rate + fgcolor * (1 - fade_rate);
|
//color = bgcolor * fade_rate + fgcolor * (1 - fade_rate);
|
||||||
//nana::pixel_color_t fade_color(nana::pixel_color_t bgcolor, nana::pixel_color_t fgcolor, double fade_rate); //deprecated
|
|
||||||
nana::pixel_color_t fade_color(nana::pixel_color_t bgcolor, nana::pixel_color_t fgcolor, const unsigned char* const fade_table);
|
nana::pixel_color_t fade_color(nana::pixel_color_t bgcolor, nana::pixel_color_t fgcolor, const unsigned char* const fade_table);
|
||||||
nana::pixel_color_t fade_color_intermedia(pixel_color_t fgcolor, const unsigned char* fade_table);
|
nana::pixel_color_t fade_color_intermedia(pixel_color_t fgcolor, const unsigned char* fade_table);
|
||||||
nana::pixel_color_t fade_color_by_intermedia(pixel_color_t bgcolor, nana::pixel_color_t fgcolor_intermedia, const unsigned char* const fade_table);
|
nana::pixel_color_t fade_color_by_intermedia(pixel_color_t bgcolor, nana::pixel_color_t fgcolor_intermedia, const unsigned char* const fade_table);
|
||||||
|
|||||||
@ -1381,7 +1381,7 @@ namespace detail
|
|||||||
Window child;
|
Window child;
|
||||||
::XTranslateCoordinates(self.display_, self.root_window(), evt.xclient.window, x, y, &self.xdnd_.pos.x, &self.xdnd_.pos.y, &child);
|
::XTranslateCoordinates(self.display_, self.root_window(), evt.xclient.window, x, y, &self.xdnd_.pos.x, &self.xdnd_.pos.y, &child);
|
||||||
|
|
||||||
auto wd = bedrock.wd_manager().find_window(reinterpret_cast<native_window_type>(evt.xclient.window), self.xdnd_.pos.x, self.xdnd_.pos.y);
|
auto wd = bedrock.wd_manager().find_window(reinterpret_cast<native_window_type>(evt.xclient.window), self.xdnd_.pos);
|
||||||
if(wd && wd->flags.dropable)
|
if(wd && wd->flags.dropable)
|
||||||
{
|
{
|
||||||
accepted = true;
|
accepted = true;
|
||||||
|
|||||||
@ -258,7 +258,7 @@ namespace nana
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
native_interface::calc_window_point(native_handle, pos);
|
native_interface::calc_window_point(native_handle, pos);
|
||||||
if (wd != wd_manager().find_window(native_handle, pos.x, pos.y))
|
if (wd != wd_manager().find_window(native_handle, pos))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
set_cursor(wd, wd->predef_cursor, thrd);
|
set_cursor(wd, wd->predef_cursor, thrd);
|
||||||
|
|||||||
@ -376,7 +376,7 @@ namespace detail
|
|||||||
switch(msg.kind)
|
switch(msg.kind)
|
||||||
{
|
{
|
||||||
case nana::detail::msg_packet_tag::kind_mouse_drop:
|
case nana::detail::msg_packet_tag::kind_mouse_drop:
|
||||||
msgwd = brock.wd_manager().find_window(native_window, msg.u.mouse_drop.x, msg.u.mouse_drop.y);
|
msgwd = brock.wd_manager().find_window(native_window, {msg.u.mouse_drop.x, msg.u.mouse_drop.y});
|
||||||
if(msgwd)
|
if(msgwd)
|
||||||
{
|
{
|
||||||
arg_dropfiles arg;
|
arg_dropfiles arg;
|
||||||
@ -511,7 +511,7 @@ namespace detail
|
|||||||
if(pressed_wd_space)
|
if(pressed_wd_space)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
msgwnd = wd_manager.find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y);
|
msgwnd = wd_manager.find_window(native_window, {xevent.xcrossing.x, xevent.xcrossing.y});
|
||||||
if(msgwnd)
|
if(msgwnd)
|
||||||
{
|
{
|
||||||
if (mouse_action::pressed != msgwnd->flags.action)
|
if (mouse_action::pressed != msgwnd->flags.action)
|
||||||
@ -568,7 +568,7 @@ namespace detail
|
|||||||
if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5)
|
if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
|
msgwnd = wd_manager.find_window(native_window, {xevent.xbutton.x, xevent.xbutton.y});
|
||||||
|
|
||||||
pressed_wd = nullptr;
|
pressed_wd = nullptr;
|
||||||
if(nullptr == msgwnd)
|
if(nullptr == msgwnd)
|
||||||
@ -614,7 +614,7 @@ namespace detail
|
|||||||
auto pos = native_interface::cursor_position();
|
auto pos = native_interface::cursor_position();
|
||||||
auto rootwd = native_interface::find_window(pos.x, pos.y);
|
auto rootwd = native_interface::find_window(pos.x, pos.y);
|
||||||
native_interface::calc_window_point(rootwd, pos);
|
native_interface::calc_window_point(rootwd, pos);
|
||||||
if(msgwnd != wd_manager.find_window(rootwd, pos.x, pos.y))
|
if(msgwnd != wd_manager.find_window(rootwd, pos))
|
||||||
{
|
{
|
||||||
//call the drawer mouse up event for restoring the surface graphics
|
//call the drawer mouse up event for restoring the surface graphics
|
||||||
msgwnd->set_action(mouse_action::normal);
|
msgwnd->set_action(mouse_action::normal);
|
||||||
@ -634,7 +634,7 @@ namespace detail
|
|||||||
if(pressed_wd_space)
|
if(pressed_wd_space)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
|
msgwnd = wd_manager.find_window(native_window, {xevent.xbutton.x, xevent.xbutton.y});
|
||||||
if(nullptr == msgwnd)
|
if(nullptr == msgwnd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -754,7 +754,7 @@ namespace detail
|
|||||||
if(pressed_wd_space)
|
if(pressed_wd_space)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
msgwnd = wd_manager.find_window(native_window, xevent.xmotion.x, xevent.xmotion.y);
|
msgwnd = wd_manager.find_window(native_window, {xevent.xmotion.x, xevent.xmotion.y});
|
||||||
if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd))
|
if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd))
|
||||||
{
|
{
|
||||||
brock.event_msleave(hovered_wd);
|
brock.event_msleave(hovered_wd);
|
||||||
@ -1282,7 +1282,7 @@ namespace detail
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
native_interface::calc_window_point(native_handle, pos);
|
native_interface::calc_window_point(native_handle, pos);
|
||||||
auto rev_wd = wd_manager().find_window(native_handle, pos.x, pos.y);
|
auto rev_wd = wd_manager().find_window(native_handle, pos);
|
||||||
if (rev_wd)
|
if (rev_wd)
|
||||||
set_cursor(rev_wd, rev_wd->predef_cursor, thrd);
|
set_cursor(rev_wd, rev_wd->predef_cursor, thrd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -893,7 +893,7 @@ namespace detail
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
pressed_wd = nullptr;
|
pressed_wd = nullptr;
|
||||||
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
|
msgwnd = wd_manager.find_window(native_window, { pmdec.mouse.x, pmdec.mouse.y });
|
||||||
if (msgwnd && msgwnd->flags.enabled)
|
if (msgwnd && msgwnd->flags.enabled)
|
||||||
{
|
{
|
||||||
if (msgwnd->flags.take_active && !msgwnd->flags.ignore_mouse_focus)
|
if (msgwnd->flags.take_active && !msgwnd->flags.ignore_mouse_focus)
|
||||||
@ -918,7 +918,7 @@ namespace detail
|
|||||||
if (pressed_wd_space)
|
if (pressed_wd_space)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
|
msgwnd = wd_manager.find_window(native_window, { pmdec.mouse.x, pmdec.mouse.y });
|
||||||
|
|
||||||
//Don't take care about whether msgwnd is equal to the pressed_wd.
|
//Don't take care about whether msgwnd is equal to the pressed_wd.
|
||||||
//
|
//
|
||||||
@ -962,7 +962,7 @@ namespace detail
|
|||||||
auto pos = native_interface::cursor_position();
|
auto pos = native_interface::cursor_position();
|
||||||
auto rootwd = native_interface::find_window(pos.x, pos.y);
|
auto rootwd = native_interface::find_window(pos.x, pos.y);
|
||||||
native_interface::calc_window_point(rootwd, pos);
|
native_interface::calc_window_point(rootwd, pos);
|
||||||
if(msgwnd != wd_manager.find_window(rootwd, pos.x, pos.y))
|
if (msgwnd != wd_manager.find_window(rootwd, pos))
|
||||||
{
|
{
|
||||||
//call the drawer mouse up event for restoring the surface graphics
|
//call the drawer mouse up event for restoring the surface graphics
|
||||||
msgwnd->set_action(mouse_action::normal);
|
msgwnd->set_action(mouse_action::normal);
|
||||||
@ -985,7 +985,7 @@ namespace detail
|
|||||||
if (pressed_wd_space)
|
if (pressed_wd_space)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
|
msgwnd = wd_manager.find_window(native_window, { pmdec.mouse.x, pmdec.mouse.y });
|
||||||
if (nullptr == msgwnd)
|
if (nullptr == msgwnd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1040,7 +1040,7 @@ namespace detail
|
|||||||
if (pressed_wd_space)
|
if (pressed_wd_space)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
|
msgwnd = wd_manager.find_window(native_window, {pmdec.mouse.x, pmdec.mouse.y});
|
||||||
if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd))
|
if (wd_manager.available(hovered_wd) && (msgwnd != hovered_wd))
|
||||||
{
|
{
|
||||||
brock.event_msleave(hovered_wd);
|
brock.event_msleave(hovered_wd);
|
||||||
@ -1121,7 +1121,7 @@ namespace detail
|
|||||||
if (pointer_wd == root_window)
|
if (pointer_wd == root_window)
|
||||||
{
|
{
|
||||||
::ScreenToClient(pointer_wd, &scr_pos);
|
::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);
|
auto scrolled_wd = wd_manager.find_window(reinterpret_cast<native_window_type>(pointer_wd), { scr_pos.x, scr_pos.y });
|
||||||
|
|
||||||
def_window_proc = true;
|
def_window_proc = true;
|
||||||
auto evt_wd = scrolled_wd;
|
auto evt_wd = scrolled_wd;
|
||||||
@ -1162,10 +1162,12 @@ namespace detail
|
|||||||
case WM_DROPFILES:
|
case WM_DROPFILES:
|
||||||
{
|
{
|
||||||
HDROP drop = reinterpret_cast<HDROP>(wParam);
|
HDROP drop = reinterpret_cast<HDROP>(wParam);
|
||||||
POINT pos;
|
POINT mswin_pos;
|
||||||
::DragQueryPoint(drop, &pos);
|
::DragQueryPoint(drop, &mswin_pos);
|
||||||
|
|
||||||
msgwnd = wd_manager.find_window(native_window, pos.x, pos.y);
|
const point pos{ mswin_pos.x, mswin_pos.y };
|
||||||
|
|
||||||
|
msgwnd = wd_manager.find_window(native_window, pos);
|
||||||
if(msgwnd)
|
if(msgwnd)
|
||||||
{
|
{
|
||||||
arg_dropfiles dropfiles;
|
arg_dropfiles dropfiles;
|
||||||
@ -1193,8 +1195,7 @@ namespace detail
|
|||||||
|
|
||||||
if(msgwnd)
|
if(msgwnd)
|
||||||
{
|
{
|
||||||
dropfiles.pos.x = pos.x;
|
dropfiles.pos = pos;
|
||||||
dropfiles.pos.y = pos.y;
|
|
||||||
|
|
||||||
wd_manager.calc_window_point(msgwnd, dropfiles.pos);
|
wd_manager.calc_window_point(msgwnd, dropfiles.pos);
|
||||||
dropfiles.window_handle = reinterpret_cast<window>(msgwnd);
|
dropfiles.window_handle = reinterpret_cast<window>(msgwnd);
|
||||||
@ -1783,7 +1784,7 @@ namespace detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
native_interface::calc_window_point(native_handle, pos);
|
native_interface::calc_window_point(native_handle, pos);
|
||||||
auto rev_wd = wd_manager().find_window(native_handle, pos.x, pos.y);
|
auto rev_wd = wd_manager().find_window(native_handle, pos);
|
||||||
if (rev_wd)
|
if (rev_wd)
|
||||||
{
|
{
|
||||||
set_cursor(rev_wd, rev_wd->predef_cursor, thrd);
|
set_cursor(rev_wd, rev_wd->predef_cursor, thrd);
|
||||||
|
|||||||
@ -14,14 +14,17 @@
|
|||||||
#include <nana/config.hpp>
|
#include <nana/config.hpp>
|
||||||
#include <nana/gui/detail/bedrock.hpp>
|
#include <nana/gui/detail/bedrock.hpp>
|
||||||
#include <nana/gui/detail/events_operation.hpp>
|
#include <nana/gui/detail/events_operation.hpp>
|
||||||
#include <nana/gui/detail/handle_manager.hpp>
|
|
||||||
#include <nana/gui/detail/window_manager.hpp>
|
#include <nana/gui/detail/window_manager.hpp>
|
||||||
|
#include <nana/gui/detail/window_layout.hpp>
|
||||||
|
#include "window_register.hpp"
|
||||||
#include <nana/gui/detail/native_window_interface.hpp>
|
#include <nana/gui/detail/native_window_interface.hpp>
|
||||||
#include <nana/gui/detail/inner_fwd_implement.hpp>
|
#include <nana/gui/detail/inner_fwd_implement.hpp>
|
||||||
#include <nana/gui/layout_utility.hpp>
|
#include <nana/gui/layout_utility.hpp>
|
||||||
#include <nana/gui/detail/effects_renderer.hpp>
|
#include <nana/gui/detail/effects_renderer.hpp>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
#if defined(STD_THREAD_NOT_SUPPORTED)
|
#if defined(STD_THREAD_NOT_SUPPORTED)
|
||||||
#include <nana/std_mutex.hpp>
|
#include <nana/std_mutex.hpp>
|
||||||
@ -34,6 +37,8 @@ namespace nana
|
|||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
using window_layer = window_layout;
|
||||||
|
|
||||||
//class shortkey_container
|
//class shortkey_container
|
||||||
struct shortkey_rep
|
struct shortkey_rep
|
||||||
{
|
{
|
||||||
@ -266,7 +271,8 @@ namespace detail
|
|||||||
struct window_manager::wdm_private_impl
|
struct window_manager::wdm_private_impl
|
||||||
{
|
{
|
||||||
root_register misc_register;
|
root_register misc_register;
|
||||||
handle_manager<core_window_t*, window_manager, window_handle_deleter> wd_register;
|
window_register wd_register;
|
||||||
|
|
||||||
paint::image default_icon_big;
|
paint::image default_icon_big;
|
||||||
paint::image default_icon_small;
|
paint::image default_icon_small;
|
||||||
|
|
||||||
@ -443,13 +449,11 @@ namespace detail
|
|||||||
delete impl_;
|
delete impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool window_manager::is_queue(core_window_t* wd)
|
|
||||||
{
|
|
||||||
return (wd && (category::flags::root == wd->other.category));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t window_manager::number_of_core_window() const
|
std::size_t window_manager::number_of_core_window() const
|
||||||
{
|
{
|
||||||
|
//Thread-Safe Required!
|
||||||
|
std::lock_guard<mutex_type> lock(mutex_);
|
||||||
|
|
||||||
return impl_->wd_register.size();
|
return impl_->wd_register.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +464,9 @@ namespace detail
|
|||||||
|
|
||||||
void window_manager::all_handles(std::vector<core_window_t*> &v) const
|
void window_manager::all_handles(std::vector<core_window_t*> &v) const
|
||||||
{
|
{
|
||||||
impl_->wd_register.all(v);
|
//Thread-Safe Required!
|
||||||
|
std::lock_guard<mutex_type> lock(mutex_);
|
||||||
|
v = impl_->wd_register.queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_manager::event_filter(core_window_t* wd, bool is_make, event_code evtid)
|
void window_manager::event_filter(core_window_t* wd, bool is_make, event_code evtid)
|
||||||
@ -477,11 +483,15 @@ namespace detail
|
|||||||
|
|
||||||
bool window_manager::available(core_window_t* wd)
|
bool window_manager::available(core_window_t* wd)
|
||||||
{
|
{
|
||||||
|
//Thread-Safe Required!
|
||||||
|
std::lock_guard<mutex_type> lock(mutex_);
|
||||||
return impl_->wd_register.available(wd);
|
return impl_->wd_register.available(wd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool window_manager::available(core_window_t * a, core_window_t* b)
|
bool window_manager::available(core_window_t * a, core_window_t* b)
|
||||||
{
|
{
|
||||||
|
//Thread-Safe Required!
|
||||||
|
std::lock_guard<mutex_type> lock(mutex_);
|
||||||
return (impl_->wd_register.available(a) && impl_->wd_register.available(b));
|
return (impl_->wd_register.available(a) && impl_->wd_register.available(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,7 +543,7 @@ namespace detail
|
|||||||
auto* value = impl_->misc_register.insert(result.native_handle, root_misc(wd, result.width, result.height));
|
auto* value = impl_->misc_register.insert(result.native_handle, root_misc(wd, result.width, result.height));
|
||||||
|
|
||||||
wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph);
|
wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph);
|
||||||
impl_->wd_register.insert(wd, wd->thread_id);
|
impl_->wd_register.insert(wd);
|
||||||
|
|
||||||
#ifndef WIDGET_FRAME_DEPRECATED
|
#ifndef WIDGET_FRAME_DEPRECATED
|
||||||
if (owner && (category::flags::frame == owner->other.category))
|
if (owner && (category::flags::frame == owner->other.category))
|
||||||
@ -614,7 +624,8 @@ namespace detail
|
|||||||
wd = new core_window_t(parent, std::move(wdg_notifier), r, (category::lite_widget_tag**)nullptr);
|
wd = new core_window_t(parent, std::move(wdg_notifier), r, (category::lite_widget_tag**)nullptr);
|
||||||
else
|
else
|
||||||
wd = new core_window_t(parent, std::move(wdg_notifier), r, (category::widget_tag**)nullptr);
|
wd = new core_window_t(parent, std::move(wdg_notifier), r, (category::widget_tag**)nullptr);
|
||||||
impl_->wd_register.insert(wd, wd->thread_id);
|
|
||||||
|
impl_->wd_register.insert(wd);
|
||||||
return wd;
|
return wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,15 +712,16 @@ namespace detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_manager::default_icon(const nana::paint::image& _small, const nana::paint::image& big)
|
|
||||||
{
|
|
||||||
impl_->default_icon_big = big;
|
|
||||||
impl_->default_icon_small = _small;
|
|
||||||
}
|
|
||||||
|
|
||||||
void window_manager::icon(core_window_t* wd, const paint::image& small_icon, const paint::image& big_icon)
|
void window_manager::icon(core_window_t* wd, const paint::image& small_icon, const paint::image& big_icon)
|
||||||
{
|
{
|
||||||
if(!big_icon.empty() || !small_icon.empty())
|
if(!big_icon.empty() || !small_icon.empty())
|
||||||
|
{
|
||||||
|
if (nullptr == wd)
|
||||||
|
{
|
||||||
|
impl_->default_icon_big = big_icon;
|
||||||
|
impl_->default_icon_small = small_icon;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
std::lock_guard<mutex_type> lock(mutex_);
|
std::lock_guard<mutex_type> lock(mutex_);
|
||||||
if (impl_->wd_register.available(wd))
|
if (impl_->wd_register.available(wd))
|
||||||
@ -719,6 +731,7 @@ namespace detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void sync_child_root_display(window_manager::core_window_t* wd)
|
void sync_child_root_display(window_manager::core_window_t* wd)
|
||||||
{
|
{
|
||||||
@ -791,7 +804,7 @@ namespace detail
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
window_manager::core_window_t* window_manager::find_window(native_window_type root, int x, int y)
|
window_manager::core_window_t* window_manager::find_window(native_window_type root, const point& pos)
|
||||||
{
|
{
|
||||||
if (nullptr == root)
|
if (nullptr == root)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -801,7 +814,6 @@ namespace detail
|
|||||||
//Thread-Safe Required!
|
//Thread-Safe Required!
|
||||||
std::lock_guard<mutex_type> lock(mutex_);
|
std::lock_guard<mutex_type> lock(mutex_);
|
||||||
auto rrt = root_runtime(root);
|
auto rrt = root_runtime(root);
|
||||||
point pos{ x, y };
|
|
||||||
if (rrt && _m_effective(rrt->window, pos))
|
if (rrt && _m_effective(rrt->window, pos))
|
||||||
return _m_find(rrt->window, pos);
|
return _m_find(rrt->window, pos);
|
||||||
}
|
}
|
||||||
@ -873,9 +885,8 @@ namespace detail
|
|||||||
//Move child widgets
|
//Move child widgets
|
||||||
if(r.x != wd->pos_owner.x || r.y != wd->pos_owner.y)
|
if(r.x != wd->pos_owner.x || r.y != wd->pos_owner.y)
|
||||||
{
|
{
|
||||||
point delta{ r.x - wd->pos_owner.x, r.y - wd->pos_owner.y };
|
auto delta = r.position() - wd->pos_owner;
|
||||||
wd->pos_owner.x = r.x;
|
wd->pos_owner = r.position();
|
||||||
wd->pos_owner.y = r.y;
|
|
||||||
_m_move_core(wd, delta);
|
_m_move_core(wd, delta);
|
||||||
moved = true;
|
moved = true;
|
||||||
|
|
||||||
@ -1807,32 +1818,18 @@ namespace detail
|
|||||||
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
|
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
|
||||||
|
|
||||||
//Delete the children widgets.
|
//Delete the children widgets.
|
||||||
for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end;)
|
while (!wd->children.empty())
|
||||||
{
|
{
|
||||||
auto child = *i;
|
auto child = wd->children.back();
|
||||||
|
|
||||||
if (category::flags::root == child->other.category)
|
if (category::flags::root == child->other.category)
|
||||||
{
|
{
|
||||||
//closing a child root window erases itself from wd->children,
|
//Only the nested_form meets the condition
|
||||||
//to make sure the iterator is valid, it must be reloaded.
|
|
||||||
|
|
||||||
auto offset = std::distance(wd->children.rbegin(), i);
|
|
||||||
|
|
||||||
//!!!
|
|
||||||
//a potential issue is that if the calling thread is not same with child's thread,
|
|
||||||
//the child root window may not be erased from wd->children now.
|
|
||||||
native_interface::close_window(child->root);
|
native_interface::close_window(child->root);
|
||||||
|
|
||||||
i = wd->children.rbegin();
|
|
||||||
std::advance(i, offset);
|
|
||||||
end = wd->children.rend();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_m_destroy(child);
|
_m_destroy(child);
|
||||||
++i;
|
wd->children.pop_back();
|
||||||
}
|
}
|
||||||
wd->children.clear();
|
|
||||||
|
|
||||||
|
|
||||||
_m_disengage(wd, nullptr);
|
_m_disengage(wd, nullptr);
|
||||||
window_layer::enable_effects_bground(wd, false);
|
window_layer::enable_effects_bground(wd, false);
|
||||||
|
|||||||
201
source/gui/detail/window_register.hpp
Normal file
201
source/gui/detail/window_register.hpp
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
#ifndef NANA_WINDOW_REGISTER_HEADER_INCLUDED
|
||||||
|
#define NANA_WINDOW_REGISTER_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#include <nana/gui/detail/basic_window.hpp>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> //std::find
|
||||||
|
|
||||||
|
namespace nana
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename Key, typename Value, std::size_t CacheSize>
|
||||||
|
class cache
|
||||||
|
: noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Key key_type;
|
||||||
|
typedef Value value_type;
|
||||||
|
typedef std::pair<key_type, value_type> pair_type;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
|
||||||
|
cache()
|
||||||
|
:addr_(reinterpret_cast<pair_type*>(::operator new(sizeof(pair_type) * CacheSize)))
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < CacheSize; ++i)
|
||||||
|
{
|
||||||
|
bitmap_[i] = 0;
|
||||||
|
seq_[i] = nana::npos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~cache()
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < CacheSize; ++i)
|
||||||
|
{
|
||||||
|
if (bitmap_[i])
|
||||||
|
addr_[i].~pair_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
::operator delete(addr_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool insert(key_type k, value_type v)
|
||||||
|
{
|
||||||
|
size_type pos = _m_find_key(k);
|
||||||
|
if (pos != nana::npos)
|
||||||
|
{
|
||||||
|
addr_[pos].second = v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//No key exists
|
||||||
|
pos = _m_find_pos();
|
||||||
|
|
||||||
|
if (pos == nana::npos)
|
||||||
|
{ //No room, and remove the last pair
|
||||||
|
pos = seq_[CacheSize - 1];
|
||||||
|
(addr_ + pos)->~pair_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seq_[0] != nana::npos)
|
||||||
|
{//Need to move
|
||||||
|
for (int i = CacheSize - 1; i > 0; --i)
|
||||||
|
seq_[i] = seq_[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
seq_[0] = pos;
|
||||||
|
|
||||||
|
new (addr_ + pos) pair_type(k, v);
|
||||||
|
bitmap_[pos] = 1;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type * get(key_type k)
|
||||||
|
{
|
||||||
|
size_type pos = _m_find_key(k);
|
||||||
|
if (pos != nana::npos)
|
||||||
|
return &(addr_[pos].second);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
size_type _m_find_key(key_type k) const
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < CacheSize; ++i)
|
||||||
|
{
|
||||||
|
if (bitmap_[i] && (addr_[i].first == k))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return nana::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type _m_find_pos() const
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < CacheSize; ++i)
|
||||||
|
{
|
||||||
|
if (bitmap_[i] == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return nana::npos;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
char bitmap_[CacheSize];
|
||||||
|
size_type seq_[CacheSize];
|
||||||
|
pair_type * addr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class window_register
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using window_handle_type = basic_window*;
|
||||||
|
|
||||||
|
void insert(window_handle_type wd)
|
||||||
|
{
|
||||||
|
if (wd)
|
||||||
|
{
|
||||||
|
base_.insert(wd);
|
||||||
|
wdcache_.insert(wd, true);
|
||||||
|
|
||||||
|
if (category::flags::root == wd->other.category)
|
||||||
|
queue_.push_back(wd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(window_handle_type wd)
|
||||||
|
{
|
||||||
|
remove(wd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove(window_handle_type wd)
|
||||||
|
{
|
||||||
|
if (base_.erase(wd))
|
||||||
|
{
|
||||||
|
wdcache_.insert(wd, false);
|
||||||
|
if (category::flags::root == wd->other.category)
|
||||||
|
{
|
||||||
|
trash_.push_back(wd);
|
||||||
|
auto i = std::find(queue_.begin(), queue_.end(), wd);
|
||||||
|
if (i != queue_.end())
|
||||||
|
queue_.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_trash(unsigned thread_id)
|
||||||
|
{
|
||||||
|
if (0 == thread_id)
|
||||||
|
{
|
||||||
|
for (auto wd : trash_)
|
||||||
|
delete wd;
|
||||||
|
|
||||||
|
trash_.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto i = trash_.begin(); i != trash_.end();)
|
||||||
|
{
|
||||||
|
if (thread_id == (*i)->thread_id)
|
||||||
|
{
|
||||||
|
delete (*i);
|
||||||
|
i = trash_.erase(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<window_handle_type>& queue() const
|
||||||
|
{
|
||||||
|
return queue_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of registered windows
|
||||||
|
std::size_t size() const
|
||||||
|
{
|
||||||
|
return base_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool available(window_handle_type wd) const
|
||||||
|
{
|
||||||
|
if (nullptr == wd)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto exists = wdcache_.get(wd);
|
||||||
|
if (exists)
|
||||||
|
return *exists;
|
||||||
|
|
||||||
|
return wdcache_.insert(wd, (base_.count(wd) != 0));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
mutable cache<window_handle_type, bool, 5> wdcache_;
|
||||||
|
std::set<window_handle_type> base_;
|
||||||
|
std::vector<window_handle_type> trash_;
|
||||||
|
std::vector<window_handle_type> queue_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -461,11 +461,12 @@ namespace API
|
|||||||
|
|
||||||
void window_icon_default(const paint::image& small_icon, const paint::image& big_icon)
|
void window_icon_default(const paint::image& small_icon, const paint::image& big_icon)
|
||||||
{
|
{
|
||||||
restrict::wd_manager().default_icon(small_icon, big_icon);
|
restrict::wd_manager().icon(nullptr, small_icon, big_icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_icon(window wd, const paint::image& small_icon, const paint::image& big_icon)
|
void window_icon(window wd, const paint::image& small_icon, const paint::image& big_icon)
|
||||||
{
|
{
|
||||||
|
if(nullptr != wd)
|
||||||
restrict::wd_manager().icon(reinterpret_cast<basic_window*>(wd), small_icon, big_icon);
|
restrict::wd_manager().icon(reinterpret_cast<basic_window*>(wd), small_icon, big_icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1320,7 +1321,7 @@ namespace API
|
|||||||
::nana::point clipos{pos};
|
::nana::point clipos{pos};
|
||||||
interface_type::calc_window_point(wd, clipos);
|
interface_type::calc_window_point(wd, clipos);
|
||||||
return reinterpret_cast<window>(
|
return reinterpret_cast<window>(
|
||||||
restrict::wd_manager().find_window(wd, clipos.x, clipos.y));
|
restrict::wd_manager().find_window(wd, clipos));
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -204,15 +204,13 @@ namespace nana
|
|||||||
range_width_px.first = minimum;
|
range_width_px.first = minimum;
|
||||||
range_width_px.second = maximum;
|
range_width_px.second = maximum;
|
||||||
|
|
||||||
if (width_px < range_width_px.first)
|
unsigned px = std::clamp(static_cast<int>(width_px), static_cast<int>(minimum), static_cast<int>(maximum));
|
||||||
width_px = range_width_px.first;
|
if (width_px != px)
|
||||||
else if (range_width_px.second < width_px)
|
{
|
||||||
width_px = range_width_px.second;
|
width_px = px;
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
_m_refresh();
|
_m_refresh();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_type position(bool disp_order) const noexcept override; //The definition is provided after essence
|
size_type position(bool disp_order) const noexcept override; //The definition is provided after essence
|
||||||
|
|
||||||
@ -3104,10 +3102,7 @@ namespace nana
|
|||||||
if (col.range_width_px.first != col.range_width_px.second)
|
if (col.range_width_px.first != col.range_width_px.second)
|
||||||
{
|
{
|
||||||
//Column ranged width
|
//Column ranged width
|
||||||
if (new_w < col.range_width_px.first)
|
new_w = std::clamp(static_cast<int>(new_w), static_cast<int>(col.range_width_px.first), static_cast<int>(col.range_width_px.second));
|
||||||
new_w = col.range_width_px.first;
|
|
||||||
else if (new_w > col.range_width_px.second)
|
|
||||||
new_w = col.range_width_px.second;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3129,7 +3124,6 @@ namespace nana
|
|||||||
{
|
{
|
||||||
const auto border_color = essence_->scheme_ptr->header_bgcolor.get_color().blend(colors::black, 0.2);
|
const auto border_color = essence_->scheme_ptr->header_bgcolor.get_color().blend(colors::black, 0.2);
|
||||||
|
|
||||||
int text_top = (r.height - essence_->text_height) / 2 + r.y;
|
|
||||||
auto text_color = essence_->scheme_ptr->header_fgcolor.get_color();
|
auto text_color = essence_->scheme_ptr->header_fgcolor.get_color();
|
||||||
|
|
||||||
auto state = item_state::normal;
|
auto state = item_state::normal;
|
||||||
@ -3153,7 +3147,7 @@ namespace nana
|
|||||||
//Make sure the column is in the display area.
|
//Make sure the column is in the display area.
|
||||||
if (right_pos > r.x)
|
if (right_pos > r.x)
|
||||||
{
|
{
|
||||||
_m_draw_header_item(graph, column_r, text_top, text_color, col, (col.index == essence_->pointer_where.second ? state : item_state::normal));
|
_m_draw_header_item(graph, column_r, text_color, col, (col.index == essence_->pointer_where.second ? state : item_state::normal));
|
||||||
graph.line({ right_pos - 1, r.y }, { right_pos - 1, r.bottom() - 2 }, border_color);
|
graph.line({ right_pos - 1, r.y }, { right_pos - 1, r.bottom() - 2 }, border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3191,10 +3185,8 @@ namespace nana
|
|||||||
{
|
{
|
||||||
//convert x to header logic coordinate.
|
//convert x to header logic coordinate.
|
||||||
auto const x_offset = essence_->content_view->origin().x;
|
auto const x_offset = essence_->content_view->origin().x;
|
||||||
if (x < x_offset)
|
|
||||||
x = x_offset;
|
x = std::clamp(x, x_offset, x_offset + static_cast<int>(rect.width));
|
||||||
else if (x > x_offset + static_cast<int>(rect.width))
|
|
||||||
x = x_offset + static_cast<int>(rect.width);
|
|
||||||
|
|
||||||
auto i = essence_->header.column_from_point(x);
|
auto i = essence_->header.column_from_point(x);
|
||||||
|
|
||||||
@ -3219,9 +3211,10 @@ namespace nana
|
|||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _m_draw_header_item(graph_reference graph, const rectangle& column_r, int text_top, const ::nana::color& fgcolor, const es_header::column& column, item_state state)
|
void _m_draw_header_item(graph_reference graph, const rectangle& column_r, const ::nana::color& fgcolor, const es_header::column& column, item_state state)
|
||||||
{
|
{
|
||||||
::nana::color bgcolor;
|
::nana::color bgcolor;
|
||||||
|
|
||||||
switch(state)
|
switch(state)
|
||||||
{
|
{
|
||||||
case item_state::normal: bgcolor = essence_->scheme_ptr->header_bgcolor.get_color(); break;
|
case item_state::normal: bgcolor = essence_->scheme_ptr->header_bgcolor.get_color(); break;
|
||||||
@ -3249,7 +3242,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
graph.palette(true, fgcolor);
|
graph.palette(true, fgcolor);
|
||||||
|
|
||||||
point text_pos{ column_r.x, text_top };
|
point text_pos{ column_r.x, (static_cast<int>(essence_->scheme_ptr->header_height) - static_cast<int>(essence_->text_height)) / 2 };
|
||||||
|
|
||||||
if (align::left == column.alignment)
|
if (align::left == column.alignment)
|
||||||
text_pos.x += text_margin;
|
text_pos.x += text_margin;
|
||||||
@ -3277,11 +3270,9 @@ namespace nana
|
|||||||
|
|
||||||
fl_graph.typeface(essence_->graph->typeface());
|
fl_graph.typeface(essence_->graph->typeface());
|
||||||
|
|
||||||
int text_top = (essence_->scheme_ptr->header_height - essence_->text_height) / 2;
|
_m_draw_header_item(fl_graph, rectangle{ fl_graph.size()}, colors::white, col, item_state::floated);
|
||||||
_m_draw_header_item(fl_graph, rectangle{ fl_graph.size()}, text_top, colors::white, col, item_state::floated);
|
|
||||||
|
|
||||||
auto xpos = essence_->header.position(col.index, nullptr) + pos.x - grabs_.start_pos;
|
auto xpos = essence_->header.position(col.index, nullptr) + pos.x - grabs_.start_pos;
|
||||||
|
|
||||||
essence_->graph->blend(rectangle{ point{ xpos - essence_->content_view->origin().x + rect.x, rect.y } , fl_graph.size() }, fl_graph, {}, 0.5);
|
essence_->graph->blend(rectangle{ point{ xpos - essence_->content_view->origin().x + rect.x, rect.y } , fl_graph.size() }, fl_graph, {}, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -419,8 +419,13 @@ namespace nana{ namespace widgets
|
|||||||
//Overrides methods of colored_area_access_interface
|
//Overrides methods of colored_area_access_interface
|
||||||
std::shared_ptr<colored_area_type> get(std::size_t line_pos) override
|
std::shared_ptr<colored_area_type> get(std::size_t line_pos) override
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
auto i = colored_areas_.cbegin();
|
auto i = colored_areas_.cbegin();
|
||||||
for (; i != colored_areas_.cend(); ++i)
|
for (; i != colored_areas_.cend(); ++i)
|
||||||
|
#else
|
||||||
|
auto i = colored_areas_.begin();
|
||||||
|
for (; i != colored_areas_.end(); ++i)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
auto & area = *(i->get());
|
auto & area = *(i->get());
|
||||||
if (area.begin <= line_pos && line_pos < area.begin + area.count)
|
if (area.begin <= line_pos && line_pos < area.begin + area.count)
|
||||||
@ -430,10 +435,9 @@ namespace nana{ namespace widgets
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto iter = colored_areas_.emplace(i, std::make_shared<colored_area_type>(colored_area_type{line_pos}));
|
return *colored_areas_.emplace(i,
|
||||||
auto & area = *(iter->get());
|
std::make_shared<colored_area_type>(colored_area_type{line_pos, 1, color{}, color{}})
|
||||||
area.count = 1;
|
);
|
||||||
return *iter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clear()
|
bool clear()
|
||||||
@ -449,7 +453,11 @@ namespace nana{ namespace widgets
|
|||||||
bool remove(std::size_t pos) override
|
bool remove(std::size_t pos) override
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
#ifdef _MSC_VER
|
||||||
for (auto i = colored_areas_.cbegin(); i != colored_areas_.cend();)
|
for (auto i = colored_areas_.cbegin(); i != colored_areas_.cend();)
|
||||||
|
#else
|
||||||
|
for (auto i = colored_areas_.begin(); i != colored_areas_.end();)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (i->get()->begin <= pos && pos < i->get()->begin + i->get()->count)
|
if (i->get()->begin <= pos && pos < i->get()->begin + i->get()->count)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user