add fit-content and improve place

This commit is contained in:
Jinhao
2017-02-05 08:37:16 +08:00
parent 2fd3aa5030
commit 2bd1cf715f
10 changed files with 1228 additions and 118 deletions

View File

@@ -17,6 +17,7 @@
#include "drawer.hpp"
#include "events_holder.hpp"
#include "widget_geometrics.hpp"
#include "widget_content_measurer_interface.hpp"
#include "widget_notifier_interface.hpp"
#include <nana/basic_types.hpp>
#include <nana/system/platform.hpp>
@@ -191,6 +192,7 @@ namespace detail
//The following pointers refer to the widget's object.
std::shared_ptr<general_events> events_ptr;
widget_geometrics* scheme{ nullptr };
::nana::dev::widget_content_measurer_interface* content_measurer{ nullptr };
}annex;
struct

View File

@@ -0,0 +1,40 @@
/*
* Widget Content Measurer Interface
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/detail/widget_content_measurer_interface.hpp
*/
#ifndef NANA_WIDGET_CONTENT_MEASURER_INTERFACE_HEADER_INCLUDED
#define NANA_WIDGET_CONTENT_MEASURER_INTERFACE_HEADER_INCLUDED
#include <nana/basic_types.hpp>
#include <nana/optional.hpp>
namespace nana
{
namespace dev
{
/// An interface for measuring content of the widget
class widget_content_measurer_interface
{
public:
virtual ~widget_content_measurer_interface() = default;
/// Measures content
/**
* @param limit_width true if limits the width, false if limits the height.
* @param limit_pixels the number of pixels of the limited edge. If this parameter is zero, it is ignored
* @return the size of content
*/
virtual optional<size> measure(bool limit_width, unsigned limit_pixels) const = 0;
};
}
}
#endif

View File

@@ -16,6 +16,7 @@
#include "effects.hpp"
#include "detail/general_events.hpp"
#include "detail/color_schemes.hpp"
#include "detail/widget_content_measurer_interface.hpp"
#include <nana/paint/image.hpp>
#include <memory>
@@ -73,6 +74,9 @@ namespace API
void set_scheme(window, widget_geometrics*);
widget_geometrics* get_scheme(window);
/// Sets a content measurer
void set_measurer(window, ::nana::dev::widget_content_measurer_interface*);
void attach_drawer(widget&, drawer_trigger&);
::nana::detail::native_string_type window_caption(window) throw();
void window_caption(window, ::nana::detail::native_string_type);

View File

@@ -31,11 +31,11 @@ namespace nana
class trigger: public drawer_trigger
{
public:
struct impl_t;
struct implement;
trigger();
~trigger();
impl_t * impl() const;
implement * impl() const;
private:
void attached(widget_reference, graph_reference) override;
void refresh(graph_reference) override;
@@ -43,7 +43,7 @@ namespace nana
void mouse_leave(graph_reference, const arg_mouse&) override;
void click(graph_reference, const arg_click&) override;
private:
impl_t * impl_;
implement * impl_;
};
}//end namespace label

364
include/nana/optional.hpp Normal file
View File

@@ -0,0 +1,364 @@
/**
* Optional
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2017 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/optional.hpp
*
* @brief An implementation of experimental library optional of C++ standard(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3793.html)
*/
#ifndef NANA_STD_OPTIONAL_HEADER_INCLUDED
#define NANA_STD_OPTIONAL_HEADER_INCLUDED
#include <stdexcept>
#include <nana/c++defines.hpp>
namespace nana
{
namespace detail
{
template<typename T>
class storage
{
public:
using value_type = T;
storage() = default;
template<typename U>
storage(U&& value)
: initialized_{ true }
{
::new (data_) value_type(std::forward<U>(value));
}
template<typename U>
storage(const U& value)
: initialized_{ true }
{
::new (data_) value_type(value);
}
storage(const storage& other)
: initialized_{ other.initialized_ }
{
if (other.initialized_)
::new (data_) value_type(*other.ptr());
}
storage(storage&& other)
: initialized_{ other.initialized_ }
{
if (other.initialized_)
::new (data_) value_type(std::move(*other.ptr()));
}
template<typename U>
storage(const storage<U>& other)
: initialized_{ other.initialized_ }
{
if (other.initialized_)
::new (data_) value_type(*other.ptr());
}
~storage()
{
destroy();
}
bool initialized() const noexcept
{
return initialized_;
}
void set_initialized()
{
initialized_ = true;
}
void destroy()
{
if (initialized_)
{
ptr()->~T();
initialized_ = false;
}
}
template<typename U>
void assign(U&& value)
{
if (initialized_)
*ptr() = std::forward<U>(value);
else
{
::new (data) value_type(std::forward<U>(value));
initialized_ = true;
}
}
void assign(const storage& other)
{
if (!other.initialized_)
{
destroy();
return;
}
if (initialized_)
*ptr = *other.ptr();
else
{
::new (data) value_type(*other.ptr());
initialized_ = true;
}
}
void assign(storage&& other)
{
if (!other.initialized_)
{
destroy();
return;
}
if (initialized_)
*ptr() = std::move(*other.ptr());
else
{
::new (data) value_type(std::move(*other.ptr()));
initialized_ = true;
}
}
const T* ptr() const
{
return reinterpret_cast<const T*>(data_);
}
T* ptr()
{
return reinterpret_cast<T*>(data_);
}
private:
bool initialized_{ false };
char data_[sizeof(value_type)];
};
}//end namespace detail
class bad_optional_access
: public std::logic_error
{
public:
bad_optional_access()
: std::logic_error("Attempted to access the value of an uninitialized optional object.")
{}
};
template<typename T>
class optional
{
public:
using value_type = T;
constexpr optional() = default;
constexpr optional(std::nullptr_t) {}
optional(const optional& other)
: storage_(other.storage_)
{}
optional(optional&& other)
: storage_(std::move(other.storage_))
{}
constexpr optional(const value_type& value)
: storage_(value)
{}
constexpr optional(value_type&& value)
: storage_(std::move(value))
{}
optional& operator=(std::nullptr_t)
{
storage_.destroy();
return *this;
}
optional& operator=(const optional& other)
{
if (this != &other)
{
storage_.assign(other.storage_);
}
return *this;
}
optional& operator=(optional&& other)
{
if (this != &other)
{
storage_.assign(std::move(other.storage_))
}
return *this;l
}
template<typename U>
optional& operator=(U&& value)
{
storage_.assign(std::forward<U>(value));
return *this;
}
//Value access
//constexpr
value_type* operator->()
{
return storage_.ptr();
}
constexpr const value_type* operator->() const
{
return storage_.ptr();
}
//constexpr
value_type& operator*()
{
return *storage_.ptr();
}
constexpr const value_type& operator*() const
{
return *storage_.ptr();
}
/*
//constexpr
value_type&& operator*() &&
{
return std::move(*storage_.ptr());
}
//constexpr
const value_type&& operator*() const &&
{
return std::move(*storage_.ptr());
}
*/
//Condition
constexpr explicit operator bool() const
{
return storage_.initialized();
}
constexpr bool has_value() const
{
return storage_.initialized();
}
//constexpr
value_type& value()
{
if (!storage_.initialized())
throw bad_optional_access{};
return *storage_.ptr();
}
constexpr const value_type& value() const
{
if (!storage_.initialized())
throw bad_optional_access{};
return *storage_.ptr();
}
/*
//constexpr
value_type&& value()
{
if (!storage_.initialized())
throw bad_optional_access{};
return std::move(*storage_.ptr());
}
constexpr const value_type&& value() const
{
if (!storage_.initialized())
throw bad_optional_access{};
return std::move(*storage_.ptr());
}
*/
template<typename U>
constexpr T value_or(U&& default_value) const
{
return (has_value() ? **this : static_cast<T>(std::forward<U>(default_value)));
}
template<typename U>
//constexpr
T value_or(U&& default_value)
{
return (has_value() ? std::move(**this) : static_cast<T>(std::forward<U>(default_value)));
}
//Modifiers
void swap(optional& other)
{
if (has_value() && other.has_value())
{
std::swap(**this, *other);
return;
}
else if (has_value())
{
other.emplace(std::move(***this));
storage_.destroy();
}
else if (other.has_value())
{
this->emplace(std::move(*other));
other.storage_.destroy();
}
}
void reset()
{
storage_.destroy();
}
template<typename... Args>
void emplace(Args&&... args)
{
storage_.destroy();
::new (storage_.ptr()) T(std::forward<Args>(args)...);
storage_.set_initialized();
}
template<typename U, typename... Args>
void emplace(std::initializer_list<U> il, Args&& ... args)
{
storage_.destroy();
::new (storage_.ptr()) T(il, std::forward<Args>(args)...);
storage_.set_initialized();
}
private:
detail::storage<T> storage_;
};
}
#endif

155
include/nana/stdc++.hpp Normal file
View File

@@ -0,0 +1,155 @@
/**
* Standard Library for C++11/14/17
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2017 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/stdc++.hpp
*
* @brief Implement the lack support of standard library.
*/
#include "c++defines.hpp"
//Implement workarounds for GCC/MinGW which version is below 4.8.2
#if defined(STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED)
namespace std
{
//Workaround for no implemenation of std::stoi in MinGW.
int stoi(const std::string&, std::size_t * pos = nullptr, int base = 10);
int stoi(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
//Workaround for no implemenation of std::stof in MinGW.
float stof(const std::string&, std::size_t * pos = nullptr);
float stof(const std::wstring&, std::size_t* pos = nullptr);
//Workaround for no implemenation of std::stod in MinGW.
double stod(const std::string&, std::size_t * pos = nullptr);
double stod(const std::wstring&, std::size_t* pos = nullptr);
//Workaround for no implemenation of std::stold in MinGW.
long double stold(const std::string&, std::size_t * pos = nullptr);
long double stold(const std::wstring&, std::size_t* pos = nullptr);
//Workaround for no implemenation of std::stol in MinGW.
long stol(const std::string&, std::size_t* pos = nullptr, int base = 10);
long stol(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
//Workaround for no implemenation of std::stoll in MinGW.
long long stoll(const std::string&, std::size_t* pos = nullptr, int base = 10);
long long stoll(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
//Workaround for no implemenation of std::stoul in MinGW.
unsigned long stoul(const std::string&, std::size_t* pos = nullptr, int base = 10);
unsigned long stoul(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
//Workaround for no implemenation of std::stoull in MinGW.
unsigned long long stoull(const std::string&, std::size_t* pos = nullptr, int base = 10);
unsigned long long stoull(const std::wstring&, std::size_t* pos = nullptr, int base = 10);
}
#endif //STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED
#ifdef STD_TO_STRING_NOT_SUPPORTED
namespace std
{
//Workaround for no implemenation of std::to_string/std::to_wstring in MinGW.
std::string to_string(long double);
std::string to_string(double);
std::string to_string(unsigned);
std::string to_string(int);
std::string to_string(long);
std::string to_string(unsigned long);
std::string to_string(long long);
std::string to_string(unsigned long long);
std::string to_string(float);
}
#endif
#ifdef STD_TO_WSTRING_NOT_SUPPORTED
namespace std
{
std::wstring to_wstring(long double);
std::wstring to_wstring(double);
std::wstring to_wstring(unsigned);
std::wstring to_wstring(int);
std::wstring to_wstring(long);
std::wstring to_wstring(unsigned long);
std::wstring to_wstring(long long);
std::wstring to_wstring(unsigned long long);
std::wstring to_wstring(float);
}
#endif
#ifdef _enable_std_make_unique
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm
#include <cstddef>
#include <memory>
#include <type_traits>
#include <utility>
namespace std {
template<class T> struct _Unique_if {
typedef unique_ptr<T> _Single_object;
};
template<class T> struct _Unique_if<T[]> {
typedef unique_ptr<T[]> _Unknown_bound;
};
template<class T, size_t N> struct _Unique_if<T[N]> {
typedef void _Known_bound;
};
template<class T, class... Args>
typename _Unique_if<T>::_Single_object
make_unique(Args&&... args) {
return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
template<class T>
typename _Unique_if<T>::_Unknown_bound
make_unique(size_t n) {
typedef typename remove_extent<T>::type U;
return unique_ptr<T>(new U[n]());
}
template<class T, class... Args>
typename _Unique_if<T>::_Known_bound
make_unique(Args&&...) = delete;
}
#endif //_enable_std_make_unique
#ifdef _enable_std_put_time
#include <ctime>
namespace std
{
//Workaround for no implemenation of std::put_time in gcc < 5.
/* std unspecified return type */
//template< class CharT, class RTSTR >// let fail for CharT != char / wchar_t
//RTSTR put_time(const std::tm* tmb, const CharT* fmt);
//template< >
std::string put_time/*<char, std::string>*/(const std::tm* tmb, const char* fmt);
//Defined in header <ctime>
// std::size_t strftime(char* str, std::size_t count, const char* format, const std::tm* time);
//template<>
//std::wstring put_time<wchar_t, std::wstring>(const std::tm* tmb, const wchar_t* fmt);
}
#endif // _enable_std_put_time
#if defined(_enable_std_clamp)
namespace std
{
//<algorithm> since C++17
template<typename T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi)
{
return (v < lo ? lo : (hi < v ? hi : v));
}
}
#endif