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
|
||||
* 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.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -20,7 +20,6 @@
|
||||
|
||||
#include <nana/push_ignore_diagnostic>
|
||||
|
||||
#include "window_layout.hpp"
|
||||
#include "event_code.hpp"
|
||||
#include "inner_fwd.hpp"
|
||||
#include <functional>
|
||||
@ -31,6 +30,7 @@ namespace nana
|
||||
namespace paint
|
||||
{
|
||||
class image;
|
||||
class graphics;
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,12 +68,10 @@ namespace detail
|
||||
using mutex_type = revertible_mutex;
|
||||
|
||||
using core_window_t = basic_window;
|
||||
using window_layer = window_layout;
|
||||
|
||||
window_manager();
|
||||
~window_manager();
|
||||
|
||||
static bool is_queue(core_window_t*);
|
||||
std::size_t number_of_core_window() const;
|
||||
mutex_type & internal_lock() 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.
|
||||
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);
|
||||
|
||||
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
|
||||
bool move(core_window_t*, int x, int y, bool passive);
|
||||
|
||||
@ -25,7 +25,6 @@ namespace detail
|
||||
void free_fade_table(const unsigned char*);
|
||||
|
||||
//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_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);
|
||||
|
||||
@ -1381,7 +1381,7 @@ namespace detail
|
||||
Window 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)
|
||||
{
|
||||
accepted = true;
|
||||
|
||||
@ -258,7 +258,7 @@ namespace nana
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
set_cursor(wd, wd->predef_cursor, thrd);
|
||||
|
||||
@ -376,7 +376,7 @@ namespace detail
|
||||
switch(msg.kind)
|
||||
{
|
||||
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)
|
||||
{
|
||||
arg_dropfiles arg;
|
||||
@ -511,7 +511,7 @@ namespace detail
|
||||
if(pressed_wd_space)
|
||||
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 (mouse_action::pressed != msgwnd->flags.action)
|
||||
@ -568,7 +568,7 @@ namespace detail
|
||||
if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5)
|
||||
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;
|
||||
if(nullptr == msgwnd)
|
||||
@ -614,7 +614,7 @@ namespace detail
|
||||
auto pos = native_interface::cursor_position();
|
||||
auto rootwd = native_interface::find_window(pos.x, pos.y);
|
||||
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
|
||||
msgwnd->set_action(mouse_action::normal);
|
||||
@ -634,7 +634,7 @@ namespace detail
|
||||
if(pressed_wd_space)
|
||||
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)
|
||||
break;
|
||||
|
||||
@ -754,7 +754,7 @@ namespace detail
|
||||
if(pressed_wd_space)
|
||||
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))
|
||||
{
|
||||
brock.event_msleave(hovered_wd);
|
||||
@ -1282,7 +1282,7 @@ namespace detail
|
||||
return;
|
||||
|
||||
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)
|
||||
set_cursor(rev_wd, rev_wd->predef_cursor, thrd);
|
||||
}
|
||||
|
||||
@ -805,10 +805,10 @@ namespace detail
|
||||
internal_scope_guard lock;
|
||||
auto msgwnd = root_runtime->window;
|
||||
|
||||
switch(message)
|
||||
switch (message)
|
||||
{
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
if(msgwnd->other.attribute.root->ime_enabled)
|
||||
if (msgwnd->other.attribute.root->ime_enabled)
|
||||
{
|
||||
auto native_font = msgwnd->drawer.graphics.typeface().handle();
|
||||
LOGFONTW logfont;
|
||||
@ -820,7 +820,7 @@ namespace detail
|
||||
POINT pos;
|
||||
::GetCaretPos(&pos);
|
||||
|
||||
COMPOSITIONFORM cf = {CFS_POINT};
|
||||
COMPOSITIONFORM cf = { CFS_POINT };
|
||||
cf.ptCurrentPos = pos;
|
||||
restrict::imm_set_composition_window(imc, &cf);
|
||||
restrict::imm_release_context(root_window, imc);
|
||||
@ -828,36 +828,36 @@ namespace detail
|
||||
def_window_proc = true;
|
||||
break;
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
bool take_over = false;
|
||||
auto mmi = reinterpret_cast<MINMAXINFO*>(lParam);
|
||||
{
|
||||
bool take_over = false;
|
||||
auto mmi = reinterpret_cast<MINMAXINFO*>(lParam);
|
||||
|
||||
if(!msgwnd->min_track_size.empty())
|
||||
if (!msgwnd->min_track_size.empty())
|
||||
{
|
||||
mmi->ptMinTrackSize.x = static_cast<LONG>(msgwnd->min_track_size.width + msgwnd->extra_width);
|
||||
mmi->ptMinTrackSize.y = static_cast<LONG>(msgwnd->min_track_size.height + msgwnd->extra_height);
|
||||
take_over = true;
|
||||
}
|
||||
|
||||
if (false == msgwnd->flags.fullscreen)
|
||||
{
|
||||
if (msgwnd->max_track_size.width && msgwnd->max_track_size.height)
|
||||
{
|
||||
mmi->ptMinTrackSize.x = static_cast<LONG>(msgwnd->min_track_size.width + msgwnd->extra_width);
|
||||
mmi->ptMinTrackSize.y = static_cast<LONG>(msgwnd->min_track_size.height + msgwnd->extra_height);
|
||||
mmi->ptMaxTrackSize.x = static_cast<LONG>(msgwnd->max_track_size.width + msgwnd->extra_width);
|
||||
mmi->ptMaxTrackSize.y = static_cast<LONG>(msgwnd->max_track_size.height + msgwnd->extra_height);
|
||||
if (mmi->ptMaxSize.x > mmi->ptMaxTrackSize.x)
|
||||
mmi->ptMaxSize.x = mmi->ptMaxTrackSize.x;
|
||||
if (mmi->ptMaxSize.y > mmi->ptMaxTrackSize.y)
|
||||
mmi->ptMaxSize.y = mmi->ptMaxTrackSize.y;
|
||||
|
||||
take_over = true;
|
||||
}
|
||||
|
||||
if(false == msgwnd->flags.fullscreen)
|
||||
{
|
||||
if(msgwnd->max_track_size.width && msgwnd->max_track_size.height)
|
||||
{
|
||||
mmi->ptMaxTrackSize.x = static_cast<LONG>(msgwnd->max_track_size.width + msgwnd->extra_width);
|
||||
mmi->ptMaxTrackSize.y = static_cast<LONG>(msgwnd->max_track_size.height + msgwnd->extra_height);
|
||||
if(mmi->ptMaxSize.x > mmi->ptMaxTrackSize.x)
|
||||
mmi->ptMaxSize.x = mmi->ptMaxTrackSize.x;
|
||||
if(mmi->ptMaxSize.y > mmi->ptMaxTrackSize.y)
|
||||
mmi->ptMaxSize.y = mmi->ptMaxTrackSize.y;
|
||||
|
||||
take_over = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (take_over)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
if (take_over)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_SHOWWINDOW:
|
||||
if (msgwnd->visible == (FALSE == wParam))
|
||||
brock.event_expose(msgwnd, !msgwnd->visible);
|
||||
@ -882,7 +882,7 @@ namespace detail
|
||||
def_window_proc = true;
|
||||
break;
|
||||
case WM_MOUSEACTIVATE:
|
||||
if(msgwnd->flags.take_active == false)
|
||||
if (msgwnd->flags.take_active == false)
|
||||
return MA_NOACTIVATE;
|
||||
|
||||
def_window_proc = true;
|
||||
@ -893,8 +893,8 @@ namespace detail
|
||||
break;
|
||||
|
||||
pressed_wd = nullptr;
|
||||
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
|
||||
if(msgwnd && msgwnd->flags.enabled)
|
||||
msgwnd = wd_manager.find_window(native_window, { pmdec.mouse.x, pmdec.mouse.y });
|
||||
if (msgwnd && msgwnd->flags.enabled)
|
||||
{
|
||||
if (msgwnd->flags.take_active && !msgwnd->flags.ignore_mouse_focus)
|
||||
{
|
||||
@ -918,7 +918,7 @@ namespace detail
|
||||
if (pressed_wd_space)
|
||||
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.
|
||||
//
|
||||
@ -934,7 +934,7 @@ namespace detail
|
||||
else
|
||||
brock.close_menu_if_focus_other_window(msgwnd->root);
|
||||
|
||||
if(msgwnd->flags.enabled)
|
||||
if (msgwnd->flags.enabled)
|
||||
{
|
||||
pressed_wd = msgwnd;
|
||||
|
||||
@ -962,7 +962,7 @@ namespace detail
|
||||
auto pos = native_interface::cursor_position();
|
||||
auto rootwd = native_interface::find_window(pos.x, pos.y);
|
||||
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
|
||||
msgwnd->set_action(mouse_action::normal);
|
||||
@ -977,7 +977,7 @@ namespace detail
|
||||
pressed_wd = nullptr;
|
||||
}
|
||||
break;
|
||||
//mouse_click, mouse_up
|
||||
//mouse_click, mouse_up
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
@ -985,12 +985,12 @@ namespace detail
|
||||
if (pressed_wd_space)
|
||||
break;
|
||||
|
||||
msgwnd = wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
|
||||
if(nullptr == msgwnd)
|
||||
msgwnd = wd_manager.find_window(native_window, { pmdec.mouse.x, pmdec.mouse.y });
|
||||
if (nullptr == msgwnd)
|
||||
break;
|
||||
|
||||
msgwnd->set_action(mouse_action::normal);
|
||||
if(msgwnd->flags.enabled)
|
||||
if (msgwnd->flags.enabled)
|
||||
{
|
||||
auto retain = msgwnd->annex.events_ptr;
|
||||
|
||||
@ -1014,7 +1014,7 @@ namespace detail
|
||||
}
|
||||
|
||||
//Do mouse_up, this handle may be closed by click handler.
|
||||
if(wd_manager.available(msgwnd) && msgwnd->flags.enabled)
|
||||
if (wd_manager.available(msgwnd) && msgwnd->flags.enabled)
|
||||
{
|
||||
arg.evt_code = event_code::mouse_up;
|
||||
draw_invoker(&drawer::mouse_up, msgwnd, arg, &context);
|
||||
@ -1040,7 +1040,7 @@ namespace detail
|
||||
if (pressed_wd_space)
|
||||
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))
|
||||
{
|
||||
brock.event_msleave(hovered_wd);
|
||||
@ -1121,7 +1121,7 @@ namespace detail
|
||||
if (pointer_wd == 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);
|
||||
auto scrolled_wd = wd_manager.find_window(reinterpret_cast<native_window_type>(pointer_wd), { scr_pos.x, scr_pos.y });
|
||||
|
||||
def_window_proc = true;
|
||||
auto evt_wd = scrolled_wd;
|
||||
@ -1162,10 +1162,12 @@ namespace detail
|
||||
case WM_DROPFILES:
|
||||
{
|
||||
HDROP drop = reinterpret_cast<HDROP>(wParam);
|
||||
POINT pos;
|
||||
::DragQueryPoint(drop, &pos);
|
||||
POINT mswin_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)
|
||||
{
|
||||
arg_dropfiles dropfiles;
|
||||
@ -1193,8 +1195,7 @@ namespace detail
|
||||
|
||||
if(msgwnd)
|
||||
{
|
||||
dropfiles.pos.x = pos.x;
|
||||
dropfiles.pos.y = pos.y;
|
||||
dropfiles.pos = pos;
|
||||
|
||||
wd_manager.calc_window_point(msgwnd, dropfiles.pos);
|
||||
dropfiles.window_handle = reinterpret_cast<window>(msgwnd);
|
||||
@ -1783,7 +1784,7 @@ namespace detail
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
set_cursor(rev_wd, rev_wd->predef_cursor, thrd);
|
||||
|
||||
@ -14,14 +14,17 @@
|
||||
#include <nana/config.hpp>
|
||||
#include <nana/gui/detail/bedrock.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_layout.hpp>
|
||||
#include "window_register.hpp"
|
||||
#include <nana/gui/detail/native_window_interface.hpp>
|
||||
#include <nana/gui/detail/inner_fwd_implement.hpp>
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
#include <nana/gui/detail/effects_renderer.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(STD_THREAD_NOT_SUPPORTED)
|
||||
#include <nana/std_mutex.hpp>
|
||||
@ -34,6 +37,8 @@ namespace nana
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using window_layer = window_layout;
|
||||
|
||||
//class shortkey_container
|
||||
struct shortkey_rep
|
||||
{
|
||||
@ -266,7 +271,8 @@ namespace detail
|
||||
struct window_manager::wdm_private_impl
|
||||
{
|
||||
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_small;
|
||||
|
||||
@ -443,13 +449,11 @@ namespace detail
|
||||
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
|
||||
{
|
||||
//Thread-Safe Required!
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
|
||||
return impl_->wd_register.size();
|
||||
}
|
||||
|
||||
@ -460,7 +464,9 @@ namespace detail
|
||||
|
||||
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)
|
||||
@ -477,11 +483,15 @@ namespace detail
|
||||
|
||||
bool window_manager::available(core_window_t* wd)
|
||||
{
|
||||
//Thread-Safe Required!
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
return impl_->wd_register.available(wd);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@ -533,7 +543,7 @@ namespace detail
|
||||
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);
|
||||
impl_->wd_register.insert(wd, wd->thread_id);
|
||||
impl_->wd_register.insert(wd);
|
||||
|
||||
#ifndef WIDGET_FRAME_DEPRECATED
|
||||
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);
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
@ -701,21 +712,23 @@ 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)
|
||||
{
|
||||
if(!big_icon.empty() || !small_icon.empty())
|
||||
{
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
if (impl_->wd_register.available(wd))
|
||||
if (nullptr == wd)
|
||||
{
|
||||
if(category::flags::root == wd->other.category)
|
||||
native_interface::window_icon(wd->root, small_icon, big_icon);
|
||||
impl_->default_icon_big = big_icon;
|
||||
impl_->default_icon_small = small_icon;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
if (impl_->wd_register.available(wd))
|
||||
{
|
||||
if (category::flags::root == wd->other.category)
|
||||
native_interface::window_icon(wd->root, small_icon, big_icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -791,7 +804,7 @@ namespace detail
|
||||
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)
|
||||
return nullptr;
|
||||
@ -801,7 +814,6 @@ namespace detail
|
||||
//Thread-Safe Required!
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
auto rrt = root_runtime(root);
|
||||
point pos{ x, y };
|
||||
if (rrt && _m_effective(rrt->window, pos))
|
||||
return _m_find(rrt->window, pos);
|
||||
}
|
||||
@ -873,9 +885,8 @@ namespace detail
|
||||
//Move child widgets
|
||||
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 };
|
||||
wd->pos_owner.x = r.x;
|
||||
wd->pos_owner.y = r.y;
|
||||
auto delta = r.position() - wd->pos_owner;
|
||||
wd->pos_owner = r.position();
|
||||
_m_move_core(wd, delta);
|
||||
moved = true;
|
||||
|
||||
@ -1807,32 +1818,18 @@ namespace detail
|
||||
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
|
||||
|
||||
//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)
|
||||
{
|
||||
//closing a child root window erases itself from wd->children,
|
||||
//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.
|
||||
//Only the nested_form meets the condition
|
||||
native_interface::close_window(child->root);
|
||||
|
||||
i = wd->children.rbegin();
|
||||
std::advance(i, offset);
|
||||
end = wd->children.rend();
|
||||
continue;
|
||||
}
|
||||
_m_destroy(child);
|
||||
++i;
|
||||
wd->children.pop_back();
|
||||
}
|
||||
wd->children.clear();
|
||||
|
||||
|
||||
_m_disengage(wd, nullptr);
|
||||
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,12 +461,13 @@ namespace API
|
||||
|
||||
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)
|
||||
{
|
||||
restrict::wd_manager().icon(reinterpret_cast<basic_window*>(wd), small_icon, big_icon);
|
||||
if(nullptr != wd)
|
||||
restrict::wd_manager().icon(reinterpret_cast<basic_window*>(wd), small_icon, big_icon);
|
||||
}
|
||||
|
||||
bool empty_window(window wd)
|
||||
@ -1320,7 +1321,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.x, clipos.y));
|
||||
restrict::wd_manager().find_window(wd, clipos));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -204,14 +204,12 @@ namespace nana
|
||||
range_width_px.first = minimum;
|
||||
range_width_px.second = maximum;
|
||||
|
||||
if (width_px < range_width_px.first)
|
||||
width_px = range_width_px.first;
|
||||
else if (range_width_px.second < width_px)
|
||||
width_px = range_width_px.second;
|
||||
else
|
||||
return;
|
||||
|
||||
_m_refresh();
|
||||
unsigned px = std::clamp(static_cast<int>(width_px), static_cast<int>(minimum), static_cast<int>(maximum));
|
||||
if (width_px != px)
|
||||
{
|
||||
width_px = px;
|
||||
_m_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
//Column ranged width
|
||||
if (new_w < col.range_width_px.first)
|
||||
new_w = col.range_width_px.first;
|
||||
else if (new_w > col.range_width_px.second)
|
||||
new_w = col.range_width_px.second;
|
||||
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));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3129,7 +3124,6 @@ namespace nana
|
||||
{
|
||||
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 state = item_state::normal;
|
||||
@ -3153,7 +3147,7 @@ namespace nana
|
||||
//Make sure the column is in the display area.
|
||||
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);
|
||||
}
|
||||
|
||||
@ -3191,10 +3185,8 @@ namespace nana
|
||||
{
|
||||
//convert x to header logic coordinate.
|
||||
auto const x_offset = essence_->content_view->origin().x;
|
||||
if (x < x_offset)
|
||||
x = x_offset;
|
||||
else if (x > x_offset + static_cast<int>(rect.width))
|
||||
x = x_offset + static_cast<int>(rect.width);
|
||||
|
||||
x = std::clamp(x, x_offset, x_offset + static_cast<int>(rect.width));
|
||||
|
||||
auto i = essence_->header.column_from_point(x);
|
||||
|
||||
@ -3219,9 +3211,10 @@ namespace nana
|
||||
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;
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case item_state::normal: bgcolor = essence_->scheme_ptr->header_bgcolor.get_color(); break;
|
||||
@ -3249,7 +3242,7 @@ namespace nana
|
||||
{
|
||||
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)
|
||||
text_pos.x += text_margin;
|
||||
@ -3277,11 +3270,9 @@ namespace nana
|
||||
|
||||
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()}, text_top, colors::white, col, item_state::floated);
|
||||
_m_draw_header_item(fl_graph, rectangle{ fl_graph.size()}, colors::white, col, item_state::floated);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -419,8 +419,13 @@ namespace nana{ namespace widgets
|
||||
//Overrides methods of colored_area_access_interface
|
||||
std::shared_ptr<colored_area_type> get(std::size_t line_pos) override
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
auto i = colored_areas_.cbegin();
|
||||
for (; i != colored_areas_.cend(); ++i)
|
||||
#else
|
||||
auto i = colored_areas_.begin();
|
||||
for (; i != colored_areas_.end(); ++i)
|
||||
#endif
|
||||
{
|
||||
auto & area = *(i->get());
|
||||
if (area.begin <= line_pos && line_pos < area.begin + area.count)
|
||||
@ -430,10 +435,9 @@ namespace nana{ namespace widgets
|
||||
break;
|
||||
}
|
||||
|
||||
auto iter = colored_areas_.emplace(i, std::make_shared<colored_area_type>(colored_area_type{line_pos}));
|
||||
auto & area = *(iter->get());
|
||||
area.count = 1;
|
||||
return *iter;
|
||||
return *colored_areas_.emplace(i,
|
||||
std::make_shared<colored_area_type>(colored_area_type{line_pos, 1, color{}, color{}})
|
||||
);
|
||||
}
|
||||
|
||||
bool clear()
|
||||
@ -449,7 +453,11 @@ namespace nana{ namespace widgets
|
||||
bool remove(std::size_t pos) override
|
||||
{
|
||||
bool changed = false;
|
||||
#ifdef _MSC_VER
|
||||
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)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user