Merge branch 'feature-listbox' into develop
This commit is contained in:
commit
0f70769816
@ -408,8 +408,8 @@ namespace nana
|
||||
{
|
||||
rectangle(); ///< a zero-size rectangle at (0, 0).
|
||||
rectangle(int x, int y, unsigned width, unsigned height);
|
||||
rectangle(const size &); ///< a rectangle with specified size at coordinate (0, 0).
|
||||
rectangle(const point&, const size& = size());
|
||||
explicit rectangle(const size &); ///< a rectangle with specified size at coordinate (0, 0).
|
||||
explicit rectangle(const point&, const size& = size());
|
||||
|
||||
bool operator==(const rectangle& rhs) const;
|
||||
bool operator!=(const rectangle& rhs) const;
|
||||
|
||||
@ -115,6 +115,8 @@ namespace detail
|
||||
bool belong_to_lazy() const;
|
||||
|
||||
bool is_draw_through() const; ///< Determines whether it is a draw-through window.
|
||||
|
||||
basic_window * seek_non_lite_widget_ancestor() const;
|
||||
public:
|
||||
//Override event_holder
|
||||
bool set_events(const std::shared_ptr<general_events>&) override;
|
||||
|
||||
@ -40,6 +40,8 @@ namespace detail
|
||||
|
||||
struct thread_context;
|
||||
|
||||
class flag_guard;
|
||||
|
||||
~bedrock();
|
||||
void pump_event(window, bool is_modal);
|
||||
void map_thread_root_buffer(core_window_t*, bool forced);
|
||||
|
||||
@ -98,10 +98,10 @@ namespace nana{
|
||||
|
||||
void _m_render_edge_nimbus(core_window_t* wd, const nana::rectangle & visual)
|
||||
{
|
||||
nana::rectangle r(visual);
|
||||
auto r = visual;
|
||||
r.pare_off(-static_cast<int>(weight()));
|
||||
nana::rectangle good_r;
|
||||
if(overlap(r, wd->root_graph->size(), good_r))
|
||||
rectangle good_r;
|
||||
if (overlap(r, rectangle{ wd->root_graph->size() }, good_r))
|
||||
{
|
||||
if( (good_r.x < wd->pos_root.x) || (good_r.y < wd->pos_root.y) ||
|
||||
(good_r.x + good_r.width > visual.x + visual.width) || (good_r.y + good_r.height > visual.y + visual.height))
|
||||
|
||||
@ -46,7 +46,7 @@ namespace nana
|
||||
class event_arg
|
||||
{
|
||||
public:
|
||||
virtual ~event_arg();
|
||||
virtual ~event_arg() = default;
|
||||
|
||||
/// ignorable handlers behind the current one in a chain of event handlers will not get called.
|
||||
void stop_propagation() const;
|
||||
|
||||
@ -116,6 +116,7 @@ namespace API
|
||||
void window_icon(window, const paint::image&);
|
||||
bool empty_window(window); ///< Determines whether a window is existing.
|
||||
bool is_window(window); ///< Determines whether a window is existing, equal to !empty_window.
|
||||
bool is_destroying(window); ///< Determines whether a window is destroying
|
||||
void enable_dropfiles(window, bool);
|
||||
|
||||
/// \brief Retrieves the native window of a Nana.GUI window.
|
||||
|
||||
85
include/nana/gui/widgets/detail/inline_widget.hpp
Normal file
85
include/nana/gui/widgets/detail/inline_widget.hpp
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* A Inline Widget Interface Definition
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2015 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/widgets/detail/inline_widget.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_INLINE_WIDGETS_HPP
|
||||
#define NANA_GUI_INLINE_WIDGETS_HPP
|
||||
#include "../../basis.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Index, typename Value>
|
||||
class inline_widget_indicator
|
||||
{
|
||||
public:
|
||||
/// A type to index a item
|
||||
using index_type = Index;
|
||||
|
||||
/// A type to the value of the item
|
||||
using value_type = Value;
|
||||
|
||||
/// The destructor
|
||||
virtual ~inline_widget_indicator() = default;
|
||||
|
||||
/// Returns the host widget of the indicator
|
||||
virtual ::nana::widget& host() const = 0;
|
||||
|
||||
/// Modifies the value of a item specified by pos
|
||||
virtual void modify(index_type pos, const value_type&) const = 0;
|
||||
|
||||
/// Sends a signal that a specified item is selected
|
||||
virtual void selected(index_type) = 0;
|
||||
|
||||
/// Sends a signal that a specified item is hovered
|
||||
virtual void hovered(index_type) = 0;
|
||||
};
|
||||
|
||||
template<typename Index, typename Value>
|
||||
class inline_widget_notifier_interface
|
||||
{
|
||||
public:
|
||||
/// A type to index a item
|
||||
using index_type = Index;
|
||||
|
||||
/// A type to the value of the item
|
||||
using value_type = Value;
|
||||
|
||||
/// A typedef name of a inline widget indicator
|
||||
using inline_indicator = inline_widget_indicator<index_type, value_type>;
|
||||
|
||||
/// A type to the notifier interface that will be refered by the abstract factory pattern
|
||||
using factory_interface = inline_widget_notifier_interface;
|
||||
|
||||
/// The destructor
|
||||
virtual ~inline_widget_notifier_interface() = default;
|
||||
|
||||
/// A message to create the inline widget
|
||||
virtual void create(window) = 0;
|
||||
|
||||
/// A message to activate the inline widget to attach a specified item
|
||||
virtual void activate(inline_indicator&, index_type) = 0;
|
||||
|
||||
/// A message to resize the inline widget
|
||||
virtual void resize(const size&) = 0;
|
||||
|
||||
/// A message to set the value from the item
|
||||
virtual void set(const value_type&) = 0;
|
||||
|
||||
/// Determines whether to draw the background of the widget
|
||||
virtual bool whether_to_draw() const = 0;
|
||||
}; //end class inline_widget_notifier_interface
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
89
include/nana/gui/widgets/detail/inline_widget_manager.hpp
Normal file
89
include/nana/gui/widgets/detail/inline_widget_manager.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* A Inline Widget Manager Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2015 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/widgets/detail/inline_widget_manager.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_INLINE_WIDGET_MANAGER_HPP
|
||||
#define NANA_GUI_INLINE_WIDGET_MANAGER_HPP
|
||||
#include "inline_widget.hpp"
|
||||
#include <nana/pat/abstract_factory.hpp>
|
||||
#include "../panel.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename Index, typename Value>
|
||||
class inline_widget_manager
|
||||
{
|
||||
using index_type = Index;
|
||||
using value_type = Value;
|
||||
using indicator_type = inline_widget_indicator<value_type>;
|
||||
using inline_widget = inline_widget_interface<index_type, value_type>;
|
||||
using factory = pat::abstract_factory<inline_widget>;
|
||||
|
||||
struct widget_holder
|
||||
{
|
||||
panel<false> docker;
|
||||
std::unique_ptr<inline_widget> widget_ptr;
|
||||
};
|
||||
public:
|
||||
void set_window(window wd)
|
||||
{
|
||||
window_handle_ = wd;
|
||||
}
|
||||
|
||||
void set_factory(std::unique_ptr<factory> fac)
|
||||
{
|
||||
factory_.swap(fac);
|
||||
}
|
||||
|
||||
void place(point pos, const size& dimension, const size & visible_size, const indicator_type& indicator, index_type index)
|
||||
{
|
||||
auto holder = _m_append();
|
||||
holder->docker.move({ pos, visible_size });
|
||||
holder->widget_ptr->move({ point(), dimension });
|
||||
|
||||
holder->widget_ptr->activate(indicator, index);
|
||||
}
|
||||
private:
|
||||
widget_holder* _m_append()
|
||||
{
|
||||
if (swap_widgets_.empty())
|
||||
{
|
||||
widgets_.emplace_back();
|
||||
widgets_.back().swap(swap_widgets_.back());
|
||||
swap_widgets_.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
widgets_.emplace_back(new widget_holder);
|
||||
auto & holder = widgets_.back();
|
||||
holder->docker.create(window_handle_, false);
|
||||
holder->widget_ptr.swap(factory_->create());
|
||||
holder->widget_ptr->create(holder->docker->handle());
|
||||
}
|
||||
return widgets_.back().get();
|
||||
}
|
||||
private:
|
||||
window window_handle_{nullptr};
|
||||
std::unique_ptr<factory> factory_;
|
||||
std::vector<std::unique_ptr<widget_holder>> widgets_;
|
||||
std::vector<std::unique_ptr<widget_holder>> swap_widgets_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -15,9 +15,10 @@
|
||||
#ifndef NANA_GUI_WIDGETS_LISTBOX_HPP
|
||||
#define NANA_GUI_WIDGETS_LISTBOX_HPP
|
||||
#include "widget.hpp"
|
||||
#include "detail/inline_widget.hpp"
|
||||
#include <nana/pat/abstract_factory.hpp>
|
||||
#include <nana/concepts.hpp>
|
||||
#include <nana/key_type.hpp>
|
||||
//#include <nana/paint/graphics.hpp>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
|
||||
@ -29,7 +30,58 @@ namespace nana
|
||||
{
|
||||
namespace listbox
|
||||
{
|
||||
using size_type = std::size_t ;
|
||||
using size_type = std::size_t;
|
||||
|
||||
/// usefull for both absolute and display (sorted) positions
|
||||
struct index_pair
|
||||
{
|
||||
size_type cat; //The pos of category
|
||||
size_type item; //the pos of item in a category.
|
||||
|
||||
index_pair(size_type cat_pos = 0, size_type item_pos = 0)
|
||||
: cat(cat_pos),
|
||||
item(item_pos)
|
||||
{}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return (npos == cat);
|
||||
}
|
||||
|
||||
void set_both(size_type n)
|
||||
{
|
||||
cat = item = n;
|
||||
}
|
||||
|
||||
bool is_category() const
|
||||
{
|
||||
return (npos != cat && npos == item);
|
||||
}
|
||||
|
||||
bool is_item() const
|
||||
{
|
||||
return (npos != cat && npos != item);
|
||||
}
|
||||
|
||||
bool operator==(const index_pair& r) const
|
||||
{
|
||||
return (r.cat == cat && r.item == item);
|
||||
}
|
||||
|
||||
bool operator!=(const index_pair& r) const
|
||||
{
|
||||
return !this->operator==(r);
|
||||
}
|
||||
|
||||
bool operator>(const index_pair& r) const
|
||||
{
|
||||
return (cat > r.cat) || (cat == r.cat && item > r.item);
|
||||
}
|
||||
};
|
||||
|
||||
using selection = std::vector<index_pair>;
|
||||
|
||||
using inline_notifier_interface = detail::inline_widget_notifier_interface<index_pair, std::wstring>;
|
||||
|
||||
struct cell
|
||||
{
|
||||
@ -114,55 +166,6 @@ namespace nana
|
||||
std::size_t pos_{0};
|
||||
};
|
||||
|
||||
/// usefull for both absolute and display (sorted) positions
|
||||
struct index_pair
|
||||
{
|
||||
size_type cat; //The pos of category
|
||||
size_type item; //the pos of item in a category.
|
||||
|
||||
index_pair(size_type cat_pos = 0, size_type item_pos = 0)
|
||||
: cat(cat_pos),
|
||||
item(item_pos)
|
||||
{}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return (npos == cat);
|
||||
}
|
||||
|
||||
void set_both(size_type n)
|
||||
{
|
||||
cat = item = n;
|
||||
}
|
||||
|
||||
bool is_category() const
|
||||
{
|
||||
return (npos != cat && npos == item);
|
||||
}
|
||||
|
||||
bool is_item() const
|
||||
{
|
||||
return (npos != cat && npos != item);
|
||||
}
|
||||
|
||||
bool operator==(const index_pair& r) const
|
||||
{
|
||||
return (r.cat == cat && r.item == item);
|
||||
}
|
||||
|
||||
bool operator!=(const index_pair& r) const
|
||||
{
|
||||
return !this->operator==(r);
|
||||
}
|
||||
|
||||
bool operator>(const index_pair& r) const
|
||||
{
|
||||
return (cat > r.cat) || (cat == r.cat && item > r.item);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<index_pair> selection;
|
||||
|
||||
//struct essence_t
|
||||
//@brief: this struct gives many data for listbox,
|
||||
// the state of the struct does not effect on member funcions, therefore all data members are public.
|
||||
@ -344,6 +347,8 @@ namespace nana
|
||||
: public std::iterator < std::input_iterator_tag, cat_proxy >
|
||||
{
|
||||
public:
|
||||
using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface;
|
||||
|
||||
cat_proxy() = default;
|
||||
cat_proxy(essence_t*, size_type pos);
|
||||
cat_proxy(essence_t*, category_t*);
|
||||
@ -423,6 +428,8 @@ namespace nana
|
||||
|
||||
/// Behavior of Iterator
|
||||
bool operator!=(const cat_proxy&) const;
|
||||
|
||||
void inline_factory(size_type column, pat::cloneable<pat::abstract_factory<inline_notifier_interface>> factory);
|
||||
private:
|
||||
void _m_append(std::vector<cell> && cells);
|
||||
void _m_cat_by_pos();
|
||||
@ -499,6 +506,7 @@ By \a clicking on a header the list get \a reordered, first up, and then down al
|
||||
using cell = drawerbase::listbox::cell;
|
||||
using export_options= drawerbase::listbox::export_options;
|
||||
using columns_indexs= drawerbase::listbox::size_type;
|
||||
using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface;
|
||||
public:
|
||||
listbox() = default;
|
||||
listbox(window, bool visible);
|
||||
|
||||
@ -19,16 +19,15 @@
|
||||
|
||||
namespace nana
|
||||
{
|
||||
template<bool Vert> class scroll;
|
||||
template<bool Vert> class scroll; //forward declaration
|
||||
|
||||
template<bool Vert>
|
||||
struct arg_scroll
|
||||
: public event_arg
|
||||
{
|
||||
scroll<Vert> & widget;
|
||||
window window_handle;
|
||||
|
||||
arg_scroll(scroll<Vert> & wdg)
|
||||
: widget(wdg)
|
||||
arg_scroll(window wd)
|
||||
: window_handle{ wd }
|
||||
{}
|
||||
};
|
||||
|
||||
@ -36,11 +35,10 @@ namespace nana
|
||||
{
|
||||
namespace scroll
|
||||
{
|
||||
template<bool Vert>
|
||||
struct scroll_events
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_scroll<Vert>> value_changed;
|
||||
basic_event<arg_scroll> value_changed;
|
||||
};
|
||||
|
||||
enum class buttons
|
||||
@ -313,7 +311,7 @@ namespace nana
|
||||
private:
|
||||
void _m_emit_value_changed()
|
||||
{
|
||||
widget_->events().value_changed.emit(::nana::arg_scroll<Vertical>(*widget_));
|
||||
widget_->events().value_changed.emit({ widget_->handle() });
|
||||
}
|
||||
|
||||
void _m_tick()
|
||||
@ -335,7 +333,7 @@ namespace nana
|
||||
/// Provides a way to display an object which is larger than the window's client area.
|
||||
template<bool Vertical>
|
||||
class scroll // add a widget scheme?
|
||||
: public widget_object<category::widget_tag, drawerbase::scroll::trigger<Vertical>, drawerbase::scroll::scroll_events<Vertical>>
|
||||
: public widget_object<category::widget_tag, drawerbase::scroll::trigger<Vertical>, drawerbase::scroll::scroll_events>
|
||||
{
|
||||
typedef widget_object<category::widget_tag, drawerbase::scroll::trigger<Vertical> > base_type;
|
||||
public:
|
||||
@ -448,7 +446,6 @@ namespace nana
|
||||
{
|
||||
return this->make_step(forward, range() - 1);
|
||||
}
|
||||
|
||||
};//end class scroll
|
||||
}//end namespace nana
|
||||
#endif
|
||||
|
||||
@ -574,7 +574,7 @@ namespace nana{ namespace widgets{ namespace skeletons
|
||||
virtual void nontext_render(graph_reference graph, int x, int y) override
|
||||
{
|
||||
if(size_ != image_.size())
|
||||
image_.stretch(image_.size(), graph, nana::rectangle(x, y, size_.width, size_.height));
|
||||
image_.stretch(::nana::rectangle{ image_.size() }, graph, nana::rectangle(x, y, size_.width, size_.height));
|
||||
else
|
||||
image_.paste(graph, x, y);
|
||||
}
|
||||
|
||||
@ -76,6 +76,7 @@ namespace nana
|
||||
|
||||
point pos() const;
|
||||
void move(int x, int y);
|
||||
void move(const point&);
|
||||
void move(const rectangle&);
|
||||
|
||||
void fgcolor(const nana::color&);
|
||||
|
||||
63
include/nana/pat/abstract_factory.hpp
Normal file
63
include/nana/pat/abstract_factory.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* A Generic Abstract Factory Pattern Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2014 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/pat/abstract_factory.hpp
|
||||
* @description: A generic easy-to-use abstract factory pattern implementation
|
||||
*/
|
||||
|
||||
#ifndef NANA_PAT_ABSFACTORY_HPP
|
||||
#define NANA_PAT_ABSFACTORY_HPP
|
||||
#include <memory>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace pat
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
//A Base class for abstract factory, avoids decorated name length exceeding for a class template.
|
||||
class abstract_factory_base
|
||||
{
|
||||
public:
|
||||
virtual ~abstract_factory_base() = default;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Interface>
|
||||
class abstract_factory
|
||||
: public detail::abstract_factory_base
|
||||
{
|
||||
public:
|
||||
using interface_type = Interface;
|
||||
|
||||
virtual ~abstract_factory() = default;
|
||||
virtual std::unique_ptr<interface_type> create() = 0;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename T, typename Interface>
|
||||
class abs_factory
|
||||
: public abstract_factory<Interface>
|
||||
{
|
||||
std::unique_ptr<Interface> create() override
|
||||
{
|
||||
return std::unique_ptr<Interface>{ new T };
|
||||
}
|
||||
};
|
||||
}//end namespace detail
|
||||
|
||||
template<typename Type>
|
||||
pat::cloneable<abstract_factory<typename Type::factory_interface>> make_factory()
|
||||
{
|
||||
return detail::abs_factory<Type, typename Type::factory_interface>();
|
||||
}
|
||||
}//end namespace pat
|
||||
}//end namespace nana
|
||||
#endif
|
||||
@ -208,7 +208,7 @@ namespace nana
|
||||
good_frame_by_frmbuilder = frmobj.u.frbuilder->frbuilder(pos_in_this_frame, framegraph, framegraph_dimension);
|
||||
if(good_frame_by_frmbuilder)
|
||||
{
|
||||
nana::rectangle r = framegraph_dimension;
|
||||
nana::rectangle r(framegraph_dimension);
|
||||
_m_render(outs, [&r, &framegraph](paint::graphics& tar, const nana::point& pos) mutable
|
||||
{
|
||||
r.x = pos.x;
|
||||
|
||||
@ -298,6 +298,15 @@ namespace nana
|
||||
return false;
|
||||
}
|
||||
|
||||
basic_window * basic_window::seek_non_lite_widget_ancestor() const
|
||||
{
|
||||
auto anc = this->parent;
|
||||
while (anc && (category::flags::lite_widget == anc->other.category))
|
||||
anc = anc->parent;
|
||||
|
||||
return anc;
|
||||
}
|
||||
|
||||
void basic_window::_m_init_pos_and_size(basic_window* parent, const rectangle& r)
|
||||
{
|
||||
pos_owner = pos_root = r;
|
||||
|
||||
@ -39,8 +39,6 @@ namespace nana
|
||||
//end class internal_scope_guard
|
||||
|
||||
//class event_arg
|
||||
event_arg::~event_arg(){}
|
||||
|
||||
void event_arg::stop_propagation() const
|
||||
{
|
||||
stop_propagation_ = true;
|
||||
@ -64,6 +62,26 @@ namespace nana
|
||||
bedrock::instance().evt_operation.cancel(evt);
|
||||
}
|
||||
|
||||
class bedrock::flag_guard
|
||||
{
|
||||
public:
|
||||
flag_guard(bedrock* brock, core_window_t * wd)
|
||||
: brock_{ brock }, wd_(wd)
|
||||
{
|
||||
wd_->flags.refreshing = true;
|
||||
}
|
||||
|
||||
~flag_guard()
|
||||
{
|
||||
if (brock_->wd_manager.available((wd_)))
|
||||
wd_->flags.refreshing = false;
|
||||
}
|
||||
private:
|
||||
bedrock *const brock_;
|
||||
core_window_t *const wd_;
|
||||
|
||||
};
|
||||
|
||||
void bedrock::event_expose(core_window_t * wd, bool exposed)
|
||||
{
|
||||
if (nullptr == wd) return;
|
||||
@ -79,11 +97,8 @@ namespace nana
|
||||
{
|
||||
if (category::flags::root != wd->other.category)
|
||||
{
|
||||
//If the wd->parent is a lite_widget then find a parent until it is not a lite_widget
|
||||
wd = wd->parent;
|
||||
|
||||
while (category::flags::lite_widget == wd->other.category)
|
||||
wd = wd->parent;
|
||||
//find an ancestor until it is not a lite_widget
|
||||
wd = wd->seek_non_lite_widget_ancestor();
|
||||
}
|
||||
else if (category::flags::frame == wd->other.category)
|
||||
wd = wd_manager.find_window(wd->root, wd->pos_root.x, wd->pos_root.y);
|
||||
@ -162,6 +177,9 @@ namespace nana
|
||||
auto retain = wd->together.events_ptr;
|
||||
auto evts_ptr = retain.get();
|
||||
|
||||
//enable refreshing flag, this is a RAII class for exception-safe
|
||||
flag_guard fguard(this, wd);
|
||||
|
||||
switch (evt_code)
|
||||
{
|
||||
case event_code::click:
|
||||
@ -214,9 +232,9 @@ namespace nana
|
||||
}
|
||||
|
||||
(wd->drawer.*drawer_event_fn)(*arg);
|
||||
|
||||
if (!draw_only)
|
||||
evt_addr->emit(*arg);
|
||||
|
||||
break;
|
||||
}
|
||||
case event_code::mouse_wheel:
|
||||
|
||||
@ -368,7 +368,7 @@ namespace nana
|
||||
void drawer::_m_bground_end()
|
||||
{
|
||||
if(core_window_->effect.bground && core_window_->effect.bground_fade_rate >= 0.01)
|
||||
core_window_->other.glass_buffer.blend(core_window_->other.glass_buffer.size(), graphics, nana::point(), core_window_->effect.bground_fade_rate);
|
||||
core_window_->other.glass_buffer.blend(::nana::rectangle{ core_window_->other.glass_buffer.size() }, graphics, nana::point(), core_window_->effect.bground_fade_rate);
|
||||
}
|
||||
|
||||
void drawer::_m_draw_dynamic_drawing_object()
|
||||
|
||||
@ -174,7 +174,7 @@ namespace nana{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return primary_monitor_size();
|
||||
return rectangle{ primary_monitor_size() };
|
||||
}
|
||||
|
||||
//platform-dependent
|
||||
|
||||
@ -1473,9 +1473,7 @@ namespace detail
|
||||
brock.erase_menu(false);
|
||||
brock.delay_restore(3); //Restores if delay_restore not decleared
|
||||
}
|
||||
|
||||
brock.wd_manager.destroy(msgwnd);
|
||||
|
||||
nana::detail::platform_spec::instance().release_window_icon(msgwnd->root);
|
||||
break;
|
||||
case WM_NCDESTROY:
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Window Layout Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -24,12 +24,13 @@ namespace nana
|
||||
//class window_layout
|
||||
void window_layout::paint(core_window_t* wd, bool is_redraw, bool is_child_refreshed)
|
||||
{
|
||||
if (wd->flags.refreshing)
|
||||
return;
|
||||
|
||||
if (nullptr == wd->effect.bground)
|
||||
{
|
||||
if (is_redraw)
|
||||
{
|
||||
if (wd->flags.refreshing) return;
|
||||
|
||||
wd->flags.refreshing = true;
|
||||
wd->drawer.refresh();
|
||||
wd->flags.refreshing = false;
|
||||
@ -42,6 +43,10 @@ namespace nana
|
||||
|
||||
bool window_layout::maproot(core_window_t* wd, bool have_refreshed, bool is_child_refreshed)
|
||||
{
|
||||
auto check_opaque = wd->seek_non_lite_widget_ancestor();
|
||||
if (check_opaque && check_opaque->flags.refreshing)
|
||||
return true;
|
||||
|
||||
nana::rectangle vr;
|
||||
if (read_visual_rectangle(wd, vr))
|
||||
{
|
||||
@ -205,7 +210,7 @@ namespace nana
|
||||
beg = beg->parent;
|
||||
}
|
||||
|
||||
glass_buffer.bitblt(wd->dimension, beg->drawer.graphics, wd->pos_root - beg->pos_root);
|
||||
glass_buffer.bitblt(::nana::rectangle{ wd->dimension }, beg->drawer.graphics, wd->pos_root - beg->pos_root);
|
||||
|
||||
nana::rectangle r(wd->pos_owner, wd->dimension);
|
||||
for (auto i = layers.rbegin(), layers_rend = layers.rend(); i != layers_rend; ++i)
|
||||
@ -235,7 +240,7 @@ namespace nana
|
||||
}
|
||||
}
|
||||
else
|
||||
glass_buffer.bitblt(wd->dimension, wd->parent->drawer.graphics, wd->pos_owner);
|
||||
glass_buffer.bitblt(::nana::rectangle{ wd->dimension }, wd->parent->drawer.graphics, wd->pos_owner);
|
||||
|
||||
const rectangle r_of_wd{ wd->pos_owner, wd->dimension };
|
||||
for (auto child : wd->parent->children)
|
||||
|
||||
@ -688,18 +688,20 @@ namespace detail
|
||||
if (wd->visible && wd->visible_parents())
|
||||
{
|
||||
if(forced || (false == wd->belong_to_lazy()))
|
||||
{
|
||||
if (!wd->flags.refreshing)
|
||||
{
|
||||
wndlayout_type::paint(wd, redraw, false);
|
||||
this->map(wd, forced);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(redraw)
|
||||
}
|
||||
else if(redraw)
|
||||
wndlayout_type::paint(wd, true, false);
|
||||
if(wd->other.upd_state == core_window_t::update_state::lazy)
|
||||
|
||||
if (wd->other.upd_state == core_window_t::update_state::lazy)
|
||||
wd->other.upd_state = core_window_t::update_state::refresh;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1333,14 +1335,16 @@ namespace detail
|
||||
delete wd->together.caret;
|
||||
wd->together.caret = nullptr;
|
||||
}
|
||||
|
||||
arg_destroy arg;
|
||||
arg.window_handle = reinterpret_cast<window>(wd);
|
||||
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; ++i)
|
||||
_m_destroy(*i);
|
||||
wd->children.clear();
|
||||
|
||||
arg_destroy arg;
|
||||
arg.window_handle = reinterpret_cast<window>(wd);
|
||||
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
|
||||
|
||||
_m_disengage(wd, nullptr);
|
||||
wndlayout_type::enable_effects_bground(wd, false);
|
||||
|
||||
@ -26,7 +26,7 @@ namespace nana
|
||||
{
|
||||
if(fade_rate_ < 0.001)
|
||||
return;
|
||||
graph.blend(graph.size(), API::bgcolor(wd), fade_rate_);
|
||||
graph.blend(::nana::rectangle{ graph.size() }, API::bgcolor(wd), fade_rate_);
|
||||
}
|
||||
private:
|
||||
const double fade_rate_;
|
||||
@ -42,7 +42,7 @@ namespace nana
|
||||
|
||||
void take_effect(window, graph_reference graph) const
|
||||
{
|
||||
graph.blur(graph.size(), radius_);
|
||||
graph.blur(::nana::rectangle{ graph.size() }, radius_);
|
||||
}
|
||||
private:
|
||||
const std::size_t radius_;
|
||||
|
||||
@ -52,11 +52,13 @@ namespace nana
|
||||
|
||||
bool overlap(const rectangle& ir, const size& valid_input_area, const rectangle & dr, const size& valid_dst_area, rectangle& op_ir, rectangle& op_dr)
|
||||
{
|
||||
if(overlap(ir, valid_input_area, op_ir) == false)
|
||||
rectangle valid_r{ valid_input_area };
|
||||
if (overlap(ir, valid_r, op_ir) == false)
|
||||
return false;
|
||||
|
||||
valid_r = valid_dst_area;
|
||||
rectangle good_dr;
|
||||
if(overlap(dr, valid_dst_area, good_dr) == false)
|
||||
if (overlap(dr, valid_r, good_dr) == false)
|
||||
return false;
|
||||
|
||||
zoom(ir, op_ir, dr, op_dr);
|
||||
|
||||
@ -374,6 +374,16 @@ namespace API
|
||||
return restrict::window_manager.available(reinterpret_cast<restrict::core_window_t*>(wd));
|
||||
}
|
||||
|
||||
bool is_destroying(window wd)
|
||||
{
|
||||
auto iwd = reinterpret_cast<restrict::core_window_t*>(wd);
|
||||
internal_scope_guard lock;
|
||||
if (!restrict::window_manager.available(iwd))
|
||||
return false;
|
||||
|
||||
return iwd->flags.destroying;
|
||||
}
|
||||
|
||||
void enable_dropfiles(window wd, bool enb)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
@ -534,12 +544,9 @@ namespace API
|
||||
internal_scope_guard lock;
|
||||
if(restrict::window_manager.move(iwd, x, y, false))
|
||||
{
|
||||
if(category::flags::root != iwd->other.category)
|
||||
{
|
||||
do{
|
||||
iwd = iwd->parent;
|
||||
} while (category::flags::lite_widget == iwd->other.category);
|
||||
}
|
||||
if (category::flags::root != iwd->other.category)
|
||||
iwd = iwd->seek_non_lite_widget_ancestor();
|
||||
|
||||
restrict::window_manager.update(iwd, false, false);
|
||||
}
|
||||
}
|
||||
@ -551,11 +558,8 @@ namespace API
|
||||
if(restrict::window_manager.move(iwd, r))
|
||||
{
|
||||
if (category::flags::root != iwd->other.category)
|
||||
{
|
||||
do{
|
||||
iwd = iwd->parent;
|
||||
} while (category::flags::lite_widget == iwd->other.category);
|
||||
}
|
||||
iwd = iwd->seek_non_lite_widget_ancestor();
|
||||
|
||||
restrict::window_manager.update(iwd, false, false);
|
||||
}
|
||||
}
|
||||
@ -624,11 +628,8 @@ namespace API
|
||||
if(restrict::window_manager.size(iwd, sz, false, false))
|
||||
{
|
||||
if (category::flags::root != iwd->other.category)
|
||||
{
|
||||
do{
|
||||
iwd = iwd->parent;
|
||||
} while (category::flags::lite_widget == iwd->other.category);
|
||||
}
|
||||
iwd = iwd->seek_non_lite_widget_ancestor();
|
||||
|
||||
restrict::window_manager.update(iwd, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,7 +282,7 @@ namespace nana{ namespace drawerbase
|
||||
else
|
||||
e_state = element_state::disabled;
|
||||
|
||||
if (false == cite_.draw(graph, attr_.bgcolor, attr_.fgcolor, graph.size(), e_state))
|
||||
if (false == cite_.draw(graph, attr_.bgcolor, attr_.fgcolor, ::nana::rectangle{ graph.size() }, e_state))
|
||||
{
|
||||
if (bground_mode::basic != API::effects_bground_mode(wdg_->handle()))
|
||||
{
|
||||
|
||||
@ -521,7 +521,7 @@ namespace nana
|
||||
}
|
||||
|
||||
nana::point pos((image_pixels_ - imgsz.width) / 2 + 2, (vpix - imgsz.height) / 2 + 2);
|
||||
img.stretch(img.size(), *graph_, nana::rectangle(pos, imgsz));
|
||||
img.stretch(::nana::rectangle{ img.size() }, *graph_, nana::rectangle(pos, imgsz));
|
||||
}
|
||||
private:
|
||||
std::vector<std::shared_ptr<item>> items_;
|
||||
|
||||
@ -414,7 +414,7 @@ namespace nana
|
||||
r.y = static_cast<int>(newbuf.height() - r.height) / 2;
|
||||
newbuf.stretch(nzbuf, r);
|
||||
|
||||
nzbuf.blend(nzbuf.size(), dzbuf, nana::point(), fade * (count - i));
|
||||
nzbuf.blend(::nana::rectangle{ nzbuf.size() }, dzbuf, nana::point(), fade * (count - i));
|
||||
graph.bitblt(refpos.x, refpos.y, dzbuf);
|
||||
|
||||
API::update_window(*widget_);
|
||||
@ -442,7 +442,7 @@ namespace nana
|
||||
nzbuf.rectangle(true, colors::white);
|
||||
newbuf.stretch(nzbuf, r);
|
||||
|
||||
nzbuf.blend(nzbuf.size(), dzbuf, nana::point(), fade * (count - i));
|
||||
nzbuf.blend(::nana::rectangle{ nzbuf.size() }, dzbuf, nana::point(), fade * (count - i));
|
||||
graph.bitblt(refpos.x, refpos.y, dzbuf);
|
||||
|
||||
API::update_window(*widget_);
|
||||
|
||||
@ -99,7 +99,7 @@ namespace nana
|
||||
nana::point to_pos(x, r.y + 2);
|
||||
to_pos.x += (image_pixels_ - imgsz.width) / 2;
|
||||
to_pos.y += (vpix - imgsz.height) / 2;
|
||||
item->image().stretch(item->image().size(), graph, nana::rectangle(to_pos, imgsz));
|
||||
item->image().stretch(::nana::rectangle{ item->image().size() }, graph, nana::rectangle(to_pos, imgsz));
|
||||
}
|
||||
x += (image_pixels_ + 2);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include <nana/gui/widgets/listbox.hpp>
|
||||
#include <nana/gui/widgets/scroll.hpp>
|
||||
#include <nana/gui/widgets/panel.hpp>
|
||||
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
#include <nana/gui/element.hpp>
|
||||
@ -408,9 +409,6 @@ namespace nana
|
||||
|
||||
void item_width(size_type pos, unsigned width)
|
||||
{
|
||||
if (pos >= cont_.size())
|
||||
return;
|
||||
|
||||
for(auto & m : cont_)
|
||||
{
|
||||
if(m.index == pos)
|
||||
@ -649,6 +647,8 @@ namespace nana
|
||||
}
|
||||
};
|
||||
|
||||
class inline_indicator;
|
||||
|
||||
struct category_t
|
||||
{
|
||||
using container = std::deque<item_t>;
|
||||
@ -661,6 +661,9 @@ namespace nana
|
||||
//A cat may have a key object to identify the category
|
||||
std::shared_ptr<nana::detail::key_interface> key_ptr;
|
||||
|
||||
std::deque<pat::cloneable<pat::abstract_factory<inline_notifier_interface>>> factories;
|
||||
std::deque<std::unique_ptr<inline_indicator>> indicators;
|
||||
|
||||
category_t() = default;
|
||||
|
||||
category_t(nana::string str)
|
||||
@ -728,8 +731,6 @@ namespace nana
|
||||
if((sorted_index_ == npos) || (!resort_))
|
||||
return;
|
||||
|
||||
|
||||
|
||||
auto weak_ordering_comp = fetch_ordering_comparer(sorted_index_);
|
||||
if(weak_ordering_comp)
|
||||
{
|
||||
@ -936,6 +937,11 @@ namespace nana
|
||||
return npos ;
|
||||
}
|
||||
|
||||
category_t& at(std::size_t cat_pos)
|
||||
{
|
||||
return *(_m_at(cat_pos));
|
||||
}
|
||||
|
||||
/// return a ref to the real item object at display!!! position pos using current sorting only if it is active, and at absolute position if no sorting is currently active.
|
||||
category_t::container::value_type& at(const index_pair& pos)
|
||||
{
|
||||
@ -946,9 +952,15 @@ namespace nana
|
||||
|
||||
return _m_at(pos.cat)->items.at(index);
|
||||
}
|
||||
|
||||
const category_t::container::value_type& at(const index_pair& pos) const
|
||||
{
|
||||
return at(pos);
|
||||
auto index = pos.item;
|
||||
|
||||
if (sorted_index_ != npos)
|
||||
index = absolute(pos);
|
||||
|
||||
return _m_at(pos.cat)->items.at(index);
|
||||
}
|
||||
|
||||
void clear(size_type cat)
|
||||
@ -1732,70 +1744,41 @@ namespace nana
|
||||
/// all arg are relative to display order, or all are absolute, but not mixed
|
||||
bool forward(index_pair from, size_type offs, index_pair& item) const
|
||||
{
|
||||
if(!good_item(from, from))
|
||||
if (!good_item(from, from))
|
||||
return false;
|
||||
|
||||
if(offs == 0)
|
||||
{
|
||||
item = from;
|
||||
return true;
|
||||
}
|
||||
auto cat = _m_at(from.cat);
|
||||
auto cat_end = list_.end();
|
||||
|
||||
if(list_.size() <= from.cat) return false;
|
||||
auto items_left = (cat->expand ? cat->items.size() : 0);
|
||||
|
||||
if(from.is_category())
|
||||
{
|
||||
// this is a category, so...
|
||||
// and offs is not 0, this category would not be candidated.
|
||||
// the algorithm above to calc the offset item is always starting with a item.
|
||||
--offs;
|
||||
from.item = 0;
|
||||
}
|
||||
|
||||
auto icat = _m_at(from.cat); // an iterator to category from.cat
|
||||
|
||||
if(icat->expand)
|
||||
{
|
||||
std::size_t item_left_in_this_cat = icat->items.size() -1- from.item;
|
||||
if(offs <= item_left_in_this_cat )
|
||||
{
|
||||
item = from;
|
||||
item.item += offs; // use absolute to know the real item
|
||||
return true; // allways return here when we have only one cat.
|
||||
}
|
||||
if (from.is_category())
|
||||
items_left += 1; //add 1 category bar
|
||||
else if (items_left >= from.item)
|
||||
items_left -= from.item;
|
||||
else
|
||||
{
|
||||
offs -= item_left_in_this_cat ;
|
||||
item = from;
|
||||
item.item += item_left_in_this_cat ;
|
||||
}
|
||||
}
|
||||
return false; //invalid argument
|
||||
|
||||
++from.cat;
|
||||
++icat;
|
||||
for(; icat != list_.end(); ++icat, ++from.cat)
|
||||
while (offs)
|
||||
{
|
||||
if (items_left > offs)
|
||||
{
|
||||
item.cat = from.cat;
|
||||
item.item = npos;
|
||||
|
||||
if(offs-- == 0)
|
||||
{
|
||||
item.item = (npos == from.item ? offs - 1 : from.item + offs);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(icat->expand)
|
||||
{
|
||||
if(offs < icat->items.size())
|
||||
{
|
||||
//item.cat = from.cat;
|
||||
item.item = offs;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
offs -= icat->items.size();
|
||||
}
|
||||
}
|
||||
offs -= items_left;
|
||||
if (++cat == cat_end)
|
||||
return false;
|
||||
|
||||
++from.cat;
|
||||
from.item = npos;
|
||||
items_left = (cat->expand ? cat->items.size() + 1 : 1);
|
||||
}
|
||||
|
||||
item = from;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// all arg are relative to display order, or all are absolute, but not mixed
|
||||
@ -1845,7 +1828,7 @@ namespace nana
|
||||
container::iterator _m_at(size_type index)
|
||||
{
|
||||
if(index >= list_.size())
|
||||
throw std::out_of_range("Nana.GUI.Listbox: invalid category index");
|
||||
throw std::out_of_range("nana::listbox: invalid category index");
|
||||
|
||||
auto i = list_.begin();
|
||||
std::advance(i, index);
|
||||
@ -1855,7 +1838,7 @@ namespace nana
|
||||
container::const_iterator _m_at(size_type index) const
|
||||
{
|
||||
if(index >= list_.size())
|
||||
throw std::out_of_range("Nana.GUI.Listbox: invalid category index");
|
||||
throw std::out_of_range("nana::listbox: invalid category index");
|
||||
|
||||
auto i = list_.cbegin();
|
||||
std::advance(i, index);
|
||||
@ -1879,6 +1862,7 @@ namespace nana
|
||||
bool single_check_category_limited_{ false };
|
||||
};//end class es_lister
|
||||
|
||||
|
||||
//struct essence_t
|
||||
//@brief: this struct gives many data for listbox,
|
||||
// the state of the struct does not effect on member funcions, therefore all data members are public.
|
||||
@ -1896,7 +1880,8 @@ namespace nana
|
||||
unsigned item_size{24};
|
||||
unsigned text_height{0};
|
||||
unsigned suspension_width{0};
|
||||
::nana::listbox::export_options def_exp_options ;
|
||||
|
||||
::nana::listbox::export_options def_exp_options;
|
||||
|
||||
::nana::listbox::export_options& def_export_options()
|
||||
{
|
||||
@ -1923,6 +1908,19 @@ namespace nana
|
||||
nana::scroll<false> h;
|
||||
}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::map<pat::detail::abstract_factory_base*, std::deque<std::unique_ptr<inline_pane>>> inline_table, inline_buffered_table;
|
||||
|
||||
essence_t()
|
||||
{
|
||||
scroll.offset_x = 0;
|
||||
@ -2107,11 +2105,11 @@ namespace nana
|
||||
{
|
||||
scroll.h.create(wd, r);
|
||||
API::take_active(scroll.h.handle(), false, wd);
|
||||
scroll.h.events().mouse_move.connect_unignorable([this](const nana::arg_mouse& arg){
|
||||
_m_answer_scroll(arg);
|
||||
});
|
||||
scroll.h.events().mouse_up.connect_unignorable([this](const nana::arg_mouse& arg){
|
||||
_m_answer_scroll(arg);
|
||||
|
||||
scroll.h.events().value_changed.connect_unignorable([this](const ::nana::arg_scroll& arg)
|
||||
{
|
||||
scroll.offset_x = static_cast<int>(scroll.h.value());
|
||||
API::refresh_window(this->lister.wd_ptr()->handle());
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -2126,13 +2124,20 @@ namespace nana
|
||||
if(scroll.v.empty())
|
||||
{
|
||||
scroll.v.create(wd, r);
|
||||
API::take_active(scroll.v.handle(), false, wd); // install value_changed() not mouse_move ????
|
||||
API::take_active(scroll.v.handle(), false, wd);
|
||||
|
||||
scroll.v.events().value_changed([this](const ::nana::arg_scroll<true>& arg)
|
||||
scroll.v.events().value_changed([this](const ::nana::arg_scroll& arg)
|
||||
{
|
||||
_m_answer_scroll_value(arg);
|
||||
});
|
||||
index_pair item;
|
||||
if (!lister.forward(item, scroll.v.value(), item)) return;
|
||||
|
||||
if (item == scroll.offset_y_dpl)
|
||||
return;
|
||||
|
||||
set_scroll_y_dpl(item);
|
||||
|
||||
API::refresh_window(this->lister.wd_ptr()->handle());
|
||||
});
|
||||
}
|
||||
else
|
||||
scroll.v.move(r);
|
||||
@ -2141,7 +2146,7 @@ namespace nana
|
||||
else if(!scroll.v.empty())
|
||||
{
|
||||
scroll.v.close();
|
||||
set_scroll_y_dpl({0,0}); // scroll.offset_y.set_both(0);
|
||||
set_scroll_y_dpl({0,0});
|
||||
|
||||
nana::rectangle r;
|
||||
if(rect_header(r))
|
||||
@ -2311,63 +2316,100 @@ namespace nana
|
||||
for(const auto& hd : header.cont())
|
||||
{
|
||||
if(false == hd.visible) continue;
|
||||
x += hd.pixels;
|
||||
x += static_cast<int>(hd.pixels);
|
||||
if(x > 0)
|
||||
seqs.push_back(hd.index);
|
||||
if(x >= static_cast<int>(lister_w))
|
||||
break;
|
||||
}
|
||||
}
|
||||
private:
|
||||
void _m_answer_scroll(const arg_mouse& arg)
|
||||
{
|
||||
if(arg.evt_code == event_code::mouse_move && arg.left_button == false) return;
|
||||
|
||||
bool update = false;
|
||||
if(arg.window_handle == scroll.v.handle())
|
||||
inline_pane * open_inline(pat::abstract_factory<inline_notifier_interface>* factory, inline_indicator* indicator)
|
||||
{
|
||||
index_pair item;
|
||||
if(lister.forward(item, scroll.v.value(), item))
|
||||
std::unique_ptr<inline_pane> pane_ptr;
|
||||
auto i = inline_buffered_table.find(factory);
|
||||
if (i != inline_buffered_table.end())
|
||||
{
|
||||
if (item != scroll.offset_y_dpl)
|
||||
auto & panes = i->second;
|
||||
if (!panes.empty())
|
||||
{
|
||||
set_scroll_y_dpl ( item );
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(arg.window_handle == scroll.h.handle())
|
||||
{
|
||||
if(scroll.offset_x != static_cast<int>(scroll.h.value()))
|
||||
{
|
||||
scroll.offset_x = static_cast<int>(scroll.h.value());
|
||||
update = true;
|
||||
pane_ptr = std::move(panes.front());
|
||||
panes.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
if(update)
|
||||
API::refresh_window(lister.wd_ptr()->handle());
|
||||
}
|
||||
void _m_answer_scroll_value(const ::nana::arg_scroll<true>& arg)
|
||||
if (!pane_ptr)
|
||||
{
|
||||
index_pair item;
|
||||
if( !lister.forward(item, scroll.v.value(), item)) return;
|
||||
pane_ptr.reset(new inline_pane);
|
||||
pane_ptr->indicator = indicator;
|
||||
pane_ptr->pane_bottom.create(this->lister.wd_ptr()->handle());
|
||||
pane_ptr->pane_widget.create(pane_ptr->pane_bottom);
|
||||
pane_ptr->inline_ptr = factory->create();
|
||||
pane_ptr->inline_ptr->create(pane_ptr->pane_widget);
|
||||
}
|
||||
|
||||
if (item == scroll.offset_y_dpl)
|
||||
auto ptr = pane_ptr.get();
|
||||
inline_table[factory].emplace_back(std::move(pane_ptr));
|
||||
return ptr;
|
||||
}
|
||||
};
|
||||
|
||||
class inline_indicator
|
||||
: public ::nana::detail::inline_widget_indicator<index_pair, std::wstring>
|
||||
{
|
||||
public:
|
||||
using parts = essence_t::parts;
|
||||
|
||||
inline_indicator(essence_t* ess, std::size_t column_pos)
|
||||
: ess_{ ess }, column_pos_{column_pos}
|
||||
{
|
||||
}
|
||||
|
||||
::nana::widget& host() const override
|
||||
{
|
||||
return *ess_->lister.wd_ptr();
|
||||
}
|
||||
|
||||
void modify(index_type pos, const value_type& value) const override
|
||||
{
|
||||
auto & cells = ess_->lister.at(pos).cells;
|
||||
if (cells.size() <= column_pos_)
|
||||
cells.resize(column_pos_ + 1);
|
||||
|
||||
cells[column_pos_].text = value;
|
||||
ess_->update();
|
||||
}
|
||||
|
||||
void selected(index_type pos) override
|
||||
{
|
||||
if (ess_->lister.at(pos).flags.selected)
|
||||
return;
|
||||
|
||||
set_scroll_y_dpl ( item );
|
||||
|
||||
API::refresh_window(lister.wd_ptr()->handle());
|
||||
ess_->lister.select_for_all(false);
|
||||
cat_proxy(ess_, pos.cat).at(pos.item).select(true);
|
||||
}
|
||||
|
||||
};
|
||||
void hovered(index_type pos) override
|
||||
{
|
||||
auto offset = ess_->lister.distance(ess_->scroll.offset_y_dpl, pos);
|
||||
|
||||
if (ess_->pointer_where.first != parts::lister || ess_->pointer_where.second != offset)
|
||||
{
|
||||
ess_->pointer_where.first = parts::lister;
|
||||
ess_->pointer_where.second = offset;
|
||||
ess_->update();
|
||||
}
|
||||
}
|
||||
private:
|
||||
essence_t * const ess_;
|
||||
const std::size_t column_pos_;
|
||||
};
|
||||
|
||||
|
||||
void es_lister::scroll_refresh()
|
||||
{
|
||||
ess_->scroll_y_dpl_refresh();
|
||||
|
||||
}
|
||||
|
||||
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; // ??
|
||||
@ -2613,7 +2655,6 @@ namespace nana
|
||||
{
|
||||
graph_reference graph = *(essence_->graph);
|
||||
|
||||
|
||||
int txtop = (rect.height - essence_->text_height) / 2 + rect.y;
|
||||
auto txtcolor = essence_->lister.wd_ptr()->fgcolor();
|
||||
|
||||
@ -2632,7 +2673,7 @@ namespace nana
|
||||
int next_x = x + static_cast<int>(i.pixels);
|
||||
if(next_x > rect.x)
|
||||
{
|
||||
_m_draw_item(graph, x, rect.y, height, txtop, txtcolor, i, (i.index == essence_->pointer_where.second ? state : item_state::normal));
|
||||
_m_draw_header_item(graph, x, rect.y, height, txtop, txtcolor, i, (i.index == essence_->pointer_where.second ? state : item_state::normal));
|
||||
graph.line({ next_x - 1, rect.y }, { next_x - 1, bottom_y }, _m_border_color());
|
||||
}
|
||||
|
||||
@ -2647,7 +2688,7 @@ namespace nana
|
||||
}
|
||||
|
||||
template<typename Item>
|
||||
void _m_draw_item(graph_reference graph, int x, int y, unsigned height, int txtop, const ::nana::color& fgcolor, const Item& item, item_state state)
|
||||
void _m_draw_header_item(graph_reference graph, int x, int y, unsigned height, int txtop, const ::nana::color& fgcolor, const Item& item, item_state state)
|
||||
{
|
||||
essence_->scheme_ptr->header_bgcolor.get_color();
|
||||
::nana::color bgcolor;
|
||||
@ -2679,10 +2720,10 @@ namespace nana
|
||||
ext_graph.typeface(essence_->graph->typeface());
|
||||
|
||||
int txtop = (essence_->header_size - essence_->text_height) / 2;
|
||||
_m_draw_item(ext_graph, 0, 0, essence_->header_size, txtop, colors::white, item, item_state::floated);
|
||||
_m_draw_header_item(ext_graph, 0, 0, essence_->header_size, txtop, colors::white, item, item_state::floated);
|
||||
|
||||
int xpos = essence_->header.item_pos(item.index, nullptr) + pos.x - ref_xpos_;
|
||||
ext_graph.blend(ext_graph.size(), *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5);
|
||||
ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), nana::point(xpos - essence_->scroll.offset_x + rect.x, rect.y), 0.5);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2709,8 +2750,6 @@ namespace nana
|
||||
|
||||
void draw(const nana::rectangle& rect) const
|
||||
{
|
||||
// essence_->scroll_y_dpl_refresh() ; // ????
|
||||
|
||||
internal_scope_guard lock;
|
||||
|
||||
size_type n = essence_->number_of_lister_items(true);
|
||||
@ -2752,6 +2791,8 @@ namespace nana
|
||||
|
||||
auto state = item_state::normal;
|
||||
|
||||
essence_->inline_buffered_table.swap(essence_->inline_table);
|
||||
|
||||
//Here we draw the root categ (0) or a first item if the first drawing is not a categ.(item!=npos))
|
||||
if(idx.cat == 0 || !idx.is_category())
|
||||
{
|
||||
@ -2762,12 +2803,16 @@ namespace nana
|
||||
}
|
||||
|
||||
std::size_t size = i_categ->items.size();
|
||||
index_pair item_index{ idx.cat, 0 };
|
||||
for(std::size_t offs = essence_->scroll.offset_y_dpl.item; offs < size; ++offs, ++idx.item)
|
||||
{
|
||||
if(n-- == 0) break;
|
||||
state = (tracker == idx ? item_state::highlighted : item_state::normal);
|
||||
|
||||
_m_draw_item(i_categ->items[lister.absolute(index_pair(idx.cat, offs)) ], x, y, txtoff, header_w, rect, subitems, bgcolor,fgcolor, state);
|
||||
item_index.item = offs;
|
||||
item_index = lister.absolute_pair(item_index);
|
||||
|
||||
_m_draw_item(*i_categ, item_index, x, y, txtoff, header_w, rect, subitems, bgcolor,fgcolor, state);
|
||||
y += essence_->item_size;
|
||||
}
|
||||
|
||||
@ -2789,17 +2834,23 @@ namespace nana
|
||||
continue;
|
||||
|
||||
auto size = i_categ->items.size();
|
||||
index_pair item_pos{ idx.cat, 0 };
|
||||
for(decltype(size) pos = 0; pos < size; ++pos)
|
||||
{
|
||||
if(n-- == 0) break;
|
||||
state = (idx == tracker ? item_state::highlighted : item_state::normal);
|
||||
|
||||
_m_draw_item(i_categ->items[ lister.absolute(index_pair(idx.cat, pos))], x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state);
|
||||
item_pos.item = pos;
|
||||
item_pos.item = lister.absolute(item_pos);
|
||||
|
||||
_m_draw_item(*i_categ, item_pos, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state);
|
||||
y += essence_->item_size;
|
||||
++idx.item;
|
||||
}
|
||||
}
|
||||
|
||||
essence_->inline_buffered_table.clear();
|
||||
|
||||
if (y < rect.y + static_cast<int>(rect.height))
|
||||
{
|
||||
essence_->graph->set_color(bgcolor);
|
||||
@ -2848,8 +2899,12 @@ namespace nana
|
||||
}
|
||||
}
|
||||
|
||||
void _m_draw_item(const item_t& item, int x, int y, int txtoff, unsigned width, const nana::rectangle& r, const std::vector<size_type>& seqs, nana::color bgcolor, nana::color fgcolor, item_state state) const
|
||||
//Draws an item
|
||||
//@param content_r the rectangle of list content
|
||||
void _m_draw_item(const category_t& cat, const index_pair& item_pos, const int x, const int y, const int txtoff, unsigned width, const nana::rectangle& content_r, const std::vector<size_type>& seqs, nana::color bgcolor, nana::color fgcolor, item_state state) const
|
||||
{
|
||||
auto & item = cat.items[item_pos.item];
|
||||
|
||||
if (item.flags.selected) // fetch the "def" colors
|
||||
bgcolor = essence_->scheme_ptr->item_selected;
|
||||
else if (!item.bgcolor.invisible())
|
||||
@ -2858,7 +2913,6 @@ namespace nana
|
||||
if(!item.fgcolor.invisible())
|
||||
fgcolor = item.fgcolor;
|
||||
|
||||
auto graph = essence_->graph;
|
||||
if (item_state::highlighted == state) // and blend it if "highlighted"
|
||||
{
|
||||
if (item.flags.selected)
|
||||
@ -2868,52 +2922,37 @@ namespace nana
|
||||
}
|
||||
|
||||
unsigned show_w = width - essence_->scroll.offset_x;
|
||||
if(show_w >= r.width) show_w = r.width;
|
||||
if(show_w >= content_r.width) show_w = content_r.width;
|
||||
|
||||
auto graph = essence_->graph;
|
||||
//draw the background
|
||||
graph->set_color(bgcolor);
|
||||
graph->rectangle(rectangle{ r.x, y, show_w, essence_->item_size }, true);
|
||||
graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->item_size }, true);
|
||||
|
||||
int item_xpos = x;
|
||||
unsigned extreme_text = x;
|
||||
bool first = true;
|
||||
|
||||
|
||||
for(size_type display_order{0}; display_order < seqs.size(); ++display_order) // get the cell (column) index in the order headers are displayed
|
||||
for (size_type display_order{ 0 }; display_order < seqs.size(); ++display_order) // get the cell (column) index in the order headers are displayed
|
||||
{
|
||||
auto index = seqs[display_order];
|
||||
const auto & header = essence_->header.column(index); // deduce the corresponding header which is in a kind of dislay order
|
||||
const auto column_pos = seqs[display_order];
|
||||
const auto & header = essence_->header.column(column_pos); // deduce the corresponding header which is in a kind of dislay order
|
||||
auto it_bgcolor = bgcolor;
|
||||
|
||||
if ((item.cells.size() > index) && (header.pixels > 5)) // process only if the cell is visible
|
||||
if (header.pixels > 5)
|
||||
{
|
||||
auto cell_txtcolor = fgcolor;
|
||||
auto & m_cell = item.cells[index];
|
||||
nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry
|
||||
int content_pos = 5;
|
||||
|
||||
if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need
|
||||
//Draw the image in the 1st column in display order
|
||||
if (0 == display_order)
|
||||
{
|
||||
it_bgcolor = m_cell.custom_format->bgcolor;
|
||||
if (item.flags.selected)
|
||||
it_bgcolor = it_bgcolor.blend( bgcolor , 0.5) ;
|
||||
if (item_state::highlighted == state)
|
||||
it_bgcolor = it_bgcolor.blend(::nana::color(0x99, 0xde, 0xfd), 0.8);
|
||||
|
||||
graph->set_color(it_bgcolor);
|
||||
graph->rectangle(rectangle{ item_xpos, y, header.pixels, essence_->item_size }, true);
|
||||
|
||||
cell_txtcolor = m_cell.custom_format->fgcolor;
|
||||
}
|
||||
|
||||
int ext_w = 5;
|
||||
if(first && essence_->checkable) // draw the checkbox if need, only before the first column (display_order=0 ?)
|
||||
if (essence_->checkable)
|
||||
{
|
||||
ext_w += 18;
|
||||
content_pos += 18;
|
||||
|
||||
element_state estate = element_state::normal;
|
||||
if(essence_->pointer_where.first == parts::checker)
|
||||
if (essence_->pointer_where.first == parts::checker)
|
||||
{
|
||||
switch(state)
|
||||
switch (state)
|
||||
{
|
||||
case item_state::highlighted:
|
||||
estate = element_state::hovered; break;
|
||||
@ -2928,56 +2967,163 @@ namespace nana
|
||||
crook_renderer_.draw(*graph, bgcolor, fgcolor, essence_->checkarea(item_xpos, y), estate);
|
||||
}
|
||||
|
||||
if ((0 == index) && essence_->if_image) // draw the image if need, ??only before the first column?? (display_order=0 ?)
|
||||
if (essence_->if_image)
|
||||
{
|
||||
//Draw the image in the 1st column in display order
|
||||
if (item.img)
|
||||
{
|
||||
nana::rectangle img_r(item.img_show_size);
|
||||
img_r.x = static_cast<int>(ext_w) + item_xpos + static_cast<int>(16 - item.img_show_size.width) / 2;
|
||||
img_r.x = content_pos + item_xpos + static_cast<int>(16 - item.img_show_size.width) / 2;
|
||||
img_r.y = y + static_cast<int>(essence_->item_size - item.img_show_size.height) / 2;
|
||||
item.img.stretch(item.img.size(), *graph, img_r);
|
||||
item.img.stretch(rectangle{ item.img.size() }, *graph, img_r);
|
||||
}
|
||||
content_pos += 18;
|
||||
}
|
||||
ext_w += 18;
|
||||
}
|
||||
|
||||
bool draw_column = true;
|
||||
|
||||
if (static_cast<unsigned>(content_pos) < header.pixels)
|
||||
{
|
||||
auto inline_wdg = _m_get_inline_pane(cat, column_pos);
|
||||
if (inline_wdg)
|
||||
{
|
||||
//Make sure the user-define inline widgets in right visible rectangle.
|
||||
rectangle pane_r;
|
||||
auto wdg_x = item_xpos + content_pos;
|
||||
auto wdg_w = header.pixels - static_cast<unsigned>(content_pos);
|
||||
|
||||
bool visible_state = true;
|
||||
if (::nana::overlap(content_r, { wdg_x, y, wdg_w, essence_->item_size }, pane_r))
|
||||
{
|
||||
::nana::point pane_pos;
|
||||
if (wdg_x < content_r.x)
|
||||
pane_pos.x = wdg_x - content_r.x;
|
||||
|
||||
if (y < content_r.y)
|
||||
pane_pos.y = y - content_r.y;
|
||||
|
||||
inline_wdg->pane_widget.move(pane_pos);
|
||||
inline_wdg->pane_bottom.move(pane_r);
|
||||
}
|
||||
else
|
||||
visible_state = false;
|
||||
|
||||
::nana::size sz{ wdg_w, essence_->item_size };
|
||||
inline_wdg->pane_widget.size(sz);
|
||||
inline_wdg->inline_ptr->resize(sz);
|
||||
inline_wdg->item_pos = item_pos;
|
||||
inline_wdg->column_pos = column_pos;
|
||||
inline_wdg->inline_ptr->activate(*inline_wdg->indicator, item_pos);
|
||||
|
||||
draw_column = inline_wdg->inline_ptr->whether_to_draw();
|
||||
|
||||
//To reduce the memory usage, the cells may not be allocated
|
||||
if (item.cells.size() > column_pos)
|
||||
inline_wdg->inline_ptr->set(item.cells[column_pos].text);
|
||||
else
|
||||
inline_wdg->inline_ptr->set({});
|
||||
|
||||
API::show_window(inline_wdg->pane_bottom, visible_state);
|
||||
}
|
||||
}
|
||||
|
||||
if (item.cells.size() > column_pos) // process only if the cell is visible
|
||||
{
|
||||
auto cell_txtcolor = fgcolor;
|
||||
auto & m_cell = item.cells[column_pos];
|
||||
nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry
|
||||
|
||||
if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need
|
||||
{
|
||||
it_bgcolor = m_cell.custom_format->bgcolor;
|
||||
if (item.flags.selected)
|
||||
it_bgcolor = it_bgcolor.blend(bgcolor, 0.5);
|
||||
if (item_state::highlighted == state)
|
||||
it_bgcolor = it_bgcolor.blend(static_cast<color_rgb>(0x99defd), 0.8);
|
||||
|
||||
graph->set_color(it_bgcolor);
|
||||
|
||||
graph->rectangle(rectangle{ item_xpos, y, header.pixels, essence_->item_size }, true);
|
||||
|
||||
cell_txtcolor = m_cell.custom_format->fgcolor;
|
||||
}
|
||||
|
||||
if (draw_column)
|
||||
{
|
||||
graph->set_text_color(cell_txtcolor);
|
||||
graph->string(point{ item_xpos + ext_w, y + txtoff }, m_cell.text); // draw full text of the cell index (column)
|
||||
graph->string(point{ item_xpos + content_pos, y + txtoff }, m_cell.text); // draw full text of the cell index (column)
|
||||
|
||||
if (ts.width + ext_w > header.pixels) // it was an excess
|
||||
if (ts.width + static_cast<unsigned>(content_pos) > header.pixels) // it was an excess
|
||||
{
|
||||
//The text is painted over the next subitem // here beging the ...
|
||||
int xpos = item_xpos + static_cast<int>(header.pixels) - static_cast<int>(essence_->suspension_width);
|
||||
|
||||
graph->set_color(it_bgcolor); // litter rect with the item bg end ...
|
||||
graph->rectangle(rectangle{ xpos, y + 2, essence_->suspension_width, essence_->item_size - 4 }, true);
|
||||
graph->set_text_color(cell_txtcolor);
|
||||
graph->string(point{ xpos, y + 2 }, STR("..."));
|
||||
|
||||
//Erase the part that over the next subitem.
|
||||
if ( display_order + 1 < seqs.size() ) // this is not the last column
|
||||
if (display_order + 1 < seqs.size()) // this is not the last column
|
||||
{
|
||||
graph->set_color(bgcolor); // we need to erase the excess, because some cell may not draw text over
|
||||
graph->rectangle(rectangle{item_xpos + static_cast<int>(header.pixels), y + 2,
|
||||
ts.width + ext_w - header.pixels, essence_->item_size - 4}, true);
|
||||
graph->rectangle(rectangle{ item_xpos + static_cast<int>(header.pixels), y + 2,
|
||||
ts.width + static_cast<unsigned>(content_pos)-header.pixels, essence_->item_size - 4 }, true);
|
||||
}
|
||||
extreme_text = std::max(extreme_text, item_xpos + content_pos + ts.width);
|
||||
}
|
||||
extreme_text = std::max (extreme_text, item_xpos + ext_w + ts.width);
|
||||
}
|
||||
}
|
||||
|
||||
graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast<int>(essence_->item_size) - 1 }, { 0xEB, 0xF4, 0xF9 });
|
||||
graph->line({ item_xpos - 1, y }, { item_xpos - 1, y + static_cast<int>(essence_->item_size) - 1 }, static_cast<color_rgb>(0xEBF4F9));
|
||||
|
||||
item_xpos += header.pixels;
|
||||
}
|
||||
|
||||
item_xpos += static_cast<int>(header.pixels);
|
||||
if (display_order + 1 >= seqs.size() && static_cast<int>(extreme_text) > item_xpos)
|
||||
{
|
||||
graph->set_color(item.bgcolor);
|
||||
graph->rectangle(rectangle{item_xpos , y + 2, extreme_text - item_xpos, essence_->item_size - 4}, true);
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
//Draw selecting inner rectangle
|
||||
if(item.flags.selected)
|
||||
_m_draw_border(r.x, y, show_w);
|
||||
_m_draw_border(content_r.x, y, show_w);
|
||||
}
|
||||
|
||||
essence_t::inline_pane * _m_get_inline_pane(const category_t& cat, std::size_t column_pos) const
|
||||
{
|
||||
if (column_pos < cat.factories.size())
|
||||
{
|
||||
auto & factory = cat.factories[column_pos];
|
||||
if (factory)
|
||||
return essence_->open_inline(factory.get(), cat.indicators[column_pos].get());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
essence_t::inline_pane* _m_find_inline_pane(const index_pair& pos, std::size_t column_pos) const
|
||||
{
|
||||
auto & cat = essence_->lister.at(pos.cat);
|
||||
|
||||
if (column_pos >= cat.factories.size())
|
||||
return nullptr;
|
||||
|
||||
auto& factory = cat.factories[column_pos];
|
||||
if (!factory)
|
||||
return nullptr;
|
||||
|
||||
auto i = essence_->inline_table.find(factory.get());
|
||||
if (i == essence_->inline_table.end())
|
||||
return nullptr;
|
||||
|
||||
for (auto & inl_widget : i->second)
|
||||
{
|
||||
if (inl_widget->item_pos == pos && inl_widget->column_pos == column_pos)
|
||||
return inl_widget.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void _m_draw_border(int x, int y, unsigned width) const
|
||||
@ -3024,6 +3170,9 @@ namespace nana
|
||||
|
||||
void trigger::draw()
|
||||
{
|
||||
if (API::is_destroying(essence_->lister.wd_ptr()->handle()))
|
||||
return;
|
||||
|
||||
nana::rectangle r;
|
||||
|
||||
if(essence_->header.visible() && essence_->rect_header(r))
|
||||
@ -3136,15 +3285,12 @@ namespace nana
|
||||
}
|
||||
}
|
||||
|
||||
switch(update)
|
||||
if (update)
|
||||
{
|
||||
case 1:
|
||||
API::update_window(essence_->lister.wd_ptr()->handle());
|
||||
break;
|
||||
case 2:
|
||||
if (2 == update)
|
||||
draw();
|
||||
|
||||
API::lazy_refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3198,7 +3344,7 @@ namespace nana
|
||||
else if (arg.ctrl)
|
||||
sel = !item_proxy(essence_, index_pair (item_pos.cat, lister.absolute(item_pos))).selected();
|
||||
else
|
||||
lister.select_for_all(false);
|
||||
lister.select_for_all(false); //cancel all selections
|
||||
}
|
||||
else
|
||||
sel = !item_proxy(essence_, index_pair (item_pos.cat, lister.absolute(item_pos))).selected();
|
||||
@ -3498,6 +3644,8 @@ namespace nana
|
||||
else if (ess_->lister.last_selected_abs == pos_)
|
||||
ess_->lister.last_selected_abs.set_both(npos);
|
||||
|
||||
ess_->update();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -3890,6 +4038,21 @@ namespace nana
|
||||
return ! this->operator==(r);
|
||||
}
|
||||
|
||||
void cat_proxy::inline_factory(size_type column, pat::cloneable<pat::abstract_factory<inline_notifier_interface>> factory)
|
||||
{
|
||||
if (column >= ess_->header.cont().size())
|
||||
throw std::out_of_range("listbox.cat_proxy.inline_factory: invalid column index");
|
||||
|
||||
if (column >= cat_->factories.size())
|
||||
{
|
||||
cat_->factories.resize(column + 1);
|
||||
cat_->indicators.resize(column + 1);
|
||||
}
|
||||
|
||||
cat_->factories[column] = std::move(factory);
|
||||
cat_->indicators[column].reset(new inline_indicator(ess_, column));
|
||||
}
|
||||
|
||||
void cat_proxy::_m_append(std::vector<cell> && cells)
|
||||
{
|
||||
//check invalid cells
|
||||
@ -3940,7 +4103,6 @@ namespace nana
|
||||
arg_listbox::arg_listbox(const drawerbase::listbox::item_proxy& m, bool selected)
|
||||
: item(m), selected(selected)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//class listbox
|
||||
|
||||
@ -112,7 +112,7 @@ namespace nana
|
||||
|
||||
_m_draw_background(fit_size.width, fit_size.height);
|
||||
|
||||
backimg.image.stretch(valid_area, graph, { pos, fit_size });
|
||||
backimg.image.stretch(valid_area, graph, ::nana::rectangle{ pos, fit_size });
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -151,7 +151,7 @@ namespace nana
|
||||
_m_draw_background(graphsize.width, graphsize.height);
|
||||
|
||||
color invalid_clr_for_call;
|
||||
backimg.bground->draw(graph, invalid_clr_for_call, invalid_clr_for_call, graphsize, element_state::normal);
|
||||
backimg.bground->draw(graph, invalid_clr_for_call, invalid_clr_for_call, rectangle{ graphsize }, element_state::normal);
|
||||
}
|
||||
|
||||
graph.setsta();
|
||||
@ -171,7 +171,7 @@ namespace nana
|
||||
else if (bground.gradual_from == bground.gradual_to)
|
||||
graph->rectangle(true, bground.gradual_from);
|
||||
else
|
||||
graph->gradual_rectangle(graph->size(), bground.gradual_from, bground.gradual_to, !bground.horizontal);
|
||||
graph->gradual_rectangle(::nana::rectangle{ graph->size() }, bground.gradual_from, bground.gradual_to, !bground.horizontal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ namespace nana
|
||||
|
||||
void trigger::_m_draw_box(graph_reference graph)
|
||||
{
|
||||
rectangle r = graph.size();
|
||||
rectangle r{ graph.size() };
|
||||
graph.gradual_rectangle(r, colors::button_face_shadow_end, colors::button_face_shadow_start, true);
|
||||
::nana::color lt{ colors::gray }, rb{colors::white};
|
||||
graph.frame_rectangle(r, lt, lt, rb, rb);
|
||||
|
||||
@ -132,7 +132,7 @@ namespace nana
|
||||
|
||||
_m_background(graph);
|
||||
|
||||
rectangle_rotator r(vertical_, graph.size());
|
||||
rectangle_rotator r(vertical_, ::nana::rectangle{ graph.size() });
|
||||
r.x_ref() = static_cast<int>(r.w() - fixedsize);
|
||||
r.w_ref() = fixedsize;
|
||||
|
||||
@ -159,7 +159,7 @@ namespace nana
|
||||
if (!metrics_.pressed || !_m_check())
|
||||
return;
|
||||
|
||||
nana::rectangle_rotator r(vertical_, graph.size());
|
||||
nana::rectangle_rotator r(vertical_, ::nana::rectangle{ graph.size() });
|
||||
if(metrics_.what == buttons::forward)
|
||||
{
|
||||
r.x_ref() = static_cast<int>(fixedsize);
|
||||
@ -253,7 +253,7 @@ namespace nana
|
||||
{
|
||||
if(_m_check())
|
||||
{
|
||||
rectangle_rotator r(vertical_, graph.size());
|
||||
rectangle_rotator r(vertical_, rectangle{ graph.size() });
|
||||
r.x_ref() = static_cast<int>(fixedsize + metrics_.scroll_pos);
|
||||
r.w_ref() = static_cast<unsigned>(metrics_.scroll_length);
|
||||
|
||||
|
||||
@ -1285,7 +1285,7 @@ namespace nana{ namespace widgets
|
||||
if (!API::widget_borderless(this->window_))
|
||||
{
|
||||
::nana::facade<element::border> facade;
|
||||
facade.draw(graph, bgcolor, API::fgcolor(this->window_), API::window_size(this->window_), API::element_state(this->window_));
|
||||
facade.draw(graph, bgcolor, API::fgcolor(this->window_), ::nana::rectangle{ API::window_size(this->window_) }, API::element_state(this->window_));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -2775,12 +2775,12 @@ namespace nana{ namespace widgets
|
||||
{
|
||||
//draw the whole text if it is a RTL text, because Arbic language is transformable.
|
||||
canvas.string({}, str, len);
|
||||
graph_.bitblt({ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas, ::nana::point{ ent_off, 0 });
|
||||
graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas, ::nana::point{ ent_off, 0 });
|
||||
}
|
||||
else
|
||||
{
|
||||
canvas.string({}, ent_begin, ent_end - ent_begin);
|
||||
graph_.bitblt({ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas);
|
||||
graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2830,7 +2830,7 @@ namespace nana{ namespace widgets
|
||||
if (selected)
|
||||
{
|
||||
graph_.set_text_color(scheme_->selection_text.get_color());
|
||||
graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true);
|
||||
graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true);
|
||||
graph_.string(text_pos, ent.begin, len);
|
||||
}
|
||||
else
|
||||
@ -2839,7 +2839,7 @@ namespace nana{ namespace widgets
|
||||
text_pos.x += static_cast<int>(str_w);
|
||||
}
|
||||
if (selected)
|
||||
graph_.rectangle({ text_pos, { whitespace_w, line_h_pixels } }, true);
|
||||
graph_.rectangle(::nana::rectangle{ text_pos, { whitespace_w, line_h_pixels } }, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2876,7 +2876,7 @@ namespace nana{ namespace widgets
|
||||
//selected all
|
||||
if (a.x <= pos && str_end <= b.x)
|
||||
{
|
||||
graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true);
|
||||
graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true);
|
||||
graph_.set_text_color(scheme_->selection_text.get_color());
|
||||
graph_.string(text_pos, ent.begin, len);
|
||||
}
|
||||
@ -2906,7 +2906,7 @@ namespace nana{ namespace widgets
|
||||
part_pos.x += static_cast<int>(head_w);
|
||||
|
||||
//Draw selected part
|
||||
graph_.rectangle({ part_pos, { sel_w, line_h_pixels } }, true);
|
||||
graph_.rectangle(::nana::rectangle{ part_pos, { sel_w, line_h_pixels } }, true);
|
||||
graph_.set_text_color(scheme_->selection_text.get_color());
|
||||
graph_.string(part_pos, ent.begin + (a.x - pos), endpos - a.x);
|
||||
|
||||
@ -2931,7 +2931,7 @@ namespace nana{ namespace widgets
|
||||
else
|
||||
{ //LTR
|
||||
//Draw selected part
|
||||
graph_.rectangle({ text_pos, { sel_w, line_h_pixels } }, true);
|
||||
graph_.rectangle(::nana::rectangle{ text_pos, { sel_w, line_h_pixels } }, true);
|
||||
graph_.set_text_color(scheme_->selection_text.get_color());
|
||||
graph_.string(text_pos, ent.begin, endpos - pos);
|
||||
|
||||
@ -2957,7 +2957,7 @@ namespace nana{ namespace widgets
|
||||
if (a.x < pos)
|
||||
{
|
||||
//Draw selected all
|
||||
graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true, { 0x33, 0x99, 0xFF });
|
||||
graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true, static_cast<color_rgb>(0x3399FF));
|
||||
graph_.set_text_color(scheme_->selection_text.get_color());
|
||||
graph_.string(text_pos, ent.begin, len);
|
||||
}
|
||||
@ -2978,7 +2978,7 @@ namespace nana{ namespace widgets
|
||||
::nana::point part_pos{ text_pos.x + static_cast<int>(head_w), text_pos.y };
|
||||
|
||||
//Draw selected part
|
||||
graph_.rectangle({ part_pos, {str_w - head_w, line_h_pixels } }, true);
|
||||
graph_.rectangle(::nana::rectangle{ part_pos, {str_w - head_w, line_h_pixels } }, true);
|
||||
graph_.set_text_color(scheme_->selection_text.get_color());
|
||||
graph_.string(part_pos, ent.begin + a.x - pos, len - (a.x - pos));
|
||||
}
|
||||
@ -2991,7 +2991,7 @@ namespace nana{ namespace widgets
|
||||
if (str_pos.y < b.y)
|
||||
{
|
||||
if (a.y < str_pos.y || ((a.y == str_pos.y) && (a.x <= str_pos.x )))
|
||||
graph_.rectangle({ text_pos, { whitespace_w, line_h_pixels } }, true);
|
||||
graph_.rectangle(::nana::rectangle{ text_pos, { whitespace_w, line_h_pixels } }, true);
|
||||
}
|
||||
}
|
||||
else if (b.y == str_pos.y)
|
||||
@ -3007,7 +3007,7 @@ namespace nana{ namespace widgets
|
||||
if (pos + len <= b.x)
|
||||
{
|
||||
//Draw selected part
|
||||
graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true);
|
||||
graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true);
|
||||
graph_.set_text_color(scheme_->selection_text.get_color());
|
||||
graph_.string(text_pos, ent.begin, len);
|
||||
}
|
||||
@ -3021,7 +3021,7 @@ namespace nana{ namespace widgets
|
||||
else
|
||||
{
|
||||
//draw selected part
|
||||
graph_.rectangle({ text_pos, { sel_w, line_h_pixels } }, true);
|
||||
graph_.rectangle(::nana::rectangle{ text_pos, { sel_w, line_h_pixels } }, true);
|
||||
graph_.set_text_color(scheme_->selection_text.get_color());
|
||||
graph_.string(text_pos, ent.begin, b.x - pos);
|
||||
|
||||
|
||||
@ -55,7 +55,7 @@ namespace nana
|
||||
|
||||
virtual void slider(window, graph_reference graph, const slider_t& s)
|
||||
{
|
||||
nana::rectangle r = graph.size();
|
||||
nana::rectangle r{ graph.size() };
|
||||
if(s.horizontal)
|
||||
{
|
||||
r.x = s.pos;
|
||||
@ -390,7 +390,7 @@ namespace nana
|
||||
nana::rectangle _m_bar_area() const
|
||||
{
|
||||
auto sz = other_.graph->size();
|
||||
nana::rectangle r = sz;
|
||||
nana::rectangle r{ sz };
|
||||
if(style::horizontal == attr_.dir)
|
||||
{
|
||||
r.x = attr_.slider_scale / 2 - attr_.border;
|
||||
|
||||
@ -947,7 +947,7 @@ namespace nana
|
||||
auto bgcolor = API::bgcolor(basis_.wd);
|
||||
auto fgcolor = API::fgcolor(basis_.wd);
|
||||
|
||||
item_renderer::item_t m = { basis_.graph->size() };
|
||||
item_renderer::item_t m{ ::nana::rectangle{ basis_.graph->size() } };
|
||||
|
||||
basis_.renderer->background(*basis_.graph, m.r, bgcolor);
|
||||
|
||||
@ -985,7 +985,7 @@ namespace nana
|
||||
}
|
||||
|
||||
if(false == item.img.empty())
|
||||
item.img.stretch(item.img.size(), *basis_.graph, nana::rectangle(m.r.x + 4, (m.r.height - 16) / 2, 16, 16));
|
||||
item.img.stretch(::nana::rectangle{ item.img.size() }, *basis_.graph, nana::rectangle(m.r.x + 4, (m.r.height - 16) / 2, 16, 16));
|
||||
|
||||
if(item.text.size())
|
||||
{
|
||||
|
||||
@ -174,11 +174,11 @@ namespace nana
|
||||
pos.x += static_cast<int>(scale + extra_size - size.width) / 2;
|
||||
pos.y += static_cast<int>(height - size.height) / 2;
|
||||
|
||||
item.image.paste(size, graph, pos);
|
||||
item.image.paste(::nana::rectangle{ size }, graph, pos);
|
||||
if(item.enable == false)
|
||||
{
|
||||
nana::paint::graphics gh(size);
|
||||
gh.bitblt(size, graph, pos);
|
||||
gh.bitblt(::nana::rectangle{ size }, graph, pos);
|
||||
gh.rgb_to_wb();
|
||||
gh.paste(graph, pos.x, pos.y);
|
||||
}
|
||||
@ -400,7 +400,7 @@ namespace nana
|
||||
|
||||
void drawer::_m_draw_background(const ::nana::color& clr)
|
||||
{
|
||||
graph_->gradual_rectangle(graph_->size(), clr.blend(colors::white, 0.9), clr.blend(colors::black, 0.95), true);
|
||||
graph_->gradual_rectangle(::nana::rectangle{ graph_->size() }, clr.blend(colors::white, 0.9), clr.blend(colors::black, 0.95), true);
|
||||
}
|
||||
|
||||
void drawer::_m_draw()
|
||||
|
||||
@ -1260,7 +1260,7 @@ namespace nana
|
||||
attr.area.x += (attr.area.width - fit_size.width) / 2;
|
||||
attr.area.y += (attr.area.height - fit_size.height) / 2;
|
||||
attr.area = fit_size;
|
||||
img->stretch(size, graph, attr.area);
|
||||
img->stretch(::nana::rectangle{ size }, graph, attr.area);
|
||||
}
|
||||
else
|
||||
img->paste(graph, attr.area.x + static_cast<int>(attr.area.width - size.width) / 2, attr.area.y + static_cast<int>(attr.area.height - size.height) / 2);
|
||||
|
||||
@ -173,6 +173,11 @@ namespace nana
|
||||
_m_move(x, y);
|
||||
}
|
||||
|
||||
void widget::move(const point& pos)
|
||||
{
|
||||
_m_move(pos.x, pos.y);
|
||||
}
|
||||
|
||||
void widget::move(const rectangle& r)
|
||||
{
|
||||
_m_move(r);
|
||||
|
||||
@ -98,13 +98,13 @@ namespace detail
|
||||
return bgcolor;
|
||||
}
|
||||
|
||||
void blend(drawable_type dw, const nana::rectangle& area, pixel_color_t color, double fade_rate)
|
||||
void blend(drawable_type dw, const rectangle& area, pixel_color_t color, double fade_rate)
|
||||
{
|
||||
if(fade_rate <= 0) return;
|
||||
if(fade_rate > 1) fade_rate = 1;
|
||||
|
||||
nana::rectangle r;
|
||||
if(false == nana::overlap(drawable_size(dw), area, r))
|
||||
rectangle r;
|
||||
if (false == ::nana::overlap(rectangle{ drawable_size(dw) }, area, r))
|
||||
return;
|
||||
|
||||
unsigned red = static_cast<unsigned>((color.value & 0xFF0000) * fade_rate);
|
||||
|
||||
@ -604,7 +604,7 @@ namespace paint
|
||||
if(dst.handle_ && handle_ && (dst.handle_ != handle_))
|
||||
{
|
||||
pixel_buffer s_pixbuf;
|
||||
s_pixbuf.attach(handle_, size());
|
||||
s_pixbuf.attach(handle_, ::nana::rectangle{ size() });
|
||||
|
||||
s_pixbuf.blend(s_r, dst.handle_, d_pos, fade_rate);
|
||||
|
||||
@ -1022,13 +1022,13 @@ namespace paint
|
||||
|
||||
void graphics::rectangle(bool solid)
|
||||
{
|
||||
rectangle(size(), solid);
|
||||
rectangle(::nana::rectangle{ size() }, solid);
|
||||
}
|
||||
|
||||
void graphics::rectangle(bool solid, const ::nana::color& clr)
|
||||
{
|
||||
set_color(clr);
|
||||
rectangle(size(), solid);
|
||||
rectangle(::nana::rectangle{ size() }, solid);
|
||||
}
|
||||
|
||||
void graphics::rectangle(const ::nana::rectangle& r, bool solid)
|
||||
|
||||
@ -263,7 +263,7 @@ namespace paint
|
||||
void image::paste(graphics& dst, int x, int y) const
|
||||
{
|
||||
if(image_ptr_)
|
||||
image_ptr_->paste(image_ptr_->size(), dst, x, y);
|
||||
image_ptr_->paste(::nana::rectangle{ image_ptr_->size() }, dst, x, y);
|
||||
}
|
||||
|
||||
void image::paste(const nana::rectangle& r_src, graphics & dst, const nana::point& p_dst) const
|
||||
|
||||
@ -22,10 +22,10 @@
|
||||
|
||||
namespace nana{ namespace paint
|
||||
{
|
||||
nana::rectangle valid_rectangle(const nana::size& s, const nana::rectangle& r)
|
||||
nana::rectangle valid_rectangle(const size& s, const rectangle& r)
|
||||
{
|
||||
nana::rectangle good_r;
|
||||
nana::overlap(s, r, good_r);
|
||||
nana::overlap(rectangle{ s }, r, good_r);
|
||||
return good_r;
|
||||
}
|
||||
|
||||
@ -384,13 +384,13 @@ namespace nana{ namespace paint
|
||||
close();
|
||||
}
|
||||
|
||||
void pixel_buffer::attach(drawable_type drawable, const nana::rectangle& want_r)
|
||||
void pixel_buffer::attach(drawable_type drawable, const ::nana::rectangle& want_r)
|
||||
{
|
||||
storage_.reset();
|
||||
if(drawable)
|
||||
{
|
||||
nana::rectangle r;
|
||||
if(nana::overlap(nana::paint::detail::drawable_size(drawable), want_r, r))
|
||||
if (::nana::overlap(::nana::rectangle{ nana::paint::detail::drawable_size(drawable) }, want_r, r))
|
||||
storage_ = std::make_shared<pixel_buffer_storage>(drawable, r);
|
||||
}
|
||||
}
|
||||
@ -429,16 +429,16 @@ namespace nana{ namespace paint
|
||||
|
||||
bool pixel_buffer::open(drawable_type drawable, const nana::rectangle & want_rectangle)
|
||||
{
|
||||
nana::size sz = nana::paint::detail::drawable_size(drawable);
|
||||
auto sz = nana::paint::detail::drawable_size(drawable);
|
||||
if(want_rectangle.x >= static_cast<int>(sz.width) || want_rectangle.y >= static_cast<int>(sz.height))
|
||||
return false;
|
||||
|
||||
nana::rectangle want_r = want_rectangle;
|
||||
auto want_r = want_rectangle;
|
||||
if(want_r.width == 0) want_r.width = sz.width - want_r.x;
|
||||
if(want_r.height == 0) want_r.height = sz.height - want_r.y;
|
||||
|
||||
nana::rectangle r;
|
||||
if(false == overlap(sz, want_r, r))
|
||||
::nana::rectangle r;
|
||||
if (false == overlap(::nana::rectangle{ sz }, want_r, r))
|
||||
return false;
|
||||
#if defined(NANA_WINDOWS)
|
||||
BITMAPINFO bmpinfo;
|
||||
@ -1039,13 +1039,13 @@ namespace nana{ namespace paint
|
||||
}
|
||||
}
|
||||
|
||||
void pixel_buffer::blur(const nana::rectangle& r, std::size_t radius)
|
||||
void pixel_buffer::blur(const ::nana::rectangle& r, std::size_t radius)
|
||||
{
|
||||
auto sp = storage_.get();
|
||||
if(nullptr == sp || radius < 1) return;
|
||||
|
||||
nana::rectangle good_r;
|
||||
if(overlap(r, this->size(), good_r))
|
||||
::nana::rectangle good_r;
|
||||
if (overlap(r, ::nana::rectangle{ this->size() }, good_r))
|
||||
(*(sp->img_pro.blur))->process(*this, good_r, radius);
|
||||
}
|
||||
}//end namespace paint
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user