Merge branch 'hotfix-1.4' into develop
This commit is contained in:
commit
340c350fcb
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Inline Widget Interface Definition
|
* A Inline Widget Interface Definition
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2016 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
|
||||||
@ -35,6 +35,9 @@ namespace nana
|
|||||||
/// Returns the host widget of the indicator
|
/// Returns the host widget of the indicator
|
||||||
virtual ::nana::widget& host() const = 0;
|
virtual ::nana::widget& host() const = 0;
|
||||||
|
|
||||||
|
/// Returns the position of column
|
||||||
|
virtual std::size_t column() const = 0;
|
||||||
|
|
||||||
/// Modifies the value of a item specified by pos
|
/// Modifies the value of a item specified by pos
|
||||||
virtual void modify(index_type pos, const value_type&) const = 0;
|
virtual void modify(index_type pos, const value_type&) const = 0;
|
||||||
|
|
||||||
@ -45,7 +48,7 @@ namespace nana
|
|||||||
virtual void hovered(index_type) = 0;
|
virtual void hovered(index_type) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Index, typename Value>
|
template<typename Index, typename Status, typename Value>
|
||||||
class inline_widget_notifier_interface
|
class inline_widget_notifier_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -55,6 +58,9 @@ namespace nana
|
|||||||
/// A type to the value of the item
|
/// A type to the value of the item
|
||||||
using value_type = Value;
|
using value_type = Value;
|
||||||
|
|
||||||
|
/// A type to the status
|
||||||
|
using status_type = Status;
|
||||||
|
|
||||||
/// A typedef name of a inline widget indicator
|
/// A typedef name of a inline widget indicator
|
||||||
using inline_indicator = inline_widget_indicator<index_type, value_type>;
|
using inline_indicator = inline_widget_indicator<index_type, value_type>;
|
||||||
|
|
||||||
@ -70,6 +76,9 @@ namespace nana
|
|||||||
/// A message to activate the inline widget to attach a specified item
|
/// A message to activate the inline widget to attach a specified item
|
||||||
virtual void activate(inline_indicator&, index_type) = 0;
|
virtual void activate(inline_indicator&, index_type) = 0;
|
||||||
|
|
||||||
|
/// A message to change the status
|
||||||
|
virtual void notify_status(status_type, bool) = 0;
|
||||||
|
|
||||||
/// A message to resize the inline widget
|
/// A message to resize the inline widget
|
||||||
virtual void resize(const size&) = 0;
|
virtual void resize(const size&) = 0;
|
||||||
|
|
||||||
|
|||||||
@ -676,8 +676,14 @@ namespace nana
|
|||||||
|
|
||||||
using index_pairs = ::std::vector<index_pair>;
|
using index_pairs = ::std::vector<index_pair>;
|
||||||
|
|
||||||
using inline_notifier_interface = detail::inline_widget_notifier_interface<index_pair, ::std::string>;
|
enum class inline_widget_status{
|
||||||
|
checked,
|
||||||
|
checking,
|
||||||
|
selected,
|
||||||
|
selecting
|
||||||
|
};
|
||||||
|
|
||||||
|
using inline_notifier_interface = detail::inline_widget_notifier_interface<index_pair, inline_widget_status, ::std::string>;
|
||||||
|
|
||||||
// struct essence
|
// struct essence
|
||||||
//@brief: this struct gives many data for listbox,
|
//@brief: this struct gives many data for listbox,
|
||||||
|
|||||||
@ -143,7 +143,11 @@ namespace nana{ namespace widgets
|
|||||||
std::wstring text() const;
|
std::wstring text() const;
|
||||||
|
|
||||||
/// Sets caret position through text coordinate.
|
/// Sets caret position through text coordinate.
|
||||||
void move_caret(const upoint&);
|
/**
|
||||||
|
* @param pos the text position
|
||||||
|
* @param reset indicates whether to reset the text position by the pos. If this parameter is true, the text position is set by pos. If the parameter is false, it only moves the UI caret to the specified position.
|
||||||
|
*/
|
||||||
|
bool move_caret(const upoint& pos, bool reset = false);
|
||||||
void move_caret_end();
|
void move_caret_end();
|
||||||
void reset_caret_pixels() const;
|
void reset_caret_pixels() const;
|
||||||
void reset_caret();
|
void reset_caret();
|
||||||
@ -184,6 +188,7 @@ namespace nana{ namespace widgets
|
|||||||
void del();
|
void del();
|
||||||
void backspace(bool record_undo = true);
|
void backspace(bool record_undo = true);
|
||||||
void undo(bool reverse);
|
void undo(bool reverse);
|
||||||
|
void set_undo_queue_length(std::size_t len);
|
||||||
void move_ns(bool to_north); //Moves up and down
|
void move_ns(bool to_north); //Moves up and down
|
||||||
void move_left();
|
void move_left();
|
||||||
void move_right();
|
void move_right();
|
||||||
|
|||||||
@ -237,6 +237,12 @@ namespace nana
|
|||||||
/// E.g. Whether caret moves to left of selected content or moves to left of last position when left arrow key is pressed.
|
/// E.g. Whether caret moves to left of selected content or moves to left of last position when left arrow key is pressed.
|
||||||
/// @param move_to_end determines whether to move caret to left of selected_content or to left of last position.
|
/// @param move_to_end determines whether to move caret to left of selected_content or to left of last position.
|
||||||
void select_behavior(bool move_to_end);
|
void select_behavior(bool move_to_end);
|
||||||
|
|
||||||
|
/// Sets the undo/redo queue length
|
||||||
|
/**
|
||||||
|
* @param len The length of the queue. If this parameter is zero, the undo/redo is disabled.
|
||||||
|
*/
|
||||||
|
void set_undo_queue_length(std::size_t len);
|
||||||
protected:
|
protected:
|
||||||
//Overrides widget's virtual functions
|
//Overrides widget's virtual functions
|
||||||
native_string_type _m_caption() const throw() override;
|
native_string_type _m_caption() const throw() override;
|
||||||
|
|||||||
@ -158,11 +158,9 @@ namespace nana
|
|||||||
: public widget
|
: public widget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~widget_base();
|
|
||||||
|
|
||||||
window handle() const override;
|
window handle() const override;
|
||||||
private:
|
protected:
|
||||||
void _m_notify_destroy() override final;
|
void _m_notify_destroy() override;
|
||||||
protected:
|
protected:
|
||||||
window handle_{ nullptr };
|
window handle_{ nullptr };
|
||||||
};
|
};
|
||||||
@ -183,6 +181,11 @@ namespace nana
|
|||||||
scheme_{ API::dev::make_scheme<Scheme>() }
|
scheme_{ API::dev::make_scheme<Scheme>() }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
~widget_object()
|
||||||
|
{
|
||||||
|
API::close_window(handle());
|
||||||
|
}
|
||||||
|
|
||||||
event_type& events() const
|
event_type& events() const
|
||||||
{
|
{
|
||||||
return *events_;
|
return *events_;
|
||||||
@ -239,6 +242,13 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return *events_;
|
return *events_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _m_notify_destroy() override final
|
||||||
|
{
|
||||||
|
widget_base::_m_notify_destroy();
|
||||||
|
events_ = std::make_shared<Events>();
|
||||||
|
API::dev::set_events(handle_, events_);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
DrawerTrigger trigger_;
|
DrawerTrigger trigger_;
|
||||||
std::shared_ptr<Events> events_;
|
std::shared_ptr<Events> events_;
|
||||||
@ -259,6 +269,11 @@ namespace nana
|
|||||||
: events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() }
|
: events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
~widget_object()
|
||||||
|
{
|
||||||
|
API::close_window(handle());
|
||||||
|
}
|
||||||
|
|
||||||
event_type& events() const
|
event_type& events() const
|
||||||
{
|
{
|
||||||
return *events_;
|
return *events_;
|
||||||
@ -292,6 +307,13 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return *events_;
|
return *events_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _m_notify_destroy() override final
|
||||||
|
{
|
||||||
|
widget_base::_m_notify_destroy();
|
||||||
|
events_ = std::make_shared<Events>();
|
||||||
|
API::dev::set_events(handle_, events_);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Events> events_;
|
std::shared_ptr<Events> events_;
|
||||||
std::unique_ptr<scheme_type> scheme_;
|
std::unique_ptr<scheme_type> scheme_;
|
||||||
@ -319,6 +341,11 @@ namespace nana
|
|||||||
_m_bind_and_attach();
|
_m_bind_and_attach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~widget_object()
|
||||||
|
{
|
||||||
|
API::close_window(handle());
|
||||||
|
}
|
||||||
|
|
||||||
event_type& events() const
|
event_type& events() const
|
||||||
{
|
{
|
||||||
return *events_;
|
return *events_;
|
||||||
@ -419,6 +446,13 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return *events_;
|
return *events_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _m_notify_destroy() override final
|
||||||
|
{
|
||||||
|
widget_base::_m_notify_destroy();
|
||||||
|
events_ = std::make_shared<Events>();
|
||||||
|
API::dev::set_events(handle_, events_);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
DrawerTrigger trigger_;
|
DrawerTrigger trigger_;
|
||||||
std::shared_ptr<Events> events_;
|
std::shared_ptr<Events> events_;
|
||||||
@ -444,6 +478,11 @@ namespace nana
|
|||||||
: events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() }
|
: events_{ std::make_shared<Events>() }, scheme_{ API::dev::make_scheme<scheme_type>() }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
~widget_object()
|
||||||
|
{
|
||||||
|
API::close_window(handle());
|
||||||
|
}
|
||||||
|
|
||||||
event_type& events() const
|
event_type& events() const
|
||||||
{
|
{
|
||||||
return *events_;
|
return *events_;
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
#define NANA_PAT_ABSFACTORY_HPP
|
#define NANA_PAT_ABSFACTORY_HPP
|
||||||
#include "cloneable.hpp"
|
#include "cloneable.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -43,21 +45,68 @@ namespace nana
|
|||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename T, typename Interface>
|
template<typename Useless, std::size_t ...Index>
|
||||||
|
struct pack{
|
||||||
|
using type = pack;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bool Negative, bool Zero, class IntConst, class Pack>
|
||||||
|
struct make_pack_helper
|
||||||
|
{ // explodes gracefully below 0
|
||||||
|
static_assert(!Negative,
|
||||||
|
"make_integer_sequence<T, N> requires N to be non-negative.");
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Useless, std::size_t ... Vals>
|
||||||
|
struct make_pack_helper<false, true,
|
||||||
|
std::integral_constant<std::size_t, 0>,
|
||||||
|
pack<Useless, Vals...> >
|
||||||
|
: pack<Useless, Vals...>
|
||||||
|
{ // ends recursion at 0
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Useless, std::size_t X, std::size_t... Vals>
|
||||||
|
struct make_pack_helper<false, false,
|
||||||
|
std::integral_constant<std::size_t, X>,
|
||||||
|
pack<Useless, Vals...> >
|
||||||
|
: make_pack_helper<false, X == 1,
|
||||||
|
std::integral_constant<std::size_t, X - 1>,
|
||||||
|
pack<Useless, X - 1, Vals...> >
|
||||||
|
{ // counts down to 0
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::size_t Size>
|
||||||
|
using make_pack = typename make_pack_helper<Size < 0, Size == 0, std::integral_constant<std::size_t, Size>, pack<int> >::type;
|
||||||
|
|
||||||
|
template<typename T, typename Interface, typename ...Args>
|
||||||
class abs_factory
|
class abs_factory
|
||||||
: public abstract_factory<Interface>
|
: public abstract_factory<Interface>
|
||||||
{
|
{
|
||||||
std::unique_ptr<Interface> create() override
|
std::unique_ptr<Interface> create() override
|
||||||
{
|
{
|
||||||
return std::unique_ptr<Interface>{ new T };
|
constexpr auto Size = std::tuple_size<decltype(args_)>::value;
|
||||||
|
return std::unique_ptr<Interface>{ _m_new(make_pack<Size>{}) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<std::size_t ... Index>
|
||||||
|
Interface* _m_new(const pack<int, Index...> &)
|
||||||
|
{
|
||||||
|
return new T(std::get<Index>(args_)...);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
abs_factory(const Args&... args)
|
||||||
|
: args_(args...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::tuple<Args...> args_;
|
||||||
};
|
};
|
||||||
}//end namespace detail
|
}//end namespace detail
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type, typename ...Args>
|
||||||
pat::cloneable<abstract_factory<typename Type::factory_interface>> make_factory()
|
pat::cloneable<abstract_factory<typename Type::factory_interface>> make_factory(Args &&... args)
|
||||||
{
|
{
|
||||||
return detail::abs_factory<Type, typename Type::factory_interface>();
|
return detail::abs_factory<Type, typename Type::factory_interface, typename std::decay<Args>::type...>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
}//end namespace pat
|
}//end namespace pat
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A Generic Cloneable Pattern Implementation
|
* A Generic Cloneable Pattern Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2016 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
|
||||||
@ -106,8 +106,8 @@ namespace nana{ namespace pat{
|
|||||||
|
|
||||||
template<typename T, typename member_enabled<T>::type* = nullptr>
|
template<typename T, typename member_enabled<T>::type* = nullptr>
|
||||||
cloneable(T&& t)
|
cloneable(T&& t)
|
||||||
: cwrapper_(new detail::cloneable_wrapper<typename std::remove_cv<typename std::remove_reference<T>::type>::type>(std::forward<T>(t)), detail::cloneable_interface_deleter()),
|
: cwrapper_(new detail::cloneable_wrapper<typename std::decay<T>::type>(std::forward<T>(t)), detail::cloneable_interface_deleter()),
|
||||||
fast_ptr_(reinterpret_cast<typename std::remove_cv<typename std::remove_reference<T>::type>::type*>(cwrapper_->get()))
|
fast_ptr_(reinterpret_cast<typename std::decay<T>::type*>(cwrapper_->get()))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
cloneable(const cloneable& r)
|
cloneable(const cloneable& r)
|
||||||
|
|||||||
@ -442,8 +442,6 @@ namespace nana
|
|||||||
|
|
||||||
bool basic_window::set_events(const std::shared_ptr<general_events>& p)
|
bool basic_window::set_events(const std::shared_ptr<general_events>& p)
|
||||||
{
|
{
|
||||||
if (annex.events_ptr)
|
|
||||||
return false;
|
|
||||||
annex.events_ptr = p;
|
annex.events_ptr = p;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -626,30 +626,38 @@ 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);
|
||||||
|
if(nullptr == msgwnd)
|
||||||
|
break;
|
||||||
|
|
||||||
if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5)
|
if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5)
|
||||||
{
|
{
|
||||||
//The hovered window receives the message, unlike in Windows, no redirection is required.
|
//The hovered window receives the message, unlike in Windows, no redirection is required.
|
||||||
nana::point mspos{xevent.xbutton.x, xevent.xbutton.y};
|
auto evt_wd = msgwnd;
|
||||||
while(msgwnd)
|
while(evt_wd)
|
||||||
{
|
{
|
||||||
if(msgwnd->annex.events_ptr->mouse_wheel.length() != 0)
|
if(evt_wd->annex.events_ptr->mouse_wheel.length() != 0)
|
||||||
{
|
{
|
||||||
mspos -= msgwnd->pos_root;
|
|
||||||
arg_wheel arg;
|
arg_wheel arg;
|
||||||
arg.which = arg_wheel::wheel::vertical;
|
arg.which = arg_wheel::wheel::vertical;
|
||||||
assign_arg(arg, msgwnd, xevent);
|
assign_arg(arg, evt_wd, xevent);
|
||||||
brock.emit(event_code::mouse_wheel, msgwnd, arg, true, &context);
|
brock.emit(event_code::mouse_wheel, evt_wd, arg, true, &context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
msgwnd = msgwnd->parent;
|
evt_wd = evt_wd->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(msgwnd && (nullptr == evt_wd))
|
||||||
|
{
|
||||||
|
arg_wheel arg;
|
||||||
|
arg.which = arg_wheel::wheel::vertical;
|
||||||
|
assign_arg(arg, msgwnd, xevent);
|
||||||
|
draw_invoker(&drawer::mouse_wheel, msgwnd, arg, &context);
|
||||||
|
wd_manager.do_lazy_refresh(msgwnd, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
|
|
||||||
if(nullptr == msgwnd)
|
|
||||||
break;
|
|
||||||
|
|
||||||
msgwnd->set_action(mouse_action::normal);
|
msgwnd->set_action(mouse_action::normal);
|
||||||
if(msgwnd->flags.enabled)
|
if(msgwnd->flags.enabled)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1124,8 +1124,6 @@ namespace detail
|
|||||||
if (evt_wd->annex.events_ptr->mouse_wheel.length() != 0)
|
if (evt_wd->annex.events_ptr->mouse_wheel.length() != 0)
|
||||||
{
|
{
|
||||||
def_window_proc = false;
|
def_window_proc = false;
|
||||||
nana::point mspos{ scr_pos.x, scr_pos.y };
|
|
||||||
wd_manager.calc_window_point(evt_wd, mspos);
|
|
||||||
|
|
||||||
arg_wheel arg;
|
arg_wheel arg;
|
||||||
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
|
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
|
||||||
@ -1138,9 +1136,6 @@ namespace detail
|
|||||||
|
|
||||||
if (scrolled_wd && (nullptr == evt_wd))
|
if (scrolled_wd && (nullptr == evt_wd))
|
||||||
{
|
{
|
||||||
nana::point mspos{ scr_pos.x, scr_pos.y };
|
|
||||||
wd_manager.calc_window_point(scrolled_wd, mspos);
|
|
||||||
|
|
||||||
arg_wheel arg;
|
arg_wheel arg;
|
||||||
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
|
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
|
||||||
assign_arg(arg, scrolled_wd, pmdec);
|
assign_arg(arg, scrolled_wd, pmdec);
|
||||||
|
|||||||
@ -1714,6 +1714,11 @@ namespace detail
|
|||||||
wd->annex.caret_ptr = nullptr;
|
wd->annex.caret_ptr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using effect_renderer = detail::edge_nimbus_renderer<basic_window>;
|
||||||
|
|
||||||
|
//remove the window from edge nimbus effect when it is destroying
|
||||||
|
effect_renderer::instance().erase(wd);
|
||||||
|
|
||||||
arg_destroy arg;
|
arg_destroy arg;
|
||||||
arg.window_handle = reinterpret_cast<window>(wd);
|
arg.window_handle = reinterpret_cast<window>(wd);
|
||||||
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
|
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
|
||||||
|
|||||||
@ -498,24 +498,26 @@ namespace nana
|
|||||||
if(name.empty() || (name.front() == '.'))
|
if(name.empty() || (name.front() == '.'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
auto fpath = i->path().native();
|
||||||
|
auto fattr = fs::status(fpath);
|
||||||
|
|
||||||
item_fs m;
|
item_fs m;
|
||||||
m.name = name;
|
m.name = name;
|
||||||
|
m.directory = fs::is_directory(fattr);
|
||||||
|
|
||||||
auto fattr = fs::status(path + m.name);
|
switch(fattr.type())
|
||||||
|
|
||||||
if(fattr.type() != fs::file_type::not_found && fattr.type() != fs::file_type::unknown)
|
|
||||||
{
|
|
||||||
m.bytes = fs::file_size(path + m.name);
|
|
||||||
m.directory = fs::is_directory(fattr);
|
|
||||||
fs_ext::modified_file_time(path + m.name, m.modified_time);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
case fs::file_type::not_found:
|
||||||
|
case fs::file_type::unknown:
|
||||||
|
case fs::file_type::directory:
|
||||||
m.bytes = 0;
|
m.bytes = 0;
|
||||||
m.directory = fs::is_directory(*i);
|
break;
|
||||||
fs_ext::modified_file_time(path + i->path().filename().native(), m.modified_time);
|
default:
|
||||||
|
m.bytes = fs::file_size(fpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs_ext::modified_file_time(fpath, m.modified_time);
|
||||||
|
|
||||||
file_container_.push_back(m);
|
file_container_.push_back(m);
|
||||||
|
|
||||||
if(m.directory)
|
if(m.directory)
|
||||||
|
|||||||
@ -679,6 +679,16 @@ namespace nana
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct inline_pane
|
||||||
|
{
|
||||||
|
::nana::panel<false> pane_bottom; //pane for pane_widget
|
||||||
|
::nana::panel<false> pane_widget; //pane for placing user-define widget
|
||||||
|
std::unique_ptr<inline_notifier_interface> inline_ptr;
|
||||||
|
inline_indicator * indicator;
|
||||||
|
index_pair item_pos; //The item index of the inline widget
|
||||||
|
std::size_t column_pos;
|
||||||
|
};
|
||||||
|
|
||||||
class es_lister
|
class es_lister
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -727,6 +737,40 @@ namespace nana
|
|||||||
|
|
||||||
std::string to_string(const export_options& exp_opt) const;
|
std::string to_string(const export_options& exp_opt) const;
|
||||||
|
|
||||||
|
std::vector<inline_pane*> get_inline_pane(const index_pair& item_pos)
|
||||||
|
{
|
||||||
|
std::vector<inline_pane*> panes;
|
||||||
|
for (auto p : active_panes_)
|
||||||
|
{
|
||||||
|
if (p && (p->item_pos == item_pos))
|
||||||
|
{
|
||||||
|
panes.emplace_back(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return panes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emit_checked(index_pair pos)
|
||||||
|
{
|
||||||
|
item_proxy i(ess_, pos);
|
||||||
|
arg_listbox arg{ i };
|
||||||
|
wd_ptr()->events().checked.emit(arg, wd_ptr()->handle());
|
||||||
|
|
||||||
|
auto panes = get_inline_pane(pos);
|
||||||
|
for (auto p : panes)
|
||||||
|
p->inline_ptr->notify_status(inline_widget_status::checking, i.checked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void emit_selected(index_pair pos)
|
||||||
|
{
|
||||||
|
item_proxy i(ess_, pos);
|
||||||
|
arg_listbox arg{ i };
|
||||||
|
wd_ptr()->events().selected.emit(arg, wd_ptr()->handle());
|
||||||
|
|
||||||
|
auto panes = get_inline_pane(pos);
|
||||||
|
for (auto p : panes)
|
||||||
|
p->inline_ptr->notify_status(inline_widget_status::selecting, i.selected());
|
||||||
|
}
|
||||||
|
|
||||||
// Definition is provided after struct essence
|
// Definition is provided after struct essence
|
||||||
unsigned column_content_pixels(size_type pos) const;
|
unsigned column_content_pixels(size_type pos) const;
|
||||||
@ -1122,6 +1166,14 @@ namespace nana
|
|||||||
return get(pos.cat)->items.at(index);
|
return get(pos.cat)->items.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void append_active_panes(inline_pane* p)
|
||||||
|
{
|
||||||
|
if (nullptr == p)
|
||||||
|
active_panes_.clear();
|
||||||
|
else
|
||||||
|
active_panes_.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
// Removes all items of a specified category
|
// Removes all items of a specified category
|
||||||
// It throws when the category is out of range or has an immutable model.
|
// It throws when the category is out of range or has an immutable model.
|
||||||
void clear(size_type cat)
|
void clear(size_type cat)
|
||||||
@ -1453,9 +1505,7 @@ namespace nana
|
|||||||
if(m.flags.checked != ck)
|
if(m.flags.checked != ck)
|
||||||
{
|
{
|
||||||
m.flags.checked = ck;
|
m.flags.checked = ck;
|
||||||
|
emit_checked(pos);
|
||||||
arg_listbox arg{ item_proxy{ess_, pos}};
|
|
||||||
wd_ptr()->events().checked.emit(arg, wd_ptr()->handle());
|
|
||||||
}
|
}
|
||||||
++pos.item;
|
++pos.item;
|
||||||
}
|
}
|
||||||
@ -1480,10 +1530,15 @@ namespace nana
|
|||||||
|
|
||||||
void select_display_range(index_pair fr_abs, index_pair to_dpl, bool sel)
|
void select_display_range(index_pair fr_abs, index_pair to_dpl, bool sel)
|
||||||
{
|
{
|
||||||
|
const auto already_selected = this->pick_items(true);
|
||||||
|
|
||||||
index_pair fr_dpl (fr_abs.cat, this->display_order(fr_abs.cat, fr_abs.item));
|
index_pair fr_dpl (fr_abs.cat, this->display_order(fr_abs.cat, fr_abs.item));
|
||||||
if (fr_dpl > to_dpl)
|
if (fr_dpl > to_dpl)
|
||||||
std::swap(fr_dpl, to_dpl);
|
std::swap(fr_dpl, to_dpl);
|
||||||
|
|
||||||
|
const auto begin = fr_dpl;
|
||||||
|
const auto last = to_dpl;
|
||||||
|
|
||||||
for (; fr_dpl != to_dpl; forward(fr_dpl, 1, fr_dpl))
|
for (; fr_dpl != to_dpl; forward(fr_dpl, 1, fr_dpl))
|
||||||
{
|
{
|
||||||
if (fr_dpl.is_item())
|
if (fr_dpl.is_item())
|
||||||
@ -1492,6 +1547,14 @@ namespace nana
|
|||||||
|
|
||||||
if (to_dpl.is_item())
|
if (to_dpl.is_item())
|
||||||
item_proxy(ess_, index_pair(to_dpl.cat, absolute( to_dpl ) )).select(sel);
|
item_proxy(ess_, index_pair(to_dpl.cat, absolute( to_dpl ) )).select(sel);
|
||||||
|
|
||||||
|
//Unselects the already selected which is out of range [begin, last]
|
||||||
|
for (auto index : already_selected)
|
||||||
|
{
|
||||||
|
index_pair disp_order{ index.cat, this->display_order(index.cat, index.item) };
|
||||||
|
if (begin > disp_order || disp_order > last)
|
||||||
|
item_proxy(ess_, index_pair(index.cat, absolute(disp_order))).select(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool select_for_all(bool sel)
|
bool select_for_all(bool sel)
|
||||||
@ -1508,8 +1571,7 @@ namespace nana
|
|||||||
changed = true;
|
changed = true;
|
||||||
m.flags.selected = sel;
|
m.flags.selected = sel;
|
||||||
|
|
||||||
arg_listbox arg{ item_proxy(ess_, i) };
|
this->emit_selected(i);
|
||||||
wd_ptr()->events().selected.emit(arg, wd_ptr()->handle());
|
|
||||||
|
|
||||||
if (m.flags.selected)
|
if (m.flags.selected)
|
||||||
last_selected_abs = i;
|
last_selected_abs = i;
|
||||||
@ -1599,18 +1661,17 @@ namespace nana
|
|||||||
return (for_selection ? m.flags.selected : m.flags.checked);
|
return (for_selection ? m.flags.selected : m.flags.checked);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto do_cancel = [this, for_selection](category_t::container::value_type& m, std::size_t cat_pos, std::size_t item_pos)
|
auto do_cancel = [this, for_selection](category_t::container::value_type& m, const index_pair& item_pos)
|
||||||
{
|
{
|
||||||
arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)) };
|
|
||||||
if (for_selection)
|
if (for_selection)
|
||||||
{
|
{
|
||||||
m.flags.selected = false;
|
m.flags.selected = false;
|
||||||
widget_->events().selected.emit(arg, widget_->handle());
|
this->emit_selected(item_pos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m.flags.checked = false;
|
m.flags.checked = false;
|
||||||
widget_->events().checked.emit(arg, widget_->handle());
|
this->emit_checked(item_pos);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1622,7 +1683,7 @@ namespace nana
|
|||||||
for (auto & m : i->items)
|
for (auto & m : i->items)
|
||||||
{
|
{
|
||||||
if ((item_pos != except.item) && pred(m))
|
if ((item_pos != except.item) && pred(m))
|
||||||
do_cancel(m, except.cat, item_pos);
|
do_cancel(m, index_pair{ except.cat, item_pos });
|
||||||
|
|
||||||
++item_pos;
|
++item_pos;
|
||||||
}
|
}
|
||||||
@ -1638,7 +1699,7 @@ namespace nana
|
|||||||
for (auto & m : cat.items)
|
for (auto & m : cat.items)
|
||||||
{
|
{
|
||||||
if (pred(m))
|
if (pred(m))
|
||||||
do_cancel(m, cat_pos, item_pos);
|
do_cancel(m, index_pair{ cat_pos, item_pos });
|
||||||
++item_pos;
|
++item_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1648,7 +1709,7 @@ namespace nana
|
|||||||
for (auto & m : cat.items)
|
for (auto & m : cat.items)
|
||||||
{
|
{
|
||||||
if ((item_pos != except.item) && pred(m))
|
if ((item_pos != except.item) && pred(m))
|
||||||
do_cancel(m, cat_pos, item_pos);
|
do_cancel(m, index_pair{ cat_pos, item_pos });
|
||||||
++item_pos;
|
++item_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1682,18 +1743,17 @@ namespace nana
|
|||||||
return (for_selection ? m.flags.selected : m.flags.checked);
|
return (for_selection ? m.flags.selected : m.flags.checked);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto cancel = [this, for_selection](category_t::container::value_type& m, std::size_t cat_pos, std::size_t item_pos)
|
auto cancel = [this, for_selection](category_t::container::value_type& m, const index_pair& item_pos)
|
||||||
{
|
{
|
||||||
arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)) };
|
|
||||||
if (for_selection)
|
if (for_selection)
|
||||||
{
|
{
|
||||||
m.flags.selected = false;
|
m.flags.selected = false;
|
||||||
widget_->events().selected.emit(arg, widget_->handle());
|
this->emit_selected(item_pos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m.flags.checked = false;
|
m.flags.checked = false;
|
||||||
widget_->events().checked.emit(arg, widget_->handle());
|
this->emit_checked(item_pos);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1709,7 +1769,7 @@ namespace nana
|
|||||||
for (auto end = cat.items.end(); i != end; ++i)
|
for (auto end = cat.items.end(); i != end; ++i)
|
||||||
{
|
{
|
||||||
if (pred(*i))
|
if (pred(*i))
|
||||||
cancel(*i, cat_pos, i - cat.items.begin());
|
cancel(*i, index_pair{ cat_pos, static_cast<size_type>(i - cat.items.begin()) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++cat_pos;
|
++cat_pos;
|
||||||
@ -1732,7 +1792,7 @@ namespace nana
|
|||||||
for (++i; i != end; ++i)
|
for (++i; i != end; ++i)
|
||||||
{
|
{
|
||||||
if (pred(*i))
|
if (pred(*i))
|
||||||
cancel(*i, cat_pos, i - cat.items.begin());
|
cancel(*i, index_pair{ cat_pos, static_cast<std::size_t>(i - cat.items.begin()) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1744,7 +1804,7 @@ namespace nana
|
|||||||
for (auto & m : cat.items)
|
for (auto & m : cat.items)
|
||||||
{
|
{
|
||||||
if (pred(m))
|
if (pred(m))
|
||||||
cancel(m, cat_pos, item_pos);
|
cancel(m, index_pair{ cat_pos, item_pos });
|
||||||
|
|
||||||
++item_pos;
|
++item_pos;
|
||||||
}
|
}
|
||||||
@ -1791,10 +1851,7 @@ namespace nana
|
|||||||
if(m.flags.checked != ck)
|
if(m.flags.checked != ck)
|
||||||
{
|
{
|
||||||
m.flags.checked = ck;
|
m.flags.checked = ck;
|
||||||
|
this->emit_checked(index_pair{cat, index});
|
||||||
arg_listbox arg{ item_proxy(ess_, index_pair(cat, index)) };
|
|
||||||
wd_ptr()->events().checked.emit(arg, widget_->handle());
|
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
++index;
|
++index;
|
||||||
@ -2050,7 +2107,7 @@ namespace nana
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
index_pair last_selected_abs, last_selected_dpl;
|
index_pair last_selected_abs;
|
||||||
private:
|
private:
|
||||||
essence * ess_{nullptr};
|
essence * ess_{nullptr};
|
||||||
nana::listbox * widget_{nullptr};
|
nana::listbox * widget_{nullptr};
|
||||||
@ -2065,6 +2122,8 @@ namespace nana
|
|||||||
bool single_selection_category_limited_{ false };
|
bool single_selection_category_limited_{ false };
|
||||||
bool single_check_{ false };
|
bool single_check_{ false };
|
||||||
bool single_check_category_limited_{ false };
|
bool single_check_category_limited_{ false };
|
||||||
|
|
||||||
|
std::vector<inline_pane*> active_panes_;
|
||||||
};//end class es_lister
|
};//end class es_lister
|
||||||
|
|
||||||
|
|
||||||
@ -2108,17 +2167,6 @@ namespace nana
|
|||||||
}scroll;
|
}scroll;
|
||||||
|
|
||||||
|
|
||||||
struct inline_pane
|
|
||||||
{
|
|
||||||
::nana::panel<false> pane_bottom; //pane for pane_widget
|
|
||||||
::nana::panel<false> pane_widget; //pane for placing user-define widget
|
|
||||||
std::unique_ptr<inline_notifier_interface> inline_ptr;
|
|
||||||
inline_indicator * indicator;
|
|
||||||
index_pair item_pos; //The item index of the inline widget
|
|
||||||
std::size_t column_pos;
|
|
||||||
::std::string text; //text in UTF-8 encoded
|
|
||||||
};
|
|
||||||
|
|
||||||
std::map<pat::detail::abstract_factory_base*, std::deque<std::unique_ptr<inline_pane>>> inline_table, inline_buffered_table;
|
std::map<pat::detail::abstract_factory_base*, std::deque<std::unique_ptr<inline_pane>>> inline_table, inline_buffered_table;
|
||||||
|
|
||||||
essence()
|
essence()
|
||||||
@ -2963,8 +3011,8 @@ namespace nana
|
|||||||
: ess_{ ess }, column_pos_{column_pos}
|
: ess_{ ess }, column_pos_{column_pos}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void attach(index_type pos, essence::inline_pane* pane)
|
void attach(index_type pos, inline_pane* pane)
|
||||||
{
|
{
|
||||||
for (auto & pn : panes_)
|
for (auto & pn : panes_)
|
||||||
{
|
{
|
||||||
@ -2988,6 +3036,11 @@ namespace nana
|
|||||||
return *ess_->lister.wd_ptr();
|
return *ess_->lister.wd_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t column() const override
|
||||||
|
{
|
||||||
|
return column_pos_;
|
||||||
|
}
|
||||||
|
|
||||||
void modify(index_type pos, const value_type& value) const override
|
void modify(index_type pos, const value_type& value) const override
|
||||||
{
|
{
|
||||||
ess_->lister.throw_if_immutable_model(pos);
|
ess_->lister.throw_if_immutable_model(pos);
|
||||||
@ -3000,15 +3053,6 @@ namespace nana
|
|||||||
|
|
||||||
if (cells[column_pos_].text != value)
|
if (cells[column_pos_].text != value)
|
||||||
{
|
{
|
||||||
for (auto & pn : panes_)
|
|
||||||
{
|
|
||||||
if (pn.first == pos)
|
|
||||||
{
|
|
||||||
pn.second->text = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cells[column_pos_].text = value;
|
cells[column_pos_].text = value;
|
||||||
|
|
||||||
if (model_cells.size())
|
if (model_cells.size())
|
||||||
@ -3040,7 +3084,7 @@ namespace nana
|
|||||||
private:
|
private:
|
||||||
essence * const ess_;
|
essence * const ess_;
|
||||||
const std::size_t column_pos_;
|
const std::size_t column_pos_;
|
||||||
std::vector<std::pair<index_type, essence::inline_pane*>> panes_;
|
std::vector<std::pair<index_type, inline_pane*>> panes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void es_lister::scroll(const index_pair& pos, bool to_bottom)
|
void es_lister::scroll(const index_pair& pos, bool to_bottom)
|
||||||
@ -3116,7 +3160,7 @@ namespace nana
|
|||||||
|
|
||||||
void es_lister::move_select(bool upwards, bool unselect_previous, bool trace_selected)
|
void es_lister::move_select(bool upwards, bool unselect_previous, bool trace_selected)
|
||||||
{
|
{
|
||||||
auto next_selected_dpl = relative_pair ( last_selected_abs); // last_selected_dpl; // ??
|
auto next_selected_dpl = relative_pair ( last_selected_abs);
|
||||||
if (next_selected_dpl.empty()) // has no cat ? (cat == npos) => beging from first cat
|
if (next_selected_dpl.empty()) // has no cat ? (cat == npos) => beging from first cat
|
||||||
{
|
{
|
||||||
bool good = false;
|
bool good = false;
|
||||||
@ -3237,7 +3281,7 @@ namespace nana
|
|||||||
if (it.selected() != sel)
|
if (it.selected() != sel)
|
||||||
it.select(sel);
|
it.select(sel);
|
||||||
}
|
}
|
||||||
last_selected_abs = last_selected_dpl = index_pair{cat, npos};
|
last_selected_abs = index_pair{cat, npos};
|
||||||
}
|
}
|
||||||
|
|
||||||
class drawer_header_impl
|
class drawer_header_impl
|
||||||
@ -3520,15 +3564,19 @@ namespace nana
|
|||||||
public:
|
public:
|
||||||
using item_state = essence::item_state;
|
using item_state = essence::item_state;
|
||||||
using parts = essence::parts;
|
using parts = essence::parts;
|
||||||
|
using status_type = inline_notifier_interface::status_type;
|
||||||
|
|
||||||
drawer_lister_impl(essence * es)
|
drawer_lister_impl(essence * es)
|
||||||
:essence_(es)
|
:essence_(es)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void draw(const nana::rectangle& rect) const
|
void draw(const nana::rectangle& rect)
|
||||||
{
|
{
|
||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
|
|
||||||
|
//clear active panes
|
||||||
|
essence_->lister.append_active_panes(nullptr);
|
||||||
|
|
||||||
//The count of items to be drawn
|
//The count of items to be drawn
|
||||||
auto item_count = essence_->number_of_lister_items(true);
|
auto item_count = essence_->number_of_lister_items(true);
|
||||||
if (0 == item_count)
|
if (0 == item_count)
|
||||||
@ -3711,7 +3759,7 @@ namespace nana
|
|||||||
nana::color bgcolor,
|
nana::color bgcolor,
|
||||||
nana::color fgcolor,
|
nana::color fgcolor,
|
||||||
item_state state
|
item_state state
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
auto & item = cat.items[item_pos.item];
|
auto & item = cat.items[item_pos.item];
|
||||||
|
|
||||||
@ -3825,35 +3873,31 @@ namespace nana
|
|||||||
else
|
else
|
||||||
visible_state = false;
|
visible_state = false;
|
||||||
|
|
||||||
::nana::size sz{ wdg_w, essence_->scheme_ptr->item_height };
|
|
||||||
inline_wdg->pane_widget.size(sz);
|
|
||||||
inline_wdg->inline_ptr->resize(sz);
|
|
||||||
|
|
||||||
draw_column = inline_wdg->inline_ptr->whether_to_draw();
|
draw_column = inline_wdg->inline_ptr->whether_to_draw();
|
||||||
|
|
||||||
inline_wdg->item_pos = item_pos;
|
inline_wdg->item_pos = item_pos;
|
||||||
inline_wdg->column_pos = column_pos;
|
inline_wdg->column_pos = column_pos;
|
||||||
inline_wdg->inline_ptr->activate(*inline_wdg->indicator, item_pos);
|
inline_wdg->inline_ptr->activate(*inline_wdg->indicator, item_pos);
|
||||||
|
|
||||||
|
::nana::size sz{ wdg_w, essence_->scheme_ptr->item_height };
|
||||||
|
inline_wdg->pane_widget.size(sz);
|
||||||
|
inline_wdg->inline_ptr->resize(sz);
|
||||||
|
|
||||||
|
inline_wdg->inline_ptr->notify_status(status_type::selected, item.flags.selected);
|
||||||
|
inline_wdg->inline_ptr->notify_status(status_type::checked, item.flags.checked);
|
||||||
|
|
||||||
inline_wdg->indicator->attach(item_pos, inline_wdg);
|
inline_wdg->indicator->attach(item_pos, inline_wdg);
|
||||||
|
|
||||||
//To reduce the memory usage, the cells may not be allocated
|
//To reduce the memory usage, the cells may not be allocated
|
||||||
if (cells.size() > column_pos)
|
if (cells.size() > column_pos)
|
||||||
{
|
inline_wdg->inline_ptr->set(cells[column_pos].text);
|
||||||
auto & text = cells[column_pos].text;
|
|
||||||
if (text != inline_wdg->text)
|
|
||||||
{
|
|
||||||
inline_wdg->text = text;
|
|
||||||
inline_wdg->inline_ptr->set(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
inline_wdg->text.clear();
|
|
||||||
inline_wdg->inline_ptr->set({});
|
inline_wdg->inline_ptr->set({});
|
||||||
}
|
|
||||||
|
|
||||||
API::show_window(inline_wdg->pane_bottom, visible_state);
|
API::show_window(inline_wdg->pane_bottom, visible_state);
|
||||||
|
|
||||||
|
essence_->lister.append_active_panes(inline_wdg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3903,18 +3947,20 @@ namespace nana
|
|||||||
_m_draw_border(content_r.x, y, show_w);
|
_m_draw_border(content_r.x, y, show_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
essence::inline_pane * _m_get_inline_pane(const category_t& cat, std::size_t column_pos) const
|
inline_pane * _m_get_inline_pane(const category_t& cat, std::size_t column_pos) const
|
||||||
{
|
{
|
||||||
if (column_pos < cat.factories.size())
|
if (column_pos < cat.factories.size())
|
||||||
{
|
{
|
||||||
auto & factory = cat.factories[column_pos];
|
auto & factory = cat.factories[column_pos];
|
||||||
if (factory)
|
if (factory)
|
||||||
|
{
|
||||||
return essence_->open_inline(factory.get(), cat.indicators[column_pos].get());
|
return essence_->open_inline(factory.get(), cat.indicators[column_pos].get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
essence::inline_pane* _m_find_inline_pane(const index_pair& pos, std::size_t column_pos) const
|
inline_pane* _m_find_inline_pane(const index_pair& pos, std::size_t column_pos) const
|
||||||
{
|
{
|
||||||
auto & cat = *essence_->lister.get(pos.cat);
|
auto & cat = *essence_->lister.get(pos.cat);
|
||||||
|
|
||||||
@ -4151,7 +4197,18 @@ namespace nana
|
|||||||
if (!lister.single_selection())
|
if (!lister.single_selection())
|
||||||
{
|
{
|
||||||
if (arg.shift)
|
if (arg.shift)
|
||||||
lister.select_display_range(lister.last_selected_abs , item_pos, sel);
|
{
|
||||||
|
//Set the first item as the begin of selected item if there
|
||||||
|
//is not a last selected item.(#154 reported by RenaudAlpes)
|
||||||
|
if (lister.last_selected_abs.empty() || lister.last_selected_abs.is_category())
|
||||||
|
lister.last_selected_abs.set_both(0);
|
||||||
|
|
||||||
|
auto before = lister.last_selected_abs;
|
||||||
|
|
||||||
|
lister.select_display_range(lister.last_selected_abs, item_pos, sel);
|
||||||
|
|
||||||
|
lister.last_selected_abs = before;
|
||||||
|
}
|
||||||
else if (arg.ctrl)
|
else if (arg.ctrl)
|
||||||
sel = !item_proxy(essence_, abs_item_pos).selected();
|
sel = !item_proxy(essence_, abs_item_pos).selected();
|
||||||
else
|
else
|
||||||
@ -4167,19 +4224,20 @@ namespace nana
|
|||||||
|
|
||||||
if(item_ptr)
|
if(item_ptr)
|
||||||
{
|
{
|
||||||
item_ptr->flags.selected = sel;
|
if (item_ptr->flags.selected != sel)
|
||||||
|
|
||||||
arg_listbox arg{ item_proxy{ essence_, abs_item_pos } };
|
|
||||||
lister.wd_ptr()->events().selected.emit(arg, lister.wd_ptr()->handle());
|
|
||||||
|
|
||||||
if (item_ptr->flags.selected)
|
|
||||||
{
|
{
|
||||||
lister.cancel_others_if_single_enabled(true, abs_item_pos);
|
item_ptr->flags.selected = sel;
|
||||||
essence_->lister.last_selected_abs = abs_item_pos;
|
|
||||||
|
|
||||||
|
lister.emit_selected(abs_item_pos);
|
||||||
|
|
||||||
|
if (item_ptr->flags.selected)
|
||||||
|
{
|
||||||
|
lister.cancel_others_if_single_enabled(true, abs_item_pos);
|
||||||
|
essence_->lister.last_selected_abs = abs_item_pos;
|
||||||
|
}
|
||||||
|
else if (essence_->lister.last_selected_abs == abs_item_pos)
|
||||||
|
essence_->lister.last_selected_abs.set_both(npos);
|
||||||
}
|
}
|
||||||
else if (essence_->lister.last_selected_abs == abs_item_pos)
|
|
||||||
essence_->lister.last_selected_abs.set_both(npos);
|
|
||||||
}
|
}
|
||||||
else if(!lister.single_selection())
|
else if(!lister.single_selection())
|
||||||
lister.categ_selected(item_pos.cat, true);
|
lister.categ_selected(item_pos.cat, true);
|
||||||
@ -4190,8 +4248,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
item_ptr->flags.checked = ! item_ptr->flags.checked;
|
item_ptr->flags.checked = ! item_ptr->flags.checked;
|
||||||
|
|
||||||
arg_listbox arg{ item_proxy{ essence_, abs_item_pos } };
|
lister.emit_checked(abs_item_pos);
|
||||||
lister.wd_ptr()->events().checked.emit(arg, lister.wd_ptr()->handle());
|
|
||||||
|
|
||||||
if (item_ptr->flags.checked)
|
if (item_ptr->flags.checked)
|
||||||
lister.cancel_others_if_single_enabled(false, abs_item_pos);
|
lister.cancel_others_if_single_enabled(false, abs_item_pos);
|
||||||
@ -4456,12 +4513,13 @@ namespace nana
|
|||||||
|
|
||||||
item_proxy & item_proxy::check(bool ck)
|
item_proxy & item_proxy::check(bool ck)
|
||||||
{
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
auto & m = cat_->items.at(pos_.item);
|
auto & m = cat_->items.at(pos_.item);
|
||||||
if(m.flags.checked != ck)
|
if(m.flags.checked != ck)
|
||||||
{
|
{
|
||||||
m.flags.checked = ck;
|
m.flags.checked = ck;
|
||||||
arg_listbox arg{*this};
|
ess_->lister.emit_checked(pos_);
|
||||||
ess_->lister.wd_ptr()->events().checked.emit(arg, ess_->lister.wd_ptr()->handle());
|
|
||||||
ess_->update();
|
ess_->update();
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
@ -4475,13 +4533,14 @@ namespace nana
|
|||||||
/// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected
|
/// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected
|
||||||
item_proxy & item_proxy::select(bool s)
|
item_proxy & item_proxy::select(bool s)
|
||||||
{
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
|
||||||
//pos_ never represents a category if this item_proxy is available.
|
//pos_ never represents a category if this item_proxy is available.
|
||||||
auto & m = cat_->items.at(pos_.item); // a ref to the real item
|
auto & m = cat_->items.at(pos_.item); // a ref to the real item
|
||||||
if(m.flags.selected == s) return *this; // ignore if no change
|
if(m.flags.selected == s) return *this; // ignore if no change
|
||||||
m.flags.selected = s; // actually change selection
|
m.flags.selected = s; // actually change selection
|
||||||
|
|
||||||
arg_listbox arg{*this};
|
ess_->lister.emit_selected(this->pos_);
|
||||||
ess_->lister.wd_ptr()->events().selected.emit(arg, ess_->lister.wd_ptr()->handle());
|
|
||||||
|
|
||||||
if (m.flags.selected)
|
if (m.flags.selected)
|
||||||
{
|
{
|
||||||
@ -4750,10 +4809,11 @@ namespace nana
|
|||||||
for (item_proxy &it : *this )
|
for (item_proxy &it : *this )
|
||||||
it.select(sel);
|
it.select(sel);
|
||||||
|
|
||||||
ess_->lister.last_selected_abs = ess_->lister.last_selected_dpl = index_pair {this->pos_, npos};
|
ess_->lister.last_selected_abs = index_pair {this->pos_, npos};
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cat_proxy::selected() const
|
bool cat_proxy::selected() const
|
||||||
{
|
{
|
||||||
for (item_proxy &it : *this )
|
for (item_proxy &it : *this )
|
||||||
|
|||||||
@ -441,6 +441,9 @@ namespace nana{ namespace widgets
|
|||||||
text_ptr = &mask_str;
|
text_ptr = &mask_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pos.x > text_ptr->size())
|
||||||
|
pos.x = text_ptr->size();
|
||||||
|
|
||||||
pos.x = editor_._m_pixels_by_char(*text_ptr, pos.x) + editor_.text_area_.area.x;
|
pos.x = editor_._m_pixels_by_char(*text_ptr, pos.x) + editor_.text_area_.area.x;
|
||||||
int pos_y = static_cast<int>((pos.y - editor_.points_.offset.y) * editor_.line_height() + editor_._m_text_top_base());
|
int pos_y = static_cast<int>((pos.y - editor_.points_.offset.y) * editor_.line_height() + editor_._m_text_top_base());
|
||||||
|
|
||||||
@ -1990,20 +1993,22 @@ namespace nana{ namespace widgets
|
|||||||
|
|
||||||
//move_caret
|
//move_caret
|
||||||
//Set caret position through text coordinate
|
//Set caret position through text coordinate
|
||||||
void text_editor::move_caret(const upoint& crtpos)
|
bool text_editor::move_caret(const upoint& crtpos, bool reset_caret)
|
||||||
{
|
{
|
||||||
if (!API::is_focus_ready(window_))
|
|
||||||
return;
|
|
||||||
|
|
||||||
const unsigned line_pixels = line_height();
|
const unsigned line_pixels = line_height();
|
||||||
auto pos = impl_->capacities.behavior->caret_to_screen(crtpos);
|
auto pos = impl_->capacities.behavior->caret_to_screen(crtpos);
|
||||||
const int line_bottom = pos.y + static_cast<int>(line_pixels);
|
const int line_bottom = pos.y + static_cast<int>(line_pixels);
|
||||||
|
|
||||||
|
if (reset_caret)
|
||||||
|
points_.caret = this->impl_->capacities.behavior->screen_to_caret(pos);
|
||||||
|
|
||||||
|
if (!API::is_focus_ready(window_))
|
||||||
|
return false;
|
||||||
|
|
||||||
auto caret = API::open_caret(window_, true);
|
auto caret = API::open_caret(window_, true);
|
||||||
|
|
||||||
auto text_area = _m_text_area();
|
|
||||||
|
|
||||||
bool visible = false;
|
bool visible = false;
|
||||||
|
auto text_area = _m_text_area();
|
||||||
if (text_area.is_hit(pos) && (line_bottom > text_area.y))
|
if (text_area.is_hit(pos) && (line_bottom > text_area.y))
|
||||||
{
|
{
|
||||||
visible = true;
|
visible = true;
|
||||||
@ -2019,6 +2024,16 @@ namespace nana{ namespace widgets
|
|||||||
caret->visible(visible);
|
caret->visible(visible);
|
||||||
if(visible)
|
if(visible)
|
||||||
caret->position(pos);
|
caret->position(pos);
|
||||||
|
|
||||||
|
//Adjust the caret into screen when the caret position is modified by this function
|
||||||
|
if (reset_caret && (!hit_text_area(pos)))
|
||||||
|
{
|
||||||
|
impl_->capacities.behavior->adjust_caret_into_screen();
|
||||||
|
render(true);
|
||||||
|
caret->visible(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_editor::move_caret_end()
|
void text_editor::move_caret_end()
|
||||||
@ -2507,6 +2522,11 @@ namespace nana{ namespace widgets
|
|||||||
_m_scrollbar();
|
_m_scrollbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void text_editor::set_undo_queue_length(std::size_t len)
|
||||||
|
{
|
||||||
|
impl_->undo.max_steps(len);
|
||||||
|
}
|
||||||
|
|
||||||
void text_editor::move_ns(bool to_north)
|
void text_editor::move_ns(bool to_north)
|
||||||
{
|
{
|
||||||
const bool redraw_required = _m_cancel_select(0);
|
const bool redraw_required = _m_cancel_select(0);
|
||||||
|
|||||||
@ -345,8 +345,8 @@ namespace drawerbase {
|
|||||||
{
|
{
|
||||||
auto editor = get_drawer_trigger().editor();
|
auto editor = get_drawer_trigger().editor();
|
||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
if (editor)
|
if (editor && editor->move_caret(pos, true))
|
||||||
editor->move_caret(pos);
|
API::refresh_window(handle());
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -628,6 +628,14 @@ namespace drawerbase {
|
|||||||
editor->select_behavior(move_to_end);
|
editor->select_behavior(move_to_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void textbox::set_undo_queue_length(std::size_t len)
|
||||||
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
auto editor = get_drawer_trigger().editor();
|
||||||
|
if (editor)
|
||||||
|
editor->set_undo_queue_length(len);
|
||||||
|
}
|
||||||
|
|
||||||
//Override _m_caption for caption()
|
//Override _m_caption for caption()
|
||||||
auto textbox::_m_caption() const throw() -> native_string_type
|
auto textbox::_m_caption() const throw() -> native_string_type
|
||||||
{
|
{
|
||||||
|
|||||||
@ -382,12 +382,6 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
//class widget_base
|
//class widget_base
|
||||||
widget_base::~widget_base()
|
|
||||||
{
|
|
||||||
if (handle_)
|
|
||||||
API::close_window(handle_);
|
|
||||||
}
|
|
||||||
|
|
||||||
window widget_base::handle() const
|
window widget_base::handle() const
|
||||||
{
|
{
|
||||||
return handle_;
|
return handle_;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user