Merge branch 'feature-listbox' into develop

This commit is contained in:
Jinhao 2017-01-13 07:21:00 +08:00
commit dccd6d4fdd
5 changed files with 6060 additions and 5830 deletions

View File

@ -457,8 +457,8 @@ namespace nana
rectangle& pare_off(int pixels); ///<Pares the specified pixels off the rectangle. It's equal to x += pixels; y + pixels; width -= (pixels << 1); height -= (pixels << 1); rectangle& pare_off(int pixels); ///<Pares the specified pixels off the rectangle. It's equal to x += pixels; y + pixels; width -= (pixels << 1); height -= (pixels << 1);
int right() const; int right() const noexcept;
int bottom() const; int bottom() const noexcept;
bool is_hit(int x, int y) const; bool is_hit(int x, int y) const;
bool is_hit(const point& pos) const; bool is_hit(const point& pos) const;
bool empty() const; ///< true if width * height == 0. bool empty() const; ///< true if width * height == 0.

View File

@ -1,14 +1,20 @@
/** /**
* A List Box Implementation * A List Box Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) * http://www.boost.org/LICENSE_1_0.txt)
* *
* @file: nana/gui/widgets/listbox.hpp * @file: nana/gui/widgets/listbox.hpp
* * @contributors:
* Hiroshi Seki
* Ariel Vina-Rodriguez
* leobackes(pr#86,pr#97)
* Benjamin Navarro(pr#81)
* besh81(pr#130)
* dankan1890(pr#158)
*/ */
#ifndef NANA_GUI_WIDGETS_LISTBOX_HPP #ifndef NANA_GUI_WIDGETS_LISTBOX_HPP
@ -106,7 +112,7 @@ namespace nana
struct intern struct intern
{ {
public: public:
virtual ~intern() = default; virtual ~intern() noexcept = default;
}; };
template<typename T> template<typename T>
@ -115,7 +121,7 @@ namespace nana
{ {
const T * ptr; const T * ptr;
real_pointer(const T* p) real_pointer(const T* p) noexcept
: ptr(p) : ptr(p)
{} {}
}; };
@ -132,13 +138,13 @@ namespace nana
{ {
} }
~const_virtual_pointer() ~const_virtual_pointer() noexcept
{ {
delete intern_; delete intern_;
} }
template<typename Type> template<typename Type>
const typename std::remove_const<Type>::type *get() const const typename std::remove_const<Type>::type *get() const noexcept
{ {
using value_type = typename std::remove_const<Type>::type; using value_type = typename std::remove_const<Type>::type;
auto target = dynamic_cast<real_pointer<value_type>*>(intern_); auto target = dynamic_cast<real_pointer<value_type>*>(intern_);
@ -155,8 +161,8 @@ namespace nana
::nana::color bgcolor; ::nana::color bgcolor;
::nana::color fgcolor; ::nana::color fgcolor;
format() = default; format() noexcept = default;
format(const ::nana::color& bgcolor, const ::nana::color& fgcolor); format(const ::nana::color& bgcolor, const ::nana::color& fgcolor) noexcept;
}; };
using format_ptr = ::std::unique_ptr<format>; using format_ptr = ::std::unique_ptr<format>;
@ -164,15 +170,14 @@ namespace nana
::std::string text; ::std::string text;
format_ptr custom_format; format_ptr custom_format;
cell() = default; cell() noexcept = default;
cell(const cell&); cell(const cell&);
cell(cell&&); cell(cell&&) noexcept;
cell(::std::string); cell(::std::string) noexcept;
cell(::std::string, const format&); cell(::std::string, const format&);
cell(::std::string, const ::nana::color& bgcolor, const ::nana::color& fgcolor);
cell& operator=(const cell&); cell& operator=(const cell&);
cell& operator=(cell&&); cell& operator=(cell&&) noexcept;
}; };
class container_interface class container_interface
@ -181,7 +186,7 @@ namespace nana
public: public:
virtual ~container_interface() = default; virtual ~container_interface() = default;
virtual void clear() = 0; virtual void clear() noexcept = 0;
virtual void erase(std::size_t pos) = 0; virtual void erase(std::size_t pos) = 0;
virtual std::size_t size() const = 0; virtual std::size_t size() const = 0;
@ -233,7 +238,7 @@ namespace nana
translator_({ vtrans, ctrans }) translator_({ vtrans, ctrans })
{} {}
private: private:
void clear() override void clear() noexcept override
{ {
container_.clear(); container_.clear();
} }
@ -322,7 +327,7 @@ namespace nana
} }
private: private:
void clear() override void clear() noexcept override
{ {
container_.clear(); container_.clear();
} }
@ -476,8 +481,8 @@ namespace nana
virtual void lock() = 0; virtual void lock() = 0;
virtual void unlock() = 0; virtual void unlock() = 0;
virtual container_interface* container() = 0; virtual container_interface* container() noexcept = 0;
virtual const container_interface* container() const = 0; virtual const container_interface* container() const noexcept = 0;
}; };
class model_guard class model_guard
@ -582,12 +587,12 @@ namespace nana
mutex_.unlock(); mutex_.unlock();
} }
container_interface* container() override container_interface* container() noexcept override
{ {
return &container_; return &container_;
} }
const container_interface* container() const override const container_interface* container() const noexcept override
{ {
return &container_; return &container_;
} }
@ -624,12 +629,12 @@ namespace nana
mutex_.unlock(); mutex_.unlock();
} }
container_interface* container() override container_interface* container() noexcept override
{ {
return container_ptr_.get(); return container_ptr_.get();
} }
const container_interface* container() const override const container_interface* container() const noexcept override
{ {
return container_ptr_.get(); return container_ptr_.get();
} }
@ -642,47 +647,48 @@ namespace nana
/// usefull for both absolute and display (sorted) positions /// usefull for both absolute and display (sorted) positions
struct index_pair struct index_pair
{ {
constexpr static size_type npos = ::nana::npos;
size_type cat; //The pos of category size_type cat; //The pos of category
size_type item; //the pos of item in a category. size_type item; //the pos of item in a category.
explicit index_pair(size_type cat_pos = 0, size_type item_pos = 0) explicit index_pair(size_type cat_pos = 0, size_type item_pos = 0) noexcept
: cat(cat_pos), : cat(cat_pos), item(item_pos)
item(item_pos)
{} {}
bool empty() const bool empty() const noexcept
{ {
return (npos == cat); return (npos == cat);
} }
void set_both(size_type n) void set_both(size_type n) noexcept
{ {
cat = item = n; cat = item = n;
} }
bool is_category() const bool is_category() const noexcept
{ {
return (npos != cat && npos == item); return (npos != cat && npos == item);
} }
bool is_item() const bool operator==(const index_pair& r) const noexcept
{
return (npos != cat && npos != item);
}
bool operator==(const index_pair& r) const
{ {
return (r.cat == cat && r.item == item); return (r.cat == cat && r.item == item);
} }
bool operator!=(const index_pair& r) const bool operator!=(const index_pair& r) const noexcept
{ {
return !this->operator==(r); return !this->operator==(r);
} }
bool operator>(const index_pair& r) const bool operator<(const index_pair& r) const noexcept
{ {
return (cat > r.cat) || (cat == r.cat && item > r.item); return (cat < r.cat) || ((cat == r.cat) && (r.item != npos) && ((item == npos) || (item < r.item)));
}
bool operator>(const index_pair& r) const noexcept
{
return (cat > r.cat) || ((cat == r.cat) && (item != npos) && ((r.item == npos) || (item > r.item)));
} }
}; };
@ -705,7 +711,7 @@ namespace nana
class oresolver class oresolver
{ {
public: public:
oresolver(essence*); oresolver(essence*) noexcept;
oresolver& operator<<(bool); oresolver& operator<<(bool);
oresolver& operator<<(short); oresolver& operator<<(short);
oresolver& operator<<(unsigned short); oresolver& operator<<(unsigned short);
@ -727,9 +733,9 @@ namespace nana
oresolver& operator<<(cell); oresolver& operator<<(cell);
oresolver& operator<<(std::nullptr_t); oresolver& operator<<(std::nullptr_t);
std::vector<cell> && move_cells(); std::vector<cell> && move_cells() noexcept;
::nana::listbox& listbox(); ::nana::listbox& listbox() noexcept;
private: private:
essence* const ess_; essence* const ess_;
std::vector<cell> cells_; std::vector<cell> cells_;
@ -738,7 +744,7 @@ namespace nana
class iresolver class iresolver
{ {
public: public:
iresolver(std::vector<cell>); iresolver(std::vector<cell>) noexcept;
iresolver& operator>>(bool&); iresolver& operator>>(bool&);
iresolver& operator>>(short&); iresolver& operator>>(short&);
@ -756,7 +762,7 @@ namespace nana
iresolver& operator>>(std::string& text_utf8); iresolver& operator>>(std::string& text_utf8);
iresolver& operator>>(std::wstring&); iresolver& operator>>(std::wstring&);
iresolver& operator>>(cell&); iresolver& operator>>(cell&);
iresolver& operator>>(std::nullptr_t); iresolver& operator>>(std::nullptr_t) noexcept;
private: private:
std::vector<cell> cells_; std::vector<cell> cells_;
std::size_t pos_{0}; std::size_t pos_{0};
@ -773,7 +779,7 @@ namespace nana
public: public:
trigger(); trigger();
~trigger(); ~trigger();
essence& ess() const; essence& ess() const noexcept;
private: private:
void attached(widget_reference, graph_reference) override; void attached(widget_reference, graph_reference) override;
void detached() override; void detached() override;
@ -783,7 +789,6 @@ namespace nana
void mouse_leave(graph_reference, const arg_mouse&) override; void mouse_leave(graph_reference, const arg_mouse&) override;
void mouse_down(graph_reference, const arg_mouse&) override; void mouse_down(graph_reference, const arg_mouse&) override;
void mouse_up(graph_reference, const arg_mouse&) override; void mouse_up(graph_reference, const arg_mouse&) override;
void mouse_wheel(graph_reference, const arg_wheel&) override;
void dbl_click(graph_reference, const arg_mouse&) override; void dbl_click(graph_reference, const arg_mouse&) override;
void resized(graph_reference, const arg_resized&) override; void resized(graph_reference, const arg_resized&) override;
void key_press(graph_reference, const arg_keyboard&) override; void key_press(graph_reference, const arg_keyboard&) override;
@ -800,8 +805,7 @@ namespace nana
: public std::iterator<std::input_iterator_tag, item_proxy> : public std::iterator<std::input_iterator_tag, item_proxy>
{ {
public: public:
item_proxy(essence*); item_proxy(essence*, const index_pair& = index_pair{});
item_proxy(essence*, const index_pair&);
/// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort() /// the main porpose of this it to make obvious that item_proxy operate with absolute positions, and dont get moved during sort()
static item_proxy from_display(essence *, const index_pair &relative) ; static item_proxy from_display(essence *, const index_pair &relative) ;
@ -813,7 +817,7 @@ namespace nana
/// Determines whether the item is displayed on the screen /// Determines whether the item is displayed on the screen
bool displayed() const; bool displayed() const;
bool empty() const; bool empty() const noexcept;
/// Checks/unchecks the item /// Checks/unchecks the item
/** /**
@ -843,9 +847,9 @@ namespace nana
item_proxy& fgcolor(const nana::color&); item_proxy& fgcolor(const nana::color&);
nana::color fgcolor() const; nana::color fgcolor() const;
index_pair pos() const; index_pair pos() const noexcept;
size_type columns() const; size_type columns() const noexcept;
/// Converts a position of column between display position and absolute position /// Converts a position of column between display position and absolute position
/** /**
@ -959,7 +963,7 @@ namespace nana
bool operator!=(const item_proxy&) const; bool operator!=(const item_proxy&) const;
//Undocumented method //Undocumented method
essence * _m_ess() const; essence * _m_ess() const noexcept;
private: private:
std::vector<cell> _m_cells() const; std::vector<cell> _m_cells() const;
nana::any * _m_value(bool alloc_if_empty); nana::any * _m_value(bool alloc_if_empty);
@ -979,9 +983,9 @@ namespace nana
template<typename Value> using value_translator = typename container_translator<Value>::value_translator; template<typename Value> using value_translator = typename container_translator<Value>::value_translator;
template<typename Value> using cell_translator = typename container_translator<Value>::cell_translator; template<typename Value> using cell_translator = typename container_translator<Value>::cell_translator;
cat_proxy() = default; cat_proxy() noexcept = default;
cat_proxy(essence*, size_type pos); cat_proxy(essence*, size_type pos) noexcept;
cat_proxy(essence*, category_t*); cat_proxy(essence*, category_t*) noexcept;
/// Append an item at abs end of the category, set_value determines whether assign T object to the value of item. /// Append an item at abs end of the category, set_value determines whether assign T object to the value of item.
template<typename T> template<typename T>
@ -1059,12 +1063,14 @@ namespace nana
item_proxy at(size_type pos_abs) const; item_proxy at(size_type pos_abs) const;
item_proxy back() const; item_proxy back() const;
/// Returns the absolute index of a item by its display pos, the index of the item isn't changed after sorting. /// Converts the index between absolute position and display position
/// convert from display order to absolute (find the real item in that display pos) but without check from current active sorting, in fact using just the last sorting !!! /**
size_type index_by_display_order(size_type disp_order) const; * @param from The index to be converted
* @param from_display_order If this parameter is true, the method converts a display position to an absolute position.
/// find display order for the real item but without check from current active sorting, in fact using just the last sorting !!! * If the parameter is false, the method converts an absolute position to a display position.
size_type display_order(size_type pos) const; * @return a display position or an absolute position that are depending on from_display_order.
*/
size_type index_cast(size_type from, bool from_display_order) const;
/// this cat position /// this cat position
size_type position() const; size_type position() const;
@ -1103,8 +1109,8 @@ namespace nana
private: private:
void _m_append(std::vector<cell> && cells); void _m_append(std::vector<cell> && cells);
void _m_try_append_model(const const_virtual_pointer&); void _m_try_append_model(const const_virtual_pointer&);
void _m_cat_by_pos(); void _m_cat_by_pos() noexcept;
void _m_update(); void _m_update() noexcept;
void _m_reset_model(model_interface*); void _m_reset_model(model_interface*);
private: private:
essence* ess_{nullptr}; essence* ess_{nullptr};
@ -1181,9 +1187,7 @@ namespace nana
unsigned suspension_width { 8 }; ///< def= . the trigger will set this to the width if ("...") unsigned suspension_width { 8 }; ///< def= . the trigger will set this to the width if ("...")
unsigned text_margin { 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1 unsigned text_margin { 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1
unsigned header_height { 25 }; ///< def=25 . header height header_size unsigned header_height { 25 }; ///< def=25 . header height header_size
unsigned text_height { 14 }; ///< the trigger will set this to the height of the text font
unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex
unsigned item_height { 24 }; ///< def=24 . the trigger will set this TO item_height = text_height + item_height_ex
unsigned header_splitter_area_before{ 2 }; ///< def=2. But 4 is better... IMO unsigned header_splitter_area_before{ 2 }; ///< def=2. But 4 is better... IMO
unsigned header_splitter_area_after { 3 }; ///< def=3. But 4 is better... unsigned header_splitter_area_after { 3 }; ///< def=3. But 4 is better...
@ -1363,7 +1367,7 @@ the nana::detail::basic_window member pointer scheme
bool assoc_ordered(bool); bool assoc_ordered(bool);
void auto_draw(bool); ///< Set state: Redraw automatically after an operation void auto_draw(bool) noexcept; ///< Set state: Redraw automatically after an operation
template<typename Function> template<typename Function>
void avoid_drawing(Function fn) void avoid_drawing(Function fn)
@ -1410,10 +1414,10 @@ the nana::detail::basic_window member pointer scheme
/// Returns the number of columns /// Returns the number of columns
size_type column_size() const; size_type column_size() const;
cat_proxy append(std::string); ///< Appends a new category to the end cat_proxy append(std::string category); ///< Appends a new category to the end
cat_proxy append(std::wstring); ///< Appends a new category to the end cat_proxy append(std::wstring category); ///< Appends a new category to the end
void append(std::initializer_list<std::string>); ///< Appends categories to the end void append(std::initializer_list<std::string> categories); ///< Appends categories to the end
void append(std::initializer_list<std::wstring>); ///< Appends categories to the end void append(std::initializer_list<std::wstring> categories); ///< Appends categories to the end
cat_proxy insert(cat_proxy, ::std::string); cat_proxy insert(cat_proxy, ::std::string);
cat_proxy insert(cat_proxy, ::std::wstring); cat_proxy insert(cat_proxy, ::std::wstring);
@ -1433,18 +1437,19 @@ the nana::detail::basic_window member pointer scheme
void insert_item(const index_pair& abs_pos, const ::std::wstring& text); void insert_item(const index_pair& abs_pos, const ::std::wstring& text);
/// Returns an index of item which contains the specified point. /// Returns an index of item which contains the specified point.
index_pair cast(const point & pos) const; index_pair cast(const point & screen_pos) const;
/// Returns the absolute position of column which contains the specified point. /// Returns the absolute position of column which contains the specified point.
size_type column_from_pos(const point & pos); size_type column_from_pos(const point & pos) const;
void checkable(bool); void checkable(bool);
index_pairs checked() const; ///<Returns the items which are checked. index_pairs checked() const; ///<Returns the items which are checked.
void clear(size_type cat); ///<Removes all the items from the specified category void clear(size_type cat); ///<Removes all the items from the specified category
void clear(); ///<Removes all the items from all categories void clear(); ///<Removes all the items from all categories
void erase(size_type cat); ///<Erases a category void erase(size_type cat); ///<Erases a category
void erase(); ///<Erases all categories. void erase(); ///<Erases all categories.
void erase(index_pairs indexes); ///<Erases specified items.
item_proxy erase(item_proxy); item_proxy erase(item_proxy);
bool sortable() const; bool sortable() const;
@ -1478,7 +1483,7 @@ the nana::detail::basic_window member pointer scheme
drawerbase::listbox::essence & _m_ess() const; drawerbase::listbox::essence & _m_ess() const;
nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const override; nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const override;
drawerbase::listbox::category_t* _m_assoc(std::shared_ptr<nana::detail::key_interface>, bool create_if_not_exists); drawerbase::listbox::category_t* _m_assoc(std::shared_ptr<nana::detail::key_interface>, bool create_if_not_exists);
void _m_erase_key(nana::detail::key_interface*); void _m_erase_key(nana::detail::key_interface*) noexcept;
}; };
}//end namespace nana }//end namespace nana

View File

@ -21,12 +21,12 @@ namespace nana
public: public:
virtual ~key_interface(){} virtual ~key_interface(){}
virtual bool same_type(const key_interface*) const = 0; virtual bool same_type(const key_interface*) const noexcept = 0;
virtual bool compare(const key_interface*) const = 0; ///< is this key less than right key? [call it less(rk), less_than(rk) or compare_less(rk)?: if (lk.less_than(rk )) ] virtual bool compare(const key_interface*) const noexcept = 0; ///< is this key less than right key? [call it less(rk), less_than(rk) or compare_less(rk)?: if (lk.less_than(rk )) ]
}; //end class key_interface }; //end class key_interface
//Use less compare for equal compare [call it equal_by_less()?] //Use less compare for equal compare [call it equal_by_less()?]
inline bool pred_equal(const key_interface * left, const key_interface* right) inline bool pred_equal(const key_interface * left, const key_interface* right) noexcept
{ {
return (left->same_type(right) && (left->compare(right) == false) && (right->compare(left) == false)); return (left->same_type(right) && (left->compare(right) == false) && (right->compare(left) == false));
} }
@ -104,12 +104,12 @@ namespace nana
} }
public: public:
//implement key_interface methods //implement key_interface methods
bool same_type(const key_interface * p) const override bool same_type(const key_interface * p) const noexcept override
{ {
return (nullptr != dynamic_cast<const key*>(p)); return (nullptr != dynamic_cast<const key*>(p));
} }
bool compare(const key_interface* p) const override bool compare(const key_interface* p) const noexcept override
{ {
auto rhs = dynamic_cast<const key*>(p); auto rhs = dynamic_cast<const key*>(p);
return rhs && compare_(key_object_, rhs->key_object_); return rhs && compare_(key_object_, rhs->key_object_);

View File

@ -649,12 +649,12 @@ namespace nana
return *this; return *this;
} }
int rectangle::right() const int rectangle::right() const noexcept
{ {
return x + static_cast<int>(width); return x + static_cast<int>(width);
} }
int rectangle::bottom() const int rectangle::bottom() const noexcept
{ {
return y + static_cast<int>(height); return y + static_cast<int>(height);
} }

File diff suppressed because it is too large Load Diff