construct the inline widget for listbox

This commit is contained in:
Jinhao
2015-06-14 21:48:35 +08:00
parent 36b3e6e6cc
commit 1822fafd79
15 changed files with 472 additions and 179 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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.

View File

@@ -0,0 +1,52 @@
/**
* 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:
using index_type = Index;
using value_type = Value;
virtual ~inline_widget_indicator() = default;
private:
virtual void modify(index_type, const value_type&) const = 0;
};
template<typename Index, typename Value>
class inline_widget_interface
{
public:
using index_type = Index;
using value_type = Value;
using inline_indicator = inline_widget_indicator<index_type, value_type>;
using factory_interface = inline_widget_interface;
virtual ~inline_widget_interface() = default;
virtual void create(window) = 0;
virtual void activate(inline_indicator&, index_type) = 0;
virtual void resize(const size&) = 0;
virtual void set(const value_type&) = 0;
};
}
}
#endif

View 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

View File

@@ -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_interface = detail::inline_widget_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_interface = drawerbase::listbox::inline_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_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_interface = drawerbase::listbox::inline_interface;
public:
listbox() = default;
listbox(window, bool visible);

View File

@@ -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

View File

@@ -0,0 +1,52 @@
/*
* 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
{
template<typename Interface>
class abstract_factory
{
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