first init of 0.9
This commit is contained in:
145
include/nana/any.hpp
Normal file
145
include/nana/any.hpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#ifndef NANA_ANY_HPP
|
||||
#define NANA_ANY_HPP
|
||||
#include <typeinfo>
|
||||
#include <utility> //C++11 for std::move
|
||||
|
||||
namespace nana
|
||||
{
|
||||
|
||||
class any
|
||||
{
|
||||
struct super_type
|
||||
{
|
||||
virtual ~super_type();
|
||||
super_type& operator=(const super_type&);
|
||||
virtual super_type& assign(const super_type&) = 0;
|
||||
virtual bool same(const super_type&) const = 0;
|
||||
virtual super_type* clone() const = 0;
|
||||
}; //end struct super_type
|
||||
|
||||
template<typename T>
|
||||
struct object_type
|
||||
: public super_type
|
||||
{
|
||||
object_type(){}
|
||||
|
||||
object_type(T const & obj)
|
||||
: object(obj)
|
||||
{}
|
||||
|
||||
object_type(T && obj)
|
||||
: object(std::move(obj))
|
||||
{}
|
||||
|
||||
object_type(const object_type& rhs)
|
||||
:object(rhs.object)
|
||||
{}
|
||||
|
||||
virtual super_type& assign(const super_type& rhs)
|
||||
{
|
||||
if(this != &rhs)
|
||||
{
|
||||
auto other = dynamic_cast<const object_type*>(&rhs);
|
||||
if(other)
|
||||
object = other->object;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual bool same(const super_type& rhs) const
|
||||
{
|
||||
return (dynamic_cast<const object_type*>(&rhs) != nullptr);
|
||||
}
|
||||
|
||||
virtual super_type* clone() const
|
||||
{
|
||||
return new object_type(object);
|
||||
}
|
||||
|
||||
T object;
|
||||
}; //end struct object_type
|
||||
public:
|
||||
template<typename T>
|
||||
any(const T & obj)
|
||||
: super_(new object_type<typename std::remove_reference<T>::type>(obj))
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
any(T && obj)
|
||||
: super_(new object_type<typename std::remove_reference<T>::type>(std::move(obj)))
|
||||
{}
|
||||
|
||||
any();
|
||||
any(const any&);
|
||||
any(any&&);
|
||||
~any();
|
||||
|
||||
bool same(const any &) const;
|
||||
any& operator=(const any&);
|
||||
any& operator=(any&&);
|
||||
|
||||
template<typename T>
|
||||
any& operator=(T const &rhs)
|
||||
{
|
||||
T * obj = get<T>();
|
||||
if(nullptr == obj)
|
||||
{
|
||||
delete super_;
|
||||
super_ = new object_type<T>(rhs);
|
||||
}
|
||||
else
|
||||
*obj = rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
any & operator=(T && rhs)
|
||||
{
|
||||
typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
|
||||
type* obj = get<type>();
|
||||
if(nullptr == obj)
|
||||
{
|
||||
delete super_;
|
||||
super_ = new object_type<type>(std::move(rhs));
|
||||
}
|
||||
else
|
||||
*obj = std::move(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T * get() const
|
||||
{
|
||||
if(super_)
|
||||
{
|
||||
typedef typename std::remove_const<T>::type type;
|
||||
object_type<type>* obj = dynamic_cast<object_type<type>*>(super_);
|
||||
if(obj) return &(obj->object);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
operator T&() const
|
||||
{
|
||||
typedef typename std::remove_const<T>::type type;
|
||||
type *obj = get<type>();
|
||||
|
||||
if(nullptr == obj)
|
||||
throw std::bad_cast();
|
||||
|
||||
return *obj;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
operator T*() const
|
||||
{
|
||||
typedef typename std::remove_const<T>::type type;
|
||||
return get<type>();
|
||||
}
|
||||
private:
|
||||
super_type * super_;
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
53
include/nana/audio/detail/audio_device.hpp
Normal file
53
include/nana/audio/detail/audio_device.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef NANA_AUDIO_DETAIL_AUDIO_DEVICE_HPP
|
||||
#define NANA_AUDIO_DETAIL_AUDIO_DEVICE_HPP
|
||||
|
||||
#include <nana/deploy.hpp>
|
||||
#include <nana/audio/detail/buffer_preparation.hpp>
|
||||
#include <vector>
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(NANA_LINUX)
|
||||
#include <alsa/asoundlib.h>
|
||||
#endif
|
||||
|
||||
namespace nana{ namespace audio
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class audio_device
|
||||
{
|
||||
public:
|
||||
audio_device();
|
||||
~audio_device();
|
||||
|
||||
bool empty() const;
|
||||
bool open(std::size_t channels, std::size_t rate, std::size_t bits_per_sample);
|
||||
void close();
|
||||
void prepare(buffer_preparation & buf_prep);
|
||||
void write(buffer_preparation::meta * m);
|
||||
void wait_for_drain() const;
|
||||
private:
|
||||
#if defined(NANA_WINDOWS)
|
||||
static void __stdcall _m_dev_callback(HWAVEOUT handle, UINT msg, audio_device * self, DWORD_PTR, DWORD_PTR);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
HWAVEOUT handle_;
|
||||
std::recursive_mutex queue_lock_;
|
||||
std::vector<buffer_preparation::meta*> done_queue_;
|
||||
#elif defined(NANA_LINUX)
|
||||
snd_pcm_t * handle_;
|
||||
std::size_t rate_;
|
||||
std::size_t channels_;
|
||||
std::size_t bytes_per_sample_;
|
||||
std::size_t bytes_per_frame_;
|
||||
#endif
|
||||
buffer_preparation * buf_prep_;
|
||||
};
|
||||
|
||||
}//end namespace detail
|
||||
}//end namespace audio
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
81
include/nana/audio/detail/audio_stream.hpp
Normal file
81
include/nana/audio/detail/audio_stream.hpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#ifndef NANA_AUDIO_DETAIL_AUDIO_STREAM_HPP
|
||||
#define NANA_AUDIO_DETAIL_AUDIO_STREAM_HPP
|
||||
#include <fstream>
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
namespace nana{ namespace audio{
|
||||
namespace detail
|
||||
{
|
||||
namespace wave_spec
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
#pragma pack(1)
|
||||
struct master_riff_chunk
|
||||
{
|
||||
unsigned long ckID; //"RIFF"
|
||||
unsigned long cksize;
|
||||
unsigned long waveID; //"WAVE"
|
||||
};
|
||||
|
||||
struct format_chunck
|
||||
{
|
||||
unsigned long ckID; //"fmt "
|
||||
unsigned long cksize;
|
||||
unsigned short wFormatTag;
|
||||
unsigned short nChannels;
|
||||
unsigned long nSamplePerSec;
|
||||
unsigned long nAvgBytesPerSec;
|
||||
unsigned short nBlockAlign;
|
||||
unsigned short wBitsPerSample;
|
||||
};
|
||||
#pragma pack()
|
||||
#elif defined(NANA_LINUX)
|
||||
struct master_riff_chunk
|
||||
{
|
||||
unsigned long ckID; //"RIFF"
|
||||
unsigned long cksize;
|
||||
unsigned long waveID; //"WAVE"
|
||||
}__attribute__((packed));
|
||||
|
||||
struct format_chunck
|
||||
{
|
||||
unsigned long ckID; //"fmt "
|
||||
unsigned long cksize;
|
||||
unsigned short wFormatTag;
|
||||
unsigned short nChannels;
|
||||
unsigned long nSamplePerSec;
|
||||
unsigned long nAvgBytesPerSec;
|
||||
unsigned short nBlockAlign;
|
||||
unsigned short wBitsPerSample;
|
||||
}__attribute__((packed));
|
||||
#endif
|
||||
}
|
||||
|
||||
class audio_stream
|
||||
{
|
||||
struct chunck
|
||||
{
|
||||
unsigned long ckID;
|
||||
unsigned long cksize;
|
||||
};
|
||||
public:
|
||||
bool open(const nana::string& file);
|
||||
void close();
|
||||
bool empty() const;
|
||||
const wave_spec::format_chunck & format() const;
|
||||
std::size_t data_length() const;
|
||||
void locate();
|
||||
std::size_t read(void * buf, std::size_t len);
|
||||
private:
|
||||
std::size_t _m_locate_chunck(unsigned ckID);
|
||||
private:
|
||||
std::ifstream fs_;
|
||||
wave_spec::format_chunck ck_format_;
|
||||
std::size_t pcm_data_pos_;
|
||||
std::size_t pcm_data_size_;
|
||||
std::size_t data_size_;
|
||||
}; //end class audio_stream
|
||||
}
|
||||
}//end namespace audio
|
||||
}//end namespace nana
|
||||
#endif
|
||||
65
include/nana/audio/detail/buffer_preparation.hpp
Normal file
65
include/nana/audio/detail/buffer_preparation.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef NANA_AUDIO_DETAIL_BUFFER_PREPARATION_HPP
|
||||
#define NANA_AUDIO_DETAIL_BUFFER_PREPARATION_HPP
|
||||
#include <nana/deploy.hpp>
|
||||
#include <nana/audio/detail/audio_stream.hpp>
|
||||
|
||||
#if defined(NANA_MINGW) && defined(STD_THREAD_NOT_SUPPORTED)
|
||||
#include <nana/std_thread.hpp>
|
||||
#include <nana/std_mutex.hpp>
|
||||
#include <nana/std_condition_variable.hpp>
|
||||
#else
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace nana{ namespace audio
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class buffer_preparation
|
||||
{
|
||||
public:
|
||||
#if defined(NANA_WINDOWS)
|
||||
typedef WAVEHDR meta;
|
||||
#elif defined(NANA_LINUX)
|
||||
struct meta
|
||||
{
|
||||
char * buf;
|
||||
std::size_t bufsize;
|
||||
};
|
||||
#endif
|
||||
|
||||
public:
|
||||
buffer_preparation(audio_stream& as, std::size_t seconds);
|
||||
|
||||
~buffer_preparation();
|
||||
|
||||
meta * read();
|
||||
//Revert the meta that returned by read()
|
||||
void revert(meta * m);
|
||||
bool data_finished() const;
|
||||
private:
|
||||
void _m_prepare_routine();
|
||||
private:
|
||||
volatile bool running_;
|
||||
volatile bool wait_for_buffer_;
|
||||
std::thread thr_;
|
||||
mutable std::mutex token_buffer_, token_prepared_;
|
||||
mutable std::condition_variable cond_buffer_, cond_prepared_;
|
||||
|
||||
std::vector<meta*> buffer_, prepared_;
|
||||
std::size_t block_size_;
|
||||
audio_stream & as_;
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace audio
|
||||
}//end namespace nana
|
||||
#endif
|
||||
25
include/nana/audio/player.hpp
Normal file
25
include/nana/audio/player.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef NANA_AUDIO_PLAYER_HPP
|
||||
#define NANA_AUDIO_PLAYER_HPP
|
||||
#include <nana/traits.hpp>
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
namespace nana{ namespace audio
|
||||
{ /// play an audio file in Windows WAV format
|
||||
class player
|
||||
: private nana::noncopyable
|
||||
{
|
||||
struct implementation;
|
||||
public:
|
||||
player();
|
||||
player(const nana::string& file);
|
||||
~player();
|
||||
|
||||
bool open(const nana::string& file);
|
||||
void play();
|
||||
void close();
|
||||
private:
|
||||
implementation* impl_;
|
||||
};
|
||||
}//end namespace audio
|
||||
}//end namespace nana
|
||||
#endif
|
||||
254
include/nana/basic_types.hpp
Normal file
254
include/nana/basic_types.hpp
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Basic Types definition
|
||||
* 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/basic_types.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_BASIC_TYPES_HPP
|
||||
#define NANA_BASIC_TYPES_HPP
|
||||
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
//A constant value for the invalid position.
|
||||
const std::size_t npos = static_cast<std::size_t>(-1);
|
||||
|
||||
|
||||
template<typename CharT>
|
||||
struct casei_char_traits
|
||||
: public std::char_traits<CharT>
|
||||
{
|
||||
typedef CharT char_type;
|
||||
|
||||
|
||||
//static constexpr bool eq(char_type c1, char_type c2) noexcept
|
||||
//VC2012 does not support constexpr and noexcept keywords
|
||||
static bool eq(char_type c1, char_type c2)
|
||||
{
|
||||
return std::toupper(c1) == std::toupper(c2);
|
||||
}
|
||||
|
||||
//static constexpr bool lt(char_type c1, char_type c2) noexcept
|
||||
//VC2012 does not support constexpr and noexcept keywords
|
||||
static bool lt(char_type c1, char_type c2)
|
||||
{
|
||||
return std::toupper(c1) < std::toupper(c2);
|
||||
}
|
||||
|
||||
static int compare(const char_type* s1, const char_type* s2, std::size_t n)
|
||||
{
|
||||
while(n--)
|
||||
{
|
||||
char_type c1 = std::toupper(*s1);
|
||||
char_type c2 = std::toupper(*s2);
|
||||
if(c1 < c2) return -1;
|
||||
if(c1 > c2) return 1;
|
||||
++s1;
|
||||
++s2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char_type* find(const char_type* s, std::size_t n, const char_type& a)
|
||||
{
|
||||
char_type ua = std::toupper(a);
|
||||
const char_type * end = s + n;
|
||||
while((s != end) && (std::toupper(*s) != ua))
|
||||
++s;
|
||||
return (s == end ? nullptr : s);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::basic_string<nana::char_t, casei_char_traits<nana::char_t> > cistring;
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct drawable_impl_type; //declearation, defined in platform_spec.hpp
|
||||
}
|
||||
|
||||
namespace paint
|
||||
{
|
||||
typedef nana::detail::drawable_impl_type* drawable_type;
|
||||
}
|
||||
|
||||
enum class mouse_action
|
||||
{
|
||||
begin, normal = begin, over, pressed, end
|
||||
};
|
||||
|
||||
enum class element_state
|
||||
{
|
||||
normal,
|
||||
hovered,
|
||||
focus_normal,
|
||||
focus_hovered,
|
||||
pressed,
|
||||
disabled
|
||||
};
|
||||
|
||||
typedef unsigned scalar_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef unsigned uint_t;
|
||||
typedef unsigned color_t;
|
||||
typedef long long long_long_t;
|
||||
|
||||
const color_t null_color = 0xFFFFFFFF;
|
||||
|
||||
struct pixel_rgb_t
|
||||
{
|
||||
union
|
||||
{
|
||||
struct element_tag
|
||||
{
|
||||
unsigned int blue:8;
|
||||
unsigned int green:8;
|
||||
unsigned int red:8;
|
||||
unsigned int alpha_channel:8;
|
||||
}element;
|
||||
|
||||
color_t color;
|
||||
}u;
|
||||
};
|
||||
|
||||
struct rectangle;
|
||||
|
||||
struct point
|
||||
{
|
||||
point();
|
||||
point(int x, int y);
|
||||
point(const rectangle&);
|
||||
|
||||
point& operator=(const rectangle&);
|
||||
bool operator==(const point&) const;
|
||||
bool operator!=(const point&) const;
|
||||
bool operator<(const point&) const;
|
||||
bool operator<=(const point&) const;
|
||||
bool operator>(const point&) const;
|
||||
bool operator>=(const point&) const;
|
||||
|
||||
point operator-(const point&) const;
|
||||
point operator+(const point&) const;
|
||||
point& operator-=(const point&);
|
||||
point& operator+=(const point&);
|
||||
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct upoint
|
||||
{
|
||||
typedef unsigned value_type;
|
||||
|
||||
upoint();
|
||||
upoint(value_type x, value_type y);
|
||||
bool operator==(const upoint&) const;
|
||||
bool operator!=(const upoint&) const;
|
||||
bool operator<(const upoint&) const;
|
||||
bool operator<=(const upoint&) const;
|
||||
bool operator>(const upoint&) const;
|
||||
bool operator>=(const upoint&) const;
|
||||
|
||||
value_type x;
|
||||
value_type y;
|
||||
};
|
||||
|
||||
struct size
|
||||
{
|
||||
size();
|
||||
size(unsigned width, unsigned height);
|
||||
size(const rectangle&);
|
||||
|
||||
size& operator=(const rectangle&);
|
||||
|
||||
bool empty() const; ///< true if width * height == 0
|
||||
bool is_hit(const point&) const; ///< Assume it is a rectangle at (0,0), and check whether a specified position is in the rectange.
|
||||
bool operator==(const size& rhs) const;
|
||||
bool operator!=(const size& rhs) const;
|
||||
size operator+(const size&) const;
|
||||
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
struct rectangle
|
||||
{
|
||||
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());
|
||||
|
||||
bool operator==(const rectangle& rhs) const;
|
||||
bool operator!=(const rectangle& rhs) const;
|
||||
|
||||
rectangle& operator=(const point&);
|
||||
rectangle& operator=(const size&);
|
||||
|
||||
rectangle& set_pos(const point&);
|
||||
rectangle& set_size(const size&);
|
||||
|
||||
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 bottom() const;
|
||||
bool is_hit(int x, int y) const;
|
||||
bool is_hit(const point& pos) const;
|
||||
bool empty() const; ///< true if width * height == 0
|
||||
|
||||
int x;
|
||||
int y;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
class area_rotator
|
||||
{
|
||||
public:
|
||||
area_rotator(bool rotated, const ::nana::rectangle& area);
|
||||
|
||||
int x() const;
|
||||
int & x_ref();
|
||||
int y() const;
|
||||
int & y_ref();
|
||||
unsigned w() const;
|
||||
unsigned & w_ref();
|
||||
unsigned h() const;
|
||||
unsigned & h_ref();
|
||||
|
||||
int right() const;
|
||||
int bottom() const;
|
||||
const ::nana::rectangle& result() const;
|
||||
private:
|
||||
bool rotated_;
|
||||
::nana::rectangle area_;
|
||||
};//end class area_rotator
|
||||
|
||||
enum class arrange
|
||||
{
|
||||
unknown, horizontal, vertical, horizontal_vertical
|
||||
};
|
||||
|
||||
///The definition of horizontal alignment
|
||||
enum class align
|
||||
{
|
||||
left, center, right
|
||||
};
|
||||
|
||||
///The definition of vertical alignment
|
||||
enum class align_v
|
||||
{
|
||||
top, center, bottom
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
67
include/nana/charset.hpp
Normal file
67
include/nana/charset.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef NANA_CHARSET_HPP
|
||||
#define NANA_CHARSET_HPP
|
||||
#include <string>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
enum class unicode
|
||||
{
|
||||
utf8, utf16, utf32
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class charset_encoding_interface;
|
||||
}
|
||||
/// An intelligent charset class for character code conversion.
|
||||
class charset
|
||||
{
|
||||
public:
|
||||
charset(const charset&);
|
||||
charset & operator=(const charset&);
|
||||
charset(charset&&);
|
||||
charset & operator=(charset&&);
|
||||
|
||||
charset(const std::string&); ///<Attempt to convert a multibytes string.
|
||||
charset(std::string&&); ///<Attempt to convert a multibytes string.
|
||||
charset(const std::string&, unicode);///<Attempt to convert a unicode string in byte sequence.
|
||||
charset(std::string&&, unicode); ///<Attempt to convert a unicode string in byte sequence.
|
||||
charset(const std::wstring&); ///<Attempt to convert a UCS2/UCS4 string.
|
||||
charset(std::wstring&&); ///<Attempt to convert a UCS2/UCS4 string.
|
||||
~charset();
|
||||
operator std::string() const; ///<Converts the string to multibytes string.
|
||||
operator std::string&&(); ///<Converts the string to multibytes string.
|
||||
operator std::wstring() const; ///<Converts the string to UCS2/UCS4 string.
|
||||
operator std::wstring&&(); ///<Converts the string to UCS2/UCS4 string.
|
||||
std::string to_bytes(unicode) const; ///<Converts the string to a unicode in bytes sequenece width a specified unicode transformation format.
|
||||
private:
|
||||
detail::charset_encoding_interface* impl_;
|
||||
};
|
||||
|
||||
}//end namespace nana
|
||||
#endif
|
||||
|
||||
/*!\class charset
|
||||
|
||||
Example
|
||||
1. A UTF-8 string from the socket.
|
||||
|
||||
int len = ::recv(sd, buf, buflen, 0);
|
||||
textbox.caption(nana::charset(std::string(buf, len), nana::unicode::utf8));
|
||||
|
||||
2. Send the string in text to the socket as UTF-8.
|
||||
|
||||
std::string utf8str = nana::charset(textbox.caption()).to_bytes(nana::unicode::utf8);
|
||||
::send(sd, utf8str.c_str(), utf8str.size(), 0);
|
||||
|
||||
3, Convert a string to the specified multi-byte character code.
|
||||
|
||||
//Convert to a multibytes string through default system language.
|
||||
std::string mbstr = nana::charset(a_wstring);
|
||||
//If the default system language is English and convert
|
||||
//a Chinese unicode string to multibytes string through GB2312
|
||||
std::setlocale(LC_CTYPE, "zh_CN.GB2312");
|
||||
//set::setlocale(LC_CTYPE, ".936"); call it in Windows
|
||||
std::string mbstr = nana::charset(a_wstring_with_chinese);
|
||||
|
||||
*/
|
||||
132
include/nana/concepts.hpp
Normal file
132
include/nana/concepts.hpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* A Concepts Definition of Nana C++ Library
|
||||
* Copyright(C) 2003-2013 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/concepts.hpp
|
||||
*/
|
||||
#ifndef NANA_CONCEPTS_HPP
|
||||
#define NANA_CONCEPTS_HPP
|
||||
|
||||
#include <nana/any.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace concepts
|
||||
{
|
||||
/// The Any Objective is an object that may attach to some other object.
|
||||
template<typename IndexType, int Dimension> // no dep. on IndexType ??
|
||||
class any_objective
|
||||
{
|
||||
public:
|
||||
virtual ~any_objective(){}
|
||||
|
||||
template<typename Target>
|
||||
void anyobj(const Target& t)
|
||||
{
|
||||
nana::any * p = _m_anyobj(true);
|
||||
if(nullptr == p)
|
||||
throw std::runtime_error("Nana.any_objective: Object does not exist");
|
||||
*p = t;
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
void anyobj(Target&& t)
|
||||
{
|
||||
nana::any * p = _m_anyobj(true);
|
||||
if(nullptr == 0)
|
||||
throw std::runtime_error("Nana.any_objective: Object does not exist");
|
||||
|
||||
*p = std::move(t);
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
Target * anyobj() const ///< Retrieves the attached object. Returns a nullptr if empty or if the type not match.
|
||||
{
|
||||
nana::any * p = _m_anyobj(false);
|
||||
return (p ? p->get<Target>() : nullptr);
|
||||
}
|
||||
private:
|
||||
virtual nana::any* _m_anyobj(bool allocate_if_empty) const = 0;
|
||||
};
|
||||
|
||||
/// The Any Objective is an object that may attach to some other object.
|
||||
template<typename IndexType>
|
||||
class any_objective<IndexType, 1>
|
||||
{
|
||||
public:
|
||||
typedef IndexType anyobj_index_t; ///< The type of index. It is available if Dimension is greater than 0.
|
||||
|
||||
virtual ~any_objective(){}
|
||||
|
||||
template<typename Target>
|
||||
void anyobj(anyobj_index_t i, const Target& t)
|
||||
{
|
||||
nana::any * p = _m_anyobj(i, true);
|
||||
if(nullptr == p)
|
||||
throw std::runtime_error("Nana.any_objective: Object does not exist.");
|
||||
*p = t;
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
void anyobj(anyobj_index_t i, Target&& t)
|
||||
{
|
||||
nana::any * p = _m_anyobj(i, true);
|
||||
if(nullptr == p)
|
||||
throw std::runtime_error("Nana.any_objective: Object does not exist");
|
||||
*p = std::move(t);
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
Target * anyobj(anyobj_index_t i) const ///< Retrieves the attached object. Returns a nullptr if empty or if the type not match.
|
||||
{
|
||||
nana::any * p = _m_anyobj(i, false);
|
||||
return (p ? p->get<Target>() : nullptr);
|
||||
}
|
||||
private:
|
||||
virtual nana::any* _m_anyobj(anyobj_index_t i, bool allocate_if_empty) const = 0;
|
||||
};
|
||||
|
||||
/// The Any Objective is an object that may attach to some other object.
|
||||
template<typename IndexType>
|
||||
class any_objective<IndexType, 2>
|
||||
{
|
||||
public:
|
||||
typedef IndexType anyobj_index_t;
|
||||
|
||||
virtual ~any_objective(){}
|
||||
|
||||
template<typename Target>
|
||||
void anyobj(anyobj_index_t i0, anyobj_index_t i1, const Target& t)
|
||||
{
|
||||
nana::any * p = _m_anyobj(i0, i1, true);
|
||||
if(nullptr == p)
|
||||
throw std::runtime_error("Nana.any_objective: Object does not exist");
|
||||
|
||||
*p = t;
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
void anyobj(anyobj_index_t i0, anyobj_index_t i1, Target&& t)
|
||||
{
|
||||
nana::any * p = _m_anyobj(i0, i1, true);
|
||||
if(nullptr == p)
|
||||
throw std::runtime_error("Nana.any_objective: Object does not exist");
|
||||
*p = std::move(t);
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
Target * anyobj(anyobj_index_t i0, anyobj_index_t i1) const ///< Retrieves the attached object. Returns a nullptr if empty or if the type not match.
|
||||
{
|
||||
nana::any * p = _m_anyobj(i0, i1, false);
|
||||
return (p ? p->get<Target>() : nullptr);
|
||||
}
|
||||
private:
|
||||
virtual nana::any* _m_anyobj(anyobj_index_t i0, anyobj_index_t i1, bool allocate_if_empty) const = 0;
|
||||
};
|
||||
}//end namespace concepts
|
||||
}//end namespace nana
|
||||
#endif
|
||||
62
include/nana/config.hpp
Normal file
62
include/nana/config.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Nana Configuration
|
||||
* 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/config.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_CONFIG_HPP
|
||||
#define NANA_CONFIG_HPP
|
||||
|
||||
//Select platform automatically
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
//Windows:
|
||||
#define NANA_WINDOWS 1
|
||||
#define PLATFORM_SPEC_HPP <nana/detail/win32/platform_spec.hpp>
|
||||
#define GUI_BEDROCK_HPP <nana/gui/detail/bedrock.hpp>
|
||||
|
||||
//Test if it is MINGW
|
||||
#if defined(__MINGW32__)
|
||||
#define NANA_MINGW
|
||||
#define STD_CODECVT_NOT_SUPPORTED
|
||||
//#define STD_THREAD_NOT_SUPPORTED //Use this flag if MinGW version is older than 4.8.1
|
||||
#endif
|
||||
#elif (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC)
|
||||
//Linux:
|
||||
#define NANA_LINUX 1
|
||||
#define NANA_X11 1
|
||||
#define PLATFORM_SPEC_HPP <nana/detail/linux_X11/platform_spec.hpp>
|
||||
#define GUI_BEDROCK_HPP <nana/gui/detail/bedrock.hpp>
|
||||
|
||||
#define STD_CODECVT_NOT_SUPPORTED
|
||||
#endif
|
||||
|
||||
//Here defines some flags that tell Nana what features will be supported.
|
||||
|
||||
#define NANA_UNICODE
|
||||
|
||||
#if defined(NANA_UNICODE) && defined(NANA_WINDOWS)
|
||||
#ifndef _UNICODE
|
||||
#define _UNICODE
|
||||
#endif
|
||||
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//Support for PNG
|
||||
// Comment it to disable the feature of support for PNG.
|
||||
//#define NANA_ENABLE_PNG
|
||||
#if defined(NANA_ENABLE_PNG)
|
||||
//Comment it to use libpng from operating system.
|
||||
#define NANA_LIBPNG
|
||||
#endif
|
||||
|
||||
|
||||
#endif //NANA_CONFIG_HPP
|
||||
75
include/nana/datetime.hpp
Normal file
75
include/nana/datetime.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* A Date Time Implementation
|
||||
* Copyright(C) 2003-2013 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/datetime.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_DATETIME_HPP
|
||||
#define NANA_DATETIME_HPP
|
||||
#include <ctime>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
/// A date operation class. \see nana::date_chooser
|
||||
class date
|
||||
{
|
||||
public:
|
||||
struct value
|
||||
{
|
||||
unsigned year; ///< 1601 - 30827
|
||||
unsigned month; ///< 1-12
|
||||
unsigned day; ///< 1-31
|
||||
};
|
||||
|
||||
date(); ///< the initialized date is today.
|
||||
date(const std::tm&);
|
||||
date(int year, int month, int day);
|
||||
|
||||
date operator - (int off) const;
|
||||
date operator + (int off) const;
|
||||
bool operator==(const date&) const;
|
||||
bool operator!=(const date&) const;
|
||||
bool operator<(const date&) const;
|
||||
bool operator>(const date&) const;
|
||||
bool operator<=(const date&) const;
|
||||
bool operator>=(const date&) const;
|
||||
|
||||
int day_of_week() const;
|
||||
const value & read() const;
|
||||
|
||||
static int day_of_week(int year, int month, int day);
|
||||
static unsigned year_days(unsigned year); ///< the number of days in the specified year.
|
||||
static unsigned month_days(unsigned year, unsigned month); ///< the number of days in the specified month.
|
||||
static unsigned day_in_year(unsigned y, unsigned m, unsigned d); ///< Returns the index of the specified day in this year, at range[1, 365] or [1, 366]
|
||||
private:
|
||||
date _m_add(unsigned x) const;
|
||||
date _m_sub(unsigned x) const;
|
||||
private:
|
||||
value value_;
|
||||
}; //end class date
|
||||
|
||||
class time
|
||||
{
|
||||
public:
|
||||
struct value
|
||||
{
|
||||
unsigned hour; ///<[0-23]
|
||||
unsigned minute; ///<[0-59]
|
||||
unsigned second; ///<[0-61], the range of [60, 61] is used for leap seconds
|
||||
};
|
||||
|
||||
time();
|
||||
time(const std::tm&);
|
||||
time(unsigned hour, unsigned minute, unsigned second);
|
||||
const value& read() const;
|
||||
private:
|
||||
value value_;
|
||||
};//end class time
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
67
include/nana/deploy.hpp
Normal file
67
include/nana/deploy.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* The Deploy 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/deploy.hpp
|
||||
*
|
||||
* What follow are dependented on what defined in nana/config.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_DEPLOY_HPP
|
||||
#define NANA_DEPLOY_HPP
|
||||
|
||||
#include <nana/config.hpp>
|
||||
#include <nana/charset.hpp>
|
||||
#if defined(NANA_LINUX)
|
||||
#undef NANA_WINDOWS
|
||||
#endif
|
||||
|
||||
#ifndef NANA_UNICODE
|
||||
namespace nana
|
||||
{
|
||||
typedef char char_t;
|
||||
typedef std::string string; ///< An alias of std::wstring or std::string, depending on the macro NANA_UNICODE
|
||||
}
|
||||
#define STR(string) string
|
||||
#else
|
||||
namespace nana
|
||||
{
|
||||
typedef wchar_t char_t;
|
||||
typedef std::wstring string; ///< An alias of std::wstring or std::string, depending on the macro NANA_UNICODE
|
||||
}
|
||||
#define STR(string) L##string
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
std::size_t strlen(const char_t* str);
|
||||
double strtod(const char_t* str, char_t** endptr);
|
||||
char_t* strcpy(char_t* dest, const char_t* source);
|
||||
}
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#define NANA_SHARED_EXPORT extern "C" _declspec(dllexport)
|
||||
#elif defined(NANA_LINUX)
|
||||
#define NANA_SHARED_EXPORT extern "C"
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
bool is_incomplete(const nana::string& str, unsigned pos);
|
||||
|
||||
inline unsigned make_rgb(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
|
||||
return ((unsigned(red) << 16)|((unsigned(green)<<8))|blue);
|
||||
}
|
||||
}
|
||||
|
||||
#define NANA_RGB(a) (((DWORD)(a) & 0xFF)<<16) | ((DWORD)(a) & 0xFF00) | (((DWORD)(a) & 0xFF0000) >> 16 )
|
||||
|
||||
|
||||
#endif //NANA_MACROS_HPP
|
||||
341
include/nana/detail/linux_X11/msg_dispatcher.hpp
Normal file
341
include/nana/detail/linux_X11/msg_dispatcher.hpp
Normal file
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Message Dispatcher Implementation
|
||||
* Copyright(C) 2003-2013 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/detail/msg_dispatcher.hpp
|
||||
*
|
||||
* @DO NOT INCLUDE THIS HEADER FILE IN YOUR SOURCE FILE!!
|
||||
*
|
||||
* This class msg_dispatcher provides a simulation of Windows-like message
|
||||
* dispatcher. Every event is dispatched into its own message queue for
|
||||
* corresponding thread.
|
||||
*/
|
||||
|
||||
#ifndef NANA_DETAIL_MSG_DISPATCHER_HPP
|
||||
#define NANA_DETAIL_MSG_DISPATCHER_HPP
|
||||
#include "msg_packet.hpp"
|
||||
#include <nana/system/platform.hpp>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class msg_dispatcher
|
||||
{
|
||||
struct thread_binder
|
||||
{
|
||||
unsigned tid;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cond;
|
||||
std::list<msg_packet_tag> msg_queue;
|
||||
std::set<Window> window;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef msg_packet_tag msg_packet;
|
||||
typedef void (*timer_proc_type)(unsigned tid);
|
||||
typedef void (*event_proc_type)(Display*, msg_packet_tag&);
|
||||
typedef int (*event_filter_type)(XEvent&, msg_packet_tag&);
|
||||
|
||||
typedef std::list<msg_packet_tag> msg_queue_type;
|
||||
|
||||
msg_dispatcher(Display* disp)
|
||||
: display_(disp), is_work_(false)
|
||||
{
|
||||
proc_.event_proc = 0;
|
||||
proc_.timer_proc = 0;
|
||||
proc_.filter_proc = 0;
|
||||
}
|
||||
|
||||
void set(timer_proc_type timer_proc, event_proc_type event_proc, event_filter_type filter)
|
||||
{
|
||||
proc_.timer_proc = timer_proc;
|
||||
proc_.event_proc = event_proc;
|
||||
proc_.filter_proc = filter;
|
||||
}
|
||||
|
||||
void insert(Window wd)
|
||||
{
|
||||
unsigned tid = nana::system::this_thread_id();
|
||||
|
||||
bool start_driver;
|
||||
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
|
||||
//No thread is running, so msg dispatcher should start the msg driver.
|
||||
start_driver = (0 == table_.thr_table.size());
|
||||
thread_binder * thr;
|
||||
|
||||
std::map<unsigned, thread_binder*>::iterator i = table_.thr_table.find(tid);
|
||||
if(i == table_.thr_table.end())
|
||||
{
|
||||
thr = new thread_binder;
|
||||
thr->tid = tid;
|
||||
table_.thr_table.insert(std::make_pair(tid, thr));
|
||||
}
|
||||
else
|
||||
thr = i->second;
|
||||
|
||||
thr->mutex.lock();
|
||||
thr->window.insert(wd);
|
||||
thr->mutex.unlock();
|
||||
|
||||
table_.wnd_table[wd] = thr;
|
||||
}
|
||||
|
||||
if(start_driver && proc_.event_proc && proc_.timer_proc)
|
||||
{
|
||||
//It should start the msg driver, before starting it, the msg driver must be inactive.
|
||||
if(thrd_)
|
||||
{
|
||||
is_work_ = false;
|
||||
thrd_->join();
|
||||
}
|
||||
is_work_ = true;
|
||||
thrd_ = std::unique_ptr<std::thread>(new std::thread([this](){ this->_m_msg_driver(); }));
|
||||
}
|
||||
}
|
||||
|
||||
void erase(Window wd)
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
|
||||
auto i = table_.wnd_table.find(wd);
|
||||
if(i != table_.wnd_table.end())
|
||||
{
|
||||
thread_binder * const thr = i->second;
|
||||
std::lock_guard<decltype(thr->mutex)> lock(thr->mutex);
|
||||
for(auto li = thr->msg_queue.begin(); li != thr->msg_queue.end();)
|
||||
{
|
||||
if(wd == _m_window(*li))
|
||||
li = thr->msg_queue.erase(li);
|
||||
else
|
||||
++li;
|
||||
}
|
||||
|
||||
table_.wnd_table.erase(i);
|
||||
thr->window.erase(wd);
|
||||
|
||||
//There still is at least one window alive.
|
||||
if(thr->window.size())
|
||||
{
|
||||
//Make a cleanup msg packet to infor the dispatcher the window is closed.
|
||||
msg_packet_tag msg;
|
||||
msg.kind = msg.kind_cleanup;
|
||||
msg.u.packet_window = wd;
|
||||
thr->msg_queue.push_back(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch(Window modal)
|
||||
{
|
||||
unsigned tid = nana::system::this_thread_id();
|
||||
msg_packet_tag msg;
|
||||
int qstate;
|
||||
|
||||
//Test whether the thread is registered for window, and retrieve the queue state for event
|
||||
while((qstate = _m_read_queue(tid, msg, modal)))
|
||||
{
|
||||
//the queue is empty
|
||||
if(-1 == qstate)
|
||||
{
|
||||
if(false == _m_wait_for_queue(tid))
|
||||
proc_.timer_proc(tid);
|
||||
}
|
||||
else
|
||||
{
|
||||
proc_.event_proc(display_, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
void _m_msg_driver()
|
||||
{
|
||||
int fd_X11 = ConnectionNumber(display_);
|
||||
|
||||
msg_packet_tag msg_pack;
|
||||
XEvent event;
|
||||
while(is_work_)
|
||||
{
|
||||
int pending;
|
||||
{
|
||||
nana::detail::platform_scope_guard psg;
|
||||
pending = ::XPending(display_);
|
||||
if(pending)
|
||||
{
|
||||
::XNextEvent(display_, &event);
|
||||
if(::XFilterEvent(&event, None))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 == pending)
|
||||
{
|
||||
fd_set fdset;
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(fd_X11, &fdset);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_usec = 10000;
|
||||
tv.tv_sec = 0;
|
||||
::select(fd_X11 + 1, &fdset, 0, 0, &tv);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(proc_.filter_proc(event, msg_pack))
|
||||
{
|
||||
case 0:
|
||||
msg_pack.kind = msg_pack.kind_xevent;
|
||||
msg_pack.u.xevent = event;
|
||||
case 1:
|
||||
_m_msg_dispatch(msg_pack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
static Window _m_event_window(const XEvent& event)
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case MapNotify:
|
||||
case UnmapNotify:
|
||||
return event.xmap.window;
|
||||
}
|
||||
return event.xkey.window;
|
||||
}
|
||||
|
||||
static Window _m_window(const msg_packet_tag& pack)
|
||||
{
|
||||
switch(pack.kind)
|
||||
{
|
||||
case msg_packet_tag::kind_xevent:
|
||||
return _m_event_window(pack.u.xevent);
|
||||
case msg_packet_tag::kind_mouse_drop:
|
||||
return pack.u.mouse_drop.window;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _m_msg_dispatch(const msg_packet_tag &msg)
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
auto i = table_.wnd_table.find(_m_window(msg));
|
||||
if(i != table_.wnd_table.end())
|
||||
{
|
||||
thread_binder * const thr = i->second;
|
||||
|
||||
std::lock_guard<decltype(thr->mutex)> lock(thr->mutex);
|
||||
thr->msg_queue.push_back(msg);
|
||||
thr->cond.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
//_m_read_queue
|
||||
//@brief:Read the event from a specified thread queue.
|
||||
//@return: 0 = exit the queue, 1 = fetch the msg, -1 = no msg
|
||||
int _m_read_queue(unsigned tid, msg_packet_tag& msg, Window modal)
|
||||
{
|
||||
bool stop_driver = false;
|
||||
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
//Find the thread whether it is registered for the window.
|
||||
auto i = table_.thr_table.find(tid);
|
||||
if(i != table_.thr_table.end())
|
||||
{
|
||||
if(i->second->window.size())
|
||||
{
|
||||
msg_queue_type & queue = i->second->msg_queue;
|
||||
if(queue.size())
|
||||
{
|
||||
msg = queue.front();
|
||||
queue.pop_front();
|
||||
|
||||
//Check whether the event dispatcher is used for the modal window
|
||||
//and when the modal window is closing, the event dispatcher would
|
||||
//stop event pumping.
|
||||
if((modal == msg.u.packet_window) && (msg.kind == msg.kind_cleanup))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
delete i->second;
|
||||
table_.thr_table.erase(i);
|
||||
stop_driver = (table_.thr_table.size() == 0);
|
||||
}
|
||||
}
|
||||
if(stop_driver)
|
||||
{
|
||||
is_work_ = false;
|
||||
thrd_->join();
|
||||
thrd_.reset();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//_m_wait_for_queue
|
||||
// wait for the insertion of queue.
|
||||
//return@ it returns true if the queue is not empty, otherwise the wait is timeout.
|
||||
bool _m_wait_for_queue(unsigned tid)
|
||||
{
|
||||
thread_binder * thr = nullptr;
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
auto i = table_.thr_table.find(tid);
|
||||
if(i != table_.thr_table.end())
|
||||
{
|
||||
if(i->second->msg_queue.size())
|
||||
return true;
|
||||
thr = i->second;
|
||||
}
|
||||
}
|
||||
|
||||
//Waits for notifying the condition variable, it indicates a new msg is pushing into the queue.
|
||||
std::unique_lock<decltype(thr->mutex)> lock(thr->mutex);
|
||||
return (thr->cond.wait_for(lock, std::chrono::milliseconds(10)) != std::cv_status::timeout);
|
||||
}
|
||||
|
||||
private:
|
||||
Display * display_;
|
||||
volatile bool is_work_;
|
||||
std::unique_ptr<std::thread> thrd_;
|
||||
|
||||
struct table_tag
|
||||
{
|
||||
std::recursive_mutex mutex;
|
||||
std::map<unsigned, thread_binder*> thr_table;
|
||||
std::map<Window, thread_binder*> wnd_table;
|
||||
}table_;
|
||||
|
||||
struct proc_tag
|
||||
{
|
||||
timer_proc_type timer_proc;
|
||||
event_proc_type event_proc;
|
||||
event_filter_type filter_proc;
|
||||
}proc_;
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
32
include/nana/detail/linux_X11/msg_packet.hpp
Normal file
32
include/nana/detail/linux_X11/msg_packet.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef NANA_DETAIL_MSG_PACKET_HPP
|
||||
#define NANA_DETAIL_MSG_PACKET_HPP
|
||||
#include <X11/Xlib.h>
|
||||
#include <vector>
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct msg_packet_tag
|
||||
{
|
||||
enum kind_t{kind_xevent, kind_mouse_drop, kind_cleanup};
|
||||
kind_t kind;
|
||||
union
|
||||
{
|
||||
XEvent xevent;
|
||||
|
||||
Window packet_window; //Avaiable if the packet is not kind_xevent
|
||||
struct mouse_drop_tag
|
||||
{
|
||||
Window window;
|
||||
int x;
|
||||
int y;
|
||||
std::vector<nana::string> * files;
|
||||
}mouse_drop;
|
||||
}u;
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
#endif
|
||||
|
||||
317
include/nana/detail/linux_X11/platform_spec.hpp
Normal file
317
include/nana/detail/linux_X11/platform_spec.hpp
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Platform Specification Implementation
|
||||
* Copyright(C) 2003-2013 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/detail/platform_spec.hpp
|
||||
*
|
||||
* This file provides basis class and data structrue that required by nana
|
||||
* This file should not be included by any header files.
|
||||
*/
|
||||
|
||||
#ifndef NANA_DETAIL_PLATFORM_SPEC_HPP
|
||||
#define NANA_DETAIL_PLATFORM_SPEC_HPP
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <condition_variable>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <nana/gui/basis.hpp>
|
||||
#include <nana/paint/image.hpp>
|
||||
#include <nana/paint/graphics.hpp>
|
||||
#include <nana/gui/detail/event_code.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "msg_packet.hpp"
|
||||
#if defined(NANA_UNICODE)
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include <iconv.h>
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class msg_dispatcher;
|
||||
#if defined(NANA_UNICODE)
|
||||
class conf
|
||||
{
|
||||
public:
|
||||
conf(const char * file);
|
||||
bool open(const char* file);
|
||||
std::string value(const char* key);
|
||||
private:
|
||||
std::ifstream ifs_;
|
||||
};
|
||||
|
||||
class charset_conv
|
||||
{
|
||||
public:
|
||||
charset_conv(const char* tocode, const char* fromcode);
|
||||
~charset_conv();
|
||||
std::string charset(const std::string& str) const;
|
||||
std::string charset(const char * buf, std::size_t len) const;
|
||||
private:
|
||||
iconv_t handle_;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct font_tag
|
||||
{
|
||||
nana::string name;
|
||||
unsigned height;
|
||||
unsigned weight;
|
||||
bool italic;
|
||||
bool underline;
|
||||
bool strikeout;
|
||||
#if defined(NANA_UNICODE)
|
||||
XftFont * handle;
|
||||
#else
|
||||
XFontSet handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct drawable_impl_type
|
||||
{
|
||||
typedef std::shared_ptr<font_tag> font_ptr_t;
|
||||
|
||||
drawable_impl_type();
|
||||
~drawable_impl_type();
|
||||
|
||||
void fgcolor(unsigned color);
|
||||
|
||||
Pixmap pixmap;
|
||||
GC context;
|
||||
font_ptr_t font;
|
||||
|
||||
nana::point line_begin_pos;
|
||||
|
||||
struct string_spec
|
||||
{
|
||||
unsigned tab_length;
|
||||
unsigned tab_pixels;
|
||||
unsigned whitespace_pixels;
|
||||
}string;
|
||||
#if defined(NANA_UNICODE)
|
||||
XftDraw * xftdraw;
|
||||
XftColor xft_fgcolor;
|
||||
XftColor xft_bgcolor;
|
||||
const std::string charset(const nana::string& str, const std::string& strcode);
|
||||
#endif
|
||||
private:
|
||||
unsigned fgcolor_;
|
||||
#if defined(NANA_UNICODE)
|
||||
struct conv_tag
|
||||
{
|
||||
iconv_t handle;
|
||||
std::string code;
|
||||
}conv_;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct atombase_tag
|
||||
{
|
||||
Atom wm_protocols;
|
||||
//window manager support
|
||||
Atom wm_change_state;
|
||||
Atom wm_delete_window;
|
||||
//ext
|
||||
Atom net_wm_state;
|
||||
Atom net_wm_state_skip_taskbar;
|
||||
Atom net_wm_state_fullscreen;
|
||||
Atom net_wm_state_maximized_horz;
|
||||
Atom net_wm_state_maximized_vert;
|
||||
Atom net_wm_state_modal;
|
||||
Atom net_wm_window_type;
|
||||
Atom net_wm_window_type_normal;
|
||||
Atom net_wm_window_type_utility;
|
||||
Atom net_wm_window_type_dialog;
|
||||
Atom motif_wm_hints;
|
||||
|
||||
Atom clipboard;
|
||||
Atom text;
|
||||
Atom text_uri_list;
|
||||
Atom utf8_string;
|
||||
Atom targets;
|
||||
|
||||
Atom xdnd_aware;
|
||||
Atom xdnd_enter;
|
||||
Atom xdnd_position;
|
||||
Atom xdnd_status;
|
||||
Atom xdnd_action_copy;
|
||||
Atom xdnd_drop;
|
||||
Atom xdnd_selection;
|
||||
Atom xdnd_typelist;
|
||||
Atom xdnd_finished;
|
||||
};
|
||||
|
||||
struct caret_tag;
|
||||
|
||||
class timer_runner;
|
||||
|
||||
class platform_scope_guard
|
||||
{
|
||||
public:
|
||||
platform_scope_guard();
|
||||
~platform_scope_guard();
|
||||
};
|
||||
|
||||
class platform_spec
|
||||
{
|
||||
typedef platform_spec self_type;
|
||||
|
||||
struct window_context_t
|
||||
{
|
||||
native_window_type owner;
|
||||
std::vector<native_window_type> * owned;
|
||||
};
|
||||
public:
|
||||
int error_code;
|
||||
public:
|
||||
typedef drawable_impl_type::font_ptr_t font_ptr_t;
|
||||
typedef void (*timer_proc_type)(unsigned tid);
|
||||
typedef void (*event_proc_type)(Display*, msg_packet_tag&);
|
||||
typedef ::nana::event_code event_code;
|
||||
typedef ::nana::native_window_type native_window_type;
|
||||
|
||||
|
||||
platform_spec();
|
||||
~platform_spec();
|
||||
|
||||
const font_ptr_t& default_native_font() const;
|
||||
void default_native_font(const font_ptr_t&);
|
||||
unsigned font_size_to_height(unsigned) const;
|
||||
unsigned font_height_to_size(unsigned) const;
|
||||
font_ptr_t make_native_font(const nana::char_t* name, unsigned height, unsigned weight, bool italic, bool underline, bool strick_out);
|
||||
|
||||
Display* open_display();
|
||||
void close_display();
|
||||
|
||||
void lock_xlib();
|
||||
void unlock_xlib();
|
||||
|
||||
Window root_window();
|
||||
int screen_depth();
|
||||
Visual* screen_visual();
|
||||
|
||||
Colormap& colormap();
|
||||
|
||||
static self_type& instance();
|
||||
const atombase_tag & atombase() const;
|
||||
|
||||
void make_owner(native_window_type owner, native_window_type wd);
|
||||
native_window_type get_owner(native_window_type) const;
|
||||
void remove(native_window_type);
|
||||
|
||||
void write_keystate(const XKeyEvent&);
|
||||
void read_keystate(XKeyEvent&);
|
||||
|
||||
XIC caret_input_context(native_window_type) const;
|
||||
void caret_open(native_window_type, unsigned width, unsigned height);
|
||||
void caret_close(native_window_type);
|
||||
void caret_pos(native_window_type, int x, int y);
|
||||
void caret_visible(native_window_type, bool);
|
||||
void caret_flash(caret_tag&);
|
||||
bool caret_update(native_window_type, nana::paint::graphics& root_graph, bool is_erase_caret_from_root_graph);
|
||||
static bool caret_reinstate(caret_tag&);
|
||||
void set_error_handler();
|
||||
int rev_error_handler();
|
||||
|
||||
//grab
|
||||
//register a grab window while capturing it if it is unviewable.
|
||||
//when native_interface::show a window that is registered as a grab
|
||||
//window, the native_interface grabs the window.
|
||||
Window grab(Window);
|
||||
void set_timer(std::size_t id, std::size_t interval, void (*timer_proc)(std::size_t id));
|
||||
void kill_timer(std::size_t id);
|
||||
void timer_proc(unsigned tid);
|
||||
|
||||
//Message dispatcher
|
||||
void msg_insert(native_window_type);
|
||||
void msg_set(timer_proc_type, event_proc_type);
|
||||
void msg_dispatch(native_window_type modal);
|
||||
|
||||
//X Selections
|
||||
void* request_selection(native_window_type requester, Atom type, size_t & bufsize);
|
||||
void write_selection(native_window_type owner, Atom type, const void* buf, size_t bufsize);
|
||||
|
||||
//Icon storage
|
||||
//@biref: The image object should be kept for a long time till the window is closed,
|
||||
// the image object is release in remove() method.
|
||||
const nana::paint::graphics& keep_window_icon(native_window_type, const nana::paint::image&);
|
||||
private:
|
||||
static int _m_msg_filter(XEvent&, msg_packet_tag&);
|
||||
void _m_caret_routine();
|
||||
private:
|
||||
Display* display_;
|
||||
Colormap colormap_;
|
||||
atombase_tag atombase_;
|
||||
font_ptr_t def_font_ptr_;
|
||||
XKeyEvent key_state_;
|
||||
int (*def_X11_error_handler_)(Display*, XErrorEvent*);
|
||||
Window grab_;
|
||||
std::recursive_mutex xlib_locker_;
|
||||
struct caret_holder_tag
|
||||
{
|
||||
volatile bool exit_thread;
|
||||
std::unique_ptr<std::thread> thr;
|
||||
std::map<native_window_type, caret_tag*> carets;
|
||||
}caret_holder_;
|
||||
|
||||
std::map<native_window_type, window_context_t> wincontext_;
|
||||
std::map<native_window_type, nana::paint::graphics> iconbase_;
|
||||
|
||||
struct timer_runner_tag
|
||||
{
|
||||
timer_runner * runner;
|
||||
std::recursive_mutex mutex;
|
||||
bool delete_declared;
|
||||
timer_runner_tag();
|
||||
}timer_;
|
||||
|
||||
struct selection_tag
|
||||
{
|
||||
struct item_t
|
||||
{
|
||||
Atom type;
|
||||
Window requestor;
|
||||
void* buffer;
|
||||
size_t bufsize;
|
||||
std::mutex cond_mutex;
|
||||
std::condition_variable cond;
|
||||
};
|
||||
|
||||
std::vector<item_t*> items;
|
||||
|
||||
struct content_tag
|
||||
{
|
||||
std::string * utf8_string;
|
||||
}content;
|
||||
}selection_;
|
||||
|
||||
struct xdnd_tag
|
||||
{
|
||||
Atom good_type;
|
||||
int timestamp;
|
||||
Window wd_src;
|
||||
nana::point pos;
|
||||
}xdnd_;
|
||||
|
||||
msg_dispatcher * msg_dispatcher_;
|
||||
};//end class platform_X11
|
||||
|
||||
}//end namespace detail
|
||||
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
179
include/nana/detail/win32/platform_spec.hpp
Normal file
179
include/nana/detail/win32/platform_spec.hpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Platform Specification Implementation
|
||||
* Copyright(C) 2003-2013 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/detail/platform_spec.hpp
|
||||
*
|
||||
* This file provides basis class and data structrue that required by nana
|
||||
* This file should not be included by any header files.
|
||||
*/
|
||||
|
||||
#ifndef NANA_DETAIL_PLATFORM_SPEC_HPP
|
||||
#define NANA_DETAIL_PLATFORM_SPEC_HPP
|
||||
|
||||
#include <nana/deploy.hpp>
|
||||
#include <nana/gui/basis.hpp>
|
||||
#include <nana/paint/image.hpp>
|
||||
#include <nana/gui/detail/event_code.hpp>
|
||||
|
||||
#include <windows.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//struct messages
|
||||
//@brief: This defines some messages that are used for remote thread invocation.
|
||||
// Some Windows APIs are window-thread-dependent, the operation in other thread
|
||||
// must be posted to its own thread.
|
||||
struct messages
|
||||
{
|
||||
struct caret
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
bool visible;
|
||||
};
|
||||
|
||||
struct move_window
|
||||
{
|
||||
enum { Pos = 1, Size = 2};
|
||||
int x;
|
||||
int y;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned ignore; //determinate that pos or size would be ignored.
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
tray = 0x501,
|
||||
async_activate,
|
||||
async_set_focus,
|
||||
map_thread_root_buffer,
|
||||
remote_thread_destroy_window,
|
||||
remote_thread_move_window,
|
||||
operate_caret, //wParam: 1=Destroy, 2=SetPos
|
||||
remote_thread_set_window_pos,
|
||||
remote_thread_set_window_text,
|
||||
user,
|
||||
};
|
||||
};
|
||||
|
||||
struct font_tag
|
||||
{
|
||||
nana::string name;
|
||||
unsigned height;
|
||||
unsigned weight;
|
||||
bool italic;
|
||||
bool underline;
|
||||
bool strikeout;
|
||||
HFONT handle;
|
||||
|
||||
struct deleter
|
||||
{
|
||||
void operator()(const font_tag*) const;
|
||||
};
|
||||
};
|
||||
|
||||
struct drawable_impl_type
|
||||
{
|
||||
typedef std::shared_ptr<font_tag> font_ptr_t;
|
||||
|
||||
HDC context;
|
||||
HBITMAP pixmap;
|
||||
pixel_rgb_t* pixbuf_ptr;
|
||||
std::size_t bytes_per_line;
|
||||
font_ptr_t font;
|
||||
|
||||
struct pen_spec
|
||||
{
|
||||
HPEN handle;
|
||||
unsigned color;
|
||||
int style;
|
||||
int width;
|
||||
|
||||
void set(HDC context, int style, int width, nana::color_t color);
|
||||
}pen;
|
||||
|
||||
struct brush_spec
|
||||
{
|
||||
enum t{Solid, HatchBDiagonal};
|
||||
|
||||
HBRUSH handle;
|
||||
t style;
|
||||
nana::color_t color;
|
||||
|
||||
void set(HDC context, t style, nana::color_t color);
|
||||
}brush;
|
||||
|
||||
struct round_region_spec
|
||||
{
|
||||
HRGN handle;
|
||||
nana::rectangle r;
|
||||
unsigned radius_x;
|
||||
unsigned radius_y;
|
||||
|
||||
void set(const nana::rectangle& r, unsigned radius_x, unsigned radius_y);
|
||||
}round_region;
|
||||
|
||||
struct string_spec
|
||||
{
|
||||
unsigned tab_length;
|
||||
unsigned tab_pixels;
|
||||
unsigned whitespace_pixels;
|
||||
}string;
|
||||
|
||||
drawable_impl_type();
|
||||
~drawable_impl_type();
|
||||
|
||||
void fgcolor(nana::color_t);
|
||||
private:
|
||||
unsigned fgcolor_;
|
||||
};
|
||||
|
||||
class platform_spec
|
||||
{
|
||||
public:
|
||||
typedef drawable_impl_type::font_ptr_t font_ptr_t;
|
||||
typedef ::nana::event_code event_code;
|
||||
typedef ::nana::native_window_type native_window_type;
|
||||
|
||||
class co_initializer
|
||||
{
|
||||
public:
|
||||
co_initializer();
|
||||
~co_initializer();
|
||||
private:
|
||||
HMODULE ole32_;
|
||||
};
|
||||
|
||||
platform_spec();
|
||||
|
||||
const font_ptr_t& default_native_font() const;
|
||||
void default_native_font(const font_ptr_t&);
|
||||
unsigned font_size_to_height(unsigned) const;
|
||||
unsigned font_height_to_size(unsigned) const;
|
||||
font_ptr_t make_native_font(const nana::char_t* name, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out);
|
||||
|
||||
static platform_spec& instance();
|
||||
|
||||
void keep_window_icon(native_window_type, const nana::paint::image&);
|
||||
void release_window_icon(native_window_type);
|
||||
private:
|
||||
font_ptr_t def_font_ptr_;
|
||||
std::map<native_window_type, nana::paint::image> iconbase_;
|
||||
};
|
||||
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
#endif
|
||||
95
include/nana/exceptions.hpp
Normal file
95
include/nana/exceptions.hpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Exception Definition
|
||||
* Copyright(C) 2003-2013 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/exceptions.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_EXCEPTIONS_H
|
||||
#define NANA_EXCEPTIONS_H
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
|
||||
/**
|
||||
* nana::threads::thread::exit throws this exception to exit thread
|
||||
* this exception is not allowed to be catch by programmer,
|
||||
* otherwise the thread may not exit
|
||||
*/
|
||||
class thrd_exit: public std::exception
|
||||
{
|
||||
public:
|
||||
thrd_exit(unsigned retval);
|
||||
~thrd_exit() throw();
|
||||
const char* what() const throw();
|
||||
unsigned retval() const;
|
||||
private:
|
||||
unsigned retval_;
|
||||
};
|
||||
|
||||
/**
|
||||
* nana::text::settings_t throws this exception if it dose not found a given member
|
||||
* in a scope
|
||||
*/
|
||||
class bad_member: public std::exception
|
||||
{
|
||||
public:
|
||||
bad_member(const std::string& what);
|
||||
~bad_member() throw();
|
||||
const char* what() const throw();
|
||||
private:
|
||||
std::string what_;
|
||||
};
|
||||
|
||||
/**
|
||||
* nana::text::settings_t throws this exception if there is a syntax error
|
||||
*/
|
||||
class bad_syntax: public std::exception
|
||||
{
|
||||
public:
|
||||
bad_syntax(const std::string& what);
|
||||
~bad_syntax() throw();
|
||||
const char* what() const throw();
|
||||
private:
|
||||
std::string what_;
|
||||
};
|
||||
|
||||
class bad_error: public std::exception
|
||||
{
|
||||
public:
|
||||
bad_error(const std::string& what);
|
||||
~bad_error() throw();
|
||||
const char* what() const throw();
|
||||
private:
|
||||
std::string what_;
|
||||
};
|
||||
|
||||
class bad_handle: public std::exception
|
||||
{
|
||||
public:
|
||||
bad_handle(const std::string& what);
|
||||
~bad_handle() throw();
|
||||
const char* what() const throw();
|
||||
private:
|
||||
std::string what_;
|
||||
};
|
||||
|
||||
class bad_window
|
||||
:public std::exception
|
||||
{
|
||||
public:
|
||||
bad_window(const char* what);
|
||||
~bad_window() throw();
|
||||
const char* what() const throw();
|
||||
private:
|
||||
std::string what_;
|
||||
};
|
||||
}// end namespace nana
|
||||
|
||||
#endif
|
||||
2654
include/nana/extrlib/png.h
Normal file
2654
include/nana/extrlib/png.h
Normal file
File diff suppressed because it is too large
Load Diff
596
include/nana/extrlib/pngconf.h
Normal file
596
include/nana/extrlib/pngconf.h
Normal file
@@ -0,0 +1,596 @@
|
||||
|
||||
/* pngconf.h - machine configurable file for libpng
|
||||
*
|
||||
* libpng version 1.5.8 - February 1, 2012
|
||||
*
|
||||
* Copyright (c) 1998-2012 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* Any machine specific code is near the front of this file, so if you
|
||||
* are configuring libpng for a machine, you may want to read the section
|
||||
* starting here down to where it starts to typedef png_color, png_text,
|
||||
* and png_info.
|
||||
*/
|
||||
|
||||
#ifndef PNGCONF_H
|
||||
#define PNGCONF_H
|
||||
|
||||
#ifndef PNG_BUILDING_SYMBOL_TABLE
|
||||
/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C
|
||||
* definition file for machine specific limits, this may impact the
|
||||
* correctness of the definitons below (see uses of INT_MAX).
|
||||
*/
|
||||
# ifndef PNG_NO_LIMITS_H
|
||||
# include <limits.h>
|
||||
# endif
|
||||
|
||||
/* For the memory copy APIs (i.e. the standard definitions of these),
|
||||
* because this file defines png_memcpy and so on the base APIs must
|
||||
* be defined here.
|
||||
*/
|
||||
# ifdef BSD
|
||||
# include <strings.h>
|
||||
# else
|
||||
# include <string.h>
|
||||
# endif
|
||||
|
||||
/* For png_FILE_p - this provides the standard definition of a
|
||||
* FILE
|
||||
*/
|
||||
# ifdef PNG_STDIO_SUPPORTED
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This controls optimization of the reading of 16 and 32 bit values
|
||||
* from PNG files. It can be set on a per-app-file basis - it
|
||||
* just changes whether a macro is used to the function is called.
|
||||
* The library builder sets the default, if read functions are not
|
||||
* built into the library the macro implementation is forced on.
|
||||
*/
|
||||
#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
|
||||
# define PNG_USE_READ_MACROS
|
||||
#endif
|
||||
#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
|
||||
# if PNG_DEFAULT_READ_MACROS
|
||||
# define PNG_USE_READ_MACROS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* COMPILER SPECIFIC OPTIONS.
|
||||
*
|
||||
* These options are provided so that a variety of difficult compilers
|
||||
* can be used. Some are fixed at build time (e.g. PNG_API_RULE
|
||||
* below) but still have compiler specific implementations, others
|
||||
* may be changed on a per-file basis when compiling against libpng.
|
||||
*/
|
||||
|
||||
/* The PNGARG macro protects us against machines that don't have function
|
||||
* prototypes (ie K&R style headers). If your compiler does not handle
|
||||
* function prototypes, define this macro and use the included ansi2knr.
|
||||
* I've always been able to use _NO_PROTO as the indicator, but you may
|
||||
* need to drag the empty declaration out in front of here, or change the
|
||||
* ifdef to suit your own needs.
|
||||
*/
|
||||
#ifndef PNGARG
|
||||
|
||||
# ifdef OF /* zlib prototype munger */
|
||||
# define PNGARG(arglist) OF(arglist)
|
||||
# else
|
||||
|
||||
# ifdef _NO_PROTO
|
||||
# define PNGARG(arglist) ()
|
||||
# else
|
||||
# define PNGARG(arglist) arglist
|
||||
# endif /* _NO_PROTO */
|
||||
|
||||
# endif /* OF */
|
||||
|
||||
#endif /* PNGARG */
|
||||
|
||||
/* Function calling conventions.
|
||||
* =============================
|
||||
* Normally it is not necessary to specify to the compiler how to call
|
||||
* a function - it just does it - however on x86 systems derived from
|
||||
* Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
|
||||
* and some others) there are multiple ways to call a function and the
|
||||
* default can be changed on the compiler command line. For this reason
|
||||
* libpng specifies the calling convention of every exported function and
|
||||
* every function called via a user supplied function pointer. This is
|
||||
* done in this file by defining the following macros:
|
||||
*
|
||||
* PNGAPI Calling convention for exported functions.
|
||||
* PNGCBAPI Calling convention for user provided (callback) functions.
|
||||
* PNGCAPI Calling convention used by the ANSI-C library (required
|
||||
* for longjmp callbacks and sometimes used internally to
|
||||
* specify the calling convention for zlib).
|
||||
*
|
||||
* These macros should never be overridden. If it is necessary to
|
||||
* change calling convention in a private build this can be done
|
||||
* by setting PNG_API_RULE (which defaults to 0) to one of the values
|
||||
* below to select the correct 'API' variants.
|
||||
*
|
||||
* PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
|
||||
* This is correct in every known environment.
|
||||
* PNG_API_RULE=1 Use the operating system convention for PNGAPI and
|
||||
* the 'C' calling convention (from PNGCAPI) for
|
||||
* callbacks (PNGCBAPI). This is no longer required
|
||||
* in any known environment - if it has to be used
|
||||
* please post an explanation of the problem to the
|
||||
* libpng mailing list.
|
||||
*
|
||||
* These cases only differ if the operating system does not use the C
|
||||
* calling convention, at present this just means the above cases
|
||||
* (x86 DOS/Windows sytems) and, even then, this does not apply to
|
||||
* Cygwin running on those systems.
|
||||
*
|
||||
* Note that the value must be defined in pnglibconf.h so that what
|
||||
* the application uses to call the library matches the conventions
|
||||
* set when building the library.
|
||||
*/
|
||||
|
||||
/* Symbol export
|
||||
* =============
|
||||
* When building a shared library it is almost always necessary to tell
|
||||
* the compiler which symbols to export. The png.h macro 'PNG_EXPORT'
|
||||
* is used to mark the symbols. On some systems these symbols can be
|
||||
* extracted at link time and need no special processing by the compiler,
|
||||
* on other systems the symbols are flagged by the compiler and just
|
||||
* the declaration requires a special tag applied (unfortunately) in a
|
||||
* compiler dependent way. Some systems can do either.
|
||||
*
|
||||
* A small number of older systems also require a symbol from a DLL to
|
||||
* be flagged to the program that calls it. This is a problem because
|
||||
* we do not know in the header file included by application code that
|
||||
* the symbol will come from a shared library, as opposed to a statically
|
||||
* linked one. For this reason the application must tell us by setting
|
||||
* the magic flag PNG_USE_DLL to turn on the special processing before
|
||||
* it includes png.h.
|
||||
*
|
||||
* Four additional macros are used to make this happen:
|
||||
*
|
||||
* PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
|
||||
* the build or imported if PNG_USE_DLL is set - compiler
|
||||
* and system specific.
|
||||
*
|
||||
* PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
|
||||
* 'type', compiler specific.
|
||||
*
|
||||
* PNG_DLL_EXPORT Set to the magic to use during a libpng build to
|
||||
* make a symbol exported from the DLL. Not used in the
|
||||
* public header files; see pngpriv.h for how it is used
|
||||
* in the libpng build.
|
||||
*
|
||||
* PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
|
||||
* from a DLL - used to define PNG_IMPEXP when
|
||||
* PNG_USE_DLL is set.
|
||||
*/
|
||||
|
||||
/* System specific discovery.
|
||||
* ==========================
|
||||
* This code is used at build time to find PNG_IMPEXP, the API settings
|
||||
* and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
|
||||
* import processing is possible. On Windows/x86 systems it also sets
|
||||
* compiler-specific macros to the values required to change the calling
|
||||
* conventions of the various functions.
|
||||
*/
|
||||
#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
|
||||
defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\
|
||||
( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\
|
||||
defined(_M_X64) || defined(_M_IA64) )
|
||||
/* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes
|
||||
* builds under Cygwin or MinGW. Also includes Watcom builds but these need
|
||||
* special treatment because they are not compatible with GCC or Visual C
|
||||
* because of different calling conventions.
|
||||
*/
|
||||
# if PNG_API_RULE == 2
|
||||
/* If this line results in an error, either because __watcall is not
|
||||
* understood or because of a redefine just below you cannot use *this*
|
||||
* build of the library with the compiler you are using. *This* build was
|
||||
* build using Watcom and applications must also be built using Watcom!
|
||||
*/
|
||||
# define PNGCAPI __watcall
|
||||
# endif
|
||||
|
||||
# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
|
||||
# define PNGCAPI __cdecl
|
||||
# if PNG_API_RULE == 1
|
||||
# define PNGAPI __stdcall
|
||||
# endif
|
||||
# else
|
||||
/* An older compiler, or one not detected (erroneously) above,
|
||||
* if necessary override on the command line to get the correct
|
||||
* variants for the compiler.
|
||||
*/
|
||||
# ifndef PNGCAPI
|
||||
# define PNGCAPI _cdecl
|
||||
# endif
|
||||
# if PNG_API_RULE == 1 && !defined(PNGAPI)
|
||||
# define PNGAPI _stdcall
|
||||
# endif
|
||||
# endif /* compiler/api */
|
||||
/* NOTE: PNGCBAPI always defaults to PNGCAPI. */
|
||||
|
||||
# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
|
||||
ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed
|
||||
# endif
|
||||
|
||||
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
|
||||
(defined(__BORLANDC__) && __BORLANDC__ < 0x500)
|
||||
/* older Borland and MSC
|
||||
* compilers used '__export' and required this to be after
|
||||
* the type.
|
||||
*/
|
||||
# ifndef PNG_EXPORT_TYPE
|
||||
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
|
||||
# endif
|
||||
# define PNG_DLL_EXPORT __export
|
||||
# else /* newer compiler */
|
||||
# define PNG_DLL_EXPORT __declspec(dllexport)
|
||||
# ifndef PNG_DLL_IMPORT
|
||||
# define PNG_DLL_IMPORT __declspec(dllimport)
|
||||
# endif
|
||||
# endif /* compiler */
|
||||
|
||||
#else /* !Windows/x86 */
|
||||
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
|
||||
# define PNGAPI _System
|
||||
# else /* !Windows/x86 && !OS/2 */
|
||||
/* Use the defaults, or define PNG*API on the command line (but
|
||||
* this will have to be done for every compile!)
|
||||
*/
|
||||
# endif /* other system, !OS/2 */
|
||||
#endif /* !Windows/x86 */
|
||||
|
||||
/* Now do all the defaulting . */
|
||||
#ifndef PNGCAPI
|
||||
# define PNGCAPI
|
||||
#endif
|
||||
#ifndef PNGCBAPI
|
||||
# define PNGCBAPI PNGCAPI
|
||||
#endif
|
||||
#ifndef PNGAPI
|
||||
# define PNGAPI PNGCAPI
|
||||
#endif
|
||||
|
||||
/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
|
||||
* then in an internal header file when building the library, otherwise (when
|
||||
* using the library) it is set here.
|
||||
*/
|
||||
#ifndef PNG_IMPEXP
|
||||
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
|
||||
/* This forces use of a DLL, disallowing static linking */
|
||||
# define PNG_IMPEXP PNG_DLL_IMPORT
|
||||
# endif
|
||||
|
||||
# ifndef PNG_IMPEXP
|
||||
# define PNG_IMPEXP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
|
||||
* 'attributes' as a storage class - the attributes go at the start of the
|
||||
* function definition, and attributes are always appended regardless of the
|
||||
* compiler. This considerably simplifies these macros but may cause problems
|
||||
* if any compilers both need function attributes and fail to handle them as
|
||||
* a storage class (this is unlikely.)
|
||||
*/
|
||||
#ifndef PNG_FUNCTION
|
||||
# define PNG_FUNCTION(type, name, args, attributes) attributes type name args
|
||||
#endif
|
||||
|
||||
#ifndef PNG_EXPORT_TYPE
|
||||
# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
|
||||
#endif
|
||||
|
||||
/* The ordinal value is only relevant when preprocessing png.h for symbol
|
||||
* table entries, so we discard it here. See the .dfn files in the
|
||||
* scripts directory.
|
||||
*/
|
||||
#ifndef PNG_EXPORTA
|
||||
|
||||
# define PNG_EXPORTA(ordinal, type, name, args, attributes)\
|
||||
PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \
|
||||
extern attributes)
|
||||
#endif
|
||||
|
||||
/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
|
||||
* so make something non-empty to satisfy the requirement:
|
||||
*/
|
||||
#define PNG_EMPTY /*empty list*/
|
||||
|
||||
#define PNG_EXPORT(ordinal, type, name, args)\
|
||||
PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
|
||||
|
||||
/* Use PNG_REMOVED to comment out a removed interface. */
|
||||
#ifndef PNG_REMOVED
|
||||
# define PNG_REMOVED(ordinal, type, name, args, attributes)
|
||||
#endif
|
||||
|
||||
#ifndef PNG_CALLBACK
|
||||
# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
|
||||
#endif
|
||||
|
||||
/* Support for compiler specific function attributes. These are used
|
||||
* so that where compiler support is available incorrect use of API
|
||||
* functions in png.h will generate compiler warnings.
|
||||
*
|
||||
* Added at libpng-1.2.41.
|
||||
*/
|
||||
|
||||
#ifndef PNG_NO_PEDANTIC_WARNINGS
|
||||
# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
|
||||
# define PNG_PEDANTIC_WARNINGS_SUPPORTED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
|
||||
/* Support for compiler specific function attributes. These are used
|
||||
* so that where compiler support is available incorrect use of API
|
||||
* functions in png.h will generate compiler warnings. Added at libpng
|
||||
* version 1.2.41.
|
||||
*/
|
||||
# if defined(__GNUC__)
|
||||
# ifndef PNG_USE_RESULT
|
||||
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
|
||||
# endif
|
||||
# ifndef PNG_NORETURN
|
||||
# define PNG_NORETURN __attribute__((__noreturn__))
|
||||
# endif
|
||||
# ifndef PNG_ALLOCATED
|
||||
# define PNG_ALLOCATED __attribute__((__malloc__))
|
||||
# endif
|
||||
# ifndef PNG_DEPRECATED
|
||||
# define PNG_DEPRECATED __attribute__((__deprecated__))
|
||||
# endif
|
||||
# ifndef PNG_PRIVATE
|
||||
# if 0 /* Doesn't work so we use deprecated instead*/
|
||||
# define PNG_PRIVATE \
|
||||
__attribute__((warning("This function is not exported by libpng.")))
|
||||
# else
|
||||
# define PNG_PRIVATE \
|
||||
__attribute__((__deprecated__))
|
||||
# endif
|
||||
# endif
|
||||
# endif /* __GNUC__ */
|
||||
|
||||
# if defined(_MSC_VER) && (_MSC_VER >= 1300)
|
||||
# ifndef PNG_USE_RESULT
|
||||
# define PNG_USE_RESULT /* not supported */
|
||||
# endif
|
||||
# ifndef PNG_NORETURN
|
||||
# define PNG_NORETURN __declspec(noreturn)
|
||||
# endif
|
||||
# ifndef PNG_ALLOCATED
|
||||
# if (_MSC_VER >= 1400)
|
||||
# define PNG_ALLOCATED __declspec(restrict)
|
||||
# endif
|
||||
# endif
|
||||
# ifndef PNG_DEPRECATED
|
||||
# define PNG_DEPRECATED __declspec(deprecated)
|
||||
# endif
|
||||
# ifndef PNG_PRIVATE
|
||||
# define PNG_PRIVATE __declspec(deprecated)
|
||||
# endif
|
||||
# endif /* _MSC_VER */
|
||||
#endif /* PNG_PEDANTIC_WARNINGS */
|
||||
|
||||
#ifndef PNG_DEPRECATED
|
||||
# define PNG_DEPRECATED /* Use of this function is deprecated */
|
||||
#endif
|
||||
#ifndef PNG_USE_RESULT
|
||||
# define PNG_USE_RESULT /* The result of this function must be checked */
|
||||
#endif
|
||||
#ifndef PNG_NORETURN
|
||||
# define PNG_NORETURN /* This function does not return */
|
||||
#endif
|
||||
#ifndef PNG_ALLOCATED
|
||||
# define PNG_ALLOCATED /* The result of the function is new memory */
|
||||
#endif
|
||||
#ifndef PNG_PRIVATE
|
||||
# define PNG_PRIVATE /* This is a private libpng function */
|
||||
#endif
|
||||
#ifndef PNG_FP_EXPORT /* A floating point API. */
|
||||
# ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
# define PNG_FP_EXPORT(ordinal, type, name, args)\
|
||||
PNG_EXPORT(ordinal, type, name, args)
|
||||
# else /* No floating point APIs */
|
||||
# define PNG_FP_EXPORT(ordinal, type, name, args)
|
||||
# endif
|
||||
#endif
|
||||
#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
|
||||
# ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
|
||||
PNG_EXPORT(ordinal, type, name, args)
|
||||
# else /* No fixed point APIs */
|
||||
# define PNG_FIXED_EXPORT(ordinal, type, name, args)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following uses const char * instead of char * for error
|
||||
* and warning message functions, so some compilers won't complain.
|
||||
* If you do not want to use const, define PNG_NO_CONST here.
|
||||
*
|
||||
* This should not change how the APIs are called, so it can be done
|
||||
* on a per-file basis in the application.
|
||||
*/
|
||||
#ifndef PNG_CONST
|
||||
# ifndef PNG_NO_CONST
|
||||
# define PNG_CONST const
|
||||
# else
|
||||
# define PNG_CONST
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some typedefs to get us started. These should be safe on most of the
|
||||
* common platforms. The typedefs should be at least as large as the
|
||||
* numbers suggest (a png_uint_32 must be at least 32 bits long), but they
|
||||
* don't have to be exactly that size. Some compilers dislike passing
|
||||
* unsigned shorts as function parameters, so you may be better off using
|
||||
* unsigned int for png_uint_16.
|
||||
*/
|
||||
|
||||
#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL)
|
||||
typedef unsigned int png_uint_32;
|
||||
typedef int png_int_32;
|
||||
#else
|
||||
typedef unsigned long png_uint_32;
|
||||
typedef long png_int_32;
|
||||
#endif
|
||||
typedef unsigned short png_uint_16;
|
||||
typedef short png_int_16;
|
||||
typedef unsigned char png_byte;
|
||||
|
||||
#ifdef PNG_NO_SIZE_T
|
||||
typedef unsigned int png_size_t;
|
||||
#else
|
||||
typedef size_t png_size_t;
|
||||
#endif
|
||||
#define png_sizeof(x) (sizeof (x))
|
||||
|
||||
/* The following is needed for medium model support. It cannot be in the
|
||||
* pngpriv.h header. Needs modification for other compilers besides
|
||||
* MSC. Model independent support declares all arrays and pointers to be
|
||||
* large using the far keyword. The zlib version used must also support
|
||||
* model independent data. As of version zlib 1.0.4, the necessary changes
|
||||
* have been made in zlib. The USE_FAR_KEYWORD define triggers other
|
||||
* changes that are needed. (Tim Wegner)
|
||||
*/
|
||||
|
||||
/* Separate compiler dependencies (problem here is that zlib.h always
|
||||
* defines FAR. (SJT)
|
||||
*/
|
||||
#ifdef __BORLANDC__
|
||||
# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
|
||||
# define LDATA 1
|
||||
# else
|
||||
# define LDATA 0
|
||||
# endif
|
||||
/* GRR: why is Cygwin in here? Cygwin is not Borland C... */
|
||||
# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
|
||||
# define PNG_MAX_MALLOC_64K /* only used in build */
|
||||
# if (LDATA != 1)
|
||||
# ifndef FAR
|
||||
# define FAR __far
|
||||
# endif
|
||||
# define USE_FAR_KEYWORD
|
||||
# endif /* LDATA != 1 */
|
||||
/* Possibly useful for moving data out of default segment.
|
||||
* Uncomment it if you want. Could also define FARDATA as
|
||||
* const if your compiler supports it. (SJT)
|
||||
# define FARDATA FAR
|
||||
*/
|
||||
# endif /* __WIN32__, __FLAT__, __CYGWIN__ */
|
||||
#endif /* __BORLANDC__ */
|
||||
|
||||
|
||||
/* Suggest testing for specific compiler first before testing for
|
||||
* FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM,
|
||||
* making reliance oncertain keywords suspect. (SJT)
|
||||
*/
|
||||
|
||||
/* MSC Medium model */
|
||||
#ifdef FAR
|
||||
# ifdef M_I86MM
|
||||
# define USE_FAR_KEYWORD
|
||||
# define FARDATA FAR
|
||||
# include <dos.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* SJT: default case */
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
/* At this point FAR is always defined */
|
||||
#ifndef FARDATA
|
||||
# define FARDATA
|
||||
#endif
|
||||
|
||||
/* Typedef for floating-point numbers that are converted
|
||||
* to fixed-point with a multiple of 100,000, e.g., gamma
|
||||
*/
|
||||
typedef png_int_32 png_fixed_point;
|
||||
|
||||
/* Add typedefs for pointers */
|
||||
typedef void FAR * png_voidp;
|
||||
typedef PNG_CONST void FAR * png_const_voidp;
|
||||
typedef png_byte FAR * png_bytep;
|
||||
typedef PNG_CONST png_byte FAR * png_const_bytep;
|
||||
typedef png_uint_32 FAR * png_uint_32p;
|
||||
typedef PNG_CONST png_uint_32 FAR * png_const_uint_32p;
|
||||
typedef png_int_32 FAR * png_int_32p;
|
||||
typedef PNG_CONST png_int_32 FAR * png_const_int_32p;
|
||||
typedef png_uint_16 FAR * png_uint_16p;
|
||||
typedef PNG_CONST png_uint_16 FAR * png_const_uint_16p;
|
||||
typedef png_int_16 FAR * png_int_16p;
|
||||
typedef PNG_CONST png_int_16 FAR * png_const_int_16p;
|
||||
typedef char FAR * png_charp;
|
||||
typedef PNG_CONST char FAR * png_const_charp;
|
||||
typedef png_fixed_point FAR * png_fixed_point_p;
|
||||
typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p;
|
||||
typedef png_size_t FAR * png_size_tp;
|
||||
typedef PNG_CONST png_size_t FAR * png_const_size_tp;
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
typedef FILE * png_FILE_p;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
typedef double FAR * png_doublep;
|
||||
typedef PNG_CONST double FAR * png_const_doublep;
|
||||
#endif
|
||||
|
||||
/* Pointers to pointers; i.e. arrays */
|
||||
typedef png_byte FAR * FAR * png_bytepp;
|
||||
typedef png_uint_32 FAR * FAR * png_uint_32pp;
|
||||
typedef png_int_32 FAR * FAR * png_int_32pp;
|
||||
typedef png_uint_16 FAR * FAR * png_uint_16pp;
|
||||
typedef png_int_16 FAR * FAR * png_int_16pp;
|
||||
typedef PNG_CONST char FAR * FAR * png_const_charpp;
|
||||
typedef char FAR * FAR * png_charpp;
|
||||
typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
typedef double FAR * FAR * png_doublepp;
|
||||
#endif
|
||||
|
||||
/* Pointers to pointers to pointers; i.e., pointer to array */
|
||||
typedef char FAR * FAR * FAR * png_charppp;
|
||||
|
||||
/* png_alloc_size_t is guaranteed to be no smaller than png_size_t,
|
||||
* and no smaller than png_uint_32. Casts from png_size_t or png_uint_32
|
||||
* to png_alloc_size_t are not necessary; in fact, it is recommended
|
||||
* not to use them at all so that the compiler can complain when something
|
||||
* turns out to be problematic.
|
||||
* Casts in the other direction (from png_alloc_size_t to png_size_t or
|
||||
* png_uint_32) should be explicitly applied; however, we do not expect
|
||||
* to encounter practical situations that require such conversions.
|
||||
*/
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
typedef unsigned long png_alloc_size_t;
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
typedef unsigned long png_alloc_size_t;
|
||||
# else
|
||||
/* This is an attempt to detect an old Windows system where (int) is
|
||||
* actually 16 bits, in that case png_malloc must have an argument with a
|
||||
* bigger size to accomodate the requirements of the library.
|
||||
*/
|
||||
# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \
|
||||
(!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL)
|
||||
typedef DWORD png_alloc_size_t;
|
||||
# else
|
||||
typedef png_size_t png_alloc_size_t;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* PNGCONF_H */
|
||||
189
include/nana/extrlib/pnglibconf.h
Normal file
189
include/nana/extrlib/pnglibconf.h
Normal file
@@ -0,0 +1,189 @@
|
||||
|
||||
/* libpng STANDARD API DEFINITION */
|
||||
|
||||
/* pnglibconf.h - library build configuration */
|
||||
|
||||
/* Libpng 1.5.8 - February 1, 2012 */
|
||||
|
||||
/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */
|
||||
|
||||
/* This code is released under the libpng license. */
|
||||
/* For conditions of distribution and use, see the disclaimer */
|
||||
/* and license in png.h */
|
||||
|
||||
/* pnglibconf.h */
|
||||
/* Derived from: scripts/pnglibconf.dfa */
|
||||
/* If you edit this file by hand you must obey the rules expressed in */
|
||||
/* pnglibconf.dfa with respect to the dependencies between the following */
|
||||
/* symbols. It is much better to generate a new file using */
|
||||
/* scripts/libpngconf.mak */
|
||||
|
||||
#ifndef PNGLCONF_H
|
||||
#define PNGLCONF_H
|
||||
/* settings */
|
||||
#define PNG_API_RULE 0
|
||||
#define PNG_CALLOC_SUPPORTED
|
||||
#define PNG_COST_SHIFT 3
|
||||
#define PNG_DEFAULT_READ_MACROS 1
|
||||
#define PNG_GAMMA_THRESHOLD_FIXED 5000
|
||||
#define PNG_MAX_GAMMA_8 11
|
||||
#define PNG_QUANTIZE_BLUE_BITS 5
|
||||
#define PNG_QUANTIZE_GREEN_BITS 5
|
||||
#define PNG_QUANTIZE_RED_BITS 5
|
||||
#define PNG_sCAL_PRECISION 5
|
||||
#define PNG_USER_CHUNK_CACHE_MAX 0
|
||||
#define PNG_USER_CHUNK_MALLOC_MAX 0
|
||||
#define PNG_USER_HEIGHT_MAX 1000000
|
||||
#define PNG_USER_WIDTH_MAX 1000000
|
||||
#define PNG_WEIGHT_SHIFT 8
|
||||
#define PNG_ZBUF_SIZE 8192
|
||||
/* end of settings */
|
||||
/* options */
|
||||
#define PNG_16BIT_SUPPORTED
|
||||
#define PNG_ALIGN_MEMORY_SUPPORTED
|
||||
#define PNG_BENIGN_ERRORS_SUPPORTED
|
||||
#define PNG_bKGD_SUPPORTED
|
||||
#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
|
||||
#define PNG_CHECK_cHRM_SUPPORTED
|
||||
#define PNG_cHRM_SUPPORTED
|
||||
#define PNG_CONSOLE_IO_SUPPORTED
|
||||
#define PNG_CONVERT_tIME_SUPPORTED
|
||||
#define PNG_EASY_ACCESS_SUPPORTED
|
||||
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
|
||||
#define PNG_ERROR_TEXT_SUPPORTED
|
||||
#define PNG_FIXED_POINT_SUPPORTED
|
||||
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
|
||||
#define PNG_FLOATING_POINT_SUPPORTED
|
||||
#define PNG_FORMAT_AFIRST_SUPPORTED
|
||||
#define PNG_FORMAT_BGR_SUPPORTED
|
||||
#define PNG_gAMA_SUPPORTED
|
||||
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||
#define PNG_hIST_SUPPORTED
|
||||
#define PNG_iCCP_SUPPORTED
|
||||
#define PNG_INCH_CONVERSIONS_SUPPORTED
|
||||
#define PNG_INFO_IMAGE_SUPPORTED
|
||||
#define PNG_IO_STATE_SUPPORTED
|
||||
#define PNG_iTXt_SUPPORTED
|
||||
#define PNG_MNG_FEATURES_SUPPORTED
|
||||
#define PNG_oFFs_SUPPORTED
|
||||
#define PNG_pCAL_SUPPORTED
|
||||
#define PNG_pHYs_SUPPORTED
|
||||
#define PNG_POINTER_INDEXING_SUPPORTED
|
||||
#define PNG_PROGRESSIVE_READ_SUPPORTED
|
||||
#define PNG_READ_16BIT_SUPPORTED
|
||||
#define PNG_READ_ALPHA_MODE_SUPPORTED
|
||||
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_BACKGROUND_SUPPORTED
|
||||
#define PNG_READ_BGR_SUPPORTED
|
||||
#define PNG_READ_bKGD_SUPPORTED
|
||||
#define PNG_READ_cHRM_SUPPORTED
|
||||
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
|
||||
#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
|
||||
#define PNG_READ_EXPAND_16_SUPPORTED
|
||||
#define PNG_READ_EXPAND_SUPPORTED
|
||||
#define PNG_READ_FILLER_SUPPORTED
|
||||
#define PNG_READ_gAMA_SUPPORTED
|
||||
#define PNG_READ_GAMMA_SUPPORTED
|
||||
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
|
||||
#define PNG_READ_hIST_SUPPORTED
|
||||
#define PNG_READ_iCCP_SUPPORTED
|
||||
#define PNG_READ_INTERLACING_SUPPORTED
|
||||
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
|
||||
#define PNG_READ_INVERT_ALPHA_SUPPORTED
|
||||
#define PNG_READ_INVERT_SUPPORTED
|
||||
#define PNG_READ_iTXt_SUPPORTED
|
||||
#define PNG_READ_oFFs_SUPPORTED
|
||||
#define PNG_READ_OPT_PLTE_SUPPORTED
|
||||
#define PNG_READ_PACK_SUPPORTED
|
||||
#define PNG_READ_PACKSWAP_SUPPORTED
|
||||
#define PNG_READ_pCAL_SUPPORTED
|
||||
#define PNG_READ_pHYs_SUPPORTED
|
||||
#define PNG_READ_QUANTIZE_SUPPORTED
|
||||
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
|
||||
#define PNG_READ_sBIT_SUPPORTED
|
||||
#define PNG_READ_SCALE_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_sCAL_SUPPORTED
|
||||
#define PNG_READ_SHIFT_SUPPORTED
|
||||
#define PNG_READ_sPLT_SUPPORTED
|
||||
#define PNG_READ_sRGB_SUPPORTED
|
||||
#define PNG_READ_STRIP_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_STRIP_ALPHA_SUPPORTED
|
||||
#define PNG_READ_SUPPORTED
|
||||
#define PNG_READ_SWAP_ALPHA_SUPPORTED
|
||||
#define PNG_READ_SWAP_SUPPORTED
|
||||
#define PNG_READ_tEXt_SUPPORTED
|
||||
#define PNG_READ_TEXT_SUPPORTED
|
||||
#define PNG_READ_tIME_SUPPORTED
|
||||
#define PNG_READ_TRANSFORMS_SUPPORTED
|
||||
#define PNG_READ_tRNS_SUPPORTED
|
||||
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_USER_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_READ_zTXt_SUPPORTED
|
||||
#define PNG_SAVE_INT_32_SUPPORTED
|
||||
#define PNG_sBIT_SUPPORTED
|
||||
#define PNG_sCAL_SUPPORTED
|
||||
#define PNG_SEQUENTIAL_READ_SUPPORTED
|
||||
#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED
|
||||
#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
|
||||
#define PNG_SETJMP_SUPPORTED
|
||||
#define PNG_SET_USER_LIMITS_SUPPORTED
|
||||
#define PNG_sPLT_SUPPORTED
|
||||
#define PNG_sRGB_SUPPORTED
|
||||
#define PNG_STDIO_SUPPORTED
|
||||
#define PNG_tEXt_SUPPORTED
|
||||
#define PNG_TEXT_SUPPORTED
|
||||
#define PNG_TIME_RFC1123_SUPPORTED
|
||||
#define PNG_tIME_SUPPORTED
|
||||
#define PNG_tRNS_SUPPORTED
|
||||
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_USER_CHUNKS_SUPPORTED
|
||||
#define PNG_USER_LIMITS_SUPPORTED
|
||||
#define PNG_USER_MEM_SUPPORTED
|
||||
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
|
||||
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
|
||||
#define PNG_WARNINGS_SUPPORTED
|
||||
#define PNG_WRITE_16BIT_SUPPORTED
|
||||
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
|
||||
#define PNG_WRITE_BGR_SUPPORTED
|
||||
#define PNG_WRITE_bKGD_SUPPORTED
|
||||
#define PNG_WRITE_cHRM_SUPPORTED
|
||||
#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
|
||||
#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
|
||||
#define PNG_WRITE_FILLER_SUPPORTED
|
||||
#define PNG_WRITE_FILTER_SUPPORTED
|
||||
#define PNG_WRITE_FLUSH_SUPPORTED
|
||||
#define PNG_WRITE_gAMA_SUPPORTED
|
||||
#define PNG_WRITE_hIST_SUPPORTED
|
||||
#define PNG_WRITE_iCCP_SUPPORTED
|
||||
#define PNG_WRITE_INTERLACING_SUPPORTED
|
||||
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_SUPPORTED
|
||||
#define PNG_WRITE_iTXt_SUPPORTED
|
||||
#define PNG_WRITE_oFFs_SUPPORTED
|
||||
#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
|
||||
#define PNG_WRITE_PACK_SUPPORTED
|
||||
#define PNG_WRITE_PACKSWAP_SUPPORTED
|
||||
#define PNG_WRITE_pCAL_SUPPORTED
|
||||
#define PNG_WRITE_pHYs_SUPPORTED
|
||||
#define PNG_WRITE_sBIT_SUPPORTED
|
||||
#define PNG_WRITE_sCAL_SUPPORTED
|
||||
#define PNG_WRITE_SHIFT_SUPPORTED
|
||||
#define PNG_WRITE_sPLT_SUPPORTED
|
||||
#define PNG_WRITE_sRGB_SUPPORTED
|
||||
#define PNG_WRITE_SUPPORTED
|
||||
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
||||
#define PNG_WRITE_SWAP_SUPPORTED
|
||||
#define PNG_WRITE_tEXt_SUPPORTED
|
||||
#define PNG_WRITE_TEXT_SUPPORTED
|
||||
#define PNG_WRITE_tIME_SUPPORTED
|
||||
#define PNG_WRITE_TRANSFORMS_SUPPORTED
|
||||
#define PNG_WRITE_tRNS_SUPPORTED
|
||||
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
||||
#define PNG_WRITE_zTXt_SUPPORTED
|
||||
#define PNG_zTXt_SUPPORTED
|
||||
/* end of options */
|
||||
#endif /* PNGLCONF_H */
|
||||
1732
include/nana/extrlib/zlib.h
Normal file
1732
include/nana/extrlib/zlib.h
Normal file
File diff suppressed because it is too large
Load Diff
255
include/nana/filesystem/file_iterator.hpp
Normal file
255
include/nana/filesystem/file_iterator.hpp
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* A File Iterator Implementation
|
||||
* Copyright(C) 2003 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: stdex/filesystem/file_iterator.hpp
|
||||
* @description:
|
||||
* file_iterator is a toolkit for applying each file and directory in a
|
||||
* specified path.
|
||||
*/
|
||||
|
||||
#ifndef NANA_FILESYSTEM_FILE_ITERATOR_HPP
|
||||
#define NANA_FILESYSTEM_FILE_ITERATOR_HPP
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
#ifdef NANA_WINDOWS
|
||||
#include <windows.h>
|
||||
typedef HANDLE find_handle_t;
|
||||
#elif defined(NANA_LINUX)
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
typedef DIR* find_handle_t;
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
struct fileinfo
|
||||
{
|
||||
fileinfo();
|
||||
#ifdef NANA_WINDOWS
|
||||
fileinfo(const WIN32_FIND_DATA& wfd);
|
||||
#elif NANA_LINUX
|
||||
fileinfo(const nana::string& filename, const struct stat &);
|
||||
#endif
|
||||
nana::string name;
|
||||
|
||||
unsigned long size;
|
||||
bool directory;
|
||||
};
|
||||
|
||||
template<typename FileInfo>
|
||||
class basic_file_iterator
|
||||
:public std::iterator<std::input_iterator_tag, FileInfo>
|
||||
{
|
||||
public:
|
||||
typedef FileInfo value_type;
|
||||
|
||||
basic_file_iterator():end_(true), handle_(nullptr){}
|
||||
|
||||
basic_file_iterator(const nana::string& file_path)
|
||||
:end_(false), handle_(nullptr)
|
||||
{
|
||||
_m_prepare(file_path);
|
||||
}
|
||||
|
||||
const value_type&
|
||||
operator*() const { return value_; }
|
||||
|
||||
const value_type*
|
||||
operator->() const { return &(operator*()); }
|
||||
|
||||
basic_file_iterator& operator++()
|
||||
{ _m_read(); return *this; }
|
||||
|
||||
basic_file_iterator operator++(int)
|
||||
{
|
||||
basic_file_iterator tmp = *this;
|
||||
_m_read();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool equal(const basic_file_iterator& x) const
|
||||
{
|
||||
if(end_ && (end_ == x.end_)) return true;
|
||||
return (value_.name == x.value_.name);
|
||||
}
|
||||
private:
|
||||
template<typename Char>
|
||||
static bool _m_ignore(const Char * p)
|
||||
{
|
||||
while(*p == '.')
|
||||
++p;
|
||||
return (*p == 0);
|
||||
}
|
||||
|
||||
void _m_prepare(const nana::string& file_path)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
path_ = file_path;
|
||||
auto pat = file_path;
|
||||
DWORD attr = ::GetFileAttributes(pat.data());
|
||||
if((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
pat += STR("\\*");
|
||||
|
||||
::HANDLE handle = ::FindFirstFile(pat.data(), &wfd_);
|
||||
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
end_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
while(_m_ignore(wfd_.cFileName))
|
||||
{
|
||||
if(::FindNextFile(handle, &wfd_) == 0)
|
||||
{
|
||||
end_ = true;
|
||||
::FindClose(handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
value_ = value_type(wfd_);
|
||||
#elif defined(NANA_LINUX)
|
||||
path_ = nana::charset(file_path);
|
||||
if(path_.size() && (path_[path_.size() - 1] != '/'))
|
||||
path_ += '/';
|
||||
find_handle_t handle = opendir(path_.c_str());
|
||||
end_ = true;
|
||||
if(handle)
|
||||
{
|
||||
struct dirent * dnt = readdir(handle);
|
||||
if(dnt)
|
||||
{
|
||||
while(_m_ignore(dnt->d_name))
|
||||
{
|
||||
dnt = readdir(handle);
|
||||
if(dnt == 0)
|
||||
{
|
||||
closedir(handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
struct stat fst;
|
||||
if(stat((path_ + dnt->d_name).c_str(), &fst) == 0)
|
||||
{
|
||||
value_ = value_type(nana::charset(dnt->d_name), fst);
|
||||
}
|
||||
else
|
||||
{
|
||||
value_.name = nana::charset(dnt->d_name);
|
||||
value_.size = 0;
|
||||
value_.directory = false;
|
||||
}
|
||||
end_ = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(false == end_)
|
||||
{
|
||||
find_ptr_ = std::shared_ptr<find_handle_t>(new find_handle_t(handle), inner_handle_deleter());
|
||||
handle_ = handle;
|
||||
}
|
||||
}
|
||||
|
||||
void _m_read()
|
||||
{
|
||||
if(handle_)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
if(::FindNextFile(handle_, &wfd_) != 0)
|
||||
{
|
||||
while(_m_ignore(wfd_.cFileName))
|
||||
{
|
||||
if(::FindNextFile(handle_, &wfd_) == 0)
|
||||
{
|
||||
end_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
value_ = value_type(wfd_);
|
||||
}
|
||||
else
|
||||
end_ = true;
|
||||
#elif defined(NANA_LINUX)
|
||||
struct dirent * dnt = readdir(handle_);
|
||||
if(dnt)
|
||||
{
|
||||
while(_m_ignore(dnt->d_name))
|
||||
{
|
||||
dnt = readdir(handle_);
|
||||
if(dnt == 0)
|
||||
{
|
||||
end_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
struct stat fst;
|
||||
if(stat((path_ + "/" + dnt->d_name).c_str(), &fst) == 0)
|
||||
value_ = value_type(nana::charset(dnt->d_name), fst);
|
||||
else
|
||||
value_.name = nana::charset(dnt->d_name);
|
||||
}
|
||||
else
|
||||
end_ = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
private:
|
||||
struct inner_handle_deleter
|
||||
{
|
||||
void operator()(find_handle_t * handle)
|
||||
{
|
||||
if(handle && *handle)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
::FindClose(*handle);
|
||||
#elif defined(NANA_LINUX)
|
||||
::closedir(*handle);
|
||||
#endif
|
||||
}
|
||||
delete handle;
|
||||
}
|
||||
};
|
||||
private:
|
||||
bool end_;
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
WIN32_FIND_DATA wfd_;
|
||||
nana::string path_;
|
||||
#elif defined(NANA_LINUX)
|
||||
std::string path_;
|
||||
#endif
|
||||
std::shared_ptr<find_handle_t> find_ptr_;
|
||||
|
||||
find_handle_t handle_;
|
||||
value_type value_;
|
||||
};
|
||||
|
||||
template<typename Value_Type>
|
||||
inline bool operator==(const basic_file_iterator<Value_Type> & x, const basic_file_iterator<Value_Type> & y)
|
||||
{
|
||||
return x.equal(y);
|
||||
}
|
||||
|
||||
template<typename Value_Type>
|
||||
inline bool operator!=(const basic_file_iterator<Value_Type> & x, const basic_file_iterator<Value_Type> & y)
|
||||
{
|
||||
return !x.equal(y);
|
||||
}
|
||||
|
||||
typedef basic_file_iterator<fileinfo> file_iterator;
|
||||
}//end namespace filesystem
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
65
include/nana/filesystem/fs_utility.hpp
Normal file
65
include/nana/filesystem/fs_utility.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
#ifndef NANA_FILESYSTEM_FS_UTILITY_HPP
|
||||
#define NANA_FILESYSTEM_FS_UTILITY_HPP
|
||||
|
||||
#include <nana/deploy.hpp>
|
||||
#include <ctime>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
struct error
|
||||
{
|
||||
enum
|
||||
{
|
||||
none = 0
|
||||
};
|
||||
};
|
||||
|
||||
struct attribute
|
||||
{
|
||||
long long bytes;
|
||||
bool is_directory;
|
||||
tm modified;
|
||||
};
|
||||
|
||||
bool file_attrib(const nana::string& file, attribute&);
|
||||
long long filesize(const nana::string& file);
|
||||
|
||||
bool mkdir(const nana::string& dir, bool & if_exist);
|
||||
bool modified_file_time(const nana::string& file, struct tm&);
|
||||
|
||||
nana::string path_user();
|
||||
nana::string path_current();
|
||||
|
||||
bool rmfile(const nana::char_t* file);
|
||||
bool rmdir(const nana::char_t* dir, bool fails_if_not_empty);
|
||||
nana::string root(const nana::string& path);
|
||||
|
||||
class path
|
||||
{
|
||||
public:
|
||||
struct type
|
||||
{ enum{not_exist, file, directory};
|
||||
};
|
||||
|
||||
path();
|
||||
path(const nana::string&);
|
||||
|
||||
bool empty() const;
|
||||
path root() const;
|
||||
int what() const;
|
||||
|
||||
nana::string name() const;
|
||||
private:
|
||||
#if defined(NANA_WINDOWS)
|
||||
nana::string text_;
|
||||
#else
|
||||
std::string text_;
|
||||
#endif
|
||||
};
|
||||
}//end namespace filesystem
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
22
include/nana/fwd.hpp
Normal file
22
include/nana/fwd.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Forward Declarations
|
||||
* 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/fwd.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_FWD_HPP
|
||||
#define NANA_FWD_HPP
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class filebox;
|
||||
class msgbox;
|
||||
}//end namespace nana
|
||||
#endif //NANA_FWD_HPP
|
||||
1
include/nana/gui.hpp
Normal file
1
include/nana/gui.hpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "gui/wvl.hpp"
|
||||
82
include/nana/gui/animation.hpp
Normal file
82
include/nana/gui/animation.hpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* An Animation Implementation
|
||||
* Copyright(C) 2003-2013 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/animation.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_ANIMATION_HPP
|
||||
#define NANA_GUI_ANIMATION_HPP
|
||||
|
||||
#include <nana/paint/image.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class animation;
|
||||
/// Holds the frames and frame builders. Have reference semantics for efficiency.
|
||||
class frameset
|
||||
{
|
||||
friend class animation;
|
||||
public:
|
||||
/// function which builds frames.
|
||||
typedef std::function<bool(std::size_t pos, paint::graphics&, nana::size&)> framebuilder;
|
||||
|
||||
struct impl;
|
||||
public:
|
||||
frameset();
|
||||
void push_back(const paint::image&); ///< Inserts frames at the end.
|
||||
void push_back(paint::image&&);
|
||||
void push_back(framebuilder& fb, std::size_t length); ///< Insters a framebuilder and the number of frames that it generates.
|
||||
void push_back(framebuilder&& fb, std::size_t length); ///< Insters a framebuilder and the number of frames that it generates.
|
||||
private:
|
||||
std::shared_ptr<impl> impl_;
|
||||
};
|
||||
/// Easy way to display an animation or create an animated GUI
|
||||
class animation
|
||||
{
|
||||
struct branch_t
|
||||
{
|
||||
frameset frames;
|
||||
std::function<std::size_t(const std::string&, std::size_t, std::size_t&)> condition;
|
||||
};
|
||||
|
||||
struct impl;
|
||||
class performance_manager;
|
||||
public:
|
||||
animation();
|
||||
|
||||
void push_back(const frameset& frms);
|
||||
/*
|
||||
void branch(const std::string& name, const frameset& frms)
|
||||
{
|
||||
impl_->branches[name].frames = frms;
|
||||
}
|
||||
|
||||
void branch(const std::string& name, const frameset& frms, std::function<std::size_t(const std::string&, std::size_t, std::size_t&)> condition)
|
||||
{
|
||||
auto & br = impl_->branches[name];
|
||||
br.frames = frms;
|
||||
br.condition = condition;
|
||||
}
|
||||
*/
|
||||
|
||||
void looped(bool enable); ///< Enables or disables the animation repeating playback.
|
||||
|
||||
void play();
|
||||
|
||||
void pause();
|
||||
|
||||
void output(window wd, const nana::point& pos);
|
||||
private:
|
||||
impl * impl_;
|
||||
};
|
||||
} //end namespace nana
|
||||
#endif //NANA_GUI_ANIMATION_HPP
|
||||
241
include/nana/gui/basis.hpp
Normal file
241
include/nana/gui/basis.hpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Basis 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/gui/basis.hpp
|
||||
*
|
||||
* This file provides basis class and data structrue that required by gui
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_BASIS_HPP
|
||||
#define NANA_GUI_BASIS_HPP
|
||||
|
||||
#include "../basic_types.hpp"
|
||||
#include "../traits.hpp" //metacomp::fixed_type_set
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct native_window_handle_impl{};
|
||||
struct window_handle_impl{};
|
||||
struct event_handle_impl{};
|
||||
}
|
||||
|
||||
enum class checkstate
|
||||
{
|
||||
unchecked, checked, partial
|
||||
};
|
||||
|
||||
enum class window_border
|
||||
{
|
||||
none,
|
||||
left, right, top, bottom,
|
||||
top_left, top_right, bottom_left, bottom_right
|
||||
};
|
||||
|
||||
enum class bground_mode
|
||||
{
|
||||
none,
|
||||
basic,
|
||||
blend
|
||||
};
|
||||
|
||||
namespace category
|
||||
{
|
||||
enum class flags
|
||||
{
|
||||
super,
|
||||
widget = 0x1,
|
||||
lite_widget = 0x3,
|
||||
root = 0x5,
|
||||
frame = 0x9
|
||||
};
|
||||
//wait for constexpr
|
||||
struct widget_tag{ static const flags value = flags::widget; };
|
||||
struct lite_widget_tag : widget_tag{ static const flags value = flags::lite_widget;};
|
||||
struct root_tag : widget_tag{ static const flags value = flags::root; };
|
||||
struct frame_tag: widget_tag{ static const flags value = flags::frame; };
|
||||
}// end namespace category
|
||||
|
||||
typedef detail::native_window_handle_impl * native_window_type;
|
||||
|
||||
typedef detail::window_handle_impl* window; ///< \see [What is window class ](https://sourceforge.net/p/nanapro/discussion/general/thread/bd0fabfb/)
|
||||
typedef detail::event_handle_impl* event_handle;
|
||||
|
||||
|
||||
struct keyboard
|
||||
{
|
||||
enum t{
|
||||
//Control Code for ASCII
|
||||
select_all = 0x1,
|
||||
end_of_text = 0x3, //Ctrl+C
|
||||
backspace = 0x8, tab = 0x9,
|
||||
enter_n = 0xA, enter = 0xD, enter_r = 0xD,
|
||||
alt = 0x12,
|
||||
sync_idel = 0x16, //Ctrl+V
|
||||
cancel = 0x18, //Ctrl+X
|
||||
end_of_medium = 0x19, //Ctrl+Y
|
||||
substitute = 0x1A, //Ctrl+Z
|
||||
escape = 0x1B,
|
||||
|
||||
//The following names are intuitive name of ASCII control codes
|
||||
copy = 0x3, //end_of_text
|
||||
paste = 0x16, //sync_idel
|
||||
cut = 0x18, //cancel
|
||||
redo = 0x19, //end_of_medium
|
||||
undo = 0x1A, //substitue
|
||||
|
||||
//System Code for OS
|
||||
os_pageup = 0x21, os_pagedown,
|
||||
os_arrow_left = 0x25, os_arrow_up, os_arrow_right, os_arrow_down,
|
||||
os_insert = 0x2D, os_del
|
||||
};
|
||||
};
|
||||
|
||||
namespace color
|
||||
{
|
||||
enum
|
||||
{
|
||||
white = 0xFFFFFF,
|
||||
blue = 0x0000FF,
|
||||
green = 0x00FF00,
|
||||
red = 0xFF0000,
|
||||
|
||||
button_face_shadow_start = 0xF5F4F2,
|
||||
button_face_shadow_end = 0xD5D2CA,
|
||||
button_face = 0xD4D0C8,
|
||||
dark_border = 0x404040,
|
||||
gray_border = 0x808080,
|
||||
highlight = 0x1CC4F7
|
||||
};
|
||||
};
|
||||
|
||||
enum class cursor
|
||||
{
|
||||
hand = 60, ///< displays a hand to indicate a text or an element is clickable
|
||||
arrow = 68, ///< the default shape
|
||||
wait = 150, ///< indicates the system is currently busy
|
||||
iterm = 152, ///< A text caret. Displays a caret to indicate the UI is input able
|
||||
size_we = 108,
|
||||
size_ns = 116,
|
||||
size_top_left = 134,
|
||||
size_top_right = 136,
|
||||
size_bottom_left = 12,
|
||||
size_bottom_right = 14
|
||||
};
|
||||
|
||||
enum class mouse
|
||||
{
|
||||
any_button,
|
||||
left_button,
|
||||
middle_button,
|
||||
right_button
|
||||
};
|
||||
|
||||
enum class z_order_action
|
||||
{
|
||||
none,
|
||||
bottom, ///< brings a window at the bottom of z-order.
|
||||
top, ///< brings a widget at the top of the z-order.
|
||||
topmost, ///< brings a window at the top of the z-order and stays here.
|
||||
foreground ///< brings a window to the foreground.
|
||||
};
|
||||
|
||||
/// Window appearance structure defined to specify the appearance of a form
|
||||
struct appearance
|
||||
{
|
||||
bool taskbar;
|
||||
bool floating;
|
||||
bool no_activate;
|
||||
|
||||
bool minimize;
|
||||
bool maximize;
|
||||
bool sizable;
|
||||
|
||||
bool decoration;
|
||||
|
||||
appearance();
|
||||
appearance(bool has_decoration, bool taskbar, bool floating, bool no_activate, bool min, bool max, bool sizable);
|
||||
};
|
||||
/// Provided to generate an appearance object with better readability and understandability
|
||||
struct appear
|
||||
{
|
||||
struct minimize{};
|
||||
struct maximize{};
|
||||
struct sizable{};
|
||||
struct taskbar{};
|
||||
struct floating{};
|
||||
struct no_activate{};
|
||||
/// Create an appearance of a window with "decoration"
|
||||
template< typename Minimize = null_type,
|
||||
typename Maximize = null_type,
|
||||
typename Sizable = null_type,
|
||||
typename Floating = null_type,
|
||||
typename NoActive = null_type>
|
||||
struct decorate
|
||||
{
|
||||
typedef meta::fixed_type_set<Minimize, Maximize, Sizable, Floating, NoActive> set_type;
|
||||
|
||||
operator appearance() const
|
||||
{
|
||||
return appearance( true, true,
|
||||
set_type::template count<floating>::value,
|
||||
set_type::template count<no_activate>::value,
|
||||
set_type::template count<minimize>::value,
|
||||
set_type::template count<maximize>::value,
|
||||
set_type::template count<sizable>::value
|
||||
);
|
||||
}
|
||||
};
|
||||
/// Create an appearance of a window without "decoration"
|
||||
template < typename Taskbar = null_type,
|
||||
typename Floating = null_type,
|
||||
typename NoActive = null_type,
|
||||
typename Minimize = null_type,
|
||||
typename Maximize = null_type,
|
||||
typename Sizable = null_type>
|
||||
struct bald
|
||||
{
|
||||
typedef meta::fixed_type_set<Taskbar, Floating, NoActive, Minimize, Maximize, Sizable> set_type;
|
||||
|
||||
operator appearance() const
|
||||
{
|
||||
return appearance( false,
|
||||
set_type::template count<taskbar>::value,
|
||||
set_type::template count<floating>::value,
|
||||
set_type::template count<no_activate>::value,
|
||||
set_type::template count<minimize>::value,
|
||||
set_type::template count<maximize>::value,
|
||||
set_type::template count<sizable>::value
|
||||
);
|
||||
}
|
||||
};
|
||||
/// Create a window with decoration depending on the first non-type template parameter
|
||||
template < bool HasDecoration = true,
|
||||
typename Sizable = null_type,
|
||||
typename Taskbar = null_type,
|
||||
typename Floating = null_type,
|
||||
typename NoActive = null_type>
|
||||
struct optional
|
||||
{
|
||||
typedef meta::fixed_type_set<Taskbar, Floating, NoActive> set_type;
|
||||
|
||||
operator appearance() const
|
||||
{
|
||||
return appearance(HasDecoration,
|
||||
set_type::template count<taskbar>::value,
|
||||
set_type::template count<floating>::value,
|
||||
set_type::template count<no_activate>::value,
|
||||
true, true,
|
||||
set_type::template count<sizable>::value);
|
||||
}
|
||||
};
|
||||
};//end namespace apper
|
||||
}//end namespace nana
|
||||
#endif
|
||||
241
include/nana/gui/detail/basic_window.hpp
Normal file
241
include/nana/gui/detail/basic_window.hpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* A Basic Window Widget Definition
|
||||
* 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/gui/detail/basic_window.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP
|
||||
#define NANA_GUI_DETAIL_BASIC_WINDOW_HPP
|
||||
#include "drawer.hpp"
|
||||
#include "events_holder.hpp"
|
||||
#include "../basis.hpp"
|
||||
#include <nana/basic_types.hpp>
|
||||
#include <nana/system/platform.hpp>
|
||||
#include <nana/gui/effects.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace nana{
|
||||
class widget; //declaration ofr nana/widgets/widget.hpp
|
||||
namespace detail
|
||||
{
|
||||
struct basic_window;
|
||||
|
||||
class caret_descriptor
|
||||
{
|
||||
public:
|
||||
typedef basic_window core_window_t;
|
||||
|
||||
caret_descriptor(core_window_t*, unsigned width, unsigned height);
|
||||
~caret_descriptor();
|
||||
void set_active(bool);
|
||||
core_window_t* window() const;
|
||||
void position(int x, int y);
|
||||
void effective_range(::nana::rectangle);
|
||||
::nana::point position() const;
|
||||
void visible(bool isshow);
|
||||
bool visible() const;
|
||||
::nana::size size() const;
|
||||
void size(const ::nana::size&);
|
||||
|
||||
void update();
|
||||
private:
|
||||
void _m_visible(bool isshow);
|
||||
private:
|
||||
core_window_t* wd_;
|
||||
::nana::point point_;
|
||||
::nana::size size_;
|
||||
::nana::size paint_size_;
|
||||
bool visible_;
|
||||
bool real_visible_state_;
|
||||
bool out_of_range_;
|
||||
::nana::rectangle effective_range_;
|
||||
};//end class caret_descriptor
|
||||
|
||||
//tab_type
|
||||
//@brief: Define some constant about tab category, these flags can be combine with operator |
|
||||
struct tab_type
|
||||
{
|
||||
enum t
|
||||
{
|
||||
none, //process by nana
|
||||
tabstop, //move to the next tabstop window
|
||||
eating, //process by current window
|
||||
};
|
||||
};
|
||||
|
||||
//struct basic_window
|
||||
//@brief: a window data structure descriptor
|
||||
struct basic_window
|
||||
: public events_holder
|
||||
{
|
||||
typedef std::vector<basic_window*> container;
|
||||
|
||||
struct root_context
|
||||
{
|
||||
bool focus_changed;
|
||||
};
|
||||
|
||||
enum class update_state
|
||||
{
|
||||
none, lazy, refresh
|
||||
};
|
||||
|
||||
struct edge_nimbus_action
|
||||
{
|
||||
basic_window * window;
|
||||
bool rendered;
|
||||
};
|
||||
|
||||
//basic_window
|
||||
//@brief: constructor for the root window
|
||||
basic_window(basic_window* owner, widget*, category::root_tag**);
|
||||
|
||||
template<typename Category>
|
||||
basic_window(basic_window* parent, const rectangle& r, widget* wdg, Category**)
|
||||
: widget_ptr(wdg), other(Category::value)
|
||||
{
|
||||
drawer.bind(this);
|
||||
if(parent)
|
||||
{
|
||||
_m_init_pos_and_size(parent, r);
|
||||
_m_initialize(parent);
|
||||
}
|
||||
}
|
||||
|
||||
~basic_window();
|
||||
|
||||
//bind_native_window
|
||||
//@brief: bind a native window and baisc_window
|
||||
void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&);
|
||||
|
||||
void frame_window(native_window_type);
|
||||
|
||||
bool is_ancestor_of(const basic_window* wd) const;
|
||||
bool visible_parents() const;
|
||||
bool belong_to_lazy() const;
|
||||
public:
|
||||
//Override event_holder
|
||||
bool set_events(const std::shared_ptr<general_events>&) override;
|
||||
general_events * get_events() const override;
|
||||
private:
|
||||
void _m_init_pos_and_size(basic_window* parent, const rectangle&);
|
||||
void _m_initialize(basic_window* parent);
|
||||
public:
|
||||
#if defined(NANA_LINUX)
|
||||
point pos_native;
|
||||
#endif
|
||||
point pos_root; //coordinate for root window
|
||||
point pos_owner;
|
||||
size dimension;
|
||||
::nana::size min_track_size;
|
||||
::nana::size max_track_size;
|
||||
|
||||
bool visible;
|
||||
|
||||
unsigned extra_width;
|
||||
unsigned extra_height;
|
||||
|
||||
basic_window *parent;
|
||||
basic_window *owner;
|
||||
|
||||
::nana::string title;
|
||||
::nana::detail::drawer drawer; //Self Drawer with owen graphics
|
||||
basic_window* root_widget; //A pointer refers to the root basic window, if the window is a root, the pointer refers to itself.
|
||||
paint::graphics* root_graph; //Refer to the root buffer graphics
|
||||
cursor predef_cursor;
|
||||
widget* const widget_ptr;
|
||||
|
||||
struct flags_type
|
||||
{
|
||||
bool enabled :1;
|
||||
bool dbl_click :1;
|
||||
bool capture :1; //if mouse button is down, it always receive mouse move even the mouse is out of its rectangle
|
||||
bool modal :1;
|
||||
bool take_active:1; //If take_active is false, other.active_window still keeps the focus.
|
||||
bool refreshing :1;
|
||||
bool destroying :1;
|
||||
bool dropable :1; //Whether the window has make mouse_drop event.
|
||||
bool fullscreen :1; //When the window is maximizing whether it fit for fullscreen.
|
||||
bool borderless :1;
|
||||
unsigned Reserved :22;
|
||||
unsigned char tab; //indicate a window that can receive the keyboard TAB
|
||||
mouse_action action;
|
||||
}flags;
|
||||
|
||||
struct
|
||||
{
|
||||
caret_descriptor* caret;
|
||||
std::shared_ptr<general_events> events_ptr;
|
||||
general_events* attached_events;
|
||||
}together;
|
||||
|
||||
struct
|
||||
{
|
||||
color_t foreground;
|
||||
color_t background;
|
||||
color_t active;
|
||||
}color;
|
||||
|
||||
struct
|
||||
{
|
||||
effects::edge_nimbus edge_nimbus;
|
||||
effects::bground_interface * bground;
|
||||
double bground_fade_rate;
|
||||
}effect;
|
||||
|
||||
struct other_tag
|
||||
{
|
||||
struct attr_frame_tag
|
||||
{
|
||||
native_window_type container{nullptr};
|
||||
std::vector<native_window_type> attach;
|
||||
};
|
||||
|
||||
struct attr_root_tag
|
||||
{
|
||||
container frames; //initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame
|
||||
container tabstop;
|
||||
std::vector<edge_nimbus_action> effects_edge_nimbus;
|
||||
basic_window* focus{nullptr};
|
||||
basic_window* menubar{nullptr};
|
||||
root_context context;
|
||||
bool ime_enabled{false};
|
||||
#if defined(NANA_WINDOWS)
|
||||
cursor running_cursor{ nana::cursor::arrow };
|
||||
#endif
|
||||
cursor state_cursor{nana::cursor::arrow};
|
||||
basic_window* state_cursor_window{ nullptr };
|
||||
};
|
||||
|
||||
const category::flags category;
|
||||
basic_window *active_window; //if flags.take_active is false, the active_window still keeps the focus,
|
||||
//if the active_window is null, the parent of this window keeps focus.
|
||||
paint::graphics glass_buffer; //if effect.bground is avaiable. Refer to window_layout::make_bground.
|
||||
update_state upd_state;
|
||||
|
||||
union
|
||||
{
|
||||
attr_root_tag * root;
|
||||
attr_frame_tag * frame;
|
||||
}attribute;
|
||||
|
||||
other_tag(category::flags);
|
||||
~other_tag();
|
||||
}other;
|
||||
|
||||
native_window_type root; //root Window handle
|
||||
unsigned thread_id; //the identifier of the thread that created the window.
|
||||
unsigned index;
|
||||
container children;
|
||||
};
|
||||
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
#endif
|
||||
|
||||
102
include/nana/gui/detail/bedrock.hpp
Normal file
102
include/nana/gui/detail/bedrock.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* A Bedrock 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/gui/detail/bedrock.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_BEDROCK_HPP
|
||||
#define NANA_GUI_DETAIL_BEDROCK_HPP
|
||||
#include "window_manager.hpp"
|
||||
#include "events_operation.hpp"
|
||||
#include "runtime_manager.hpp"
|
||||
#include "general_events.hpp"
|
||||
#include "internal_scope_guard.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct native_interface;
|
||||
|
||||
class element_store;
|
||||
|
||||
//class bedrock
|
||||
//@brief: bedrock is a fundamental core component, it provides a abstract to the OS platform
|
||||
// and some basic functions.
|
||||
class bedrock
|
||||
{
|
||||
bedrock();
|
||||
public:
|
||||
typedef native_interface interface_type;
|
||||
typedef window_manager window_manager_t;
|
||||
typedef window_manager_t::core_window_t core_window_t;
|
||||
|
||||
struct thread_context;
|
||||
|
||||
~bedrock();
|
||||
void pump_event(window, bool is_modal);
|
||||
void map_thread_root_buffer(core_window_t* );
|
||||
static int inc_window(unsigned tid = 0);
|
||||
thread_context* open_thread_context(unsigned tid = 0);
|
||||
thread_context* get_thread_context(unsigned tid = 0);
|
||||
void remove_thread_context(unsigned tid = 0);
|
||||
static bedrock& instance();
|
||||
|
||||
::nana::category::flags category(core_window_t*);
|
||||
core_window_t* focus();
|
||||
native_window_type root(core_window_t*);
|
||||
|
||||
void set_menubar_taken(core_window_t*);
|
||||
core_window_t* get_menubar_taken();
|
||||
bool close_menu_if_focus_other_window(native_window_type focus);
|
||||
void set_menu(native_window_type menu_window, bool is_keyboard_condition);
|
||||
native_window_type get_menu(native_window_type owner, bool is_keyboard_condition);
|
||||
native_window_type get_menu();
|
||||
void remove_menu();
|
||||
void empty_menu();
|
||||
|
||||
void get_key_state(arg_keyboard&);
|
||||
bool set_keyboard_shortkey(bool yes);
|
||||
bool whether_keyboard_shortkey() const;
|
||||
|
||||
element_store& get_element_store() const;
|
||||
public:
|
||||
void event_expose(core_window_t *, bool exposed);
|
||||
void event_move(core_window_t*, int x, int y);
|
||||
bool event_msleave(core_window_t*);
|
||||
void thread_context_destroy(core_window_t*);
|
||||
void thread_context_lazy_refresh();
|
||||
void update_cursor(core_window_t*);
|
||||
void set_cursor(core_window_t*, nana::cursor, thread_context*);
|
||||
void define_state_cursor(core_window_t*, nana::cursor, thread_context*);
|
||||
void undefine_state_cursor(core_window_t*, thread_context*);
|
||||
public:
|
||||
window_manager_t wd_manager;
|
||||
events_operation evt_operation;
|
||||
|
||||
runtime_manager<core_window_t*, bedrock> rt_manager;
|
||||
|
||||
bool emit(event_code, core_window_t*, const arg_mouse&, bool ask_update, thread_context*);
|
||||
bool emit(event_code, core_window_t*, const event_arg_interface&, bool ask_update, thread_context*);
|
||||
bool emit_drawer(event_code, core_window_t*, const event_arg_interface&, thread_context*);
|
||||
private:
|
||||
void _m_emit_core(event_code, core_window_t*, bool draw_only, const event_arg_interface&);
|
||||
void _m_event_filter(event_code, core_window_t*, thread_context*);
|
||||
void _m_except_handler();
|
||||
private:
|
||||
static bedrock bedrock_object;
|
||||
|
||||
struct private_impl;
|
||||
private_impl *impl_;
|
||||
};//end class bedrock
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
165
include/nana/gui/detail/drawer.hpp
Normal file
165
include/nana/gui/detail/drawer.hpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* A Drawer 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/gui/detail/drawer.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_DRAWER_HPP
|
||||
#define NANA_GUI_DETAIL_DRAWER_HPP
|
||||
|
||||
#include <vector>
|
||||
#include "general_events.hpp"
|
||||
#include <nana/paint/graphics.hpp>
|
||||
#include <nana/paint/image.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class widget;
|
||||
|
||||
class drawer_trigger
|
||||
: ::nana::noncopyable, ::nana::nonmovable
|
||||
{
|
||||
public:
|
||||
typedef widget& widget_reference;
|
||||
typedef paint::graphics& graph_reference;
|
||||
|
||||
virtual ~drawer_trigger();
|
||||
virtual void attached(widget_reference, graph_reference); //none-const
|
||||
virtual void detached(); //none-const
|
||||
|
||||
virtual void typeface_changed(graph_reference);
|
||||
virtual void refresh(graph_reference);
|
||||
|
||||
virtual void resizing(graph_reference, const arg_resizing&);
|
||||
virtual void resized(graph_reference, const arg_resized&);
|
||||
virtual void move(graph_reference, const arg_move&);
|
||||
virtual void click(graph_reference, const arg_mouse&);
|
||||
virtual void dbl_click(graph_reference, const arg_mouse&);
|
||||
virtual void mouse_enter(graph_reference, const arg_mouse&);
|
||||
virtual void mouse_move(graph_reference, const arg_mouse&);
|
||||
virtual void mouse_leave(graph_reference, const arg_mouse&);
|
||||
virtual void mouse_down(graph_reference, const arg_mouse&);
|
||||
virtual void mouse_up(graph_reference, const arg_mouse&);
|
||||
virtual void mouse_wheel(graph_reference, const arg_wheel&);
|
||||
virtual void mouse_dropfiles(graph_reference, const arg_dropfiles&);
|
||||
|
||||
virtual void focus(graph_reference, const arg_focus&);
|
||||
virtual void key_press(graph_reference, const arg_keyboard&);
|
||||
virtual void key_char(graph_reference, const arg_keyboard&);
|
||||
virtual void key_release(graph_reference, const arg_keyboard&);
|
||||
virtual void shortkey(graph_reference, const arg_keyboard&);
|
||||
|
||||
void _m_reset_overrided();
|
||||
bool _m_overrided() const;
|
||||
private:
|
||||
bool overrided_{false};
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct basic_window;
|
||||
|
||||
namespace dynamic_drawing
|
||||
{
|
||||
//declaration
|
||||
class object;
|
||||
}
|
||||
|
||||
//@brief: Every window has a drawer, the drawer holds a drawer_trigger for
|
||||
// a widget.
|
||||
class drawer
|
||||
: nana::noncopyable, nana::nonmovable
|
||||
{
|
||||
enum{
|
||||
event_size = static_cast<int>(event_code::end)
|
||||
};
|
||||
|
||||
enum class method_state
|
||||
{
|
||||
unknown,
|
||||
overrided,
|
||||
not_overrided
|
||||
};
|
||||
public:
|
||||
~drawer();
|
||||
|
||||
void bind(basic_window*);
|
||||
|
||||
void typeface_changed();
|
||||
void click(const arg_mouse&);
|
||||
void dbl_click(const arg_mouse&);
|
||||
void mouse_enter(const arg_mouse&);
|
||||
void mouse_move(const arg_mouse&);
|
||||
void mouse_leave(const arg_mouse&);
|
||||
void mouse_down(const arg_mouse&);
|
||||
void mouse_up(const arg_mouse&);
|
||||
void mouse_wheel(const arg_wheel&);
|
||||
void mouse_dropfiles(const arg_dropfiles&);
|
||||
void resizing(const arg_resizing&);
|
||||
void resized(const arg_resized&);
|
||||
void move(const arg_move&);
|
||||
void focus(const arg_focus&);
|
||||
void key_press(const arg_keyboard&);
|
||||
void key_char(const arg_keyboard&);
|
||||
void key_release(const arg_keyboard&);
|
||||
void shortkey(const arg_keyboard&);
|
||||
void map(window); //Copy the root buffer to screen
|
||||
void refresh();
|
||||
drawer_trigger* realizer() const;
|
||||
void attached(widget&, drawer_trigger&);
|
||||
drawer_trigger* detached();
|
||||
public:
|
||||
void clear();
|
||||
void* draw(std::function<void(paint::graphics&)> &&, bool diehard);
|
||||
void erase(void* diehard);
|
||||
private:
|
||||
void _m_bground_pre();
|
||||
void _m_bground_end();
|
||||
void _m_draw_dynamic_drawing_object();
|
||||
void _m_use_refresh();
|
||||
|
||||
template<typename Arg, typename Mfptr>
|
||||
void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr)
|
||||
{
|
||||
if (realizer_)
|
||||
{
|
||||
const int pos = static_cast<int>(evt_code);
|
||||
if (method_state::not_overrided != mth_state_[pos])
|
||||
{
|
||||
_m_bground_pre();
|
||||
|
||||
if (method_state::unknown == mth_state_[pos])
|
||||
{
|
||||
realizer_->_m_reset_overrided();
|
||||
(realizer_->*mfptr)(graphics, arg);
|
||||
mth_state_[pos] = (realizer_->_m_overrided() ? method_state::overrided : method_state::not_overrided);
|
||||
}
|
||||
else
|
||||
(realizer_->*mfptr)(graphics, arg);
|
||||
|
||||
_m_use_refresh();
|
||||
_m_draw_dynamic_drawing_object();
|
||||
_m_bground_end();
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
nana::paint::graphics graphics;
|
||||
private:
|
||||
basic_window* core_window_{nullptr};
|
||||
drawer_trigger* realizer_{nullptr};
|
||||
std::vector<dynamic_drawing::object*> dynamic_drawing_objects_;
|
||||
bool refreshing_{false};
|
||||
method_state mth_state_[event_size];
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
69
include/nana/gui/detail/dynamic_drawing_object.hpp
Normal file
69
include/nana/gui/detail/dynamic_drawing_object.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Dynamic Drawing Object Implementation
|
||||
* Copyright(C) 2003-2013 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/dynamic_drawing_object.hpp
|
||||
*
|
||||
* !DON'T INCLUDE THIS HEADER FILE IN YOUR SOURCE CODE
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_DYNAMIC_DRAWING_OBJECT_HPP
|
||||
#define NANA_GUI_DETAIL_DYNAMIC_DRAWING_OBJECT_HPP
|
||||
|
||||
#include <nana/paint/graphics.hpp>
|
||||
#include <nana/paint/image.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace dynamic_drawing
|
||||
{
|
||||
class object
|
||||
{
|
||||
object(const object&) = delete;
|
||||
object& operator=(const object&) = delete;
|
||||
public:
|
||||
object(){}
|
||||
virtual ~object(){}
|
||||
|
||||
virtual bool diehard() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void draw(nana::paint::graphics&) const = 0;
|
||||
};
|
||||
|
||||
//user_draw_function
|
||||
class user_draw_function
|
||||
: public object
|
||||
{
|
||||
public:
|
||||
user_draw_function(std::function<void(paint::graphics&)> && f, bool diehard)
|
||||
: diehard_(diehard), fn_(std::move(f))
|
||||
{}
|
||||
|
||||
void draw(paint::graphics& graph) const
|
||||
{
|
||||
fn_(graph);
|
||||
}
|
||||
|
||||
bool diehard() const
|
||||
{
|
||||
return diehard_;
|
||||
}
|
||||
private:
|
||||
bool diehard_;
|
||||
std::function<void(paint::graphics&)> fn_;
|
||||
};
|
||||
}//end namespace dynamic_drawing
|
||||
}
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
152
include/nana/gui/detail/effects_renderer.hpp
Normal file
152
include/nana/gui/detail/effects_renderer.hpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#ifndef NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
|
||||
#define NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
|
||||
#include <nana/gui/effects.hpp>
|
||||
#include <nana/paint/graphics.hpp>
|
||||
#include <nana/paint/pixel_buffer.hpp>
|
||||
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
|
||||
namespace nana{
|
||||
namespace detail
|
||||
{
|
||||
template<typename CoreWindow>
|
||||
class edge_nimbus_renderer
|
||||
{
|
||||
edge_nimbus_renderer(){}
|
||||
public:
|
||||
typedef CoreWindow core_window_t;
|
||||
typedef window_layout window_layer;
|
||||
typedef nana::paint::graphics & graph_reference;
|
||||
|
||||
static edge_nimbus_renderer& instance()
|
||||
{
|
||||
static edge_nimbus_renderer object;
|
||||
return object;
|
||||
}
|
||||
|
||||
std::size_t weight() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool render(core_window_t * wd)
|
||||
{
|
||||
bool rendered = false;
|
||||
core_window_t * root_wd = wd->root_widget;
|
||||
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
|
||||
|
||||
if(nimbus.size())
|
||||
{
|
||||
core_window_t * focused = root_wd->other.attribute.root->focus;
|
||||
native_window_type native = root_wd->root;
|
||||
std::size_t pixels = weight();
|
||||
|
||||
auto graph = root_wd->root_graph;
|
||||
|
||||
std::vector<core_window_t*> erase;
|
||||
std::vector<rectangle> r_set;
|
||||
nana::rectangle r;
|
||||
for(auto & action : nimbus)
|
||||
{
|
||||
if(_m_edge_nimbus(focused, action.window) && window_layer::read_visual_rectangle(action.window, r))
|
||||
{
|
||||
if(action.window == wd)
|
||||
rendered = true;
|
||||
|
||||
r_set.push_back(r);
|
||||
action.rendered = true;
|
||||
}
|
||||
else if(action.rendered)
|
||||
{
|
||||
action.rendered = false;
|
||||
erase.push_back(action.window);
|
||||
}
|
||||
}
|
||||
|
||||
//Erase
|
||||
for(auto el : erase)
|
||||
{
|
||||
if(el == wd)
|
||||
rendered = true;
|
||||
|
||||
r.x = el->pos_root.x - static_cast<int>(pixels);
|
||||
r.y = el->pos_root.y - static_cast<int>(pixels);
|
||||
r.width = static_cast<unsigned>(el->dimension.width + (pixels << 1));
|
||||
r.height = static_cast<unsigned>(el->dimension.height + (pixels << 1));
|
||||
|
||||
graph->paste(native, r, r.x, r.y);
|
||||
}
|
||||
|
||||
auto visual_iterator = r_set.begin();
|
||||
//Render
|
||||
for(auto & action : nimbus)
|
||||
{
|
||||
if(action.rendered)
|
||||
_m_render_edge_nimbus(action.window, *(visual_iterator++));
|
||||
}
|
||||
}
|
||||
return rendered;
|
||||
}
|
||||
private:
|
||||
static bool _m_edge_nimbus(core_window_t * focused_wd, core_window_t * wd)
|
||||
{
|
||||
if((focused_wd == wd) && (static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::active)))
|
||||
return true;
|
||||
else if((static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::over)) && (wd->flags.action == mouse_action::over))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _m_render_edge_nimbus(core_window_t* wd, const nana::rectangle & visual)
|
||||
{
|
||||
nana::rectangle r(visual);
|
||||
r.pare_off(-static_cast<int>(weight()));
|
||||
nana::rectangle good_r;
|
||||
if(overlap(r, nana::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))
|
||||
{
|
||||
auto graph = wd->root_graph;
|
||||
nana::paint::pixel_buffer pixbuf(graph->handle(), r);
|
||||
|
||||
pixel_rgb_t px0, px1, px2, px3;
|
||||
|
||||
px0 = pixbuf.pixel(0, 0);
|
||||
px1 = pixbuf.pixel(r.width - 1, 0);
|
||||
px2 = pixbuf.pixel(0, r.height - 1);
|
||||
px3 = pixbuf.pixel(r.width - 1, r.height - 1);
|
||||
|
||||
good_r.x = good_r.y = 1;
|
||||
good_r.width = r.width - 2;
|
||||
good_r.height = r.height - 2;
|
||||
pixbuf.rectangle(good_r, wd->color.active, 0.95, false);
|
||||
|
||||
good_r.x = good_r.y = 0;
|
||||
good_r.width = r.width;
|
||||
good_r.height = r.height;
|
||||
pixbuf.rectangle(good_r, wd->color.active, 0.4, false);
|
||||
|
||||
pixbuf.pixel(0, 0, px0);
|
||||
pixbuf.pixel(r.width - 1, 0, px1);
|
||||
pixbuf.pixel(0, r.height - 1, px2);
|
||||
pixbuf.pixel(r.width - 1, r.height - 1, px3);
|
||||
|
||||
pixbuf.paste(wd->root, r.x, r.y);
|
||||
|
||||
std::vector<typename window_layer::wd_rectangle> overlaps;
|
||||
if(window_layer::read_overlaps(wd, visual, overlaps))
|
||||
{
|
||||
for(auto & wdr : overlaps)
|
||||
graph->paste(wd->root, wdr.r, wdr.r.x, wdr.r.y);
|
||||
}
|
||||
}
|
||||
else
|
||||
wd->root_graph->paste(wd->root, visual, visual.x, visual.y);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
52
include/nana/gui/detail/element_store.hpp
Normal file
52
include/nana/gui/detail/element_store.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* The Store for the Storage Of Elements
|
||||
* 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/gui/detail/element_store.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_ELEMENT_STORE_HPP
|
||||
#define NANA_GUI_DETAIL_ELEMENT_STORE_HPP
|
||||
|
||||
#include <nana/gui/element.hpp>
|
||||
#include <nana/pat/cloneable.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class element_store
|
||||
{
|
||||
typedef ::nana::element::element_interface element_interface;
|
||||
typedef pat::cloneable< ::nana::element::element_interface> cloneable_element;
|
||||
|
||||
struct data
|
||||
{
|
||||
cloneable_element object;
|
||||
::nana::element::element_interface * fast_ptr;
|
||||
|
||||
data();
|
||||
};
|
||||
|
||||
struct store
|
||||
{
|
||||
std::map<std::string, data> table;
|
||||
};
|
||||
public:
|
||||
element_interface * const * bground(const std::string&);
|
||||
void bground(const std::string&, const pat::cloneable<element_interface>&);
|
||||
void bground(const std::string&, pat::cloneable<element_interface>&&);
|
||||
private:
|
||||
store bground_;
|
||||
};
|
||||
}//end namespace detail
|
||||
}
|
||||
|
||||
#endif
|
||||
48
include/nana/gui/detail/event_code.hpp
Normal file
48
include/nana/gui/detail/event_code.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Definitions of General Events Code
|
||||
* 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/event_code.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_DETAIL_EVENT_CODE_HPP
|
||||
#define NANA_DETAIL_EVENT_CODE_HPP
|
||||
|
||||
namespace nana
|
||||
{
|
||||
enum class event_code
|
||||
{
|
||||
click, ///< A mouse click event.
|
||||
dbl_click, ///< A mouse double click event.
|
||||
mouse_enter, ///< A mouse enters a widget.
|
||||
mouse_move, ///< A mouse moves over a widget.
|
||||
mouse_leave, ///< A mouse leaves a widget.
|
||||
mouse_down, ///< A mouse button is pressed on a widget.
|
||||
mouse_up, ///< A mouse button is released on a widget.
|
||||
mouse_wheel, ///< A mouse scrolls the wheel on a widget.
|
||||
mouse_drop, ///< A mouse release over a window that is registered as recipient of drag and drop.
|
||||
expose, ///<
|
||||
resizing, ///< A widget's size is sizing. In this event, A widget's size can be overrided with a new size.
|
||||
resized, ///< A widget's size is changing.
|
||||
move, ///<
|
||||
unload, ///< A form is closed by clicking the X button, only works for root widget.
|
||||
destroy, ///< A widget is about to be destroyed.
|
||||
focus, ///< A widget's focus is changed.
|
||||
key_press, ///< A keyboard is pressed on a focus widget.
|
||||
key_char, ///< The focus widget received a character.
|
||||
key_release, ///< A keyboard is released on a focus widget.
|
||||
shortkey, ///< The widgets received a shortkey message.
|
||||
|
||||
elapse, ///< Unoperational events? . A widget received a tick that is sended by timer.
|
||||
|
||||
end ///< End indicator, it's not an event.
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
20
include/nana/gui/detail/events_holder.hpp
Normal file
20
include/nana/gui/detail/events_holder.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef NANA_DETAIL_EVENTS_HOLDER_HPP
|
||||
#define NANA_DETAIL_EVENTS_HOLDER_HPP
|
||||
#include <memory>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
struct general_events;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class events_holder
|
||||
{
|
||||
public:
|
||||
virtual ~events_holder(){}
|
||||
virtual bool set_events(const std::shared_ptr<general_events>&) = 0;
|
||||
virtual general_events* get_events() const = 0;
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
#endif
|
||||
35
include/nana/gui/detail/events_operation.hpp
Normal file
35
include/nana/gui/detail/events_operation.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef NANA_DETAIL_EVENTS_OPERATION_HPP
|
||||
#define NANA_DETAIL_EVENTS_OPERATION_HPP
|
||||
|
||||
#include <nana/gui/detail/general_events.hpp>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
|
||||
#if defined(NANA_MINGW) && defined(STD_THREAD_NOT_SUPPORTED)
|
||||
#include <nana/std_mutex.hpp>
|
||||
#else
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class events_operation
|
||||
{
|
||||
public:
|
||||
void make(window, const std::shared_ptr<general_events> &);
|
||||
void umake(window);
|
||||
void register_evt(event_handle);
|
||||
void cancel(event_handle);
|
||||
void erase(event_handle);
|
||||
std::size_t size() const;
|
||||
private:
|
||||
mutable std::recursive_mutex mutex_;
|
||||
std::unordered_set<event_handle> register_;
|
||||
std::unordered_map<window, std::shared_ptr<general_events>> evt_table_;
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
497
include/nana/gui/detail/general_events.hpp
Normal file
497
include/nana/gui/detail/general_events.hpp
Normal file
@@ -0,0 +1,497 @@
|
||||
/*
|
||||
* Definition of General Events
|
||||
* 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/gui/detail/general_events.hpp
|
||||
*/
|
||||
#ifndef NANA_DETAIL_GENERAL_EVENTS_HPP
|
||||
#define NANA_DETAIL_GENERAL_EVENTS_HPP
|
||||
|
||||
#include <nana/gui/basis.hpp>
|
||||
#include "event_code.hpp"
|
||||
#include "internal_scope_guard.hpp"
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class event_interface
|
||||
{
|
||||
public:
|
||||
virtual ~event_interface(){}
|
||||
virtual void remove(event_handle) = 0;
|
||||
};
|
||||
|
||||
class docker_interface
|
||||
{
|
||||
public:
|
||||
virtual ~docker_interface(){}
|
||||
virtual event_interface* get_event() const = 0;
|
||||
};
|
||||
|
||||
class event_arg_interface
|
||||
{
|
||||
public:
|
||||
virtual ~event_arg_interface(){}
|
||||
};
|
||||
|
||||
void events_operation_register(event_handle);
|
||||
void events_operation_cancel(event_handle);
|
||||
}//end namespace detail
|
||||
|
||||
struct general_events;
|
||||
|
||||
template<typename Arg>
|
||||
class basic_event : public detail::event_interface
|
||||
{
|
||||
public:
|
||||
typedef const typename std::remove_reference<Arg>::type & arg_reference;
|
||||
private:
|
||||
struct docker
|
||||
: public detail::docker_interface
|
||||
{
|
||||
basic_event * const event_ptr;
|
||||
std::function<void(arg_reference)> invoke;
|
||||
bool flag_entered = false;
|
||||
bool flag_deleted = false;
|
||||
|
||||
docker(basic_event * s, std::function<void(arg_reference)> && ivk)
|
||||
: event_ptr(s), invoke(std::move(ivk))
|
||||
{}
|
||||
|
||||
docker(basic_event * s, const std::function<void(arg_reference)> & ivk)
|
||||
: event_ptr(s), invoke(ivk)
|
||||
{}
|
||||
|
||||
~docker()
|
||||
{
|
||||
detail::events_operation_cancel(reinterpret_cast<event_handle>(this));
|
||||
}
|
||||
|
||||
detail::event_interface * get_event() const override
|
||||
{
|
||||
return event_ptr;
|
||||
}
|
||||
};
|
||||
public:
|
||||
template<typename Function>
|
||||
event_handle connect_front(Function && fn)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
if (nullptr == dockers_)
|
||||
dockers_.reset(new std::vector<std::unique_ptr<docker>>);
|
||||
|
||||
typedef typename std::remove_reference<Function>::type prototype;
|
||||
std::unique_ptr<docker> dck(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn))));
|
||||
auto evt = reinterpret_cast<event_handle>(static_cast<detail::docker_interface*>(dck.get()));
|
||||
dockers_->emplace(dockers_->begin(), std::move(dck));
|
||||
detail::events_operation_register(evt);
|
||||
return evt;
|
||||
}
|
||||
|
||||
event_handle connect(void (*fn)(arg_reference))
|
||||
{
|
||||
return connect([fn](arg_reference arg){
|
||||
fn(arg);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Function>
|
||||
event_handle connect(Function && fn)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
if (nullptr == dockers_)
|
||||
dockers_.reset(new std::vector<std::unique_ptr<docker>>);
|
||||
|
||||
typedef typename std::remove_reference<Function>::type prototype;
|
||||
std::unique_ptr<docker> dck(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn))));
|
||||
auto evt = reinterpret_cast<event_handle>(static_cast<detail::docker_interface*>(dck.get()));
|
||||
dockers_->emplace_back(std::move(dck));
|
||||
detail::events_operation_register(evt);
|
||||
return evt;
|
||||
}
|
||||
|
||||
template<typename Function>
|
||||
event_handle operator()(Function&& fn)
|
||||
{
|
||||
return connect(std::forward<Function>(fn));
|
||||
}
|
||||
|
||||
std::size_t length() const
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
return (nullptr == dockers_ ? 0 : dockers_->size());
|
||||
}
|
||||
|
||||
void emit(arg_reference& arg) const
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
if (nullptr == dockers_)
|
||||
return;
|
||||
|
||||
//Make a copy to allow create/destroy a new event handler when the call of emit in an event.
|
||||
const std::size_t fixed_size = 10;
|
||||
docker* fixed_buffer[fixed_size];
|
||||
docker** transitory = fixed_buffer;
|
||||
|
||||
std::unique_ptr<docker*[]> variable_buffer;
|
||||
auto& dockers = *dockers_;
|
||||
if (dockers.size() > fixed_size)
|
||||
{
|
||||
variable_buffer.reset(new docker*[dockers.size()]);
|
||||
transitory = variable_buffer.get();
|
||||
}
|
||||
|
||||
auto output = transitory;
|
||||
for (auto & dck : dockers)
|
||||
{
|
||||
(*output++) = dck.get();
|
||||
}
|
||||
|
||||
for (; transitory != output; ++transitory)
|
||||
{
|
||||
std::unique_ptr<docker> p(*transitory);
|
||||
auto i = std::find(dockers.begin(), dockers.end(), p);
|
||||
if (i != dockers.end())
|
||||
{
|
||||
(*transitory)->flag_entered = true;
|
||||
(*transitory)->invoke(arg);
|
||||
(*transitory)->flag_entered = false;
|
||||
|
||||
if ((*transitory)->flag_deleted)
|
||||
dockers.erase(i);
|
||||
}
|
||||
p.release();
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
if (dockers_)
|
||||
dockers_.reset();
|
||||
}
|
||||
|
||||
void remove(event_handle evt)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
if (dockers_)
|
||||
{
|
||||
auto i = std::find_if(dockers_->begin(), dockers_->end(), [evt](const std::unique_ptr<docker>& sp)
|
||||
{
|
||||
return (reinterpret_cast<detail::docker_interface*>(evt) == sp.get());
|
||||
});
|
||||
|
||||
if (i != dockers_->end())
|
||||
{
|
||||
if (i->get()->flag_entered)
|
||||
i->get()->flag_deleted = true;
|
||||
else
|
||||
dockers_->erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
template<typename Fn, bool IsBind>
|
||||
struct factory
|
||||
{
|
||||
static std::function<void(arg_reference)> build(Fn && fn)
|
||||
{
|
||||
return std::move(fn);
|
||||
}
|
||||
|
||||
static std::function<void(arg_reference)> build(const Fn & fn)
|
||||
{
|
||||
return fn;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Fn>
|
||||
struct factory<Fn, false>
|
||||
{
|
||||
typedef typename std::remove_reference<arg_reference>::type arg_type;
|
||||
typedef typename std::remove_reference<Fn>::type fn_type;
|
||||
|
||||
template<typename Tfn>
|
||||
static std::function<void(arg_reference)> build(Tfn && fn)
|
||||
{
|
||||
typedef typename std::remove_reference<Tfn>::type type;
|
||||
return build_second(std::forward<Tfn>(fn), &type::operator());
|
||||
}
|
||||
|
||||
template<typename Tfn, typename Ret>
|
||||
static std::function<void(arg_reference)> build_second(Tfn&& fn, Ret(fn_type::*)())
|
||||
{
|
||||
return [fn](arg_reference) mutable
|
||||
{
|
||||
fn();
|
||||
};
|
||||
}
|
||||
|
||||
static std::function<void(arg_reference)> build_second(fn_type&& fn, void(fn_type::*)(arg_reference))
|
||||
{
|
||||
return std::move(fn);
|
||||
}
|
||||
|
||||
template<typename Tfn, typename Ret>
|
||||
static std::function<void(arg_reference)> build_second(Tfn&& fn, Ret(fn_type::*)()const)
|
||||
{
|
||||
return [fn](arg_reference) mutable
|
||||
{
|
||||
fn();
|
||||
};
|
||||
}
|
||||
|
||||
static std::function<void(arg_reference)> build_second(fn_type&& fn, void(fn_type::*)(arg_reference) const)
|
||||
{
|
||||
return std::move(fn);
|
||||
}
|
||||
|
||||
template<typename Tfn, typename Ret, typename Arg2>
|
||||
static std::function<void(arg_reference)> build_second(Tfn&& fn, Ret(fn_type::*)(Arg2))
|
||||
{
|
||||
static_assert(std::is_convertible<arg_type, Arg2>::value, "The parameter type is not allowed, please check the function parameter type where you connected the event function.");
|
||||
return[fn](arg_reference arg) mutable
|
||||
{
|
||||
fn(arg);
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Tfn, typename Ret, typename Arg2>
|
||||
static std::function<void(arg_reference)> build_second(Tfn&& fn, Ret(fn_type::*)(Arg2)const)
|
||||
{
|
||||
static_assert(std::is_convertible<arg_type, Arg2>::value, "The parameter type is not allowed, please check the function parameter type where you connected the event function.");
|
||||
return [fn](arg_reference arg) mutable
|
||||
{
|
||||
fn(arg);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ret, typename Arg2>
|
||||
struct factory < std::function<Ret(Arg2)>, false>
|
||||
{
|
||||
typedef typename std::remove_reference<arg_reference>::type arg_type;
|
||||
static_assert(std::is_convertible<arg_type, Arg2>::value, "The parameter type is not allowed, please check the function parameter type where you connected the event function.");
|
||||
|
||||
static std::function<void(arg_reference)> build(const std::function<Ret(Arg2)>& fn)
|
||||
{
|
||||
return [fn](arg_reference arg) mutable{
|
||||
fn(arg);
|
||||
};
|
||||
}
|
||||
|
||||
static std::function<void(arg_reference)> build_second(std::function<void(arg_reference)> && fn)
|
||||
{
|
||||
return std::move(fn);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ret>
|
||||
struct factory < std::function<Ret()>, false>
|
||||
{
|
||||
static std::function<void(arg_reference)> build(const std::function<Ret()>& fn)
|
||||
{
|
||||
return[fn](arg_reference) mutable{
|
||||
fn();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ret>
|
||||
struct factory < Ret(*)(), false>
|
||||
{
|
||||
static std::function<void(arg_reference)> build(Ret(*fn)())
|
||||
{
|
||||
return[fn](arg_reference) mutable{
|
||||
fn();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ret, typename Arg2>
|
||||
struct factory < Ret(*)(Arg2), false>
|
||||
{
|
||||
typedef typename std::remove_reference<arg_reference>::type arg_type;
|
||||
static_assert(std::is_convertible<arg_type, Arg2>::value, "The parameter type is not allowed, please check the function parameter type where you connected the event function.");
|
||||
|
||||
static std::function<void(arg_reference)> build(Ret(*fn)(Arg2))
|
||||
{
|
||||
return[fn](arg_reference arg) mutable {
|
||||
fn(arg);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ret>
|
||||
struct factory < Ret(), false>
|
||||
{
|
||||
static std::function<void(arg_reference)> build(Ret(*fn)())
|
||||
{
|
||||
return[fn](arg_reference){
|
||||
fn();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ret, typename Arg2>
|
||||
struct factory < Ret(Arg2), false>
|
||||
{
|
||||
typedef typename std::remove_reference<arg_reference>::type arg_type;
|
||||
static_assert(std::is_convertible<arg_type, Arg2>::value, "The parameter type is not allowed, please check the function parameter type where you connected the event function.");
|
||||
|
||||
static std::function<void(arg_reference)> build(Ret(*fn)(Arg))
|
||||
{
|
||||
return[fn](arg_reference arg){
|
||||
fn(arg);
|
||||
};
|
||||
}
|
||||
};
|
||||
private:
|
||||
std::unique_ptr<std::vector<std::unique_ptr<docker>>> dockers_;
|
||||
};
|
||||
|
||||
struct arg_mouse
|
||||
: public detail::event_arg_interface
|
||||
{
|
||||
event_code evt_code;
|
||||
::nana::window window_handle;
|
||||
::nana::point pos;
|
||||
bool left_button;
|
||||
bool mid_button;
|
||||
bool right_button;
|
||||
bool shift;
|
||||
bool ctrl;
|
||||
};
|
||||
|
||||
struct arg_wheel : public arg_mouse
|
||||
{
|
||||
enum class wheel{
|
||||
vertical,
|
||||
horizontal
|
||||
};
|
||||
|
||||
wheel which; ///<which wheel is rotated
|
||||
bool upwards; ///< true if the wheel is rotated to the top/left, depends on which. false otherwise.
|
||||
unsigned distance; //expressed in multiples or divisions of 120
|
||||
};
|
||||
|
||||
struct arg_dropfiles : public detail::event_arg_interface
|
||||
{
|
||||
::nana::window window_handle;
|
||||
::nana::point pos;
|
||||
std::vector<nana::string> files;
|
||||
};
|
||||
|
||||
struct arg_expose : public detail::event_arg_interface
|
||||
{
|
||||
::nana::window window_handle;
|
||||
bool exposed;
|
||||
};
|
||||
|
||||
struct arg_focus : public detail::event_arg_interface
|
||||
{
|
||||
::nana::window window_handle;
|
||||
::nana::native_window_type receiver;
|
||||
bool getting;
|
||||
};
|
||||
|
||||
struct arg_keyboard : public detail::event_arg_interface
|
||||
{
|
||||
event_code evt_code;
|
||||
::nana::window window_handle;
|
||||
mutable nana::char_t key;
|
||||
mutable bool ignore;
|
||||
bool ctrl;
|
||||
bool shift;
|
||||
};
|
||||
|
||||
struct arg_move : public detail::event_arg_interface
|
||||
{
|
||||
::nana::window window_handle;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct arg_resized : public detail::event_arg_interface
|
||||
{
|
||||
::nana::window window_handle;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
struct arg_resizing : public detail::event_arg_interface
|
||||
{
|
||||
::nana::window window_handle;
|
||||
window_border border;
|
||||
mutable unsigned width;
|
||||
mutable unsigned height;
|
||||
};
|
||||
|
||||
struct arg_unload : public detail::event_arg_interface
|
||||
{
|
||||
::nana::window window_handle;
|
||||
mutable bool cancel;
|
||||
};
|
||||
|
||||
struct arg_destroy : public detail::event_arg_interface
|
||||
{
|
||||
::nana::window window_handle;
|
||||
};
|
||||
|
||||
struct general_events
|
||||
{
|
||||
virtual ~general_events(){}
|
||||
basic_event<arg_mouse> mouse_enter;
|
||||
basic_event<arg_mouse> mouse_move;
|
||||
basic_event<arg_mouse> mouse_leave;
|
||||
basic_event<arg_mouse> mouse_down;
|
||||
basic_event<arg_mouse> mouse_up;
|
||||
basic_event<arg_mouse> click;
|
||||
basic_event<arg_mouse> dbl_click;
|
||||
basic_event<arg_wheel> mouse_wheel;
|
||||
basic_event<arg_dropfiles> mouse_dropfiles;
|
||||
basic_event<arg_expose> expose;
|
||||
basic_event<arg_focus> focus;
|
||||
basic_event<arg_keyboard> key_press;
|
||||
basic_event<arg_keyboard> key_release;
|
||||
basic_event<arg_keyboard> key_char;
|
||||
basic_event<arg_keyboard> shortkey;
|
||||
|
||||
basic_event<arg_move> move;
|
||||
basic_event<arg_resizing> resizing;
|
||||
basic_event<arg_resized> resized;
|
||||
basic_event<arg_destroy> destroy;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct events_root_extension
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_unload> unload;
|
||||
};
|
||||
}//end namespace detail
|
||||
|
||||
namespace dev
|
||||
{
|
||||
template<typename Widget>
|
||||
struct event_mapping
|
||||
{
|
||||
typedef general_events type;
|
||||
};
|
||||
}//end namespace dev
|
||||
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
287
include/nana/gui/detail/handle_manager.hpp
Normal file
287
include/nana/gui/detail/handle_manager.hpp
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Handle Manager Implementation
|
||||
* Copyright(C) 2003-2013 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/handle_manager.hpp
|
||||
*
|
||||
* @description:
|
||||
* this manages all the window handles
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_HANDLE_MANAGER_HPP
|
||||
#define NANA_GUI_DETAIL_HANDLE_MANAGER_HPP
|
||||
|
||||
#include <nana/traits.hpp>
|
||||
#include <nana/config.hpp>
|
||||
#if defined(NANA_MINGW) && defined(STD_THREAD_NOT_SUPPORTED)
|
||||
#include <nana/std_mutex.hpp>
|
||||
#else
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Key, typename Value, std::size_t CacheSize>
|
||||
class cache
|
||||
: noncopyable
|
||||
{
|
||||
public:
|
||||
typedef Key key_type;
|
||||
typedef Value value_type;
|
||||
typedef std::pair<key_type, value_type> pair_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
cache()
|
||||
:addr_(reinterpret_cast<pair_type*>(::operator new(sizeof(pair_type) * CacheSize)))
|
||||
{
|
||||
for(std::size_t i = 0; i < CacheSize; ++i)
|
||||
{
|
||||
bitmap_[i] = 0;
|
||||
seq_[i] = nana::npos;
|
||||
}
|
||||
}
|
||||
|
||||
~cache()
|
||||
{
|
||||
for(std::size_t i = 0; i < CacheSize; ++i)
|
||||
{
|
||||
if(bitmap_[i])
|
||||
addr_[i].~pair_type();
|
||||
}
|
||||
|
||||
::operator delete(addr_);
|
||||
}
|
||||
|
||||
bool insert(key_type k, value_type v)
|
||||
{
|
||||
size_type pos = _m_find_key(k);
|
||||
if(pos != nana::npos)
|
||||
{
|
||||
addr_[pos].second = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
//No key exists
|
||||
pos = _m_find_pos();
|
||||
|
||||
if(pos == nana::npos)
|
||||
{ //No room, and remove the last pair
|
||||
pos = seq_[CacheSize - 1];
|
||||
(addr_ + pos)->~pair_type();
|
||||
}
|
||||
|
||||
if(seq_[0] != nana::npos)
|
||||
{//Need to move
|
||||
for(int i = CacheSize - 1; i > 0; --i)
|
||||
seq_[i] = seq_[i - 1];
|
||||
}
|
||||
|
||||
seq_[0] = pos;
|
||||
|
||||
new (addr_ + pos) pair_type(k, v);
|
||||
bitmap_[pos] = 1;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type * get(key_type k)
|
||||
{
|
||||
size_type pos = _m_find_key(k);
|
||||
if(pos != nana::npos)
|
||||
return &(addr_[pos].second);
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
size_type _m_find_key(key_type k) const
|
||||
{
|
||||
for(std::size_t i = 0; i < CacheSize; ++i)
|
||||
{
|
||||
if(bitmap_[i] && (addr_[i].first == k))
|
||||
return i;
|
||||
}
|
||||
return nana::npos;
|
||||
}
|
||||
|
||||
size_type _m_find_pos() const
|
||||
{
|
||||
for(std::size_t i = 0; i < CacheSize; ++i)
|
||||
{
|
||||
if(bitmap_[i] == 0)
|
||||
return i;
|
||||
}
|
||||
return nana::npos;
|
||||
}
|
||||
private:
|
||||
char bitmap_[CacheSize];
|
||||
size_type seq_[CacheSize];
|
||||
pair_type * addr_;
|
||||
};
|
||||
|
||||
//handle_manager
|
||||
//@brief
|
||||
// handle_manager maintains handles of a type. removing a handle dose not destroy it,
|
||||
// it will be inserted to a trash queue for deleting at a safe time.
|
||||
// For efficiency, this class is not a thread-safe.
|
||||
template<typename HandleType, typename Condition, typename Deleter>
|
||||
class handle_manager
|
||||
: nana::noncopyable
|
||||
{
|
||||
public:
|
||||
typedef HandleType handle_type;
|
||||
typedef Condition cond_type;
|
||||
typedef Deleter deleter_type;
|
||||
typedef std::map<handle_type, unsigned> handle_map_t;
|
||||
typedef std::pair<handle_type, unsigned> holder_pair;
|
||||
|
||||
~handle_manager()
|
||||
{
|
||||
delete_trash(0);
|
||||
}
|
||||
|
||||
void insert(handle_type handle, unsigned tid)
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
|
||||
holder_[handle] = tid;
|
||||
|
||||
is_queue<std::is_same<cond_type, nana::null_type>::value, std::vector<handle_type> >::insert(handle, queue_);
|
||||
cacher_.insert(handle, true);
|
||||
}
|
||||
|
||||
void operator()(const handle_type handle)
|
||||
{
|
||||
remove(handle);
|
||||
}
|
||||
|
||||
void remove(const handle_type handle)
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
|
||||
auto i = static_cast<const handle_map_t&>(holder_).find(handle);
|
||||
if(holder_.cend() != i)
|
||||
{
|
||||
is_queue<std::is_same<cond_type, nana::null_type>::value, std::vector<handle_type> >::erase(handle, queue_);
|
||||
cacher_.insert(handle, false);
|
||||
trash_.emplace_back(i->first, i->second);
|
||||
holder_.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void delete_trash(unsigned tid)
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
|
||||
if(trash_.size())
|
||||
{
|
||||
deleter_type del_functor;
|
||||
if(tid == 0)
|
||||
{
|
||||
for(auto & m : trash_)
|
||||
del_functor(m.first);
|
||||
trash_.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto i = trash_.begin(), end = trash_.end(); i != end;)
|
||||
{
|
||||
if(tid == i->second)
|
||||
{
|
||||
del_functor(i->first);
|
||||
i = trash_.erase(i);
|
||||
end = trash_.end();
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle_type last() const
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
if(queue_.size())
|
||||
return queue_.back();
|
||||
return handle_type();
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return holder_.size();
|
||||
}
|
||||
|
||||
handle_type get(unsigned index) const
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
if(index < queue_.size())
|
||||
return queue_[index];
|
||||
return handle_type();
|
||||
}
|
||||
|
||||
bool available(const handle_type handle) const
|
||||
{
|
||||
if (nullptr == handle)
|
||||
return false;
|
||||
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
bool * v = cacher_.get(handle);
|
||||
if(v) return *v;
|
||||
return cacher_.insert(handle, (holder_.count(handle) != 0));
|
||||
}
|
||||
|
||||
void all(std::vector<handle_type> & v) const
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
std::copy(queue_.cbegin(), queue_.cend(), std::back_inserter(v));
|
||||
}
|
||||
private:
|
||||
|
||||
template<bool IsQueueOperation, typename Container>
|
||||
struct is_queue
|
||||
{
|
||||
public:
|
||||
static void insert(handle_type handle, Container& queue)
|
||||
{
|
||||
if(cond_type::is_queue(handle))
|
||||
queue.push_back(handle);
|
||||
}
|
||||
|
||||
static void erase(handle_type handle, Container& queue)
|
||||
{
|
||||
if(cond_type::is_queue(handle))
|
||||
{
|
||||
auto i = std::find(queue.begin(), queue.end(), handle);
|
||||
if(i != queue.end())
|
||||
queue.erase(i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
struct is_queue<true, Container>
|
||||
{
|
||||
public:
|
||||
static void insert(handle_type handle, Container& queue){}
|
||||
static void erase(handle_type handle, Container& queue){}
|
||||
};
|
||||
|
||||
private:
|
||||
mutable std::recursive_mutex mutex_;
|
||||
mutable cache<const handle_type, bool, 5> cacher_;
|
||||
handle_map_t holder_;
|
||||
std::vector<handle_type> queue_;
|
||||
std::vector<holder_pair> trash_;
|
||||
};//end class handle_manager
|
||||
}//end namespace detail
|
||||
}// end namespace nana
|
||||
#endif
|
||||
55
include/nana/gui/detail/inner_fwd.hpp
Normal file
55
include/nana/gui/detail/inner_fwd.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Inner Forward Declaration
|
||||
* 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/gui/detail/inner_fwd.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_INNER_FWD_HPP
|
||||
#define NANA_GUI_INNER_FWD_HPP
|
||||
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
namespace nana{
|
||||
namespace detail
|
||||
{
|
||||
struct signals
|
||||
{
|
||||
enum class code
|
||||
{
|
||||
caption,
|
||||
read_caption,
|
||||
destroy,
|
||||
size,
|
||||
end
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
const nana::char_t* caption;
|
||||
nana::string * str;
|
||||
struct
|
||||
{
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
}size;
|
||||
}info;
|
||||
};
|
||||
|
||||
class signal_invoker_interface
|
||||
{
|
||||
public:
|
||||
virtual ~signal_invoker_interface()
|
||||
{}
|
||||
|
||||
virtual void call_signal(signals::code, const signals&) = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif //NANA_GUI_INNER_FWD_HPP
|
||||
201
include/nana/gui/detail/inner_fwd_implement.hpp
Normal file
201
include/nana/gui/detail/inner_fwd_implement.hpp
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Implementations of Inner Forward Declaration
|
||||
* 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/gui/detail/inner_fwd_implement.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_INNER_FWD_IMPLEMENT_HPP
|
||||
#define NANA_GUI_INNER_FWD_IMPLEMENT_HPP
|
||||
|
||||
#include "inner_fwd.hpp"
|
||||
#include "basic_window.hpp"
|
||||
#include "../../paint/graphics.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
namespace nana{
|
||||
namespace detail
|
||||
{
|
||||
class shortkey_container
|
||||
{
|
||||
struct item_type
|
||||
{
|
||||
window handle;
|
||||
std::vector<unsigned long> keys;
|
||||
};
|
||||
public:
|
||||
void clear()
|
||||
{
|
||||
keybase_.clear();
|
||||
}
|
||||
|
||||
bool make(window wd, unsigned long key)
|
||||
{
|
||||
if (wd == nullptr) return false;
|
||||
if (key < 0x61) key += (0x61 - 0x41);
|
||||
|
||||
for (auto & m : keybase_)
|
||||
{
|
||||
if (m.handle == wd)
|
||||
{
|
||||
m.keys.push_back(key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
item_type m;
|
||||
m.handle = wd;
|
||||
m.keys.push_back(key);
|
||||
keybase_.push_back(m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void umake(window wd)
|
||||
{
|
||||
if (wd == nullptr) return;
|
||||
auto i = std::find_if(keybase_.begin(), keybase_.end(), [wd](const item_type& m){
|
||||
return (m.handle == wd);
|
||||
});
|
||||
|
||||
if (i != keybase_.end())
|
||||
keybase_.erase(i);
|
||||
}
|
||||
|
||||
std::vector<unsigned long> keys(window wd) const
|
||||
{
|
||||
std::vector<unsigned long> v;
|
||||
if (wd)
|
||||
{
|
||||
for (auto & m : keybase_)
|
||||
{
|
||||
if (m.handle == wd)
|
||||
{
|
||||
v = m.keys;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return v;
|
||||
|
||||
}
|
||||
|
||||
window find(unsigned long key) const
|
||||
{
|
||||
if (key < 0x61) key += (0x61 - 0x41);
|
||||
|
||||
for (auto & m : keybase_)
|
||||
{
|
||||
for (auto n : m.keys)
|
||||
{
|
||||
if (key == n)
|
||||
return m.handle;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
private:
|
||||
std::vector<item_type> keybase_;
|
||||
};
|
||||
|
||||
|
||||
struct root_misc
|
||||
{
|
||||
typedef basic_window core_window_t;
|
||||
|
||||
core_window_t * window;
|
||||
nana::paint::graphics root_graph;
|
||||
shortkey_container shortkeys;
|
||||
|
||||
struct condition_tag
|
||||
{
|
||||
core_window_t* pressed{nullptr}; //The handle to a window which is being pressed
|
||||
core_window_t* hovered{nullptr}; //the latest window that mouse moved
|
||||
bool tabstop_focus_changed{false}; //KeyDown may set it true, if it is true KeyChar will ignore the message
|
||||
}condition;
|
||||
|
||||
root_misc(core_window_t * wd, unsigned width, unsigned height)
|
||||
: window(wd),
|
||||
root_graph(width, height)
|
||||
{}
|
||||
};//end struct root_misc
|
||||
|
||||
class root_register
|
||||
{
|
||||
public:
|
||||
root_misc* insert(native_window_type wd, const root_misc& misc)
|
||||
{
|
||||
recent_ = wd;
|
||||
auto ret = table_.insert(std::make_pair(wd, misc));
|
||||
misc_ptr_ = &(ret.first->second);
|
||||
return misc_ptr_;
|
||||
}
|
||||
|
||||
root_misc * find(native_window_type wd)
|
||||
{
|
||||
if (wd == recent_)
|
||||
return misc_ptr_;
|
||||
|
||||
recent_ = wd;
|
||||
|
||||
auto i = table_.find(wd);
|
||||
if (i != table_.end())
|
||||
misc_ptr_ = &(i->second);
|
||||
else
|
||||
misc_ptr_ = nullptr;
|
||||
|
||||
return misc_ptr_;
|
||||
}
|
||||
|
||||
void erase(native_window_type wd)
|
||||
{
|
||||
table_.erase(wd);
|
||||
recent_ = wd;
|
||||
misc_ptr_ = nullptr;
|
||||
}
|
||||
private:
|
||||
//Cached
|
||||
mutable native_window_type recent_{nullptr};
|
||||
mutable root_misc * misc_ptr_{nullptr};
|
||||
|
||||
std::map<native_window_type, root_misc> table_;
|
||||
};
|
||||
|
||||
|
||||
class signal_manager
|
||||
{
|
||||
typedef basic_window core_window_t;
|
||||
public:
|
||||
void make(core_window_t* wd, signal_invoker_interface* si)
|
||||
{
|
||||
if (si)
|
||||
table_[wd].reset(si);
|
||||
else
|
||||
table_.erase(wd);
|
||||
}
|
||||
|
||||
void umake(core_window_t * wd)
|
||||
{
|
||||
table_.erase(wd);
|
||||
}
|
||||
|
||||
void call_signal(core_window_t * wd, signals::code code, const signals& s)
|
||||
{
|
||||
auto i = table_.find(wd);
|
||||
if (i != table_.end())
|
||||
i->second->call_signal(code, s);
|
||||
}
|
||||
private:
|
||||
std::map<core_window_t*, std::unique_ptr<signal_invoker_interface>> table_;
|
||||
};
|
||||
}
|
||||
}//end namespace nana
|
||||
#endif //NANA_GUI_INNER_FWD_IMPLEMENT_HPP
|
||||
31
include/nana/gui/detail/internal_scope_guard.hpp
Normal file
31
include/nana/gui/detail/internal_scope_guard.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Forward Declaration of Internal Scope Guard
|
||||
* 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/gui/detail/internal_scope_guard.hpp
|
||||
*/
|
||||
#ifndef NANA_GUI_DETAIL_INTERNAL_SCOPE_GUARD_HPP
|
||||
#define NANA_GUI_DETAIL_INTERNAL_SCOPE_GUARD_HPP
|
||||
|
||||
namespace nana
|
||||
{
|
||||
//Implemented in bedrock
|
||||
class internal_scope_guard
|
||||
{
|
||||
internal_scope_guard(const internal_scope_guard&) = delete;
|
||||
internal_scope_guard(internal_scope_guard&&) = delete;
|
||||
|
||||
internal_scope_guard& operator=(const internal_scope_guard&) = delete;
|
||||
internal_scope_guard& operator=(internal_scope_guard&&) = delete;
|
||||
public:
|
||||
internal_scope_guard();
|
||||
~internal_scope_guard();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
89
include/nana/gui/detail/native_window_interface.hpp
Normal file
89
include/nana/gui/detail/native_window_interface.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Platform Implementation
|
||||
* Copyright(C) 2003-2013 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/native_window_interface.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_NATIVE_WINDOW_INTERFACE_HPP
|
||||
#define NANA_GUI_DETAIL_NATIVE_WINDOW_INTERFACE_HPP
|
||||
|
||||
#include "../basis.hpp"
|
||||
#include <nana/paint/image.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct native_interface
|
||||
{
|
||||
struct window_result
|
||||
{
|
||||
native_window_type native_handle;
|
||||
|
||||
unsigned width; //client size
|
||||
unsigned height; //client size
|
||||
|
||||
unsigned extra_width; //extra border size, it is useful in Windows, ignore in X11 always 0
|
||||
unsigned extra_height; //extra border size, it is useful in Windows, ignore in X11 always 0
|
||||
};
|
||||
|
||||
static nana::size screen_size();
|
||||
static rectangle screen_area_from_point(const point&);
|
||||
static window_result create_window(native_window_type, bool nested, const rectangle&, const appearance&);
|
||||
static native_window_type create_child_window(native_window_type, const rectangle&);
|
||||
|
||||
#if defined(NANA_X11)
|
||||
static void set_modal(native_window_type);
|
||||
#endif
|
||||
static void enable_dropfiles(native_window_type, bool);
|
||||
static void enable_window(native_window_type, bool);
|
||||
static bool window_icon(native_window_type, const paint::image&);
|
||||
static void activate_owner(native_window_type);
|
||||
static void activate_window(native_window_type);
|
||||
static void close_window(native_window_type);
|
||||
static void show_window(native_window_type, bool show, bool active);
|
||||
static void restore_window(native_window_type);
|
||||
static void zoom_window(native_window_type, bool ask_for_max);
|
||||
static void refresh_window(native_window_type);
|
||||
static bool is_window(native_window_type);
|
||||
static bool is_window_visible(native_window_type);
|
||||
static bool is_window_zoomed(native_window_type, bool ask_for_max);
|
||||
|
||||
static nana::point window_position(native_window_type);
|
||||
static void move_window(native_window_type, int x, int y);
|
||||
static void move_window(native_window_type, const rectangle&);
|
||||
static void bring_to_top(native_window_type);
|
||||
static void set_window_z_order(native_window_type, native_window_type wd_after, z_order_action action_if_no_wd_after);
|
||||
|
||||
static void window_size(native_window_type, const size&);
|
||||
static void get_window_rect(native_window_type, rectangle&);
|
||||
static void window_caption(native_window_type, const nana::string&);
|
||||
static nana::string window_caption(native_window_type);
|
||||
static void capture_window(native_window_type, bool);
|
||||
static nana::point cursor_position();
|
||||
static native_window_type get_owner_window(native_window_type);
|
||||
//For Caret
|
||||
static void caret_create(native_window_type, unsigned width, unsigned height);
|
||||
static void caret_destroy(native_window_type);
|
||||
static void caret_pos(native_window_type, int x, int y);
|
||||
static void caret_visible(native_window_type, bool);
|
||||
|
||||
static void set_focus(native_window_type);
|
||||
static native_window_type get_focus_window();
|
||||
static bool calc_screen_point(native_window_type, nana::point&);
|
||||
static bool calc_window_point(native_window_type, nana::point&);
|
||||
|
||||
static native_window_type find_window(int x, int y);
|
||||
static nana::size check_track_size(nana::size sz, unsigned extra_width, unsigned extra_height, bool true_for_max);
|
||||
};
|
||||
|
||||
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
#endif
|
||||
100
include/nana/gui/detail/runtime_manager.hpp
Normal file
100
include/nana/gui/detail/runtime_manager.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* A Runtime Manager Implementation
|
||||
* Copyright(C) 2003-2013 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/runtime_manager.hpp
|
||||
*
|
||||
*/
|
||||
#ifndef NANA_GUI_DETAIL_RUNTIME_MANAGER_HPP
|
||||
#define NANA_GUI_DETAIL_RUNTIME_MANAGER_HPP
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Window, typename Bedrock>
|
||||
class runtime_manager
|
||||
{
|
||||
public:
|
||||
typedef Window window_handle;
|
||||
|
||||
template<typename Form, typename... Args>
|
||||
Form* create_form(Args&&... args)
|
||||
{
|
||||
widget_placer<Form> * holder = new widget_placer<Form>;
|
||||
if (holder->create(std::forward<Args>(args)...))
|
||||
{
|
||||
holder_[holder->get_handle()] = holder;
|
||||
return holder->get();
|
||||
}
|
||||
|
||||
delete holder;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void remove_if_exists(window_handle wd)
|
||||
{
|
||||
auto i = holder_.find(wd);
|
||||
if(i != holder_.cend())
|
||||
{
|
||||
delete i->second;
|
||||
holder_.erase(i);
|
||||
}
|
||||
}
|
||||
private:
|
||||
class widget_holder
|
||||
{
|
||||
public:
|
||||
virtual ~widget_holder(){}
|
||||
virtual window_handle get_handle() const = 0;
|
||||
};
|
||||
|
||||
template<typename Form>
|
||||
class widget_placer : public widget_holder
|
||||
{
|
||||
public:
|
||||
widget_placer()
|
||||
: form_(nullptr)
|
||||
{}
|
||||
|
||||
~widget_placer()
|
||||
{
|
||||
delete form_;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
bool create(Args&&... args)
|
||||
{
|
||||
if (nullptr == form_)
|
||||
form_ = new Form(std::forward<Args>(args)...);
|
||||
|
||||
return (form_ && !form_->empty());
|
||||
}
|
||||
|
||||
Form* get() const
|
||||
{
|
||||
return form_;
|
||||
}
|
||||
|
||||
window_handle get_handle() const override
|
||||
{
|
||||
return reinterpret_cast<window_handle>(form_ ? form_->handle() : nullptr);
|
||||
}
|
||||
private:
|
||||
Form * form_;
|
||||
};
|
||||
private:
|
||||
std::map<window_handle, widget_holder*> holder_;
|
||||
}; //end class runtime_manager
|
||||
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
|
||||
|
||||
#endif
|
||||
88
include/nana/gui/detail/window_layout.hpp
Normal file
88
include/nana/gui/detail/window_layout.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Window Layout Implementation
|
||||
* Copyright(C) 2003-2013 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/window_layout.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP
|
||||
#define NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP
|
||||
|
||||
#include <nana/gui/basis.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
class image;
|
||||
class graphics;
|
||||
}
|
||||
}
|
||||
|
||||
namespace nana{
|
||||
namespace detail
|
||||
{
|
||||
struct basic_window;
|
||||
|
||||
//class window_layout
|
||||
class window_layout
|
||||
{
|
||||
public:
|
||||
typedef basic_window core_window_t;
|
||||
|
||||
struct wd_rectangle
|
||||
{
|
||||
core_window_t * window;
|
||||
rectangle r;
|
||||
};
|
||||
public:
|
||||
static void paint(core_window_t*, bool is_redraw, bool is_child_refreshed);
|
||||
|
||||
static bool maproot(core_window_t*, bool have_refreshed, bool is_child_refreshed);
|
||||
|
||||
static void paste_children_to_graphics(core_window_t*, nana::paint::graphics& graph);
|
||||
|
||||
//read_visual_rectangle
|
||||
//@brief: Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget,
|
||||
// the visual rectangle is a rectangular block that a window should be displayed on screen.
|
||||
// The result is a rectangle that is a visible area for its ancesters.
|
||||
static bool read_visual_rectangle(core_window_t*, nana::rectangle& visual);
|
||||
|
||||
//read_overlaps
|
||||
// reads the overlaps that are overlapped a rectangular block
|
||||
static bool read_overlaps(core_window_t*, const nana::rectangle& vis_rect, std::vector<wd_rectangle>& blocks);
|
||||
|
||||
static bool enable_effects_bground(core_window_t *, bool enabled);
|
||||
|
||||
//make_bground
|
||||
// update the glass buffer of a glass window.
|
||||
static void make_bground(core_window_t* const);
|
||||
private:
|
||||
|
||||
//_m_paste_children
|
||||
//@brief:paste children window to the root graphics directly. just paste the visual rectangle
|
||||
static void _m_paste_children(core_window_t*, bool is_child_refreshed, bool have_refreshed, const nana::rectangle& parent_rect, nana::paint::graphics& graph, const nana::point& graph_rpos);
|
||||
|
||||
static void _m_paint_glass_window(core_window_t*, bool is_redraw, bool is_child_refreshed, bool called_by_notify, bool notify_other);
|
||||
|
||||
//_m_notify_glasses
|
||||
//@brief: Notify the glass windows that are overlapped with the specified vis_rect
|
||||
static void _m_notify_glasses(core_window_t* const sigwd, const nana::rectangle& r_visual);
|
||||
private:
|
||||
struct data_section
|
||||
{
|
||||
std::vector<core_window_t*> effects_bground_windows;
|
||||
};
|
||||
static data_section data_sect;
|
||||
};//end class window_layout
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
|
||||
#endif //NANA_GUI_DETAIL_WINDOW_LAYOUT_HPP
|
||||
|
||||
225
include/nana/gui/detail/window_manager.hpp
Normal file
225
include/nana/gui/detail/window_manager.hpp
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Window Manager 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/gui/detail/window_manager.hpp
|
||||
*
|
||||
* <Knowledge: 1, 2007-8-17, "Difference between destroy and destroy_handle">
|
||||
* destroy method destroys a window handle and the handles of its children, but it doesn't delete the handle which type is a root window or a frame
|
||||
* destroy_handle method just destroys the handle which type is a root window or a frame
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_WINDOW_MANAGER_HPP
|
||||
#define NANA_GUI_DETAIL_WINDOW_MANAGER_HPP
|
||||
|
||||
#include <vector>
|
||||
#include "window_layout.hpp"
|
||||
#include "event_code.hpp"
|
||||
#include "inner_fwd.hpp"
|
||||
#include <functional>
|
||||
|
||||
#if defined(STD_THREAD_NOT_SUPPORTED)
|
||||
#include <nana/std_mutex.hpp>
|
||||
#else
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class widget; //forward declaration
|
||||
namespace paint
|
||||
{
|
||||
class image;
|
||||
}
|
||||
}
|
||||
|
||||
namespace nana{
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
class signal_invoker_mf
|
||||
: public signal_invoker_interface
|
||||
{
|
||||
public:
|
||||
signal_invoker_mf(T& obj, void(T::*mf)(signals::code, const signals&))
|
||||
: obj_(obj),
|
||||
mf_(mf)
|
||||
{}
|
||||
|
||||
void call_signal(signals::code code, const signals& s) override
|
||||
{
|
||||
(obj_.*mf_)(code, s);
|
||||
}
|
||||
private:
|
||||
T& obj_;
|
||||
void(T::*mf_)(signals::code, const signals&);
|
||||
};
|
||||
|
||||
struct root_misc;
|
||||
|
||||
class window_manager
|
||||
{
|
||||
class revertible_mutex
|
||||
: public std::recursive_mutex
|
||||
{
|
||||
struct thr_refcnt
|
||||
{
|
||||
unsigned tid;
|
||||
std::size_t refcnt;
|
||||
};
|
||||
public:
|
||||
revertible_mutex();
|
||||
|
||||
void lock();
|
||||
bool try_lock();
|
||||
void unlock();
|
||||
|
||||
void revert();
|
||||
void forward();
|
||||
private:
|
||||
thr_refcnt thr_;
|
||||
std::vector<thr_refcnt> stack_;
|
||||
};
|
||||
public:
|
||||
typedef native_window_type native_window;
|
||||
typedef revertible_mutex mutex_type;
|
||||
|
||||
typedef basic_window core_window_t;
|
||||
typedef std::vector<core_window_t*> cont_type;
|
||||
|
||||
typedef window_layout wndlayout_type;
|
||||
|
||||
window_manager();
|
||||
~window_manager();
|
||||
|
||||
static bool is_queue(core_window_t*);
|
||||
std::size_t number_of_core_window() const;
|
||||
mutex_type & internal_lock() const;
|
||||
void all_handles(std::vector<core_window_t*>&) const;
|
||||
|
||||
template<typename T, typename Concept>
|
||||
void attach_signal(core_window_t* wd, T& obj, void(Concept::*mf)(signals::code, const signals&))
|
||||
{
|
||||
return _m_attach_signal(wd, new signal_invoker_mf<Concept>(obj, mf));
|
||||
}
|
||||
|
||||
void signal_fire_caption(core_window_t*, const nana::char_t*);
|
||||
nana::string signal_fire_caption(core_window_t*);
|
||||
void event_filter(core_window_t*, bool is_make, event_code);
|
||||
void default_icon(const nana::paint::image&);
|
||||
|
||||
bool available(core_window_t*);
|
||||
bool available(core_window_t *, core_window_t*);
|
||||
bool available(native_window_type);
|
||||
|
||||
core_window_t* create_root(core_window_t* owner, bool nested, rectangle, const appearance&, widget*);
|
||||
core_window_t* create_widget(core_window_t* parent, const rectangle&, bool is_lite, widget*);
|
||||
core_window_t* create_frame(core_window_t* parent, const rectangle&, widget*);
|
||||
bool insert_frame(core_window_t* frame, native_window);
|
||||
bool insert_frame(core_window_t* frame, core_window_t*);
|
||||
void close(core_window_t*);
|
||||
|
||||
//destroy
|
||||
//@brief: Delete the window handle
|
||||
void destroy(core_window_t*);
|
||||
|
||||
//destroy_handle
|
||||
//@brief: Delete window handle, the handle type must be a root and a frame.
|
||||
void destroy_handle(core_window_t*);
|
||||
|
||||
void icon(core_window_t*, const paint::image&);
|
||||
|
||||
//show
|
||||
//@brief: show or hide a window
|
||||
bool show(core_window_t* wd, bool visible);
|
||||
|
||||
core_window_t* find_window(native_window_type root, int x, int y);
|
||||
|
||||
//move the wnd and its all children window, x and y is a relatively coordinate for wnd's parent window
|
||||
bool move(core_window_t*, int x, int y, bool passive);
|
||||
bool move(core_window_t*, const rectangle&);
|
||||
|
||||
bool size(core_window_t*, nana::size, bool passive, bool ask_update);
|
||||
|
||||
core_window_t* root(native_window_type) const;
|
||||
|
||||
//Copy the root buffer that wnd specified into DeviceContext
|
||||
void map(core_window_t*);
|
||||
|
||||
bool update(core_window_t*, bool redraw, bool force);
|
||||
void refresh_tree(core_window_t*);
|
||||
|
||||
bool do_lazy_refresh(core_window_t*, bool force_copy_to_screen);
|
||||
|
||||
bool get_graphics(core_window_t*, nana::paint::graphics&);
|
||||
bool get_visual_rectangle(core_window_t*, nana::rectangle&);
|
||||
|
||||
::nana::widget* get_widget(core_window_t*) const;
|
||||
std::vector<core_window_t*> get_children(core_window_t*) const;
|
||||
bool set_parent(core_window_t* wd, core_window_t* new_parent);
|
||||
core_window_t* set_focus(core_window_t*, bool root_has_been_focused);
|
||||
|
||||
core_window_t* capture_redirect(core_window_t*);
|
||||
void capture_ignore_children(bool ignore);
|
||||
bool capture_window_entered(int root_x, int root_y, bool& prev);
|
||||
core_window_t * capture_window() const;
|
||||
core_window_t* capture_window(core_window_t*, bool value);
|
||||
|
||||
void enable_tabstop(core_window_t*);
|
||||
core_window_t* tabstop(core_window_t*, bool forward) const; //forward means move to next in logic.
|
||||
|
||||
void remove_trash_handle(unsigned tid);
|
||||
|
||||
bool enable_effects_bground(core_window_t*, bool);
|
||||
|
||||
bool calc_window_point(core_window_t*, nana::point&);
|
||||
|
||||
root_misc* root_runtime(native_window_type) const;
|
||||
|
||||
bool register_shortkey(core_window_t*, unsigned long key);
|
||||
void unregister_shortkey(core_window_t*, bool with_children);
|
||||
std::vector<std::pair<core_window_t*, unsigned long>> shortkeys(core_window_t*, bool with_children);
|
||||
|
||||
core_window_t* find_shortkey(native_window_type, unsigned long key);
|
||||
private:
|
||||
void _m_attach_signal(core_window_t*, signal_invoker_interface*);
|
||||
void _m_disengage(core_window_t*, core_window_t* for_new);
|
||||
void _m_destroy(core_window_t*);
|
||||
void _m_move_core(core_window_t*, const point& delta);
|
||||
core_window_t* _m_find(core_window_t*, const point&);
|
||||
static bool _m_effective(core_window_t*, const point& root_pos);
|
||||
private:
|
||||
mutable mutex_type mutex_;
|
||||
|
||||
struct wdm_private_impl;
|
||||
wdm_private_impl * const impl_;
|
||||
|
||||
signals signals_;
|
||||
|
||||
struct attribute
|
||||
{
|
||||
struct captured
|
||||
{
|
||||
core_window_t *window;
|
||||
bool inside;
|
||||
bool ignore_children;
|
||||
std::vector<std::pair<core_window_t*, bool> > history;
|
||||
}capture;
|
||||
}attr_;
|
||||
|
||||
struct menu_tag
|
||||
{
|
||||
native_window_type window;
|
||||
native_window_type owner;
|
||||
bool has_keyboard;
|
||||
}menu_;
|
||||
};//end class window_manager
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
#endif
|
||||
29
include/nana/gui/dragger.hpp
Normal file
29
include/nana/gui/dragger.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef NANA_GUI_DRAGGER_HPP
|
||||
#define NANA_GUI_DRAGGER_HPP
|
||||
#include "programming_interface.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
/// \brief Helper class that allows the user to drag windows.
|
||||
///
|
||||
/// If a user presses the mouse on the specified window and moves the mouse, the specified window is dragged.
|
||||
/// The drag target window and trigger window can be set more than once.
|
||||
/// See [Is it possible to make event inside event handler?](https://nanapro.codeplex.com/discussions/444121)
|
||||
/// and [How to make widget movable by mouse the best way](https://nanapro.codeplex.com/discussions/444058)
|
||||
|
||||
class dragger
|
||||
: nana::noncopyable
|
||||
{
|
||||
class dragger_impl_t;
|
||||
public:
|
||||
dragger();
|
||||
~dragger();
|
||||
void target(window);
|
||||
void target(window, const rectangle& restrict_area, nana::arrange);
|
||||
void remove_target(window);
|
||||
void trigger(window);
|
||||
private:
|
||||
dragger_impl_t * impl_;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
49
include/nana/gui/drawing.hpp
Normal file
49
include/nana/gui/drawing.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* A Drawing 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/gui/drawing.hpp
|
||||
*/
|
||||
#ifndef NANA_GUI_DRAWING_HPP
|
||||
#define NANA_GUI_DRAWING_HPP
|
||||
#include "widgets/widget.hpp"
|
||||
#include "../traits.hpp"
|
||||
namespace nana
|
||||
{
|
||||
/// \brief Draw pictures on a widget by specifying a drawing method that will be employed everytime the widget refreshes.
|
||||
/// By the end of drawing, the picture may not be displayed immediately.
|
||||
/// If a picture need to be displayed immediately call nana::gui::API::refresh_window() .
|
||||
class drawing
|
||||
:private nana::noncopyable
|
||||
{
|
||||
public:
|
||||
typedef struct{}* diehard_t; ///< A handle to a drawing method
|
||||
typedef std::function<void(paint::graphics&)> draw_fn_t; ///< A function to draw
|
||||
|
||||
drawing(window w); ///< Create a drawing object for a widget w
|
||||
|
||||
virtual ~drawing(); ///< Just for polymorphism
|
||||
|
||||
bool empty() const; ///< Returns true if the drawing object is invalid.
|
||||
void update() const;
|
||||
|
||||
void draw(const draw_fn_t&); ///< Draws things that are defined by draw_fn_t.
|
||||
void draw(draw_fn_t&&); ///< Draws things that are defined by draw_fn_t.
|
||||
|
||||
/// Draws things that are defined by draw_fn_t but will not be deleted when clear() is called.
|
||||
diehard_t draw_diehard(const draw_fn_t&);
|
||||
/// Draws things that are defined by draw_fn_t but will not be deleted when clear() is called.
|
||||
diehard_t draw_diehard(draw_fn_t&&);
|
||||
void erase(diehard_t); ///< Erases a diehard drawing method.
|
||||
|
||||
void clear(); ///< Erases all.
|
||||
private:
|
||||
window handle_;
|
||||
};//end class drawing
|
||||
}//end namespace nana
|
||||
#endif
|
||||
67
include/nana/gui/effects.hpp
Normal file
67
include/nana/gui/effects.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Background Effects Implementation
|
||||
* Copyright(C) 2003-2013 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/effects.hpp
|
||||
*
|
||||
*/
|
||||
#ifndef NANA_GUI_EFFECTS_HPP
|
||||
#define NANA_GUI_EFFECTS_HPP
|
||||
#include <cstddef>
|
||||
#include <nana/paint/graphics.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace effects
|
||||
{
|
||||
enum class edge_nimbus
|
||||
{
|
||||
none, active = 0x1, over = 0x2
|
||||
};
|
||||
|
||||
class bground_interface
|
||||
{
|
||||
public:
|
||||
typedef paint::graphics & graph_reference;
|
||||
|
||||
virtual ~bground_interface() = 0;
|
||||
virtual void take_effect(window, graph_reference) const = 0;
|
||||
};
|
||||
|
||||
class bground_factory_interface
|
||||
{
|
||||
friend class effects_accessor;
|
||||
public:
|
||||
virtual ~bground_factory_interface() = 0;
|
||||
private:
|
||||
virtual bground_interface * create() const = 0;
|
||||
};
|
||||
|
||||
class bground_transparent
|
||||
: public bground_factory_interface
|
||||
{
|
||||
public:
|
||||
bground_transparent(std::size_t percent);
|
||||
private:
|
||||
virtual bground_interface* create() const;
|
||||
private:
|
||||
std::size_t percent_;
|
||||
};
|
||||
|
||||
class bground_blur
|
||||
: public bground_factory_interface
|
||||
{
|
||||
public:
|
||||
bground_blur(std::size_t radius);
|
||||
private:
|
||||
virtual bground_interface * create() const;
|
||||
private:
|
||||
std::size_t radius_;
|
||||
};
|
||||
}
|
||||
}//end namespace nana
|
||||
#endif
|
||||
194
include/nana/gui/element.hpp
Normal file
194
include/nana/gui/element.hpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Elements of GUI Gadgets
|
||||
* 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/gui/element.hpp
|
||||
*/
|
||||
#ifndef NANA_GUI_ELEMENT_HPP
|
||||
#define NANA_GUI_ELEMENT_HPP
|
||||
|
||||
#include <nana/paint/graphics.hpp>
|
||||
#include <nana/pat/cloneable.hpp>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
//forward declaration
|
||||
class image;
|
||||
}
|
||||
|
||||
namespace element
|
||||
{
|
||||
class element_interface
|
||||
{
|
||||
public:
|
||||
typedef paint::graphics & graph_reference;
|
||||
|
||||
virtual ~element_interface()
|
||||
{}
|
||||
|
||||
virtual bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle&, element_state) = 0;
|
||||
};
|
||||
|
||||
class crook_interface
|
||||
{
|
||||
public:
|
||||
typedef paint::graphics & graph_reference;
|
||||
typedef checkstate state;
|
||||
|
||||
struct data
|
||||
{
|
||||
state check_state;
|
||||
bool radio;
|
||||
};
|
||||
|
||||
virtual ~crook_interface()
|
||||
{}
|
||||
|
||||
virtual bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle&, element_state, const data&) = 0;
|
||||
};
|
||||
|
||||
class provider
|
||||
{
|
||||
public:
|
||||
template<typename ElementInterface>
|
||||
struct factory_interface
|
||||
{
|
||||
virtual ~factory_interface(){}
|
||||
virtual ElementInterface* create() const = 0;
|
||||
virtual void destroy(ElementInterface*) const = 0;
|
||||
};
|
||||
|
||||
template<typename Element, typename ElementInterface>
|
||||
class factory
|
||||
: public factory_interface<ElementInterface>
|
||||
{
|
||||
public:
|
||||
typedef factory_interface<ElementInterface> interface_type;
|
||||
|
||||
ElementInterface * create() const override
|
||||
{
|
||||
return (new Element);
|
||||
}
|
||||
|
||||
void destroy(ElementInterface * p) const override
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
};
|
||||
|
||||
void add_crook(const std::string& name, const pat::cloneable<factory_interface<crook_interface>>&);
|
||||
crook_interface* const * keeper_crook(const std::string& name);
|
||||
};
|
||||
|
||||
template<typename UserElement>
|
||||
void add_crook(const std::string& name)
|
||||
{
|
||||
typedef provider::factory<UserElement, crook_interface> factory_t;
|
||||
provider().add_crook(name, pat::cloneable<typename factory_t::interface_type>(factory_t()));
|
||||
}
|
||||
|
||||
class crook;
|
||||
}//end namespace element
|
||||
|
||||
template<typename Element> class facade;
|
||||
|
||||
template<>
|
||||
class facade<element::crook>
|
||||
: public element::element_interface
|
||||
{
|
||||
public:
|
||||
typedef ::nana::paint::graphics & graph_reference;
|
||||
typedef element::crook_interface::state state;
|
||||
|
||||
facade();
|
||||
facade(const char* name);
|
||||
|
||||
facade & reverse();
|
||||
facade & check(state);
|
||||
state checked() const;
|
||||
|
||||
facade& radio(bool);
|
||||
bool radio() const;
|
||||
|
||||
void switch_to(const char*);
|
||||
public:
|
||||
//Implement element_interface
|
||||
bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle& r, element_state) override;
|
||||
private:
|
||||
element::crook_interface::data data_;
|
||||
element::crook_interface* const * keeper_;
|
||||
};
|
||||
|
||||
namespace element
|
||||
{
|
||||
void set_bground(const char* name, const pat::cloneable<element_interface>&);
|
||||
void set_bground(const char* name, pat::cloneable<element_interface> &&);
|
||||
|
||||
class cite_bground
|
||||
{
|
||||
public:
|
||||
typedef paint::graphics& graph_reference;
|
||||
typedef pat::cloneable<element_interface> cloneable_element;
|
||||
|
||||
cite_bground(const char*);
|
||||
|
||||
void set(const cloneable_element&);
|
||||
void set(const char*);
|
||||
|
||||
bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle&, element_state);
|
||||
private:
|
||||
cloneable_element holder_;
|
||||
element_interface * place_ptr_;
|
||||
element_interface * const * ref_ptr_;
|
||||
};
|
||||
|
||||
class bground
|
||||
: public element_interface
|
||||
{
|
||||
public:
|
||||
typedef paint::graphics& graph_reference;
|
||||
|
||||
bground();
|
||||
bground(const bground&);
|
||||
~bground();
|
||||
bground& operator=(const bground&);
|
||||
|
||||
bground& image(const paint::image&, bool vertical, const nana::rectangle& valid_area); ///< Set a picture for the background
|
||||
bground& image(const paint::graphics&, bool vertical, const nana::rectangle& valid_area); ///< Set a picture for the background
|
||||
|
||||
void states(const std::vector<element_state> &); ///< Set the state sequence of the background picture.
|
||||
void states(std::vector<element_state> &&); ///< Set the state sequence of the background picture.
|
||||
void reset_states();
|
||||
|
||||
void join(element_state target, element_state joiner);
|
||||
|
||||
void stretch_parts(unsigned left, unsigned top, unsigned right, unsigned bottom);
|
||||
|
||||
//Implement the methods of element_interface.
|
||||
virtual bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle&, element_state);
|
||||
private:
|
||||
struct draw_method;
|
||||
struct draw_image;
|
||||
struct draw_graph;
|
||||
|
||||
draw_method * method_;
|
||||
bool vertical_;
|
||||
nana::rectangle valid_area_;
|
||||
std::vector<element_state> states_;
|
||||
std::map<element_state, element_state> join_;
|
||||
bool stretch_all_;
|
||||
unsigned left_, top_, right_, bottom_;
|
||||
}; //end class bground
|
||||
}//end namespace element
|
||||
}//end namespace nana
|
||||
|
||||
#endif //NANA_GUI_ELEMENT_HPP
|
||||
60
include/nana/gui/filebox.hpp
Normal file
60
include/nana/gui/filebox.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef NANA_GUI_FILEBOX_HPP
|
||||
#define NANA_GUI_FILEBOX_HPP
|
||||
#include <nana/gui/wvl.hpp>
|
||||
|
||||
namespace nana
|
||||
{ /// Create an Open or Save dialog box to let user select the name of a file.
|
||||
class filebox
|
||||
: nana::noncopyable
|
||||
{
|
||||
struct implement;
|
||||
public:
|
||||
typedef std::vector<std::pair<nana::string, nana::string>> filters;
|
||||
|
||||
filebox(window owner, bool is_open_mode);
|
||||
~filebox();
|
||||
|
||||
/** @brief specify a title for the dialog
|
||||
* @param string a text for title
|
||||
*/
|
||||
nana::string title( nana::string new_title); ///< . Set a new title for the dialog and \return the old title
|
||||
|
||||
/** @brief specify a suggestion directory
|
||||
* @param string a path of initial directory
|
||||
* @note the behavior of init_path is different between Win7 and Win2K/XP/Vista, but its behavior under Linux is conformed with Win7.
|
||||
*/
|
||||
filebox& init_path(const nana::string&); ///< Suggested init path used to locate a directory when the filebox starts.
|
||||
filebox& init_file(const nana::string&); ///< Init file, if it contains a path, the init path is replaced by the path of init file.
|
||||
/// \brief Add a filetype filter.
|
||||
/// To specify multiple filter in a single description, use a semicolon to separate the patterns(for example,"*.TXT;*.DOC;*.BAK").
|
||||
filebox& add_filter(const nana::string& description, ///< for example. "Text File"
|
||||
const nana::string& filetype ///< filter pattern(for example, "*.TXT")
|
||||
);
|
||||
|
||||
filebox& add_filter(const filters &ftres)
|
||||
{
|
||||
for (auto &f : ftres)
|
||||
add_filter(f.first, f.second);
|
||||
return *this;
|
||||
};
|
||||
|
||||
|
||||
nana::string path() const;
|
||||
nana::string file() const;
|
||||
|
||||
/** @brief Display the filebox dialog
|
||||
*/
|
||||
bool show() const;
|
||||
|
||||
/** @brief Display the filebox dialog
|
||||
* @note A function object method alternative to show()
|
||||
*/
|
||||
bool operator()() const
|
||||
{
|
||||
return show();
|
||||
}
|
||||
private:
|
||||
implement * impl_;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
43
include/nana/gui/layout_utility.hpp
Normal file
43
include/nana/gui/layout_utility.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Utility Implementation
|
||||
* Copyright(C) 2003-2013 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/layout_utility.hpp
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_LAYOUT_UTILITY_HPP
|
||||
#define NANA_GUI_LAYOUT_UTILITY_HPP
|
||||
|
||||
#include "basis.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
//overlap test if overlaped between r1 and r2
|
||||
bool overlap(const rectangle& r1, const rectangle& r2);
|
||||
|
||||
// overlap, compute the overlap area between r1 and r2. the r is for root
|
||||
bool overlap(const rectangle& r1, const rectangle& r2, rectangle& r);
|
||||
|
||||
bool overlap(const rectangle& ir, const size& valid_input_area, const rectangle & dr, const size& valid_dst_area, rectangle& output_src_r, rectangle& output_dst_r);
|
||||
|
||||
bool intersection(const rectangle & r, point pos_beg, point pos_end, point& good_pos_beg, point& good_pos_end);
|
||||
|
||||
/// Zoom the input_s to fit for ref_s
|
||||
void fit_zoom(const size& input_s, const size& ref_s, size& result_s);
|
||||
|
||||
//zoom
|
||||
//@brief: Calculate the scaled rectangle by refer dst rectangle, that scale factor is same as that between scaled and refer.
|
||||
void zoom(const rectangle& refer, const rectangle& scaled, const rectangle& refer_dst, rectangle& r);
|
||||
|
||||
//covered
|
||||
//@brief: Tests a rectangle whether it is wholly covered by another.
|
||||
bool covered(const rectangle& underlying, //Rectangle 1 is must under rectangle 2
|
||||
const rectangle& cover);
|
||||
}//end namespace nana
|
||||
#endif
|
||||
96
include/nana/gui/msgbox.hpp
Normal file
96
include/nana/gui/msgbox.hpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* A Message Box Class
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2013 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/msgbox.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_MSGBOX_HPP
|
||||
#define NANA_GUI_MSGBOX_HPP
|
||||
|
||||
#include <sstream>
|
||||
#include <nana/gui/basis.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
/// Prefabricated modal dialog box (with text, icon and actions buttons) that inform and instruct the user.
|
||||
class msgbox
|
||||
{
|
||||
public:
|
||||
/// Identifiers of icons.
|
||||
enum icon_t{icon_none, icon_information, icon_warning, icon_error, icon_question};
|
||||
|
||||
/// Identifiers of buttons.
|
||||
enum button_t{ok, yes_no, yes_no_cancel};
|
||||
|
||||
/// Identifiers of buttons that a user clicked.
|
||||
enum pick_t{pick_ok, pick_yes, pick_no, pick_cancel};
|
||||
|
||||
/// Default construct that creates a message box with default title and default button, the default button is OK.
|
||||
msgbox();
|
||||
|
||||
/// Copy construct from an existing msgbox object.
|
||||
msgbox(const msgbox&);
|
||||
|
||||
/// Assign from an existing msgbox object.
|
||||
msgbox& operator=(const msgbox&);
|
||||
|
||||
/// Construct that creates a message box with a specified title and default button.
|
||||
msgbox(const nana::string&);
|
||||
|
||||
/// Construct that creates a message box with an owner window and a specified title.
|
||||
msgbox(window, const nana::string&);
|
||||
|
||||
/// Construct that creates a message box with an owner windoow, a specified title and buttons.
|
||||
msgbox(window, const nana::string&, button_t);
|
||||
|
||||
/// Sets an icon for informing user.
|
||||
msgbox& icon(icon_t);
|
||||
|
||||
/// Clears the text message buffer.
|
||||
void clear();
|
||||
|
||||
/// Writes a string to the buffer.
|
||||
msgbox & operator<<(const nana::string&);
|
||||
|
||||
/// Writes a string to the buffer.
|
||||
msgbox & operator<<(const nana::char_t*);
|
||||
|
||||
/// Writes a string to the buffer.
|
||||
msgbox & operator<<(const nana::charset&);
|
||||
|
||||
// Calls a manipulator to the stream.
|
||||
msgbox & operator<<(std::ostream& (*)(std::ostream&));
|
||||
|
||||
/// Write a streamizable object to the buffer.
|
||||
template<typename T>
|
||||
msgbox & operator<<(const T& t)
|
||||
{
|
||||
sstream_<<t;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Displays the message that buffered in the stream.
|
||||
/// @return, the button that user clicked.
|
||||
pick_t show() const;
|
||||
|
||||
/// A function object method alternative to show()
|
||||
pick_t operator()() const
|
||||
{
|
||||
return show();
|
||||
}
|
||||
private:
|
||||
std::stringstream sstream_;
|
||||
window wd_;
|
||||
nana::string title_;
|
||||
button_t button_;
|
||||
icon_t icon_;
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
67
include/nana/gui/notifier.hpp
Normal file
67
include/nana/gui/notifier.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Definition of Notifier
|
||||
* 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/gui/notifier.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_NOTIFIER_HPP
|
||||
#define NANA_GUI_NOTIFIER_HPP
|
||||
#include <nana/gui/basis.hpp>
|
||||
#include <nana/gui/detail/general_events.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class notifier;
|
||||
|
||||
struct arg_notifier
|
||||
{
|
||||
event_code evt_code;
|
||||
notifier* notifier_ptr;
|
||||
nana::point pos;
|
||||
bool left_button;
|
||||
bool mid_button;
|
||||
bool right_button;
|
||||
|
||||
operator arg_mouse() const;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct notifier_events
|
||||
{
|
||||
basic_event<arg_notifier> mouse_move;
|
||||
basic_event<arg_notifier> mouse_down;
|
||||
basic_event<arg_notifier> mouse_up;
|
||||
basic_event<arg_notifier> mouse_leave;
|
||||
basic_event<arg_notifier> dbl_click;
|
||||
};
|
||||
}
|
||||
|
||||
class notifier
|
||||
{
|
||||
struct implement;
|
||||
notifier(const notifier&) = delete;
|
||||
notifier(notifier&&) = delete;
|
||||
notifier& operator=(const notifier&) = delete;
|
||||
notifier& operator=(notifier&&) = delete;
|
||||
public:
|
||||
notifier(window);
|
||||
~notifier();
|
||||
void close();
|
||||
void text(const nana::string&);
|
||||
void icon(const nana::string& icon_file);
|
||||
void insert_icon(const nana::string& icon_file);
|
||||
void period(unsigned millisecond);
|
||||
detail::notifier_events& events();
|
||||
window handle() const;
|
||||
private:
|
||||
implement * impl_;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
130
include/nana/gui/place.hpp
Normal file
130
include/nana/gui/place.hpp
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* An Implementation of Place for Layout
|
||||
* 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/gui/place.cpp
|
||||
*
|
||||
* @contributions:
|
||||
* min/max and splitter bar initial weight by qPCR4vir.
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_PLACE_HPP
|
||||
#define NANA_GUI_PLACE_HPP
|
||||
#include <nana/gui/basis.hpp>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class widget;
|
||||
namespace detail
|
||||
{
|
||||
class place_agent
|
||||
{
|
||||
public:
|
||||
virtual ~place_agent() = default;
|
||||
virtual std::unique_ptr<nana::widget> create(nana::window) const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Widget>
|
||||
class agent
|
||||
: public detail::place_agent
|
||||
{
|
||||
public:
|
||||
agent(std::function<void(Widget&)> initializer)
|
||||
: init_(std::move(initializer))
|
||||
{}
|
||||
|
||||
agent(const nana::char_t* text)
|
||||
: text_(text)
|
||||
{}
|
||||
|
||||
agent(nana::string text, std::function<void(Widget&)> initializer = {})
|
||||
: text_(std::move(text)), init_(std::move(initializer))
|
||||
{}
|
||||
|
||||
private:
|
||||
std::unique_ptr<nana::widget> create(nana::window handle) const override
|
||||
{
|
||||
std::unique_ptr<Widget> ptr(new Widget(handle));
|
||||
ptr->caption(text_);
|
||||
if (init_)
|
||||
init_(*ptr);
|
||||
return std::move(ptr);
|
||||
}
|
||||
private:
|
||||
nana::string text_;
|
||||
std::function<void(Widget&)> init_;
|
||||
};
|
||||
|
||||
/// Layout managment - an object of class place is attached to a widget, and it automatically positions and resizes the children widgets.
|
||||
class place
|
||||
: ::nana::noncopyable
|
||||
{
|
||||
struct implement;
|
||||
|
||||
class field_interface
|
||||
{
|
||||
field_interface(const field_interface&) = delete;
|
||||
field_interface& operator=(const field_interface&) = delete;
|
||||
field_interface(field_interface&&) = delete;
|
||||
field_interface& operator=(field_interface&&) = delete;
|
||||
public:
|
||||
field_interface() = default;
|
||||
virtual ~field_interface() = default;
|
||||
virtual field_interface& operator<<(const nana::char_t* label) = 0;
|
||||
virtual field_interface& operator<<(nana::string label) = 0;
|
||||
virtual field_interface& operator<<(window) = 0;
|
||||
virtual field_interface& fasten(window) = 0;
|
||||
|
||||
template<typename Widget>
|
||||
field_interface& operator<<(const agent<Widget>& ag)
|
||||
{
|
||||
_m_add_agent(ag);
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
virtual void _m_add_agent(const detail::place_agent&) = 0;
|
||||
};
|
||||
public:
|
||||
/// reference to a field manipulator which refers to a field object created by place
|
||||
typedef field_interface & field_reference;
|
||||
|
||||
place();
|
||||
place(window);///< Attaches to a specified widget.
|
||||
~place();
|
||||
|
||||
/** @brief Bind to a window
|
||||
* @param handle A handle to a window which the place wants to attach.
|
||||
* @remark It will throw an exception if the place has already binded to a window.
|
||||
*/
|
||||
void bind(window handle);
|
||||
window window_handle() const;
|
||||
|
||||
void div(const char* s); ///< Divides the attached widget into fields.
|
||||
field_reference field(const char* name);///< Returns a field with the specified name.
|
||||
|
||||
void field_visible(const char* filed_name, bool visible); ///<<Shows/Hides an existing field.
|
||||
bool field_visible(const char* field_name) const; ///<Determines whether the specified field is visible.
|
||||
|
||||
void field_display(const char* field_name, bool display); ///<Displays/Discards an existing field.
|
||||
bool field_display(const char* field_name) const; ///<Determines whether the specified field is displayed.
|
||||
|
||||
void collocate(); ///< Layouts the widgets.
|
||||
|
||||
void erase(window handle); ///< Erases a window from field.
|
||||
|
||||
field_reference operator[](const char* name); ///< Returns a field with the specified name. Equal to field();
|
||||
private:
|
||||
implement * impl_;
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
#endif //#ifndef NANA_GUI_PLACE_HPP
|
||||
260
include/nana/gui/programming_interface.hpp
Normal file
260
include/nana/gui/programming_interface.hpp
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Nana GUI Programming Interface 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/gui/programming_interface.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_PROGRAMMING_INTERFACE_HPP
|
||||
#define NANA_GUI_PROGRAMMING_INTERFACE_HPP
|
||||
#include <nana/config.hpp>
|
||||
#include GUI_BEDROCK_HPP
|
||||
#include "effects.hpp"
|
||||
#include "detail/general_events.hpp"
|
||||
#include <nana/paint/image.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class drawer_trigger;
|
||||
class widget;
|
||||
|
||||
namespace API
|
||||
{
|
||||
void effects_edge_nimbus(window, effects::edge_nimbus);
|
||||
effects::edge_nimbus effects_edge_nimbus(window);
|
||||
|
||||
void effects_bground(window, const effects::bground_factory_interface&, double fade_rate);
|
||||
bground_mode effects_bground_mode(window);
|
||||
void effects_bground_remove(window);
|
||||
|
||||
//namespace dev
|
||||
//@brief: The interfaces defined in namespace dev are used for developing the nana.gui
|
||||
namespace dev
|
||||
{
|
||||
template<typename Object, typename Concept>
|
||||
void attach_signal(window wd, Object& object, void (Concept::*f)(::nana::detail::signals::code, const ::nana::detail::signals&))
|
||||
{
|
||||
using namespace ::nana::detail;
|
||||
bedrock::instance().wd_manager.attach_signal(reinterpret_cast<bedrock::core_window_t*>(wd), object, f);
|
||||
}
|
||||
|
||||
bool set_events(window, const std::shared_ptr<general_events>&);
|
||||
|
||||
void attach_drawer(widget&, drawer_trigger&);
|
||||
nana::string window_caption(window);
|
||||
void window_caption(window, nana::string);
|
||||
|
||||
window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached);
|
||||
window create_widget(window, const rectangle&, widget* attached);
|
||||
window create_lite_widget(window, const rectangle&, widget* attached);
|
||||
window create_frame(window, const rectangle&, widget* attached);
|
||||
|
||||
paint::graphics* window_graphics(window);
|
||||
}//end namespace dev
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
general_events* get_general_events(window);
|
||||
}//end namespace detail
|
||||
|
||||
void exit();
|
||||
|
||||
nana::string transform_shortkey_text(nana::string text, nana::string::value_type &shortkey, nana::string::size_type *skpos);
|
||||
bool register_shortkey(window, unsigned long);
|
||||
void unregister_shortkey(window);
|
||||
|
||||
nana::size screen_size();
|
||||
rectangle screen_area_from_point(const point&);
|
||||
nana::point cursor_position();
|
||||
rectangle make_center(unsigned width, unsigned height); ///< Retrieves a rectangle which is in the center of the screen.
|
||||
rectangle make_center(window, unsigned width, unsigned height); ///< Retrieves a rectangle which is in the center of the window
|
||||
|
||||
template<typename Widget=::nana::widget, typename EnumFunction>
|
||||
void enum_widgets(window wd, bool recursive, EnumFunction && ef)
|
||||
{
|
||||
static_assert(std::is_convertible<Widget, ::nana::widget>::value, "enum_widgets<Widget>: The specified Widget is not a widget type.");
|
||||
|
||||
typedef ::nana::detail::basic_window core_window_t;
|
||||
auto & brock = ::nana::detail::bedrock::instance();
|
||||
internal_scope_guard lock;
|
||||
|
||||
auto children = brock.wd_manager.get_children(reinterpret_cast<core_window_t*>(wd));
|
||||
for (auto child : children)
|
||||
{
|
||||
auto wgt = dynamic_cast<Widget*>(brock.wd_manager.get_widget(child));
|
||||
if (nullptr == wgt)
|
||||
continue;
|
||||
|
||||
ef(*wgt);
|
||||
if (recursive)
|
||||
enum_widgets<Widget>(wd, recursive, std::forward<EnumFunction>(ef));
|
||||
}
|
||||
}
|
||||
|
||||
void window_icon_default(const paint::image&);
|
||||
void window_icon(window, const paint::image&);
|
||||
bool empty_window(window); ///< Determines whether a window is existing.
|
||||
void enable_dropfiles(window, bool);
|
||||
|
||||
/// \brief Retrieves the native window of a Nana.GUI window.
|
||||
///
|
||||
/// The native window type is platform-dependent. Under Microsoft Windows, a conversion can be employed between
|
||||
/// nana::native_window_type and HWND through reinterpret_cast operator. Under X System, a conversion can
|
||||
/// be employed between nana::native_window_type and Window through reinterpret_cast operator.
|
||||
/// \return If the function succeeds, the return value is the native window handle to the Nana.GUI window. If fails return zero.
|
||||
native_window_type root(window);
|
||||
window root(native_window_type); ///< Retrieves the native window of a Nana.GUI window.
|
||||
|
||||
void fullscreen(window, bool);
|
||||
bool enabled_double_click(window, bool);
|
||||
bool insert_frame(window frame, native_window_type);
|
||||
native_window_type frame_container(window frame);
|
||||
native_window_type frame_element(window frame, unsigned index);
|
||||
void close_window(window);
|
||||
void show_window(window, bool show); ///< Sets a window visible state.
|
||||
void restore_window(window);
|
||||
void zoom_window(window, bool ask_for_max);
|
||||
bool visible(window);
|
||||
window get_parent_window(window);
|
||||
window get_owner_window(window);
|
||||
bool set_parent_window(window, window new_parent);
|
||||
|
||||
template<typename Widget=::nana::widget>
|
||||
typename ::nana::dev::event_mapping<Widget>::type & events(window wd)
|
||||
{
|
||||
typedef typename ::nana::dev::event_mapping<Widget>::type event_type;
|
||||
|
||||
internal_scope_guard lock;
|
||||
auto * general_evt = detail::get_general_events(wd);
|
||||
if (nullptr == general_evt)
|
||||
throw std::invalid_argument("API::events(): bad parameter window handle, no events object or invalid window handle.");
|
||||
|
||||
if (std::is_same<decltype(*general_evt), event_type>::value)
|
||||
return *static_cast<event_type*>(general_evt);
|
||||
|
||||
auto * widget_evt = dynamic_cast<event_type*>(general_evt);
|
||||
if (nullptr == widget_evt)
|
||||
throw std::invalid_argument("API::events(): bad template parameter Widget, the widget type and window handle do not match.");
|
||||
return *widget_evt;
|
||||
}
|
||||
|
||||
template<typename EventArg, typename std::enable_if<std::is_base_of< ::nana::detail::event_arg_interface, EventArg>::value>::type* = nullptr>
|
||||
bool emit_event(event_code evt_code, window wd, const EventArg& arg)
|
||||
{
|
||||
auto & brock = ::nana::detail::bedrock::instance();
|
||||
return brock.emit(evt_code, reinterpret_cast< ::nana::detail::bedrock::core_window_t*>(wd), arg, true, brock.get_thread_context());
|
||||
}
|
||||
|
||||
void umake_event(event_handle);
|
||||
|
||||
nana::point window_position(window);
|
||||
void move_window(window, int x, int y);
|
||||
void move_window(window wd, const rectangle&);
|
||||
|
||||
void bring_to_top(window);
|
||||
bool set_window_z_order(window wd, window wd_after, z_order_action action_if_no_wd_after);
|
||||
|
||||
nana::size window_size(window);
|
||||
void window_size(window, const size&);
|
||||
bool window_rectangle(window, rectangle&);
|
||||
bool track_window_size(window, const size&, bool true_for_max); ///< Sets the minimum or maximum tracking size of a window.
|
||||
void window_enabled(window, bool);
|
||||
bool window_enabled(window);
|
||||
|
||||
/** @brief A widget drawer draws the widget surface in answering an event.
|
||||
*
|
||||
* This function will tell the drawer to copy the graphics into window after event answering.
|
||||
* Tells Nana.GUI to copy the buffer of event window to screen after the event is processed.
|
||||
* This function only works for a drawer_trigger, when a drawer_trigger receives an event,
|
||||
* after drawing, a drawer_trigger should call lazy_refresh to tell the Nana.GUI to refresh
|
||||
* the window to the screen after the event process finished.
|
||||
*/
|
||||
void lazy_refresh();
|
||||
|
||||
/** @brief: calls refresh() of a widget's drawer. if currently state is lazy_refresh, Nana.GUI may paste the drawing on the window after an event processing.
|
||||
* @param window: specify a window to be refreshed.
|
||||
*/
|
||||
void refresh_window(window); ///< Refreshs the window and display it immediately calling the refresh method of its drawer_trigger..
|
||||
void refresh_window_tree(window); ///< Refreshs the specified window and all it<69>s children windows, then display it immediately
|
||||
void update_window(window); ///< Copies the off-screen buffer to the screen for immediate display.
|
||||
|
||||
void window_caption(window, const nana::string& title);
|
||||
nana::string window_caption(window);
|
||||
|
||||
void window_cursor(window, cursor);
|
||||
cursor window_cursor(window);
|
||||
|
||||
void activate_window(window);
|
||||
bool is_focus_window(window);
|
||||
window focus_window();
|
||||
void focus_window(window);
|
||||
|
||||
window capture_window();
|
||||
window capture_window(window, bool); ///< Enables or disables the window to grab the mouse input
|
||||
void capture_ignore_children(bool ignore); ///< Enables or disables the captured window whether redirects the mouse input to its children if the mouse is over its children.
|
||||
void modal_window(window); ///< Blocks the routine til the specified window is closed.
|
||||
void wait_for(window);
|
||||
color_t foreground(window);
|
||||
color_t foreground(window, color_t);
|
||||
color_t background(window);
|
||||
color_t background(window, color_t);
|
||||
color_t active(window);
|
||||
color_t active(window, color_t);
|
||||
|
||||
void create_caret(window, unsigned width, unsigned height);
|
||||
void destroy_caret(window);
|
||||
void caret_effective_range(window, const rectangle&);
|
||||
void caret_pos(window, int x, int y);
|
||||
nana::point caret_pos(window);
|
||||
nana::size caret_size(window);
|
||||
void caret_size(window, const size&);
|
||||
void caret_visible(window, bool is_show);
|
||||
bool caret_visible(window);
|
||||
|
||||
void tabstop(window); ///< Sets the window that owns the tabstop.
|
||||
/// treu: The focus is not to be changed when Tab key is pressed, and a key_char event with tab will be generated.
|
||||
void eat_tabstop(window, bool);
|
||||
window move_tabstop(window, bool next); ///< Sets the focus to the window which tabstop is near to the specified window.
|
||||
|
||||
bool glass_window(window); /// \deprecated
|
||||
bool glass_window(window, bool); /// \deprecated
|
||||
|
||||
/// Sets the window active state. If a window active state is false, the window will not obtain the focus when a mouse clicks on it wich will be obteined by take_if_has_active_false.
|
||||
void take_active(window, bool has_active, window take_if_has_active_false);
|
||||
|
||||
bool window_graphics(window, nana::paint::graphics&);
|
||||
bool root_graphics(window, nana::paint::graphics&);
|
||||
bool get_visual_rectangle(window, nana::rectangle&);
|
||||
|
||||
void typeface(window, const nana::paint::font&);
|
||||
paint::font typeface(window);
|
||||
|
||||
bool calc_screen_point(window, point&); ///<Converts window coordinates to screen coordinates
|
||||
bool calc_window_point(window, point&); ///<Converts screen coordinates to window coordinates.
|
||||
|
||||
window find_window(const nana::point& mspos);
|
||||
|
||||
void register_menu_window(window, bool has_keyboard);
|
||||
bool attach_menubar(window menubar);
|
||||
void detach_menubar(window menubar);
|
||||
void restore_menubar_taken_window();
|
||||
|
||||
bool is_window_zoomed(window, bool ask_for_max); ///<Tests a window whether it is maximized or minimized.
|
||||
|
||||
void widget_borderless(window, bool); ///<Enables or disables a borderless widget.
|
||||
bool widget_borderless(window); ///<Tests a widget whether it is borderless.
|
||||
|
||||
nana::mouse_action mouse_action(window);
|
||||
nana::element_state element_state(window);
|
||||
}//end namespace API
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
28
include/nana/gui/state_cursor.hpp
Normal file
28
include/nana/gui/state_cursor.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* State Cursor
|
||||
* 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/gui/state_cursor.hpp
|
||||
*/
|
||||
|
||||
#include <nana/gui/basis.hpp>
|
||||
namespace nana
|
||||
{
|
||||
class state_cursor
|
||||
{
|
||||
state_cursor(const state_cursor&) = delete;
|
||||
state_cursor& operator=(const state_cursor&) = delete;
|
||||
public:
|
||||
state_cursor(window, cursor);
|
||||
state_cursor(state_cursor&&);
|
||||
state_cursor& operator=(state_cursor&&);
|
||||
~state_cursor();
|
||||
private:
|
||||
window handle_;
|
||||
};
|
||||
}
|
||||
60
include/nana/gui/timer.hpp
Normal file
60
include/nana/gui/timer.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* A Timer Implementation
|
||||
* Copyright(C) 2003-2013 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/timer.hpp
|
||||
* @description:
|
||||
* A timer can repeatedly call a piece of code. The duration between
|
||||
* calls is specified in milliseconds. Timer is defferent from other graphics
|
||||
* controls, it has no graphics interface.
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_TIMER_HPP
|
||||
#define NANA_GUI_TIMER_HPP
|
||||
#include <nana/gui/detail/general_events.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
/// Can repeatedly call a piece of code.
|
||||
|
||||
struct arg_elapse
|
||||
{
|
||||
long long id; //timer identifier;
|
||||
};
|
||||
|
||||
class timer
|
||||
{
|
||||
struct implement;
|
||||
|
||||
timer(const timer&) = delete;
|
||||
timer& operator=(const timer&) = delete;
|
||||
timer(timer&&) = delete;
|
||||
timer& operator=(timer&&) = delete;
|
||||
public:
|
||||
timer();
|
||||
|
||||
~timer();
|
||||
|
||||
template<typename Function>
|
||||
void elapse(Function && fn)
|
||||
{
|
||||
elapse_.connect(std::forward<Function>(fn));
|
||||
}
|
||||
|
||||
void reset();
|
||||
void start();
|
||||
bool started() const;
|
||||
void stop();
|
||||
|
||||
void interval(unsigned milliseconds); ///< Set the duration between calls (millisec ??)
|
||||
unsigned interval() const;
|
||||
private:
|
||||
nana::basic_event<arg_elapse> elapse_;
|
||||
implement * const impl_;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
76
include/nana/gui/tooltip.hpp
Normal file
76
include/nana/gui/tooltip.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* A Tooltip Implementation
|
||||
* Copyright(C) 2003-2013 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/tooltip.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_TOOLTIP_HPP
|
||||
#define NANA_GUI_WIDGETS_TOOLTIP_HPP
|
||||
#include "widgets/widget.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
///tooltip_interface
|
||||
///An interface for user-defined tooltip window.
|
||||
class tooltip_interface
|
||||
{
|
||||
public:
|
||||
virtual ~tooltip_interface(){}
|
||||
|
||||
virtual bool tooltip_empty() const = 0;
|
||||
virtual nana::size tooltip_size() const = 0;
|
||||
virtual void tooltip_text(const nana::string&) = 0;
|
||||
virtual void tooltip_move(const nana::point& screen_pos, bool ignore_pos) = 0;
|
||||
virtual void duration(std::size_t) = 0;
|
||||
};
|
||||
|
||||
class tooltip
|
||||
{
|
||||
class factory_interface
|
||||
{
|
||||
public:
|
||||
virtual ~factory_interface(){}
|
||||
virtual tooltip_interface* create() = 0;
|
||||
virtual void destroy(tooltip_interface*) = 0;
|
||||
};
|
||||
|
||||
template<typename TooltipWindow>
|
||||
class factory
|
||||
: public factory_interface
|
||||
{
|
||||
tooltip_interface * create() override
|
||||
{
|
||||
return new TooltipWindow;
|
||||
}
|
||||
|
||||
void destroy(tooltip_interface* p) override
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
};
|
||||
public:
|
||||
typedef factory_interface factory_if_type;
|
||||
|
||||
template<typename TooltipWindow>
|
||||
static void make_factory()
|
||||
{
|
||||
_m_hold_factory(new factory<TooltipWindow>);
|
||||
}
|
||||
|
||||
tooltip(){}
|
||||
tooltip(window w, const nana::string &tip){set(w,tip);}
|
||||
|
||||
|
||||
static void set(window, const nana::string&);
|
||||
static void show(window, point pos, const nana::string&, std::size_t duration);
|
||||
static void close();
|
||||
private:
|
||||
static void _m_hold_factory(factory_interface*);
|
||||
};//class tooltip
|
||||
}//namespace nana
|
||||
#endif
|
||||
113
include/nana/gui/widgets/button.hpp
Normal file
113
include/nana/gui/widgets/button.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* A Button 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/gui/widgets/button.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_BUTTON_HPP
|
||||
#define NANA_GUI_WIDGET_BUTTON_HPP
|
||||
#include "widget.hpp"
|
||||
#include <nana/gui/element.hpp>
|
||||
|
||||
|
||||
namespace nana{
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace button
|
||||
{
|
||||
/// Draw the button
|
||||
class trigger: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
trigger();
|
||||
~trigger();
|
||||
|
||||
void emit_click();
|
||||
void icon(const nana::paint::image&);
|
||||
bool enable_pushed(bool);
|
||||
bool pushed(bool);
|
||||
bool pushed() const;
|
||||
void omitted(bool);
|
||||
bool focus_color(bool);
|
||||
|
||||
element::cite_bground & cite();
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void refresh(graph_reference) override;
|
||||
void mouse_enter(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_up(graph_reference, const arg_mouse&) override;
|
||||
void key_char(graph_reference, const arg_keyboard&) override;
|
||||
void key_press(graph_reference, const arg_keyboard&) override;
|
||||
void focus(graph_reference, const arg_focus&) override;
|
||||
private:
|
||||
void _m_draw(graph_reference);
|
||||
void _m_draw_title(graph_reference, bool enabled);
|
||||
void _m_draw_background(graph_reference);
|
||||
void _m_draw_border(graph_reference);
|
||||
private:
|
||||
widget* widget_;
|
||||
paint::graphics* graph_;
|
||||
|
||||
element::cite_bground cite_;
|
||||
|
||||
struct attr_tag
|
||||
{
|
||||
element_state e_state;
|
||||
bool omitted;
|
||||
bool focused;
|
||||
bool pushed;
|
||||
bool keep_pressed;
|
||||
bool enable_pushed;
|
||||
bool focus_color;
|
||||
paint::image * icon;
|
||||
color_t bgcolor;
|
||||
color_t fgcolor;
|
||||
}attr_;
|
||||
};
|
||||
}//end namespace button
|
||||
}//end namespace drawerbase
|
||||
|
||||
/// Define a button widget and provides the interfaces to be operational
|
||||
class button
|
||||
: public widget_object<category::widget_tag, drawerbase::button::trigger>
|
||||
{
|
||||
typedef widget_object<category::widget_tag, drawerbase::button::trigger> base_type;
|
||||
public:
|
||||
button();
|
||||
button(window, bool visible);
|
||||
button(window, const nana::string& caption, bool visible = true);
|
||||
button(window, const nana::char_t* caption, bool visible = true);
|
||||
button(window, const nana::rectangle& = rectangle(), bool visible = true);
|
||||
|
||||
button& icon(const nana::paint::image&);
|
||||
button& enable_pushed(bool);
|
||||
bool pushed() const;
|
||||
button& pushed(bool);
|
||||
button& omitted(bool); ///< Enables/Disables omitting displaying the caption if the text is too long.
|
||||
button& enable_focus_color(bool); ///< Enables/Disables showing the caption with a special color to indicate the button is focused.
|
||||
|
||||
button& set_bground(const pat::cloneable<element::element_interface>&); ///< Sets a user-defined background element.
|
||||
button& set_bground(const std::string&); ///< Sets a pre-defined background element by a name.
|
||||
|
||||
button& transparent(bool enable);
|
||||
bool transparent() const;
|
||||
|
||||
button& edge_effects(bool enable);
|
||||
private:
|
||||
void _m_shortkey();
|
||||
private:
|
||||
//Overrides widget virtual functions
|
||||
void _m_complete_creation() override;
|
||||
void _m_caption(nana::string&&) override;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
|
||||
247
include/nana/gui/widgets/categorize.hpp
Normal file
247
include/nana/gui/widgets/categorize.hpp
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* A Categorize 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/gui/widgets/categorize.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_CATEGORIZE_HPP
|
||||
#define NANA_GUI_WIDGET_CATEGORIZE_HPP
|
||||
|
||||
#include <nana/gui/widgets/widget.hpp>
|
||||
#include <nana/pat/cloneable.hpp>
|
||||
#include <nana/any.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
template<typename T> class categorize;
|
||||
|
||||
template<typename ValueType>
|
||||
struct arg_categorize
|
||||
{
|
||||
categorize<ValueType> & widget;
|
||||
ValueType & value;
|
||||
|
||||
arg_categorize(categorize<ValueType> & wdg, ValueType& v)
|
||||
: widget(wdg), value(v)
|
||||
{}
|
||||
};
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace categorize
|
||||
{
|
||||
template<typename T>
|
||||
struct categorize_events
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_categorize<T>> selected;
|
||||
};
|
||||
|
||||
class event_agent_interface
|
||||
{
|
||||
public:
|
||||
virtual ~event_agent_interface(){}
|
||||
virtual void selected(::nana::any&) = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class event_agent
|
||||
: public event_agent_interface
|
||||
{
|
||||
public:
|
||||
event_agent(::nana::categorize<T>& wdg)
|
||||
: widget_(wdg)
|
||||
{}
|
||||
|
||||
void selected(::nana::any & var)
|
||||
{
|
||||
auto vp = var.get<T>();
|
||||
|
||||
T null_val;
|
||||
arg_categorize<T> arg(widget_, vp ? *vp : null_val);
|
||||
widget_.events().selected.emit(arg);
|
||||
}
|
||||
private:
|
||||
::nana::categorize<T> & widget_;
|
||||
};
|
||||
|
||||
class renderer
|
||||
{
|
||||
public:
|
||||
typedef nana::paint::graphics & graph_reference;
|
||||
|
||||
struct ui_element
|
||||
{
|
||||
enum t
|
||||
{
|
||||
none, //Out of the widget
|
||||
somewhere, item_root, item_name, item_arrow
|
||||
};
|
||||
|
||||
t what;
|
||||
std::size_t index;
|
||||
|
||||
ui_element();
|
||||
};
|
||||
|
||||
virtual ~renderer() = 0;
|
||||
virtual void background(graph_reference, window wd, const nana::rectangle&, const ui_element&) = 0;
|
||||
virtual void root_arrow(graph_reference, const nana::rectangle&, mouse_action) = 0;
|
||||
virtual void item(graph_reference, const nana::rectangle&, std::size_t index, const nana::string& name, unsigned textheight, bool has_child, mouse_action) = 0;
|
||||
virtual void border(graph_reference) = 0;
|
||||
};
|
||||
|
||||
class trigger
|
||||
: public drawer_trigger
|
||||
{
|
||||
class scheme;
|
||||
public:
|
||||
typedef renderer::ui_element ui_element;
|
||||
|
||||
trigger();
|
||||
~trigger();
|
||||
|
||||
void insert(const nana::string&, nana::any);
|
||||
bool childset(const nana::string&, nana::any);
|
||||
bool childset_erase(const nana::string&);
|
||||
bool clear();
|
||||
|
||||
//splitstr
|
||||
//@brief: Sets the splitstr. If the parameter will be ingored if it is an empty string.
|
||||
void splitstr(const nana::string&);
|
||||
const nana::string& splitstr() const;
|
||||
|
||||
void path(const nana::string&);
|
||||
nana::string path() const;
|
||||
|
||||
template<typename T>
|
||||
void create_event_agent(::nana::categorize<T>& wdg)
|
||||
{
|
||||
event_agent_.reset(new event_agent<T>(wdg));
|
||||
_m_event_agent_ready();
|
||||
}
|
||||
|
||||
nana::any & value() const;
|
||||
private:
|
||||
void _m_event_agent_ready() const;
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void detached() override;
|
||||
void refresh(graph_reference) override;
|
||||
void mouse_down(graph_reference, const arg_mouse&) override;
|
||||
void mouse_up(graph_reference, const arg_mouse&) override;
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||
private:
|
||||
std::unique_ptr<event_agent_interface> event_agent_;
|
||||
scheme * scheme_;
|
||||
};
|
||||
}//end namespace categorize
|
||||
}//end namespace drawerbase
|
||||
|
||||
|
||||
|
||||
/// \brief Represent an architecture of categories and what category is chosen.
|
||||
/// The categorize widget can be used for representing a path of a directory or the order of a hierarchy.
|
||||
template<typename T>
|
||||
class categorize
|
||||
: public widget_object<category::widget_tag, drawerbase::categorize::trigger, drawerbase::categorize::categorize_events<T>>
|
||||
{
|
||||
public:
|
||||
typedef T value_type; ///< The type of objects stored
|
||||
typedef drawerbase::categorize::renderer renderer; ///< The interface for user-defined renderer.
|
||||
|
||||
categorize()
|
||||
{
|
||||
this->get_drawer_trigger().create_event_agent(*this);
|
||||
}
|
||||
|
||||
categorize(window wd, const rectangle& r = rectangle(), bool visible = true)
|
||||
{
|
||||
this->get_drawer_trigger().template create_event_agent(*this);
|
||||
this->create(wd, r, visible);
|
||||
}
|
||||
|
||||
categorize(window wd, bool visible)
|
||||
: categorize(wd, ::nana::rectangle(), visible)
|
||||
{
|
||||
}
|
||||
|
||||
categorize(window wd, const nana::string& text, bool visible = true)
|
||||
: categorize(wd, ::nana::rectangle(), visible)
|
||||
{
|
||||
this->caption(text);
|
||||
}
|
||||
|
||||
categorize(window wd, const nana::char_t* text, bool visible = true)
|
||||
: categorize(wd, ::nana::rectangle(), visible)
|
||||
{
|
||||
this->caption(text);
|
||||
}
|
||||
|
||||
/// Insert a new category with a specified name and the object of value type.
|
||||
/// The new category would be inserted as a child in current category,
|
||||
/// and after inserting, the new category is replaced of the current category as a new current one.
|
||||
categorize& insert(const nana::string& name, const value_type& value)
|
||||
{
|
||||
this->get_drawer_trigger().insert(name, value);
|
||||
API::update_window(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Inserts a child category into current category.
|
||||
categorize& childset(const nana::string& name, const value_type& value)
|
||||
{
|
||||
if(this->get_drawer_trigger().childset(name, value))
|
||||
API::update_window(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Erases a child category with a specified name from current category.
|
||||
categorize& childset_erase(const nana::string& name)
|
||||
{
|
||||
if(this->get_drawer_trigger().childset_erase(name))
|
||||
API::update_window(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
if(this->get_drawer_trigger().clear())
|
||||
API::update_window(*this);
|
||||
}
|
||||
|
||||
/// Sets the splitter string
|
||||
categorize& splitstr(const nana::string& sstr)
|
||||
{
|
||||
this->get_drawer_trigger().splitstr(sstr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
nana::string splitstr() const
|
||||
{
|
||||
return this->get_drawer_trigger().splitstr();
|
||||
}
|
||||
|
||||
/// Retrieves a reference of the current category's value type object. If current category is empty, it throws a exception of std::runtime_error.
|
||||
value_type& value() const
|
||||
{
|
||||
return this->get_drawer_trigger().value();
|
||||
}
|
||||
private:
|
||||
//Overrides widget's virtual functions
|
||||
void _m_caption(nana::string&& str) override
|
||||
{
|
||||
this->get_drawer_trigger().path(str);
|
||||
API::dev::window_caption(*this, this->get_drawer_trigger().path());
|
||||
}
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
100
include/nana/gui/widgets/checkbox.hpp
Normal file
100
include/nana/gui/widgets/checkbox.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* A CheckBox 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/gui/widgets/checkbox.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_CHECKBOX_HPP
|
||||
#define NANA_GUI_WIDGET_CHECKBOX_HPP
|
||||
#include "widget.hpp"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace nana {
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace checkbox
|
||||
{
|
||||
class drawer
|
||||
: public drawer_trigger
|
||||
{
|
||||
struct implement;
|
||||
public:
|
||||
drawer();
|
||||
~drawer(); //To instance imptr_;
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void refresh(graph_reference) override;
|
||||
void mouse_enter(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_up(graph_reference, const arg_mouse&) override;
|
||||
public:
|
||||
implement * impl() const;
|
||||
private:
|
||||
void _m_draw(graph_reference);
|
||||
void _m_draw_background(graph_reference);
|
||||
void _m_draw_checkbox(graph_reference, unsigned first_line_height);
|
||||
void _m_draw_title(graph_reference);
|
||||
private:
|
||||
static const int interval = 4;
|
||||
widget* widget_;
|
||||
unsigned state_;
|
||||
std::unique_ptr<implement> imptr_;
|
||||
implement * impl_;
|
||||
};
|
||||
}//end namespace checkbox
|
||||
}//end namespace drawerbase
|
||||
|
||||
|
||||
class checkbox
|
||||
: public widget_object<category::widget_tag, drawerbase::checkbox::drawer>
|
||||
{
|
||||
public:
|
||||
checkbox();
|
||||
checkbox(window, bool visible);
|
||||
checkbox(window, const nana::string& text, bool visible = true);
|
||||
checkbox(window, const nana::char_t* text, bool visible = true);
|
||||
checkbox(window, const rectangle& = rectangle(), bool visible = true);
|
||||
|
||||
void element_set(const char* name);
|
||||
void react(bool want); ///< Enables the reverse check while clicking on the checkbox.
|
||||
bool checked() const;
|
||||
void check(bool chk);
|
||||
|
||||
/// \brief With the radio mode, users make a choice among a set of mutually exclusive,
|
||||
/// related options. Users can choose one and only one option.
|
||||
/// There is a helper class manages checkboxs for radio mode,
|
||||
/// \see radio_group.
|
||||
void radio(bool);
|
||||
void transparent(bool value);
|
||||
bool transparent() const;
|
||||
};//end class checkbox
|
||||
/// for managing checkboxs in radio mode
|
||||
class radio_group
|
||||
{
|
||||
struct element_tag
|
||||
{
|
||||
checkbox * uiobj;
|
||||
event_handle eh_checked;
|
||||
event_handle eh_destroy;
|
||||
};
|
||||
public:
|
||||
~radio_group();
|
||||
void add(checkbox&);
|
||||
std::size_t checked() const; ///< Retrieves the index of the checkbox which is checked.
|
||||
std::size_t size() const;
|
||||
private:
|
||||
void _m_checked(const arg_mouse&);
|
||||
void _m_destroy(const arg_destroy&);
|
||||
private:
|
||||
std::vector<element_tag> ui_container_;
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
233
include/nana/gui/widgets/combox.hpp
Normal file
233
include/nana/gui/widgets/combox.hpp
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* A Combox 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/gui/widgets/combox.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_COMBOX_HPP
|
||||
#define NANA_GUI_WIDGETS_COMBOX_HPP
|
||||
#include "widget.hpp"
|
||||
#include "float_listbox.hpp"
|
||||
#include <nana/key_type.hpp>
|
||||
#include <nana/concepts.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
/// A list box combined with a textbox - the list box should drop down when the user selects the arrow next to the control
|
||||
class combox;
|
||||
|
||||
struct arg_combox
|
||||
{
|
||||
combox & widget;
|
||||
|
||||
arg_combox(combox& wdg)
|
||||
: widget(wdg)
|
||||
{}
|
||||
};
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace combox
|
||||
{
|
||||
struct combox_events
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_combox> selected;
|
||||
};
|
||||
|
||||
class drawer_impl;
|
||||
|
||||
class trigger
|
||||
: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
trigger();
|
||||
~trigger();
|
||||
|
||||
void set_accept(std::function<bool(nana::char_t)>&&);
|
||||
|
||||
drawer_impl& get_drawer_impl();
|
||||
const drawer_impl& get_drawer_impl() const;
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void detached() override;
|
||||
void refresh(graph_reference) override;
|
||||
void focus(graph_reference, const arg_focus&) override;
|
||||
void mouse_enter(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_up(graph_reference, const arg_mouse&) override;
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_wheel(graph_reference, const arg_wheel&) override;
|
||||
void key_press(graph_reference, const arg_keyboard&) override;
|
||||
void key_char(graph_reference, const arg_keyboard&) override;
|
||||
private:
|
||||
std::function<bool(nana::char_t)> pred_acceptive_;
|
||||
drawer_impl * drawer_;
|
||||
};
|
||||
|
||||
class item_proxy
|
||||
: public std::iterator<std::input_iterator_tag, item_proxy>
|
||||
{
|
||||
public:
|
||||
item_proxy(drawer_impl*, std::size_t pos);
|
||||
item_proxy& text(const nana::string&);
|
||||
nana::string text() const;
|
||||
item_proxy& select();
|
||||
bool selected() const;
|
||||
item_proxy& icon(const nana::paint::image&);
|
||||
nana::paint::image icon() const;
|
||||
|
||||
template<typename T>
|
||||
T * value_ptr() const
|
||||
{
|
||||
auto p = _m_anyobj(false);
|
||||
return (p ? p->get<T>() : nullptr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T & value() const
|
||||
{
|
||||
auto * pany = _m_anyobj(false);
|
||||
if (nullptr == pany)
|
||||
throw std::runtime_error("combox::item_proxy.value<T>() is empty");
|
||||
|
||||
T * p = pany->get<T>();
|
||||
if (nullptr == p)
|
||||
throw std::runtime_error("combox::item_proxy.value<T>() invalid type of value");
|
||||
return *p;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
item_proxy& value(const T& t)
|
||||
{
|
||||
*_m_anyobj(true) = t;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
item_proxy& value(T&& t)
|
||||
{
|
||||
*_m_anyobj(true) = std::move(t);
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
/// Behavior of Iterator's value_type
|
||||
bool operator==(const nana::string&) const;
|
||||
bool operator==(const char*) const;
|
||||
bool operator==(const wchar_t*) const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy & operator=(const item_proxy&);
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy & operator++();
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy operator++(int);
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy& operator*();
|
||||
|
||||
/// Behavior of Iterator
|
||||
const item_proxy& operator*() const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy* operator->();
|
||||
|
||||
/// Behavior of Iterator
|
||||
const item_proxy* operator->() const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
bool operator==(const item_proxy&) const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
bool operator!=(const item_proxy&) const;
|
||||
private:
|
||||
nana::any * _m_anyobj(bool alloc_if_empty) const;
|
||||
private:
|
||||
drawer_impl * impl_;
|
||||
std::size_t pos_;
|
||||
};
|
||||
}//end namespace combox
|
||||
}//end namespace drawerbase
|
||||
|
||||
class combox
|
||||
: public widget_object<category::widget_tag, drawerbase::combox::trigger, drawerbase::combox::combox_events>,
|
||||
public nana::concepts::any_objective<std::size_t, 1>
|
||||
{
|
||||
public:
|
||||
typedef float_listbox::item_renderer item_renderer;
|
||||
typedef drawerbase::combox::item_proxy item_proxy;
|
||||
|
||||
combox();
|
||||
combox(window, bool visible);
|
||||
combox(window, const nana::string& text, bool visible = true);
|
||||
combox(window, const nana::char_t* text, bool visible = true);
|
||||
combox(window, const rectangle& r = rectangle(), bool visible = true);
|
||||
|
||||
void clear();
|
||||
void editable(bool);
|
||||
bool editable() const;
|
||||
void set_accept(std::function<bool(nana::char_t)>);
|
||||
combox& push_back(const nana::string&);
|
||||
std::size_t the_number_of_options() const;
|
||||
std::size_t option() const; ///< Index of the last selected, from drop-down list, item.
|
||||
void option(std::size_t); ///< Select the text specified by index
|
||||
nana::string text(std::size_t) const;
|
||||
void erase(std::size_t pos);
|
||||
|
||||
template<typename Key>
|
||||
item_proxy operator[](const Key& kv)
|
||||
{
|
||||
typedef typename nana::detail::type_escape<Key>::type key_t;
|
||||
std::shared_ptr<nana::detail::key_interface> p(new nana::key<key_t, std::less<key_t> >(kv), [](nana::detail::key_interface*p)
|
||||
{
|
||||
delete p;
|
||||
});
|
||||
|
||||
return _m_at_key(std::move(p));
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
void erase_key(const Key& kv)
|
||||
{
|
||||
typedef typename nana::detail::type_escape<Key>::type key_t;
|
||||
std::unique_ptr<nana::detail::key_interface> p(new nana::key<key_t, std::less<key_t> >(kv));
|
||||
_m_erase(p.get());
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
void erase_key(Key&& kv)
|
||||
{
|
||||
typedef typename nana::detail::type_escape<Key>::type key_t;
|
||||
std::unique_ptr<nana::detail::key_interface> p(new nana::key<key_t, std::less<key_t> >(std::move(kv)));
|
||||
_m_erase(p.get());
|
||||
}
|
||||
|
||||
/// \brief Set user-defined item renderer object.
|
||||
/// It is an address therefore the user should not destroy the renderer object
|
||||
/// after it is set to the combox. Passing null_ptr cancels the user-defined renderer object.
|
||||
void renderer(item_renderer*);
|
||||
|
||||
void image(std::size_t, const nana::paint::image&);
|
||||
nana::paint::image image(std::size_t) const;
|
||||
void image_pixels(unsigned); ///<Sets the width of image area. Default is 16 pixels.
|
||||
private:
|
||||
item_proxy _m_at_key(std::shared_ptr<nana::detail::key_interface>&&);
|
||||
void _m_erase(nana::detail::key_interface*);
|
||||
private:
|
||||
//Overrides widget's virtual functions
|
||||
nana::string _m_caption() const override;
|
||||
void _m_caption(nana::string&&) override;
|
||||
nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
123
include/nana/gui/widgets/date_chooser.hpp
Normal file
123
include/nana/gui/widgets/date_chooser.hpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* A date chooser 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/gui/widgets/date_chooser.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_DATE_CHOOSER_HPP
|
||||
#define NANA_GUI_WIDGETS_DATE_CHOOSER_HPP
|
||||
|
||||
#include "widget.hpp"
|
||||
#include <nana/datetime.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace date_chooser
|
||||
{
|
||||
class trigger : public drawer_trigger
|
||||
{
|
||||
public:
|
||||
static const int topbar_height = 34;
|
||||
static const int border_size = 3;
|
||||
|
||||
enum class transform_action{none, to_left, to_right, to_enter, to_leave};
|
||||
enum class where{none, left_button, right_button, topbar, textarea};
|
||||
enum class page{date, month};
|
||||
|
||||
struct drawing_basis
|
||||
{
|
||||
nana::point refpos;
|
||||
double line_s;
|
||||
double row_s;
|
||||
};
|
||||
|
||||
trigger();
|
||||
bool chose() const;
|
||||
nana::date read() const;
|
||||
void week_name(unsigned index, const nana::string&);
|
||||
void month_name(unsigned index, const nana::string&);
|
||||
private:
|
||||
void _m_init_color();
|
||||
where _m_pos_where(graph_reference, int x, int y);
|
||||
void _m_draw(graph_reference);
|
||||
void _m_draw_topbar(graph_reference);
|
||||
void _m_make_drawing_basis(drawing_basis&, graph_reference, const nana::point& refpos);
|
||||
void _m_draw_pos(drawing_basis &, graph_reference, int x, int y, const nana::string&, bool primary, bool sel);
|
||||
void _m_draw_pos(drawing_basis &, graph_reference, int x, int y, int number, bool primary, bool sel);
|
||||
void _m_draw_ex_days(drawing_basis &, graph_reference, int begx, int begy, bool before);
|
||||
void _m_draw_days(const nana::point& refpos, graph_reference);
|
||||
void _m_draw_months(const nana::point& refpos, graph_reference);
|
||||
bool _m_get_trace(point, int & res);
|
||||
void _m_perf_transform(transform_action tfid, graph_reference, graph_reference dirtybuf, graph_reference newbuf, const nana::point& refpos);
|
||||
private:
|
||||
void refresh(graph_reference);
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||
void mouse_up(graph_reference, const arg_mouse&) override;
|
||||
private:
|
||||
nana::string weekstr_[7];
|
||||
nana::string monthstr_[12];
|
||||
|
||||
widget * widget_;
|
||||
|
||||
bool chose_;
|
||||
page page_;
|
||||
where pos_;
|
||||
nana::point trace_pos_;
|
||||
|
||||
drawing_basis dbasis_;
|
||||
|
||||
struct
|
||||
{
|
||||
int year;
|
||||
int month;
|
||||
int day;
|
||||
}chdate_;
|
||||
|
||||
struct
|
||||
{
|
||||
int year;
|
||||
int month;
|
||||
}chmonth_;
|
||||
|
||||
struct color_tag
|
||||
{
|
||||
nana::color_t highlight;
|
||||
nana::color_t selected;
|
||||
nana::color_t normal;
|
||||
nana::color_t bkcolor;
|
||||
}color_;
|
||||
};
|
||||
|
||||
}//end namespace date_chooser
|
||||
|
||||
}//end namespace drawerbase
|
||||
|
||||
/// \see nana::date
|
||||
class date_chooser
|
||||
: public widget_object<category::widget_tag, drawerbase::date_chooser::trigger>
|
||||
{
|
||||
public:
|
||||
date_chooser();
|
||||
date_chooser(window, bool visible);
|
||||
date_chooser(window, const nana::string& text, bool visible = true);
|
||||
date_chooser(window, const nana::char_t* text, bool visible = true);
|
||||
date_chooser(window, const nana::rectangle& r = rectangle(), bool visible = true);
|
||||
|
||||
bool chose() const;
|
||||
nana::date read() const;
|
||||
void weekstr(unsigned index, const nana::string&);///<Set the week strings which will be displayed for day, index is in range of [0, 6]
|
||||
void monthstr(unsigned index, const nana::string&);///<Set the month strings which will be displayed for month. index is in range of [0, 11]
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
84
include/nana/gui/widgets/detail/compset.hpp
Normal file
84
include/nana/gui/widgets/detail/compset.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Concept of Component Set
|
||||
* Copyright(C) 2003-2013 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/compset.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_DETAIL_COMPSET_HPP
|
||||
#define NANA_GUI_WIDGETS_DETAIL_COMPSET_HPP
|
||||
|
||||
#include <nana/basic_types.hpp>
|
||||
|
||||
namespace nana{ namespace widgets{ namespace detail
|
||||
{
|
||||
/// A component set used for accessing the components of items of a widget.
|
||||
template<typename Component, typename ItemAttribute>
|
||||
class compset
|
||||
{
|
||||
public:
|
||||
/// A type of widget-defined components.
|
||||
typedef Component component_t;
|
||||
|
||||
/// A type of widget-defined item attribute.
|
||||
typedef ItemAttribute item_attribute_t;
|
||||
|
||||
/// A type of a componenet state for rendering.
|
||||
struct comp_attribute_t
|
||||
{
|
||||
nana::rectangle area;
|
||||
bool mouse_pointed;
|
||||
};
|
||||
|
||||
public:
|
||||
/// The destrcutor
|
||||
virtual ~compset(){}
|
||||
|
||||
/// Access the widget-defined item attribute.
|
||||
virtual const item_attribute_t& item_attribute() const = 0;
|
||||
|
||||
/// Access a specified component of the item.
|
||||
virtual bool comp_attribute(component_t, comp_attribute_t &) const = 0;
|
||||
};
|
||||
|
||||
/// A component set placer used for specifying component position and size.
|
||||
template<typename Component, typename ItemAttribute>
|
||||
class compset_placer
|
||||
{
|
||||
public:
|
||||
typedef ::nana::paint::graphics & graph_reference;
|
||||
/// A type of widget-defined components.
|
||||
typedef Component component_t;
|
||||
|
||||
/// A type of widget-defined item attribute.
|
||||
typedef ItemAttribute item_attribute_t;
|
||||
public:
|
||||
/// The destrcutor.
|
||||
virtual ~compset_placer(){}
|
||||
|
||||
/// Enable/Disable the specified component.
|
||||
virtual void enable(component_t, bool) = 0;
|
||||
virtual bool enabled(component_t) const = 0;
|
||||
|
||||
/// Height of an item, in pixels.
|
||||
// this method is content-indepented, this feature is easy for implementation.
|
||||
virtual unsigned item_height(graph_reference) const = 0;
|
||||
|
||||
/// Width of an item, in pixels
|
||||
virtual unsigned item_width(graph_reference, const item_attribute_t&) const = 0;
|
||||
|
||||
/// Locate a component through the specified coordinate.
|
||||
/// @param comp the component of the item.
|
||||
/// @param attr the attribute of the item.
|
||||
/// @param r the pointer refers to a rectangle for receiving the position and size of the component.
|
||||
/// @returns the true when the component is located by the locator.
|
||||
virtual bool locate(component_t comp, const item_attribute_t& attr, rectangle * r) const = 0;
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace widgets
|
||||
}//end namespace nana
|
||||
#endif
|
||||
518
include/nana/gui/widgets/detail/tree_cont.hpp
Normal file
518
include/nana/gui/widgets/detail/tree_cont.hpp
Normal file
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
* A Tree Container class implementation
|
||||
* Copyright(C) 2003-2013 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/tree_cont.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP
|
||||
#define NANA_GUI_WIDGETS_DETAIL_TREE_CONT_HPP
|
||||
#include <stack>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace widgets
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
struct tree_node
|
||||
{
|
||||
typedef std::pair<nana::string, T> value_type;
|
||||
|
||||
value_type value;
|
||||
|
||||
tree_node *owner;
|
||||
tree_node *next;
|
||||
tree_node *child;
|
||||
|
||||
tree_node(tree_node* owner)
|
||||
:owner(owner), next(nullptr), child(nullptr)
|
||||
{}
|
||||
|
||||
~tree_node()
|
||||
{
|
||||
if(owner)
|
||||
{
|
||||
tree_node * t = owner->child;
|
||||
if(t != this)
|
||||
{
|
||||
while(t->next != this)
|
||||
t = t->next;
|
||||
t->next = next;
|
||||
}
|
||||
else
|
||||
owner->child = next;
|
||||
}
|
||||
|
||||
tree_node * t = child;
|
||||
while(t)
|
||||
{
|
||||
tree_node * t_next = t->next;
|
||||
delete t;
|
||||
t = t_next;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename UserData>
|
||||
class tree_cont
|
||||
{
|
||||
typedef tree_cont self_type;
|
||||
|
||||
public:
|
||||
typedef UserData element_type;
|
||||
typedef tree_node<element_type> node_type;
|
||||
typedef typename node_type::value_type value_type;
|
||||
|
||||
tree_cont()
|
||||
:root_(nullptr)
|
||||
{}
|
||||
|
||||
~tree_cont()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
remove(root_.child);
|
||||
}
|
||||
|
||||
bool verify(const node_type* node) const
|
||||
{
|
||||
if(node)
|
||||
{
|
||||
while(node->owner)
|
||||
{
|
||||
if(node->owner == &root_)
|
||||
return true;
|
||||
|
||||
node = node->owner;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
node_type* get_root() const
|
||||
{
|
||||
return &root_;
|
||||
}
|
||||
|
||||
node_type* get_owner(const node_type* node) const
|
||||
{
|
||||
return (verify(node) && (node->owner != &root_) ? node->owner : nullptr);
|
||||
}
|
||||
|
||||
node_type * node(node_type* node, const nana::string& key)
|
||||
{
|
||||
if(node)
|
||||
{
|
||||
for(node_type * child = node->child; child; child = child->next)
|
||||
{
|
||||
if(child->value.first == key)
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
node_type* insert(node_type* node, const nana::string& key, const element_type& elem)
|
||||
{
|
||||
if(nullptr == node)
|
||||
return insert(key, elem);
|
||||
|
||||
if(verify(node))
|
||||
{
|
||||
node_type **new_node_ptr;
|
||||
if(node->child)
|
||||
{
|
||||
node_type* child = node->child;
|
||||
for(; child; child = child->next)
|
||||
{
|
||||
if(child->value.first == key)
|
||||
{
|
||||
child->value.second = elem;
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
child = node->child;
|
||||
while(child->next)
|
||||
child = child->next;
|
||||
|
||||
new_node_ptr = &(child->next);
|
||||
}
|
||||
else
|
||||
new_node_ptr = &(node->child);
|
||||
|
||||
*new_node_ptr = new node_type(node);
|
||||
|
||||
(*new_node_ptr)->value.first = key;
|
||||
(*new_node_ptr)->value.second = elem;
|
||||
return (*new_node_ptr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
node_type* insert(const nana::string& key, const element_type& elem)
|
||||
{
|
||||
auto node = _m_locate<true>(key);
|
||||
if(node)
|
||||
node->value.second = elem;
|
||||
return node;
|
||||
}
|
||||
|
||||
void remove(node_type* node)
|
||||
{
|
||||
if(verify(node))
|
||||
delete node;
|
||||
}
|
||||
|
||||
node_type* find(const nana::string& path) const
|
||||
{
|
||||
return _m_locate(path);
|
||||
}
|
||||
|
||||
node_type* ref(const nana::string& path)
|
||||
{
|
||||
return _m_locate<true>(path);
|
||||
}
|
||||
|
||||
unsigned indent_size(const node_type* node) const
|
||||
{
|
||||
if(node)
|
||||
{
|
||||
unsigned indent = 0;
|
||||
for(;(node = node->owner); ++indent)
|
||||
{
|
||||
if(node == &root_) return indent;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename Functor>
|
||||
void for_each(node_type* node, Functor f)
|
||||
{
|
||||
if(nullptr == node) node = root_.child;
|
||||
int state = 0; //0: Sibling, the last is a sibling of node
|
||||
//1: Owner, the last is the owner of node
|
||||
//>= 2: Children, the last is is a child of the node that before this node.
|
||||
while(node)
|
||||
{
|
||||
switch(f(*node, state))
|
||||
{
|
||||
case 0: return;
|
||||
case 1:
|
||||
{
|
||||
if(node->child)
|
||||
{
|
||||
node = node->child;
|
||||
state = 1;
|
||||
}
|
||||
else
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(node->next)
|
||||
{
|
||||
node = node->next;
|
||||
state = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = 1;
|
||||
if(node == &root_) return;
|
||||
|
||||
while(true)
|
||||
{
|
||||
++state;
|
||||
if(node->owner->next)
|
||||
{
|
||||
node = node->owner->next;
|
||||
break;
|
||||
}
|
||||
else
|
||||
node = node->owner;
|
||||
|
||||
if(node == &root_) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Functor>
|
||||
void for_each(node_type* node, Functor f) const
|
||||
{
|
||||
if(nullptr == node) node = root_.child;
|
||||
int state = 0; //0: Sibling, the last is a sibling of node
|
||||
//1: Owner, the last is the owner of node
|
||||
//>= 2: Children, the last is is a child of the node that before this node.
|
||||
while(node)
|
||||
{
|
||||
switch(f(*node, state))
|
||||
{
|
||||
case 0: return;
|
||||
case 1:
|
||||
{
|
||||
if(node->child)
|
||||
{
|
||||
node = node->child;
|
||||
state = 1;
|
||||
}
|
||||
else
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(node->next)
|
||||
{
|
||||
node = node->next;
|
||||
state = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = 1;
|
||||
if(node == &root_) return;
|
||||
|
||||
while(true)
|
||||
{
|
||||
++state;
|
||||
if(node->owner->next)
|
||||
{
|
||||
node = node->owner->next;
|
||||
break;
|
||||
}
|
||||
else
|
||||
node = node->owner;
|
||||
|
||||
if(node == &root_) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename PredAllowChild>
|
||||
unsigned child_size_if(const nana::string& key, PredAllowChild pac) const
|
||||
{
|
||||
auto node = _m_locate(key);
|
||||
return (node ? child_size_if<PredAllowChild>(*node, pac) : 0);
|
||||
}
|
||||
|
||||
template<typename PredAllowChild>
|
||||
unsigned child_size_if(const node_type& node, PredAllowChild pac) const
|
||||
{
|
||||
unsigned size = 0;
|
||||
const node_type* pnode = node.child;
|
||||
while(pnode)
|
||||
{
|
||||
++size;
|
||||
if(pnode->child && pac(*pnode))
|
||||
size += child_size_if<PredAllowChild>(*pnode, pac);
|
||||
|
||||
pnode = pnode->next;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
template<typename PredAllowChild>
|
||||
unsigned distance_if(const node_type * node, PredAllowChild pac) const
|
||||
{
|
||||
if(nullptr == node) return 0;
|
||||
const node_type * iterator = root_.child;
|
||||
|
||||
unsigned off = 0;
|
||||
std::stack<const node_type* > stack;
|
||||
|
||||
while(iterator && iterator != node)
|
||||
{
|
||||
++off;
|
||||
|
||||
if(iterator->child && pac(*iterator))
|
||||
{
|
||||
stack.push(iterator);
|
||||
iterator = iterator->child;
|
||||
}
|
||||
else
|
||||
iterator = iterator->next;
|
||||
|
||||
while((nullptr == iterator) && stack.size())
|
||||
{
|
||||
iterator = stack.top()->next;
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
return off;
|
||||
}
|
||||
|
||||
template<typename PredAllowChild>
|
||||
node_type* advance_if(node_type* node, std::size_t off, PredAllowChild pac)
|
||||
{
|
||||
if(nullptr == node) node = root_.child;
|
||||
|
||||
std::stack<node_type* > stack;
|
||||
|
||||
while(node && off)
|
||||
{
|
||||
--off;
|
||||
if(node->child && pac(*node))
|
||||
{
|
||||
stack.push(node);
|
||||
node = node->child;
|
||||
}
|
||||
else
|
||||
node = node->next;
|
||||
|
||||
while(nullptr == node && stack.size())
|
||||
{
|
||||
node = stack.top();
|
||||
stack.pop();
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
private:
|
||||
//Functor defintions
|
||||
|
||||
struct each_make_node
|
||||
{
|
||||
each_make_node(self_type& self)
|
||||
:node(&(self.root_))
|
||||
{}
|
||||
|
||||
bool operator()(const nana::string& key_node)
|
||||
{
|
||||
node_type *child = node->child;
|
||||
node_type *tail = nullptr;
|
||||
while(child)
|
||||
{
|
||||
if(key_node == child->value.first)
|
||||
{
|
||||
node = child;
|
||||
return true;
|
||||
}
|
||||
tail = child;
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
child = new node_type(node);
|
||||
if(tail)
|
||||
tail->next = child;
|
||||
else
|
||||
node->child = child;
|
||||
|
||||
child->value.first = key_node;
|
||||
node = child;
|
||||
return true;
|
||||
}
|
||||
|
||||
node_type * node;
|
||||
};
|
||||
|
||||
|
||||
struct find_key_node
|
||||
{
|
||||
find_key_node(const self_type& self)
|
||||
:node(&self.root_)
|
||||
{}
|
||||
|
||||
bool operator()(const nana::string& key_node)
|
||||
{
|
||||
return ((node = _m_find(node->child, key_node)) != nullptr);
|
||||
}
|
||||
|
||||
node_type *node;
|
||||
};
|
||||
private:
|
||||
static node_type* _m_find(node_type* node, const nana::string& key_node)
|
||||
{
|
||||
while(node)
|
||||
{
|
||||
if(key_node == node->value.first)
|
||||
return node;
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename Function>
|
||||
void _m_for_each(const nana::string& key, Function function) const
|
||||
{
|
||||
if(key.size())
|
||||
{
|
||||
nana::string::size_type beg = 0;
|
||||
auto end = key.find_first_of(STR("\\/"));
|
||||
|
||||
while(end != nana::string::npos)
|
||||
{
|
||||
if(beg != end)
|
||||
{
|
||||
if(function(key.substr(beg, end - beg)) == false)
|
||||
return;
|
||||
}
|
||||
|
||||
auto next = key.find_first_not_of(STR("\\/"), end);
|
||||
if(next != nana::string::npos)
|
||||
{
|
||||
beg = next;
|
||||
end = key.find_first_of(STR("\\/"), beg);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
function(key.substr(beg, key.size() - beg));
|
||||
}
|
||||
}
|
||||
|
||||
template<bool CreateIfNotExists>
|
||||
node_type* _m_locate(const nana::string& key)
|
||||
{
|
||||
if(key.size())
|
||||
{
|
||||
if(CreateIfNotExists)
|
||||
{
|
||||
each_make_node emn(*this);
|
||||
_m_for_each<each_make_node&>(key, emn);
|
||||
return emn.node;
|
||||
}
|
||||
else
|
||||
{
|
||||
find_key_node fkn(*this);
|
||||
_m_for_each<find_key_node&>(key, fkn);
|
||||
return const_cast<node_type*>(fkn.node);
|
||||
}
|
||||
}
|
||||
return &root_;
|
||||
}
|
||||
|
||||
node_type* _m_locate(const nana::string& key) const
|
||||
{
|
||||
if(key.size())
|
||||
{
|
||||
find_key_node fkn(*this);
|
||||
_m_for_each<find_key_node&>(key, fkn);
|
||||
return fkn.node;
|
||||
}
|
||||
return &root_;
|
||||
}
|
||||
private:
|
||||
mutable node_type root_;
|
||||
};//end class tree_cont
|
||||
}//end namespace detail
|
||||
}//end namespace widgets
|
||||
}//end namesace nana
|
||||
#endif
|
||||
107
include/nana/gui/widgets/float_listbox.hpp
Normal file
107
include/nana/gui/widgets/float_listbox.hpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* A float_listbox 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/gui/widgets/float_listbox.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP
|
||||
#define NANA_GUI_WIDGETS_FLOAT_LISTBOX_HPP
|
||||
|
||||
#include "widget.hpp"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace drawerbase{
|
||||
namespace float_listbox
|
||||
{
|
||||
class item_interface
|
||||
{
|
||||
public:
|
||||
virtual ~item_interface(){}
|
||||
|
||||
virtual const nana::paint::image & image() const = 0;
|
||||
virtual const nana::char_t* text() const = 0;
|
||||
};
|
||||
|
||||
//struct module_def
|
||||
//@brief: This defines a data structure used for float_listbox
|
||||
struct module_def
|
||||
{
|
||||
std::vector<std::shared_ptr<item_interface>> items;
|
||||
|
||||
std::size_t max_items; // the number of items display.
|
||||
mutable std::size_t index; // the result of the selection.
|
||||
mutable bool have_selected;
|
||||
|
||||
module_def();
|
||||
};
|
||||
|
||||
class item_renderer
|
||||
{
|
||||
public:
|
||||
typedef widget& widget_reference;
|
||||
typedef paint::graphics& graph_reference;
|
||||
enum state_t{StateNone, StateHighlighted};
|
||||
|
||||
virtual ~item_renderer() = 0;
|
||||
virtual void image(bool enabled, unsigned pixels) = 0;
|
||||
virtual void render(widget_reference, graph_reference, const nana::rectangle&, const item_interface*, state_t) = 0;
|
||||
virtual unsigned item_pixels(graph_reference) const = 0;
|
||||
};
|
||||
|
||||
class drawer_impl;
|
||||
|
||||
class trigger
|
||||
: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
trigger();
|
||||
~trigger();
|
||||
drawer_impl& get_drawer_impl();
|
||||
const drawer_impl& get_drawer_impl() const;
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void detached() override;
|
||||
void refresh(graph_reference) override;
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_up(graph_reference, const arg_mouse&) override;
|
||||
private:
|
||||
class drawer_impl *drawer_;
|
||||
};
|
||||
}
|
||||
}//end namespace drawerbase
|
||||
|
||||
class float_listbox
|
||||
: public widget_object<category::root_tag, drawerbase::float_listbox::trigger>
|
||||
{
|
||||
typedef widget_object<category::root_tag, drawerbase::float_listbox::trigger> base_type;
|
||||
public:
|
||||
typedef drawerbase::float_listbox::item_renderer item_renderer;
|
||||
typedef drawerbase::float_listbox::module_def module_type;
|
||||
typedef drawerbase::float_listbox::item_interface item_interface;
|
||||
|
||||
/** @brief Constructor
|
||||
* @param window A handle to a window which is a owner of float_listbox
|
||||
* @param rectangle A position and a size of float_listbox
|
||||
* @param is_ignore_first_mouse_up The flost_listbox will be closed when a mouse_up is emitted, this parameter is specified for ignoring the first mouse_up emitting.
|
||||
* @remark The float_listbox can be popupped in a mouse_down event, the next mouse_up may be ignored, otherwise the float_listbox will be closed when user releases the button.
|
||||
*/
|
||||
float_listbox(window, const rectangle&, bool is_ignore_first_mouse_up);
|
||||
|
||||
void set_module(const module_type&, unsigned image_pixels);
|
||||
void scroll_items(bool upwards);
|
||||
void move_items(bool upwards, bool circle);
|
||||
void renderer(item_renderer*);
|
||||
std::size_t index() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
64
include/nana/gui/widgets/form.hpp
Normal file
64
include/nana/gui/widgets/form.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* A Form 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/gui/widgets/form.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_FORM_HPP
|
||||
#define NANA_GUI_WIDGET_FORM_HPP
|
||||
|
||||
#include "widget.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace form
|
||||
{
|
||||
class trigger: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
trigger();
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void refresh(graph_reference) override;
|
||||
void resized(graph_reference, const arg_resized&) override;
|
||||
private:
|
||||
widget* wd_;
|
||||
};
|
||||
}//end namespace form
|
||||
}//end namespace drawerbase
|
||||
|
||||
/// \brief Pop-up window. Is different from other window widgets: its default constructor create the window.
|
||||
/// \see nana::appearance
|
||||
class form: public widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension>
|
||||
{
|
||||
public:
|
||||
typedef ::nana::appear appear;
|
||||
|
||||
/// Creates a window at the point and size specified by rect, and with the specified appearance. Creates a form owned by the desktop.
|
||||
form(const rectangle& = API::make_center(300, 200), const appearance& = {}); //Default constructor
|
||||
form(const form&, const ::nana::size& = { 300, 200 }, const appearance& = {}); //Copy constructor
|
||||
form(window, const ::nana::size& = { 300, 200 }, const appearance& = {});
|
||||
/// Creates a window at the point and size specified by rect, with the specified appearance. This window is always floating above its owner.
|
||||
form(window, const rectangle&, const appearance& = {});
|
||||
};
|
||||
|
||||
class nested_form : public widget_object<category::root_tag, drawerbase::form::trigger, detail::events_root_extension>
|
||||
{
|
||||
public:
|
||||
typedef ::nana::appear appear;
|
||||
|
||||
nested_form(const form&, const rectangle& = {}, const appearance& = {});
|
||||
nested_form(const nested_form&, const rectangle& = {}, const appearance& = {});
|
||||
|
||||
nested_form(window, const appearance&);
|
||||
nested_form(window, const rectangle& = {}, const appearance& = {});
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
53
include/nana/gui/widgets/frame.hpp
Normal file
53
include/nana/gui/widgets/frame.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* A Frame 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/gui/widgets/frame.hpp
|
||||
*
|
||||
* A frame provides a way to contain the platform window in a stdex GUI Window
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_FRAME_HPP
|
||||
#define NANA_GUI_WIDGET_FRAME_HPP
|
||||
|
||||
#include "widget.hpp"
|
||||
namespace nana
|
||||
{
|
||||
/**
|
||||
\brief Container for system native windows. Provides an approach to
|
||||
display a control that is not written with Nana.GUI in a Nana.GUI window.
|
||||
|
||||
Notes:
|
||||
|
||||
1. nana::native_window_type is a type of system handle of windows.
|
||||
2. all the children windows of a nana::frame is topmost to Nana.GUI windows.
|
||||
3. a simple example. Displaying a Windows Edit Control.
|
||||
|
||||
nana::frame frame(parent, 0, 0 200, 100);
|
||||
HWND frame_handle = reinterpret_cast<HWND>(frame.container());
|
||||
HWND edit = ::CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"Test",
|
||||
WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 0, 200, 100,
|
||||
frame_handle, 0, ::GetModuleHandle(0), 0);
|
||||
if(edit)
|
||||
frame.insert(edit);
|
||||
|
||||
*/
|
||||
class frame: public widget_object<category::frame_tag, int, nana::general_events>
|
||||
{
|
||||
typedef widget_object<category::frame_tag, int> base_type;
|
||||
public:
|
||||
frame();
|
||||
frame(window, bool visible);
|
||||
frame(window, const rectangle& = rectangle(), bool visible = true);
|
||||
bool insert(native_window_type); ///< Inserts a platform native window.
|
||||
native_window_type element(unsigned index); ///< Returns the child window through index.
|
||||
|
||||
native_window_type container() const; ///< Returns the frame container native window handle.
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
78
include/nana/gui/widgets/label.hpp
Normal file
78
include/nana/gui/widgets/label.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* A Label Control 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/gui/widgets/label.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_LABEL_HPP
|
||||
#define NANA_GUI_WIDGET_LABEL_HPP
|
||||
#include "widget.hpp"
|
||||
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace label
|
||||
{
|
||||
enum class command /// Defines the event type for format listener.
|
||||
{
|
||||
enter, leave, click
|
||||
};
|
||||
|
||||
/// draw the label
|
||||
class trigger: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
struct impl_t;
|
||||
|
||||
trigger();
|
||||
~trigger();
|
||||
impl_t * impl() const;
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void refresh(graph_reference) override;
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||
void click(graph_reference, const arg_mouse&) override;
|
||||
private:
|
||||
impl_t * impl_;
|
||||
};
|
||||
|
||||
}//end namespace label
|
||||
}//end namespace drawerbase
|
||||
|
||||
class label
|
||||
: public widget_object<category::widget_tag, drawerbase::label::trigger>
|
||||
{
|
||||
label(const label&) = delete;
|
||||
label(label&&) = delete;
|
||||
public:
|
||||
typedef drawerbase::label::command command;
|
||||
label();
|
||||
label(window, bool visible);
|
||||
label(window, const nana::string& text, bool visible = true);
|
||||
label(window, const nana::char_t* text, bool visible = true);
|
||||
label(window, const rectangle& = {}, bool visible = true);
|
||||
label& transparent(bool); ///< Switchs the label widget to the transparent background mode.
|
||||
bool transparent() const;
|
||||
label& format(bool); ///< Switches the format mode of the widget.
|
||||
label& add_format_listener(std::function<void(command, const nana::string&)>);
|
||||
|
||||
/// \briefReturn the size of the text. If *allowed_width_in_pixel* is not zero, returns a
|
||||
/// "corrected" size that changes lines to fit the text into the specified width
|
||||
nana::size measure(unsigned allowed_width_in_pixel) const;
|
||||
|
||||
label& text_align(align horizontal_align, align_v vertical_align= align_v::top);
|
||||
private:
|
||||
//Overrides widget's virtual function
|
||||
void _m_caption(nana::string&&) override;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
550
include/nana/gui/widgets/listbox.hpp
Normal file
550
include/nana/gui/widgets/listbox.hpp
Normal file
@@ -0,0 +1,550 @@
|
||||
/*
|
||||
* A List Box 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/gui/widgets/listbox.hpp
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_LISTBOX_HPP
|
||||
#define NANA_GUI_WIDGETS_LISTBOX_HPP
|
||||
#include "widget.hpp"
|
||||
#include <nana/concepts.hpp>
|
||||
#include <nana/key_type.hpp>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class listbox;
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace listbox
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
|
||||
struct cell
|
||||
{
|
||||
struct format
|
||||
{
|
||||
::nana::color_t bgcolor;
|
||||
::nana::color_t fgcolor;
|
||||
|
||||
format(color_t bgcolor = 0xFF000000, color_t fgcolor = 0xFF000000);
|
||||
};
|
||||
|
||||
using format_ptr = std::unique_ptr < format > ;
|
||||
|
||||
::nana::string text;
|
||||
format_ptr custom_format;
|
||||
|
||||
cell() = default;
|
||||
cell(const cell&);
|
||||
cell(cell&&);
|
||||
cell(nana::string);
|
||||
cell(nana::string, const format&);
|
||||
cell(nana::string, color_t bgcolor, color_t fgcolor);
|
||||
|
||||
cell& operator=(const cell&);
|
||||
cell& operator=(cell&&);
|
||||
};
|
||||
|
||||
class oresolver
|
||||
{
|
||||
public:
|
||||
oresolver& operator<<(bool);
|
||||
oresolver& operator<<(short);
|
||||
oresolver& operator<<(unsigned short);
|
||||
oresolver& operator<<(int);
|
||||
oresolver& operator<<(unsigned int);
|
||||
oresolver& operator<<(long);
|
||||
oresolver& operator<<(unsigned long);
|
||||
oresolver& operator<<(long long);
|
||||
oresolver& operator<<(unsigned long long);
|
||||
oresolver& operator<<(float);
|
||||
oresolver& operator<<(double);
|
||||
oresolver& operator<<(long double);
|
||||
|
||||
oresolver& operator<<(const char*);
|
||||
oresolver& operator<<(const wchar_t*);
|
||||
oresolver& operator<<(const std::string&);
|
||||
oresolver& operator<<(const std::wstring&);
|
||||
oresolver& operator<<(std::wstring&&);
|
||||
oresolver& operator<<(cell);
|
||||
oresolver& operator<<(std::nullptr_t);
|
||||
|
||||
std::vector<cell> && move_cells();
|
||||
private:
|
||||
std::vector<cell> cells_;
|
||||
};
|
||||
|
||||
class iresolver
|
||||
{
|
||||
public:
|
||||
iresolver(const std::vector<cell>&);
|
||||
|
||||
iresolver& operator>>(bool&);
|
||||
iresolver& operator>>(short&);
|
||||
iresolver& operator>>(unsigned short&);
|
||||
iresolver& operator>>(int&);
|
||||
iresolver& operator>>(unsigned int&);
|
||||
iresolver& operator>>(long&);
|
||||
iresolver& operator>>(unsigned long&);
|
||||
iresolver& operator>>(long long&);
|
||||
iresolver& operator>>(unsigned long long&);
|
||||
iresolver& operator>>(float&);
|
||||
iresolver& operator>>(double&);
|
||||
iresolver& operator>>(long double&);
|
||||
|
||||
iresolver& operator>>(std::string&);
|
||||
iresolver& operator>>(std::wstring&);
|
||||
iresolver& operator>>(cell&);
|
||||
iresolver& operator>>(std::nullptr_t);
|
||||
private:
|
||||
const std::vector<cell>& cells_;
|
||||
std::size_t pos_{0};
|
||||
};
|
||||
|
||||
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.
|
||||
struct essence_t;
|
||||
|
||||
struct category_t;
|
||||
class drawer_header_impl;
|
||||
class drawer_lister_impl;
|
||||
|
||||
class trigger: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
trigger();
|
||||
~trigger();
|
||||
essence_t& essence();
|
||||
essence_t& essence() const;
|
||||
void draw();
|
||||
private:
|
||||
void _m_draw_border();
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void detached() override;
|
||||
void typeface_changed(graph_reference) override;
|
||||
void refresh(graph_reference) override;
|
||||
void mouse_move(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_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 resized(graph_reference, const arg_resized&) override;
|
||||
void key_press(graph_reference, const arg_keyboard&) override;
|
||||
private:
|
||||
essence_t * essence_;
|
||||
drawer_header_impl *drawer_header_;
|
||||
drawer_lister_impl *drawer_lister_;
|
||||
};//end class trigger
|
||||
|
||||
class item_proxy
|
||||
: public std::iterator<std::input_iterator_tag, item_proxy>
|
||||
{
|
||||
public:
|
||||
item_proxy(essence_t*);
|
||||
item_proxy(essence_t*, const index_pair&);
|
||||
|
||||
bool empty() const;
|
||||
|
||||
item_proxy & check(bool ck);
|
||||
bool checked() const;
|
||||
|
||||
item_proxy & select(bool);
|
||||
bool selected() const;
|
||||
|
||||
item_proxy & bgcolor(nana::color_t);
|
||||
nana::color_t bgcolor() const;
|
||||
|
||||
item_proxy& fgcolor(nana::color_t);
|
||||
nana::color_t fgcolor() const;
|
||||
|
||||
index_pair pos() const;
|
||||
|
||||
size_type columns() const;
|
||||
|
||||
item_proxy& text(size_type col, cell);
|
||||
item_proxy& text(size_type col, nana::string);
|
||||
nana::string text(size_type col) const;
|
||||
|
||||
void icon(const nana::paint::image&);
|
||||
|
||||
template<typename T>
|
||||
item_proxy & resolve_from(const T& t)
|
||||
{
|
||||
oresolver ores;
|
||||
ores << t;
|
||||
auto && cells = ores.move_cells();
|
||||
auto cols = columns();
|
||||
cells.resize(cols);
|
||||
for (auto pos = 0; pos < cols; ++pos)
|
||||
{
|
||||
auto & el = cells[pos];
|
||||
if (el.text.size() == 1 && el.text[0] == nana::char_t(0))
|
||||
continue;
|
||||
text(pos, std::move(el));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void resolve_to(T& t) const
|
||||
{
|
||||
iresolver ires(_m_cells());
|
||||
ires >> t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* value_ptr() const
|
||||
{
|
||||
auto * pany = _m_value();
|
||||
return (pany ? pany->get<T>() : nullptr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T & value() const
|
||||
{
|
||||
auto * pany = _m_value();
|
||||
if(nullptr == pany)
|
||||
throw std::runtime_error("listbox::item_proxy.value<T>() is empty");
|
||||
|
||||
T * p = pany->get<T>();
|
||||
if(nullptr == p)
|
||||
throw std::runtime_error("listbox::item_proxy.value<T>() invalid type of value");
|
||||
return *p;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
item_proxy & value(T&& t)
|
||||
{
|
||||
*_m_value(true) = std::forward<T>(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Behavior of Iterator's value_type
|
||||
bool operator==(const nana::string& s) const;
|
||||
bool operator==(const char * s) const;
|
||||
bool operator==(const wchar_t * s) const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy & operator=(const item_proxy&);
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy & operator++();
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy operator++(int);
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy& operator*();
|
||||
|
||||
/// Behavior of Iterator
|
||||
const item_proxy& operator*() const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy* operator->();
|
||||
|
||||
/// Behavior of Iterator
|
||||
const item_proxy* operator->() const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
bool operator==(const item_proxy&) const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
bool operator!=(const item_proxy&) const;
|
||||
|
||||
//Undocumented method
|
||||
essence_t * _m_ess() const;
|
||||
private:
|
||||
std::vector<cell> & _m_cells() const;
|
||||
nana::any * _m_value(bool alloc_if_empty);
|
||||
const nana::any * _m_value() const;
|
||||
private:
|
||||
essence_t * ess_;
|
||||
category_t* cat_{nullptr};
|
||||
index_pair pos_;
|
||||
};
|
||||
|
||||
class cat_proxy
|
||||
: public std::iterator < std::input_iterator_tag, cat_proxy >
|
||||
{
|
||||
public:
|
||||
cat_proxy() = default;
|
||||
cat_proxy(essence_t*, size_type pos);
|
||||
cat_proxy(essence_t*, category_t*);
|
||||
|
||||
/// Append an item at end of the category, set_value determines whether assign T object to the value of item.
|
||||
template<typename T>
|
||||
item_proxy append(T&& t, bool set_value = false)
|
||||
{
|
||||
oresolver ores;
|
||||
if (set_value)
|
||||
ores << t; //copy it if it is rvalue and set_value is true.
|
||||
else
|
||||
ores << std::forward<T>(t);
|
||||
|
||||
_m_append(ores.move_cells());
|
||||
|
||||
item_proxy iter{ ess_, index_pair(pos_, size() - 1) };
|
||||
if (set_value)
|
||||
iter.value(std::forward<T>(t));
|
||||
return iter;
|
||||
}
|
||||
|
||||
void append(std::initializer_list<nana::string>);
|
||||
|
||||
size_type columns() const;
|
||||
|
||||
cat_proxy& text(nana::string);
|
||||
nana::string text() const;
|
||||
|
||||
/// Behavior of a container
|
||||
void push_back(nana::string);
|
||||
|
||||
item_proxy begin() const;
|
||||
item_proxy end() const;
|
||||
item_proxy cbegin() const;
|
||||
item_proxy cend() const;
|
||||
|
||||
item_proxy at(size_type pos) const;
|
||||
item_proxy back() const;
|
||||
|
||||
/// Returns the index of a item by its display pos, the index of the item isn't changed after sorting.
|
||||
size_type index_by_display_order(size_type disp_order) const;
|
||||
size_type display_order(size_type pos) const;
|
||||
size_type position() const;
|
||||
|
||||
/// Returns the number of items
|
||||
size_type size() const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
cat_proxy& operator=(const cat_proxy&);
|
||||
|
||||
/// Behavior of Iterator
|
||||
cat_proxy & operator++();
|
||||
|
||||
/// Behavior of Iterator
|
||||
cat_proxy operator++(int);
|
||||
|
||||
/// Behavior of Iterator
|
||||
cat_proxy& operator*();
|
||||
|
||||
/// Behavior of Iterator
|
||||
const cat_proxy& operator*() const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
cat_proxy* operator->();
|
||||
|
||||
/// Behavior of Iterator
|
||||
const cat_proxy* operator->() const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
bool operator==(const cat_proxy&) const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
bool operator!=(const cat_proxy&) const;
|
||||
private:
|
||||
void _m_append(std::vector<cell> && cells);
|
||||
void _m_cat_by_pos();
|
||||
private:
|
||||
essence_t* ess_{nullptr};
|
||||
category_t* cat_{nullptr};
|
||||
size_type pos_{0};
|
||||
};
|
||||
}
|
||||
}//end namespace drawerbase
|
||||
|
||||
struct arg_listbox
|
||||
{
|
||||
mutable drawerbase::listbox::item_proxy item;
|
||||
bool selected;
|
||||
};
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace listbox
|
||||
{
|
||||
struct listbox_events
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_listbox> checked;
|
||||
basic_event<arg_listbox> selected;
|
||||
};
|
||||
}
|
||||
}//end namespace drawerbase
|
||||
|
||||
/*! \brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain \a items.
|
||||
A category is a text with can be \a selected, \a checked and \a expanded to show the items.
|
||||
An item is formed by \a column-fields, each corresponding to one of the \a headers.
|
||||
An item can be \a selected and \a checked.
|
||||
The user can \a drag the header to \a reisize it or to \a reorganize it.
|
||||
By \a clicking on a header the list get \a reordered, first up, and then down alternatively,
|
||||
*/
|
||||
class listbox
|
||||
: public widget_object<category::widget_tag, drawerbase::listbox::trigger, drawerbase::listbox::listbox_events>,
|
||||
public concepts::any_objective<drawerbase::listbox::size_type, 2>
|
||||
{
|
||||
public:
|
||||
using size_type = drawerbase::listbox::size_type;
|
||||
using index_pair = drawerbase::listbox::index_pair;
|
||||
using cat_proxy = drawerbase::listbox::cat_proxy;
|
||||
using item_proxy = drawerbase::listbox::item_proxy;
|
||||
using selection = drawerbase::listbox::selection; ///<A container type for items.
|
||||
using iresolver = drawerbase::listbox::iresolver;
|
||||
using oresolver = drawerbase::listbox::oresolver;
|
||||
using cell = drawerbase::listbox::cell;
|
||||
public:
|
||||
listbox() = default;
|
||||
listbox(window, bool visible);
|
||||
listbox(window, const rectangle& = {}, bool visible = true);
|
||||
|
||||
void auto_draw(bool); ///<Set state: Redraw automatically after an operation?
|
||||
|
||||
void append_header(nana::string, unsigned width = 120);///<Appends a new column with a header text and the specified width at the end
|
||||
|
||||
cat_proxy append(nana::string); ///<Appends a new category at the end
|
||||
void append(std::initializer_list<nana::string>); ///<Appends categories at the end
|
||||
cat_proxy insert(cat_proxy, nana::string);
|
||||
cat_proxy at(size_type pos) const;
|
||||
listbox& ordered_categories(bool);
|
||||
|
||||
template<typename Key>
|
||||
cat_proxy operator[](const Key & ck)
|
||||
{
|
||||
typedef typename nana::detail::type_escape<Key>::type key_t;
|
||||
std::shared_ptr<nana::detail::key_interface> p(new nana::key<key_t, std::less<key_t>>(ck), [](nana::detail::key_interface* p)
|
||||
{
|
||||
delete p;
|
||||
});
|
||||
|
||||
return cat_proxy(&_m_ess(), _m_at_key(p));
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
cat_proxy operator[](Key && ck)
|
||||
{
|
||||
typedef typename nana::detail::type_escape<Key>::type key_t;
|
||||
std::shared_ptr<nana::detail::key_interface> p(new nana::key<key_t, std::less<key_t>>(std::move(ck)), [](nana::detail::key_interface* p)
|
||||
{
|
||||
delete p;
|
||||
});
|
||||
|
||||
return cat_proxy(&_m_ess(), _m_at_key(p));
|
||||
}
|
||||
|
||||
item_proxy at(const index_pair&) const;
|
||||
|
||||
void insert(const index_pair&, nana::string); ///<Insert a new item with a text in the first column.
|
||||
|
||||
void checkable(bool);
|
||||
selection checked() const; ///<Returns the items which are checked.
|
||||
|
||||
void clear(size_type cat); ///<Removes all the items from the specified category
|
||||
void clear(); ///<Removes all the items from all categories
|
||||
void erase(size_type cat); ///<Erases a category
|
||||
void erase(); ///<Erases all categories.
|
||||
item_proxy erase(item_proxy);
|
||||
|
||||
template<typename Key>
|
||||
void erase_key(const Key& kv)
|
||||
{
|
||||
typedef typename nana::detail::type_escape<Key>::type key_t;
|
||||
nana::key<key_t, std::less<key_t> > key(kv);
|
||||
_m_ease_key(&key);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
void erase_key(Key&& kv)
|
||||
{
|
||||
typedef typename nana::detail::type_escape<Key>::type key_t;
|
||||
nana::key<key_t, std::less<key_t> > key(std::move(kv));
|
||||
_m_ease_key(&key);
|
||||
}
|
||||
|
||||
///Sets a strick weak ordering comparer for a column
|
||||
void set_sort_compare(size_type col, std::function<bool(const nana::string&, nana::any*,
|
||||
const nana::string&, nana::any*, bool reverse)> strick_ordering);
|
||||
|
||||
void sort_col(size_type col, bool reverse = false);
|
||||
size_type sort_col() const;
|
||||
void unsort();
|
||||
bool freeze_sort(bool freeze);
|
||||
|
||||
selection selected() const; ///<Get the indexs of all the selected items
|
||||
|
||||
void show_header(bool);
|
||||
bool visible_header() const;
|
||||
void move_select(bool upwards); ///<Selects an item besides the current selected item.
|
||||
|
||||
size_type size_categ() const; ///<Get the number of categories
|
||||
size_type size_item() const; ///<The number of items in the default category
|
||||
size_type size_item(size_type cat) const; ///<The number of items in category "cat"
|
||||
private:
|
||||
drawerbase::listbox::essence_t & _m_ess() const;
|
||||
nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const;
|
||||
size_type _m_headers() const;
|
||||
drawerbase::listbox::category_t* _m_at_key(std::shared_ptr<nana::detail::key_interface>);
|
||||
void _m_ease_key(nana::detail::key_interface*);
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
200
include/nana/gui/widgets/menu.hpp
Normal file
200
include/nana/gui/widgets/menu.hpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* A Menu implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2009-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/gui/widgets/menu.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_MENU_HPP
|
||||
#define NANA_GUI_WIDGETS_MENU_HPP
|
||||
#include "widget.hpp"
|
||||
#include <vector>
|
||||
#include <nana/gui/timer.hpp>
|
||||
#include <nana/pat/cloneable.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace menu
|
||||
{
|
||||
struct menu_type; //declaration
|
||||
|
||||
enum class checks
|
||||
{
|
||||
none,
|
||||
option,
|
||||
highlight
|
||||
};
|
||||
|
||||
struct menu_item_type
|
||||
{
|
||||
/// This class is used as parameter of menu event function.
|
||||
class item_proxy
|
||||
{
|
||||
public:
|
||||
item_proxy(std::size_t n, menu_item_type &);
|
||||
item_proxy& enabled(bool);
|
||||
bool enabled() const;
|
||||
|
||||
item_proxy& check_style(checks);
|
||||
item_proxy& checked(bool);
|
||||
bool checked() const;
|
||||
|
||||
std::size_t index() const;
|
||||
private:
|
||||
std::size_t index_;
|
||||
menu_item_type &item_;
|
||||
};
|
||||
/// A callback functor type.
|
||||
typedef std::function<void(item_proxy&)> event_fn_t;
|
||||
|
||||
//Default constructor initializes the item as a splitter
|
||||
menu_item_type();
|
||||
menu_item_type(nana::string, const event_fn_t&);
|
||||
|
||||
struct
|
||||
{
|
||||
bool enabled:1;
|
||||
bool splitter:1;
|
||||
bool checked:1;
|
||||
}flags;
|
||||
|
||||
menu_type *sub_menu{nullptr};
|
||||
nana::string text;
|
||||
event_fn_t functor;
|
||||
checks style{checks::none};
|
||||
paint::image image;
|
||||
mutable nana::char_t hotkey{0};
|
||||
};
|
||||
|
||||
struct menu_type
|
||||
{
|
||||
typedef std::vector<menu_item_type> item_container;
|
||||
typedef item_container::iterator iterator;
|
||||
typedef item_container::const_iterator const_iterator;
|
||||
|
||||
std::vector<menu_type*> owner;
|
||||
std::vector<menu_item_type> items;
|
||||
unsigned max_pixels;
|
||||
unsigned item_pixels;
|
||||
nana::point gaps;
|
||||
};
|
||||
|
||||
class renderer_interface
|
||||
{
|
||||
public:
|
||||
typedef nana::paint::graphics & graph_reference;
|
||||
|
||||
enum class state
|
||||
{
|
||||
normal, active
|
||||
};
|
||||
|
||||
struct attr
|
||||
{
|
||||
state item_state;
|
||||
bool enabled;
|
||||
bool checked;
|
||||
checks check_style;
|
||||
};
|
||||
|
||||
virtual ~renderer_interface() = 0;
|
||||
|
||||
virtual void background(graph_reference, window) = 0;
|
||||
virtual void item(graph_reference, const nana::rectangle&, const attr&) = 0;
|
||||
virtual void item_image(graph_reference, const nana::point&, const paint::image&) = 0;
|
||||
virtual void item_text(graph_reference, const nana::point&, const nana::string&, unsigned text_pixels, const attr&) = 0;
|
||||
virtual void sub_arrow(graph_reference, const nana::point&, unsigned item_pixels, const attr&) = 0;
|
||||
};
|
||||
}//end namespace menu
|
||||
}//end namespace drawerbase
|
||||
|
||||
class menu
|
||||
: private noncopyable
|
||||
{
|
||||
struct implement;
|
||||
|
||||
//let menubar access the private _m_popup() method.
|
||||
friend class menu_accessor;
|
||||
public:
|
||||
typedef drawerbase::menu::checks checks;
|
||||
|
||||
typedef drawerbase::menu::renderer_interface renderer_interface;
|
||||
typedef drawerbase::menu::menu_item_type item_type;
|
||||
typedef item_type::item_proxy item_proxy;
|
||||
typedef item_type::event_fn_t event_fn_t; ///< A callback functor type. Prototype: `void(item_proxy&)`
|
||||
|
||||
menu(); ///< The default constructor. NO OTHER CONSTRUCTOR.
|
||||
~menu();
|
||||
|
||||
/// Appends an item to the menu.
|
||||
item_proxy append(const nana::string& text, const event_fn_t& callback= event_fn_t());
|
||||
void append_splitter();
|
||||
void clear(); ///< Erases all of the items.
|
||||
/// Closes the menu. It does not destroy the menu; just close the window for the menu.
|
||||
void close();
|
||||
void image(std::size_t index, const paint::image& icon);
|
||||
void check_style(std::size_t index, checks);
|
||||
void checked(std::size_t index, bool);
|
||||
bool checked(std::size_t index) const;
|
||||
void enabled(std::size_t index, bool);///< Enables or disables the mouse or keyboard input for the item.
|
||||
bool enabled(std::size_t index) const;
|
||||
void erase(std::size_t index); ///< Removes the item
|
||||
bool link(std::size_t index, menu& menu_obj);///< Link a menu to the item as a sub menu.
|
||||
menu * link(std::size_t index); ///< Retrieves a linked sub menu of the item.
|
||||
menu *create_sub_menu(std::size_t index);
|
||||
void popup(window owner, int x, int y); ///< Popup the menu at the owner window.
|
||||
void popup_await(window owner, int x, int y);
|
||||
void answerer(std::size_t index, const event_fn_t&); ///< Modify answerer of the specified item.
|
||||
void destroy_answer(const std::function<void()>&); ///< Sets an answerer for the callback while the menu window is closing.
|
||||
void gaps(const nana::point&); ///< Sets the gap between a menu and its sub menus.(\See Note4)
|
||||
void goto_next(bool forward); ///< Moves the focus to the next or previous item.
|
||||
bool goto_submen();///< Popup the submenu of the current item if it has a sub menu. Returns true if succeeds.
|
||||
bool exit_submenu(); ///< Closes the current window of the sub menu.
|
||||
std::size_t size() const; ///< Return the number of items.
|
||||
int send_shortkey(nana::char_t key);
|
||||
void pick();
|
||||
|
||||
menu& max_pixels(unsigned); ///< Sets the max width in pixels of the item.
|
||||
unsigned max_pixels() const;
|
||||
|
||||
menu& item_pixels(unsigned); ///< Sets the height in pixel for the items.
|
||||
unsigned item_pixels() const;
|
||||
|
||||
void renderer(const pat::cloneable<renderer_interface>&); ///< Sets a user-defined renderer.
|
||||
const pat::cloneable<renderer_interface>& renderer() const;
|
||||
|
||||
private:
|
||||
void _m_destroy_menu_window();
|
||||
void _m_popup(window, int x, int y, bool called_by_menubar);
|
||||
private:
|
||||
implement * impl_;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class popuper
|
||||
{
|
||||
public:
|
||||
popuper(menu&, mouse);
|
||||
popuper(menu&, window owner, const point&, mouse);
|
||||
void operator()(const arg_mouse&);
|
||||
private:
|
||||
menu & mobj_;
|
||||
window owner_;
|
||||
bool take_mouse_pos_;
|
||||
nana::point pos_;
|
||||
mouse mouse_;
|
||||
};
|
||||
}
|
||||
|
||||
detail::popuper menu_popuper(menu&, mouse = mouse::right_button);
|
||||
detail::popuper menu_popuper(menu&, window owner, const point&, mouse = mouse::right_button);
|
||||
}//end namespace nana
|
||||
#endif
|
||||
113
include/nana/gui/widgets/menubar.hpp
Normal file
113
include/nana/gui/widgets/menubar.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* A Menubar implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2009-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/gui/widgets/menubar.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_MENUBAR_HPP
|
||||
#define NANA_GUI_WIDGETS_MENUBAR_HPP
|
||||
#include "widget.hpp"
|
||||
#include "menu.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace menubar
|
||||
{
|
||||
class item_renderer
|
||||
{
|
||||
public:
|
||||
enum state_t{state_normal, state_highlight, state_selected};
|
||||
typedef nana::paint::graphics& graph_reference;
|
||||
|
||||
item_renderer(window, graph_reference);
|
||||
virtual void background(const nana::point& pos, const nana::size& size, state_t);
|
||||
virtual void caption(int x, int y, const nana::string& text);
|
||||
private:
|
||||
window handle_;
|
||||
graph_reference graph_;
|
||||
};
|
||||
|
||||
class trigger
|
||||
: public drawer_trigger
|
||||
{
|
||||
class itembase;
|
||||
public:
|
||||
trigger();
|
||||
~trigger();
|
||||
nana::menu* push_back(const nana::string&);
|
||||
nana::menu* at(size_t) const;
|
||||
std::size_t size() const;
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void refresh(graph_reference) override;
|
||||
void mouse_move(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_up(graph_reference, const arg_mouse&) override;
|
||||
void focus(graph_reference, const arg_focus&) override;
|
||||
void key_press(graph_reference, const arg_keyboard&) override;
|
||||
void key_release(graph_reference, const arg_keyboard&) override;
|
||||
void shortkey(graph_reference, const arg_keyboard&) override;
|
||||
private:
|
||||
void _m_move(bool to_left);
|
||||
bool _m_popup_menu();
|
||||
void _m_total_close();
|
||||
bool _m_close_menu();
|
||||
void _m_unload_menu_window();
|
||||
std::size_t _m_item_by_pos(const ::nana::point&);
|
||||
bool _m_track_mouse(const ::nana::point&);
|
||||
void _m_draw();
|
||||
private:
|
||||
widget *widget_;
|
||||
nana::paint::graphics *graph_;
|
||||
|
||||
itembase* items_;
|
||||
|
||||
struct state_type
|
||||
{
|
||||
enum behavior_t
|
||||
{
|
||||
behavior_none, behavior_focus, behavior_menu,
|
||||
};
|
||||
|
||||
state_type();
|
||||
|
||||
std::size_t active;
|
||||
behavior_t behavior;
|
||||
|
||||
bool menu_active;
|
||||
bool passive_close;
|
||||
|
||||
bool nullify_mouse;
|
||||
|
||||
nana::menu *menu;
|
||||
nana::point mouse_pos;
|
||||
}state_;
|
||||
};
|
||||
}//end namespace menubar
|
||||
}//end namespace drawerbase
|
||||
|
||||
/// \brief A toolbar at the top of window for popuping menus.
|
||||
///
|
||||
/// The widget sets as shortkey the character behind the first of & in the text, for the item. e.g. "File(&F)" or "&File".
|
||||
class menubar
|
||||
: public widget_object<category::widget_tag, drawerbase::menubar::trigger>
|
||||
{
|
||||
public:
|
||||
menubar(); ///< The default constructor delay creation.
|
||||
menubar(window); ///< Create a menubar at the top of the specified window.
|
||||
void create(window); ///< Create a menubar at the top of the specified window.
|
||||
menu& push_back(const nana::string&); ///< Appends a new (empty) menu.
|
||||
menu& at(size_t index) const; ///< Gets the menu specified by index.
|
||||
std::size_t length() const; ///< Number of menus.
|
||||
};//end class menubar
|
||||
}//end namespace nana
|
||||
#endif
|
||||
71
include/nana/gui/widgets/panel.hpp
Normal file
71
include/nana/gui/widgets/panel.hpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* A Panel Implementation
|
||||
* Nana C++ Library(http://www.nanaro.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/gui/widgets/panel.hpp
|
||||
*
|
||||
* @brief: panel is a widget used for placing some widgets.
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_PANEL_HPP
|
||||
#define NANA_GUI_WIDGETS_PANEL_HPP
|
||||
#include "widget.hpp"
|
||||
#include <type_traits>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace panel
|
||||
{
|
||||
class drawer: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
drawer();
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void refresh(graph_reference) override;
|
||||
private:
|
||||
window window_;
|
||||
};
|
||||
}// end namespace panel
|
||||
}//end namespace drawerbase
|
||||
/// For placing other widgets, where the bool template parameter determinte if it is widget or lite_widget, wich in actual use make no difference.
|
||||
template<bool HasBackground>
|
||||
class panel
|
||||
: public widget_object<typename std::conditional<HasBackground, category::widget_tag, category::lite_widget_tag>::type,
|
||||
drawerbase::panel::drawer>
|
||||
{
|
||||
public:
|
||||
panel(){}
|
||||
|
||||
panel(window wd, bool visible)
|
||||
{
|
||||
this->create(wd, rectangle(), visible);
|
||||
}
|
||||
|
||||
panel(window wd, const nana::rectangle& r = rectangle(), bool visible = true)
|
||||
{
|
||||
this->create(wd, r, visible);
|
||||
}
|
||||
|
||||
bool transparent() const
|
||||
{
|
||||
return (bground_mode::basic == API::effects_bground_mode(*this));
|
||||
}
|
||||
|
||||
void transparent(bool tr)
|
||||
{
|
||||
if(tr)
|
||||
API::effects_bground(*this, effects::bground_transparent(0), 0);
|
||||
else
|
||||
API::effects_bground_remove(*this);
|
||||
}
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
81
include/nana/gui/widgets/picture.hpp
Normal file
81
include/nana/gui/widgets/picture.hpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* A Picture 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/gui/widgets/picture.hpp
|
||||
*
|
||||
* Used for showing a picture
|
||||
*/
|
||||
#ifndef NANA_GUI_WIDGET_PICTURE_HPP
|
||||
#define NANA_GUI_WIDGET_PICTURE_HPP
|
||||
#include "widget.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace xpicture
|
||||
{
|
||||
class picture_drawer: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
picture_drawer();
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void load(const nana::char_t* file);
|
||||
void load(const nana::paint::image&);
|
||||
void set_shadow_background(unsigned begin_color, unsigned end_color, bool horizontal);
|
||||
bool bgstyle(bool is_stretch, nana::arrange, int beg, int end);
|
||||
private:
|
||||
void refresh(graph_reference) override;
|
||||
void _m_draw_background();
|
||||
private:
|
||||
widget* widget_;
|
||||
nana::paint::graphics* graph_;
|
||||
|
||||
struct runtime_type
|
||||
{
|
||||
runtime_type();
|
||||
unsigned background_shadow_start;
|
||||
unsigned background_shadow_end;
|
||||
bool horizontal;
|
||||
}runtime_;
|
||||
|
||||
struct back_image_tag
|
||||
{
|
||||
nana::paint::image image;
|
||||
bool is_stretch;
|
||||
nana::arrange arg;
|
||||
int beg, end;
|
||||
}backimg_;
|
||||
|
||||
};
|
||||
|
||||
}//end namespace xpicture
|
||||
/// Rectangle area for displaying a bitmap file
|
||||
class picture
|
||||
: public widget_object<category::widget_tag, xpicture::picture_drawer>
|
||||
{
|
||||
public:
|
||||
picture();
|
||||
picture(window, bool visible);
|
||||
picture(window, const rectangle& = rectangle(), bool visible = true);
|
||||
|
||||
void load(const nana::paint::image&);
|
||||
|
||||
/// Sets the background image style.
|
||||
void bgstyle(bool stretchable, ///< if false the other arguments will be ignored
|
||||
nana::arrange arg, ///< stretching the image horizontally or vertically
|
||||
int beg, ///< specify the stretchy area of image.
|
||||
int end ///< specify the stretchy area of image.
|
||||
);
|
||||
|
||||
/// Fills a gradual change color in background.
|
||||
void set_shadow_background(unsigned begin_color, unsigned end_color, bool horizontal);
|
||||
void transparent(bool);
|
||||
bool transparent() const;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
73
include/nana/gui/widgets/progress.hpp
Normal file
73
include/nana/gui/widgets/progress.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* A Progress Indicator 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/gui/widgets/progress.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_PROGRESS_HPP
|
||||
#define NANA_GUI_WIDGET_PROGRESS_HPP
|
||||
#include "widget.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace progress
|
||||
{
|
||||
class trigger: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
trigger();
|
||||
unsigned value() const;
|
||||
unsigned value(unsigned);
|
||||
unsigned inc();
|
||||
unsigned Max() const;
|
||||
unsigned Max(unsigned);
|
||||
void unknown(bool);
|
||||
bool unknown() const;
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void refresh(graph_reference) override;
|
||||
private:
|
||||
void _m_draw();
|
||||
void _m_draw_box(graph_reference);
|
||||
void _m_draw_progress(graph_reference);
|
||||
bool _m_check_changing(unsigned) const;
|
||||
private:
|
||||
static const unsigned border = 2;
|
||||
widget * widget_;
|
||||
nana::paint::graphics* graph_;
|
||||
unsigned draw_width_;
|
||||
bool has_value_;
|
||||
bool unknown_;
|
||||
unsigned max_;
|
||||
unsigned value_;
|
||||
}; //end class drawer
|
||||
}
|
||||
}//end namespace drawerbase
|
||||
/// \brief A progressbar widget with two styles: know, and unknow amount value (goal).
|
||||
/// In unknow style the amount is ignored and the bar is scrolled when value change.
|
||||
class progress
|
||||
: public widget_object<category::widget_tag, drawerbase::progress::trigger>
|
||||
{
|
||||
public:
|
||||
progress();
|
||||
progress(window, bool visible);
|
||||
progress(window, const rectangle & = rectangle(), bool visible = true);
|
||||
|
||||
unsigned value() const;
|
||||
unsigned value(unsigned val);
|
||||
unsigned inc();
|
||||
unsigned amount() const;
|
||||
unsigned amount(unsigned value);
|
||||
void unknown(bool);
|
||||
bool unknown() const;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
444
include/nana/gui/widgets/scroll.hpp
Normal file
444
include/nana/gui/widgets/scroll.hpp
Normal file
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
* A Scroll 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/gui/widgets/scroll.hpp
|
||||
*/
|
||||
#ifndef NANA_GUI_WIDGET_SCROLL_HPP
|
||||
#define NANA_GUI_WIDGET_SCROLL_HPP
|
||||
|
||||
#include "widget.hpp"
|
||||
#include <nana/paint/gadget.hpp>
|
||||
#include <nana/gui/timer.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
template<bool Vert> class scroll;
|
||||
|
||||
template<bool Vert>
|
||||
struct arg_scroll
|
||||
{
|
||||
scroll<Vert> & widget;
|
||||
};
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace scroll
|
||||
{
|
||||
template<bool Vert>
|
||||
struct scroll_events
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_scroll<Vert>> value_changed;
|
||||
};
|
||||
|
||||
enum class buttons
|
||||
{
|
||||
none, forward, backward, scroll, first, second
|
||||
};
|
||||
|
||||
struct metrics_type
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
|
||||
size_type peak;
|
||||
size_type range;
|
||||
size_type step;
|
||||
size_type value;
|
||||
|
||||
buttons what;
|
||||
bool pressed;
|
||||
size_type scroll_length;
|
||||
int scroll_pos;
|
||||
int scroll_mouse_offset;
|
||||
|
||||
metrics_type();
|
||||
};
|
||||
|
||||
class drawer
|
||||
{
|
||||
public:
|
||||
struct states
|
||||
{
|
||||
enum{none, highlight, actived, selected};
|
||||
};
|
||||
|
||||
typedef nana::paint::graphics& graph_reference;
|
||||
const static unsigned fixedsize = 16;
|
||||
|
||||
drawer(metrics_type& m);
|
||||
void set_vertical(bool);
|
||||
buttons what(graph_reference, const point&);
|
||||
void scroll_delta_pos(graph_reference, int);
|
||||
void auto_scroll();
|
||||
void draw(graph_reference, buttons);
|
||||
private:
|
||||
bool _m_check() const;
|
||||
void _m_adjust_scroll(graph_reference);
|
||||
void _m_background(graph_reference);
|
||||
void _m_button_frame(graph_reference, int x, int y, unsigned width, unsigned height, int state);
|
||||
void _m_draw_scroll(graph_reference, int state);
|
||||
void _m_draw_button(graph_reference, int x, int y, unsigned width, unsigned height, buttons what, int state);
|
||||
private:
|
||||
metrics_type &metrics_;
|
||||
bool vertical_;
|
||||
};
|
||||
|
||||
template<bool Vertical>
|
||||
class trigger
|
||||
: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
typedef metrics_type::size_type size_type;
|
||||
|
||||
trigger()
|
||||
: graph_(nullptr), drawer_(metrics_)
|
||||
{
|
||||
drawer_.set_vertical(Vertical);
|
||||
}
|
||||
|
||||
const metrics_type& metrics() const
|
||||
{
|
||||
return metrics_;
|
||||
}
|
||||
|
||||
void peak(size_type s)
|
||||
{
|
||||
if(graph_ && (metrics_.peak != s))
|
||||
{
|
||||
metrics_.peak = s;
|
||||
API::refresh_window(widget_->handle());
|
||||
}
|
||||
}
|
||||
|
||||
void value(size_type s)
|
||||
{
|
||||
if(s + metrics_.range > metrics_.peak)
|
||||
s = metrics_.peak - metrics_.range;
|
||||
|
||||
if(graph_ && (metrics_.value != s))
|
||||
{
|
||||
metrics_.value = s;
|
||||
_m_emit_value_changed();
|
||||
|
||||
API::refresh_window(*widget_);
|
||||
}
|
||||
}
|
||||
|
||||
void range(size_type s)
|
||||
{
|
||||
if(graph_ && (metrics_.range != s))
|
||||
{
|
||||
metrics_.range = s;
|
||||
API::refresh_window(widget_->handle());
|
||||
}
|
||||
}
|
||||
|
||||
void step(size_type s)
|
||||
{
|
||||
metrics_.step = s;
|
||||
}
|
||||
|
||||
bool make_step(bool forward, unsigned multiple)
|
||||
{
|
||||
if(graph_)
|
||||
{
|
||||
size_type step = (multiple > 1 ? metrics_.step * multiple : metrics_.step);
|
||||
size_type value = metrics_.value;
|
||||
if(forward)
|
||||
{
|
||||
size_type maxv = metrics_.peak - metrics_.range;
|
||||
if(metrics_.peak > metrics_.range && value < maxv)
|
||||
{
|
||||
if(maxv - value >= step)
|
||||
value += step;
|
||||
else
|
||||
value = maxv;
|
||||
}
|
||||
}
|
||||
else if(value)
|
||||
{
|
||||
if(value > step)
|
||||
value -= step;
|
||||
else
|
||||
value = 0;
|
||||
}
|
||||
size_type cmpvalue = metrics_.value;
|
||||
metrics_.value = value;
|
||||
if(value != cmpvalue)
|
||||
{
|
||||
_m_emit_value_changed();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
void attached(widget_reference widget, graph_reference graph)
|
||||
{
|
||||
graph_ = &graph;
|
||||
widget_ = static_cast< ::nana::scroll<Vertical>*>(&widget);
|
||||
widget.caption(STR("Nana Scroll"));
|
||||
|
||||
timer_.stop();
|
||||
timer_.elapse(std::bind(&trigger::_m_tick, this));
|
||||
}
|
||||
|
||||
void detached()
|
||||
{
|
||||
graph_ = nullptr;
|
||||
}
|
||||
|
||||
void refresh(graph_reference graph)
|
||||
{
|
||||
drawer_.draw(graph, metrics_.what);
|
||||
}
|
||||
|
||||
void resized(graph_reference graph, const ::nana::arg_resized&) override
|
||||
{
|
||||
drawer_.draw(graph, metrics_.what);
|
||||
API::lazy_refresh();
|
||||
}
|
||||
|
||||
void mouse_enter(graph_reference graph, const ::nana::arg_mouse& arg) override
|
||||
{
|
||||
metrics_.what = drawer_.what(graph, arg.pos);
|
||||
drawer_.draw(graph, metrics_.what);
|
||||
API::lazy_refresh();
|
||||
}
|
||||
|
||||
void mouse_move(graph_reference graph, const ::nana::arg_mouse& arg)
|
||||
{
|
||||
bool redraw = false;
|
||||
if(metrics_.pressed && (metrics_.what == buttons::scroll))
|
||||
{
|
||||
size_type cmpvalue = metrics_.value;
|
||||
drawer_.scroll_delta_pos(graph, (Vertical ? arg.pos.y : arg.pos.x));
|
||||
if(cmpvalue != metrics_.value)
|
||||
_m_emit_value_changed();
|
||||
redraw = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
buttons what = drawer_.what(graph, arg.pos);
|
||||
if(metrics_.what != what)
|
||||
{
|
||||
redraw = true;
|
||||
metrics_.what = what;
|
||||
}
|
||||
}
|
||||
if(redraw)
|
||||
{
|
||||
drawer_.draw(graph, metrics_.what);
|
||||
API::lazy_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void mouse_down(graph_reference graph, const arg_mouse& arg)
|
||||
{
|
||||
if(arg.left_button)
|
||||
{
|
||||
metrics_.pressed = true;
|
||||
metrics_.what = drawer_.what(graph, arg.pos);
|
||||
switch(metrics_.what)
|
||||
{
|
||||
case buttons::first:
|
||||
case buttons::second:
|
||||
make_step(metrics_.what == buttons::second, 1);
|
||||
timer_.interval(1000);
|
||||
timer_.start();
|
||||
break;
|
||||
case buttons::scroll:
|
||||
API::capture_window(widget_->handle(), true);
|
||||
metrics_.scroll_mouse_offset = (Vertical ? arg.pos.y : arg.pos.x) - metrics_.scroll_pos;
|
||||
break;
|
||||
case buttons::forward:
|
||||
case buttons::backward:
|
||||
{
|
||||
size_type cmpvalue = metrics_.value;
|
||||
drawer_.auto_scroll();
|
||||
if(cmpvalue != metrics_.value)
|
||||
_m_emit_value_changed();
|
||||
}
|
||||
break;
|
||||
default: //Ignore buttons::none
|
||||
break;
|
||||
}
|
||||
drawer_.draw(graph, metrics_.what);
|
||||
API::lazy_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void mouse_up(graph_reference graph, const arg_mouse& arg)
|
||||
{
|
||||
timer_.stop();
|
||||
|
||||
API::capture_window(widget_->handle(), false);
|
||||
|
||||
metrics_.pressed = false;
|
||||
metrics_.what = drawer_.what(graph, arg.pos);
|
||||
drawer_.draw(graph, metrics_.what);
|
||||
API::lazy_refresh();
|
||||
}
|
||||
|
||||
void mouse_leave(graph_reference graph, const arg_mouse&)
|
||||
{
|
||||
if(metrics_.pressed) return;
|
||||
|
||||
metrics_.what = buttons::none;
|
||||
drawer_.draw(graph, buttons::none);
|
||||
API::lazy_refresh();
|
||||
}
|
||||
|
||||
void mouse_wheel(graph_reference graph, const arg_wheel& arg)
|
||||
{
|
||||
if(make_step(arg.upwards == false, 3))
|
||||
{
|
||||
drawer_.draw(graph, metrics_.what);
|
||||
API::lazy_refresh();
|
||||
}
|
||||
}
|
||||
private:
|
||||
void _m_emit_value_changed()
|
||||
{
|
||||
widget_->events().value_changed.emit(::nana::arg_scroll<Vertical>({*widget_}));
|
||||
}
|
||||
|
||||
void _m_tick()
|
||||
{
|
||||
make_step(metrics_.what == buttons::second, 1);
|
||||
API::refresh_window(widget_->handle());
|
||||
timer_.interval(100);
|
||||
}
|
||||
private:
|
||||
::nana::scroll<Vertical> * widget_;
|
||||
nana::paint::graphics * graph_;
|
||||
metrics_type metrics_;
|
||||
drawer drawer_;
|
||||
timer timer_;
|
||||
};
|
||||
}//end namespace scroll
|
||||
}//end namespace drawerbase
|
||||
|
||||
/// Provides a way to display an object which is larger than the window's client area.
|
||||
template<bool Vertical>
|
||||
class scroll
|
||||
: public widget_object<category::widget_tag, drawerbase::scroll::trigger<Vertical>, drawerbase::scroll::scroll_events<Vertical>>
|
||||
{
|
||||
typedef widget_object<category::widget_tag, drawerbase::scroll::trigger<Vertical> > base_type;
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
|
||||
/// \brief The default constructor without creating the widget.
|
||||
scroll(){}
|
||||
|
||||
/// \brief The construct that creates a widget.
|
||||
/// @param wd A handle to the parent window of the widget being created.
|
||||
/// @param visible specifying the visible after creating.
|
||||
scroll(window wd, bool visible)
|
||||
{
|
||||
this->create(wd, rectangle(), visible);
|
||||
}
|
||||
|
||||
/// \brief The construct that creates a widget.
|
||||
/// @param wd A handle to the parent window of the widget being created.
|
||||
/// @param r the size and position of the widget in its parent window coordinate.
|
||||
/// @param visible specifying the visible after creating.
|
||||
scroll(window wd, const rectangle& r, bool visible = true)
|
||||
{
|
||||
this->create(wd, r, visible);
|
||||
}
|
||||
|
||||
/// \brief Determines whether it is scrollable.
|
||||
/// @param for_less whether it can be scrolled for a less value.
|
||||
bool scrollable(bool for_less) const
|
||||
{
|
||||
auto & m = this->get_drawer_trigger().metrics();
|
||||
return (for_less ? (0 != m.value) : (m.value < m.peak - m.range));
|
||||
}
|
||||
|
||||
size_type amount() const
|
||||
{
|
||||
return this->get_drawer_trigger().metrics().peak;
|
||||
}
|
||||
|
||||
void amount(size_type Max)
|
||||
{
|
||||
return this->get_drawer_trigger().peak(Max);
|
||||
}
|
||||
|
||||
/// Get the range of the widget.
|
||||
size_type range() const
|
||||
{
|
||||
return this->get_drawer_trigger().metrics().range;
|
||||
}
|
||||
|
||||
/// Set the range of the widget.
|
||||
void range(size_type r)
|
||||
{
|
||||
return this->get_drawer_trigger().range(r);
|
||||
}
|
||||
|
||||
/// \brief Get the value.
|
||||
/// @return the value.
|
||||
size_type value() const
|
||||
{
|
||||
return this->get_drawer_trigger().metrics().value;
|
||||
}
|
||||
|
||||
/// \brief Set the value.
|
||||
/// @param s a new value.
|
||||
void value(size_type s)
|
||||
{
|
||||
return this->get_drawer_trigger().value(s);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Get the step of the sroll widget. The step indicates a variation of the value.
|
||||
/// @return the step.
|
||||
size_type step() const
|
||||
{
|
||||
return this->get_drawer_trigger().metrics().step;
|
||||
}
|
||||
|
||||
/// \brief Set the step.
|
||||
/// @param s a value for step.
|
||||
void step(size_type s)
|
||||
{
|
||||
return this->get_drawer_trigger().step(s);
|
||||
}
|
||||
|
||||
/// \brief Increase/decrease values by a step.
|
||||
/// @param forward it determines whether increase or decrease.
|
||||
/// @return true if the value is changed.
|
||||
bool make_step(bool forward)
|
||||
{
|
||||
if(this->get_drawer_trigger().make_step(forward, 1))
|
||||
{
|
||||
API::refresh_window(this->handle());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Increase/decrease values by steps as if it is scrolled through mouse wheel.
|
||||
/// @param forward it determines whether increase or decrease.
|
||||
/// @return true if the vlaue is changed.
|
||||
bool make_scroll(bool forward)
|
||||
{
|
||||
if(this->get_drawer_trigger().make_step(forward, 3))
|
||||
{
|
||||
API::refresh_window(this->handle());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};//end class scroll
|
||||
}//end namespace nana
|
||||
#endif
|
||||
335
include/nana/gui/widgets/skeletons/text_editor.hpp
Normal file
335
include/nana/gui/widgets/skeletons/text_editor.hpp
Normal file
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* A text editor 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/gui/widgets/skeletons/text_editor.hpp
|
||||
* @description:
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_SKELETONS_TEXT_EDITOR_HPP
|
||||
#define NANA_GUI_SKELETONS_TEXT_EDITOR_HPP
|
||||
#include "textbase.hpp"
|
||||
#include <nana/gui/widgets/scroll.hpp>
|
||||
#include <nana/unicode_bidi.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace nana{ namespace widgets
|
||||
{
|
||||
namespace skeletons
|
||||
{
|
||||
template<typename EnumCommand>
|
||||
class undoable_command_interface
|
||||
{
|
||||
public:
|
||||
virtual ~undoable_command_interface() = default;
|
||||
|
||||
virtual EnumCommand get() const = 0;
|
||||
virtual bool merge(const undoable_command_interface&) = 0;
|
||||
virtual void execute(bool redo) = 0;
|
||||
};
|
||||
|
||||
template<typename EnumCommand>
|
||||
class undoable
|
||||
{
|
||||
public:
|
||||
using command = EnumCommand;
|
||||
using container = std::deque < std::unique_ptr<undoable_command_interface<command>> >;
|
||||
|
||||
void max_steps(std::size_t maxs)
|
||||
{
|
||||
max_steps_ = maxs;
|
||||
if (maxs && (commands_.size() >= maxs))
|
||||
commands_.erase(commands_.begin(), commands_.begin() + (commands_.size() - maxs + 1));
|
||||
}
|
||||
|
||||
std::size_t max_steps() const
|
||||
{
|
||||
return max_steps_;
|
||||
}
|
||||
|
||||
void enable(bool enb)
|
||||
{
|
||||
enabled_ = enb;
|
||||
if (!enb)
|
||||
commands_.clear();
|
||||
}
|
||||
|
||||
bool enabled() const
|
||||
{
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
void push(std::unique_ptr<undoable_command_interface<command>> && ptr)
|
||||
{
|
||||
if (!ptr || !enabled_)
|
||||
return;
|
||||
|
||||
if (pos_ < commands_.size())
|
||||
commands_.erase(commands_.begin() + pos_, commands_.end());
|
||||
else if (max_steps_ && (commands_.size() >= max_steps_))
|
||||
commands_.erase(commands_.begin(), commands_.begin() + (commands_.size() - max_steps_ + 1));
|
||||
|
||||
pos_ = commands_.size();
|
||||
if (!commands_.empty())
|
||||
{
|
||||
if (commands_.back().get()->merge(*ptr))
|
||||
return;
|
||||
}
|
||||
|
||||
commands_.emplace_back(std::move(ptr));
|
||||
++pos_;
|
||||
}
|
||||
|
||||
std::size_t count(bool is_undo) const
|
||||
{
|
||||
return (is_undo ? pos_ : commands_.size() - pos_);
|
||||
}
|
||||
|
||||
void undo()
|
||||
{
|
||||
if (pos_ > 0)
|
||||
{
|
||||
--pos_;
|
||||
commands_[pos_].get()->execute(false);
|
||||
}
|
||||
}
|
||||
|
||||
void redo()
|
||||
{
|
||||
if (pos_ != commands_.size())
|
||||
commands_[pos_++].get()->execute(true);
|
||||
}
|
||||
|
||||
private:
|
||||
container commands_;
|
||||
bool enabled_{ true };
|
||||
std::size_t max_steps_{ 30 };
|
||||
std::size_t pos_{ 0 };
|
||||
};
|
||||
|
||||
class text_editor
|
||||
{
|
||||
struct attributes;
|
||||
class editor_behavior_interface;
|
||||
class behavior_normal;
|
||||
class behavior_linewrapped;
|
||||
|
||||
enum class command{
|
||||
backspace, input_text, move_text,
|
||||
};
|
||||
//Commands for undoable
|
||||
template<typename EnumCommand> class basic_undoable;
|
||||
class undo_backspace;
|
||||
class undo_input_text;
|
||||
class undo_move_text;
|
||||
public:
|
||||
typedef nana::char_t char_type;
|
||||
typedef textbase<char_type>::size_type size_type;
|
||||
typedef textbase<char_type>::string_type string_type;
|
||||
|
||||
typedef nana::paint::graphics & graph_reference;
|
||||
|
||||
struct ext_renderer_tag
|
||||
{
|
||||
std::function<void(graph_reference, const nana::rectangle& text_area, nana::color_t)> background;
|
||||
};
|
||||
|
||||
text_editor(window, graph_reference);
|
||||
~text_editor();
|
||||
|
||||
bool respone_keyboard(nana::char_t, bool enterable);
|
||||
|
||||
void typeface_changed();
|
||||
|
||||
/// Determine whether the text_editor is line wrapped.
|
||||
bool line_wrapped() const;
|
||||
/// Set the text_editor whether it is line wrapped, it returns false if the state is not changed.
|
||||
bool line_wrapped(bool);
|
||||
|
||||
void border_renderer(std::function<void(graph_reference, nana::color_t bgcolor)>);
|
||||
|
||||
bool load(const nana::char_t*);
|
||||
|
||||
//text_area
|
||||
//@return: Returns true if the area of text is changed.
|
||||
bool text_area(const nana::rectangle&);
|
||||
bool tip_string(nana::string&&);
|
||||
|
||||
const attributes & attr() const;
|
||||
bool multi_lines(bool);
|
||||
void editable(bool);
|
||||
void enable_background(bool);
|
||||
void enable_background_counterpart(bool);
|
||||
|
||||
void undo_enabled(bool);
|
||||
bool undo_enabled() const;
|
||||
void undo_max_steps(std::size_t);
|
||||
std::size_t undo_max_steps() const;
|
||||
|
||||
ext_renderer_tag& ext_renderer() const;
|
||||
|
||||
unsigned line_height() const;
|
||||
unsigned screen_lines() const;
|
||||
|
||||
bool getline(std::size_t pos, nana::string&) const;
|
||||
void text(nana::string);
|
||||
nana::string text() const;
|
||||
|
||||
//move_caret
|
||||
//@brief: Set caret position through text coordinate
|
||||
void move_caret(const upoint&);
|
||||
void move_caret_end();
|
||||
void reset_caret_height() const;
|
||||
void reset_caret();
|
||||
void show_caret(bool isshow);
|
||||
|
||||
bool selected() const;
|
||||
bool select(bool);
|
||||
//Set the end position of a selected string
|
||||
void set_end_caret();
|
||||
bool hit_text_area(const point&) const;
|
||||
bool hit_select_area(nana::upoint pos) const;
|
||||
bool move_select();
|
||||
bool mask(char_t);
|
||||
|
||||
/// Returns width of text area excluding the vscroll size.
|
||||
unsigned width_pixels() const;
|
||||
public:
|
||||
void draw_scroll_rectangle();
|
||||
void render(bool focused);
|
||||
public:
|
||||
void put(nana::string);
|
||||
void put(nana::char_t);
|
||||
void copy() const;
|
||||
void cut();
|
||||
void paste();
|
||||
void enter(bool record_undo = true);
|
||||
void del();
|
||||
void backspace(bool record_undo = true);
|
||||
void undo(bool reverse);
|
||||
bool move(nana::char_t);
|
||||
void move_ns(bool to_north); //Moves up and down
|
||||
void move_left();
|
||||
void move_right();
|
||||
nana::upoint mouse_caret(const point& screen_pos);
|
||||
nana::upoint caret() const;
|
||||
bool scroll(bool upwards, bool vertical);
|
||||
bool mouse_enter(bool);
|
||||
bool mouse_down(bool left_button, const point& screen_pos);
|
||||
bool mouse_move(bool left_button, const point& screen_pos);
|
||||
bool mouse_up(bool left_button, const point& screen_pos);
|
||||
|
||||
skeletons::textbase<nana::char_t>& textbase();
|
||||
const skeletons::textbase<nana::char_t>& textbase() const;
|
||||
private:
|
||||
nana::color_t _m_bgcolor() const;
|
||||
bool _m_scroll_text(bool vertical);
|
||||
void _m_on_scroll(const arg_mouse&);
|
||||
void _m_scrollbar();
|
||||
nana::size _m_text_area() const;
|
||||
void _m_get_scrollbar_size();
|
||||
void _m_reset();
|
||||
nana::upoint _m_put(nana::string);
|
||||
nana::upoint _m_erase_select();
|
||||
|
||||
bool _m_make_select_string(nana::string&) const;
|
||||
static bool _m_resolve_text(const nana::string&, std::vector<std::pair<std::size_t, std::size_t>> & lines);
|
||||
|
||||
bool _m_cancel_select(int align);
|
||||
unsigned _m_tabs_pixels(size_type tabs) const;
|
||||
nana::size _m_text_extent_size(const char_type*) const;
|
||||
nana::size _m_text_extent_size(const char_type*, size_type n) const;
|
||||
|
||||
//_m_move_offset_x_while_over_border
|
||||
//@brief: Moves the view window
|
||||
bool _m_move_offset_x_while_over_border(int many);
|
||||
bool _m_move_select(bool record_undo);
|
||||
|
||||
int _m_text_top_base() const;
|
||||
//_m_endx
|
||||
//@brief: Gets the right point of text area
|
||||
int _m_endx() const;
|
||||
//_m_endy
|
||||
//@brief: Get the bottom point of text area
|
||||
int _m_endy() const;
|
||||
|
||||
void _m_draw_tip_string() const;
|
||||
|
||||
//_m_draw_string
|
||||
//@brief: Draw a line of string
|
||||
void _m_draw_string(int top, nana::color_t color, const nana::upoint& str_pos, const nana::string&, bool if_mask) const;
|
||||
//_m_draw
|
||||
//@brief: Draw a character at a position specified by caret pos.
|
||||
//@return: true if beyond the border
|
||||
bool _m_draw(nana::char_t, std::size_t secondary_before);
|
||||
bool _m_get_sort_select_points(nana::upoint&, nana::upoint&) const;
|
||||
|
||||
void _m_offset_y(int y);
|
||||
|
||||
unsigned _m_char_by_pixels(const nana::char_t*, std::size_t len, unsigned* pxbuf, int str_px, int pixels, bool is_rtl);
|
||||
unsigned _m_pixels_by_char(const nana::string&, std::size_t pos) const;
|
||||
static bool _m_is_right_text(const unicode_bidi::entity&);
|
||||
private:
|
||||
std::unique_ptr<editor_behavior_interface> behavior_;
|
||||
undoable<command> undo_;
|
||||
nana::window window_;
|
||||
graph_reference graph_;
|
||||
skeletons::textbase<nana::char_t> textbase_;
|
||||
nana::char_t mask_char_{0};
|
||||
|
||||
mutable ext_renderer_tag ext_renderer_;
|
||||
|
||||
struct attributes
|
||||
{
|
||||
nana::string tip_string;
|
||||
|
||||
bool line_wrapped{false};
|
||||
bool multi_lines{true};
|
||||
bool editable{true};
|
||||
bool enable_background{true};
|
||||
bool enable_counterpart{false};
|
||||
nana::paint::graphics counterpart; //this is used to keep the background that painted by external part.
|
||||
|
||||
std::unique_ptr<nana::scroll<true>> vscroll;
|
||||
std::unique_ptr<nana::scroll<false>> hscroll;
|
||||
}attributes_;
|
||||
|
||||
struct text_area_type
|
||||
{
|
||||
nana::rectangle area;
|
||||
|
||||
bool captured;
|
||||
unsigned tab_space;
|
||||
unsigned scroll_pixels;
|
||||
unsigned vscroll;
|
||||
unsigned hscroll;
|
||||
std::function<void(nana::paint::graphics&, nana::color_t)> border_renderer;
|
||||
}text_area_;
|
||||
|
||||
struct selection
|
||||
{
|
||||
enum mode_selection_t{mode_no_selected, mode_mouse_selected, mode_method_selected};
|
||||
|
||||
mode_selection_t mode_selection;
|
||||
bool dragged;
|
||||
nana::upoint a, b;
|
||||
}select_;
|
||||
|
||||
struct coordinate
|
||||
{
|
||||
nana::point offset; //x stands for pixels, y for lines
|
||||
nana::upoint caret; //position of caret by text, it specifies the position of a new character
|
||||
unsigned xpos{0}; //This data is used for move up/down
|
||||
}points_;
|
||||
};
|
||||
}//end namespace skeletons
|
||||
}//end namespace widgets
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
952
include/nana/gui/widgets/skeletons/text_token_stream.hpp
Normal file
952
include/nana/gui/widgets/skeletons/text_token_stream.hpp
Normal file
@@ -0,0 +1,952 @@
|
||||
/*
|
||||
* Text Token Stream
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2013 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/skeletons/text_token_stream.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_SKELETONS_TEXT_TOKEN_STREAM
|
||||
#define NANA_GUI_WIDGETS_SKELETONS_TEXT_TOKEN_STREAM
|
||||
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <stack>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace nana{ namespace widgets{ namespace skeletons
|
||||
{
|
||||
//The tokens are defined for representing a text, the tokens are divided
|
||||
//into two parts.
|
||||
//Formatted tokens: The tokens present in a format block, they form the format-syntax.
|
||||
//Data tokens: The tokens present a text displaying on the screen.
|
||||
enum class token
|
||||
{
|
||||
tag_begin, tag_end, format_end,
|
||||
font, bold, size, color, url, target, image, top, center, bottom, baseline,
|
||||
number, string, _true, _false, red, green, blue, white, black, binary, min_limited, max_limited,
|
||||
|
||||
equal, comma, backslash,
|
||||
data, endl,
|
||||
eof
|
||||
};
|
||||
|
||||
class tokenizer
|
||||
{
|
||||
public:
|
||||
tokenizer(const nana::string& s, bool format_enabled)
|
||||
: iptr_(s.data()),
|
||||
endptr_(s.data() + s.size()),
|
||||
format_enabled_(format_enabled),
|
||||
format_state_(false),
|
||||
revert_token_(token::eof)
|
||||
{
|
||||
}
|
||||
|
||||
void push(token tk)
|
||||
{
|
||||
revert_token_ = tk;
|
||||
}
|
||||
|
||||
//Read the token.
|
||||
token read()
|
||||
{
|
||||
if(revert_token_ != token::eof)
|
||||
{
|
||||
token tk = revert_token_;
|
||||
revert_token_ = token::eof;
|
||||
return tk;
|
||||
}
|
||||
|
||||
if(iptr_ == endptr_)
|
||||
return token::eof;
|
||||
|
||||
//Check whether it is a format token.
|
||||
if(format_enabled_ && format_state_)
|
||||
return _m_format_token();
|
||||
|
||||
return _m_token();
|
||||
}
|
||||
|
||||
const nana::string& idstr() const
|
||||
{
|
||||
return idstr_;
|
||||
}
|
||||
|
||||
const std::pair<nana::string, nana::string>& binary() const
|
||||
{
|
||||
return binary_;
|
||||
}
|
||||
|
||||
std::pair<unsigned, unsigned> binary_number() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss<<static_cast<std::string>(nana::charset(binary_.first))<<' '<<static_cast<std::string>(nana::charset(binary_.second));
|
||||
|
||||
std::pair<unsigned, unsigned> r;
|
||||
ss>>r.first>>r.second;
|
||||
return r;
|
||||
}
|
||||
|
||||
int number() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss<<static_cast<std::string>(nana::charset(idstr_));
|
||||
|
||||
//It's a hex number.
|
||||
if(idstr_.size() > 2 && idstr_[0] == '0' && (idstr_[1] == 'x' || idstr_[1] == 'X'))
|
||||
ss>>std::hex;
|
||||
|
||||
int n;
|
||||
ss>>n;
|
||||
return n;
|
||||
}
|
||||
private:
|
||||
static bool _m_unicode_word_breakable(nana::char_t ch)
|
||||
{
|
||||
return ((0x4E00 <= ch) && (ch <= 0x9FFF));
|
||||
}
|
||||
|
||||
//Read the data token
|
||||
token _m_token()
|
||||
{
|
||||
nana::char_t ch = *iptr_;
|
||||
|
||||
if(ch > 0xFF)
|
||||
{
|
||||
//This is the Unicode.
|
||||
|
||||
idstr_.clear();
|
||||
idstr_.append(1, ch);
|
||||
|
||||
if(_m_unicode_word_breakable(ch))
|
||||
{
|
||||
++iptr_;
|
||||
return token::data;
|
||||
}
|
||||
|
||||
ch = *++iptr_;
|
||||
while((iptr_ != endptr_) && (ch > 0xFF) && (false == _m_unicode_word_breakable(ch)))
|
||||
{
|
||||
idstr_.append(1, ch);
|
||||
|
||||
ch = *++iptr_;
|
||||
}
|
||||
|
||||
return token::data;
|
||||
}
|
||||
|
||||
if('\n' == ch)
|
||||
{
|
||||
++iptr_;
|
||||
return token::endl;
|
||||
}
|
||||
|
||||
if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'))
|
||||
{
|
||||
const nana::char_t * idstr = iptr_;
|
||||
do
|
||||
{
|
||||
ch = *(++iptr_);
|
||||
}
|
||||
while(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'));
|
||||
|
||||
idstr_.assign(idstr, iptr_);
|
||||
|
||||
return token::data;
|
||||
}
|
||||
|
||||
if('0' <= ch && ch <= '9')
|
||||
{
|
||||
_m_read_number();
|
||||
return token::data;
|
||||
}
|
||||
|
||||
if(('<' == ch) && format_enabled_)
|
||||
{
|
||||
//pos keeps the current position, and it used for restring
|
||||
//iptr_ when the search is failed.
|
||||
const nana::char_t * pos = ++iptr_;
|
||||
_m_eat_whitespace();
|
||||
if(*iptr_ == '/')
|
||||
{
|
||||
++iptr_;
|
||||
_m_eat_whitespace();
|
||||
if(*iptr_ == '>')
|
||||
{
|
||||
++iptr_;
|
||||
return token::format_end;
|
||||
}
|
||||
}
|
||||
|
||||
//Restore the iptr_;
|
||||
iptr_ = pos;
|
||||
|
||||
format_state_ = true;
|
||||
return token::tag_begin;
|
||||
}
|
||||
|
||||
//Escape
|
||||
if(ch == '\\')
|
||||
{
|
||||
if(iptr_ + 1 < endptr_)
|
||||
{
|
||||
ch = *(iptr_ + 1);
|
||||
iptr_ += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
iptr_ = endptr_;
|
||||
return token::eof;
|
||||
}
|
||||
}
|
||||
|
||||
++iptr_;
|
||||
|
||||
idstr_.clear();
|
||||
idstr_.append(1, ch);
|
||||
return token::data;
|
||||
}
|
||||
|
||||
//Read the format token
|
||||
token _m_format_token()
|
||||
{
|
||||
_m_eat_whitespace();
|
||||
|
||||
nana::char_t ch = *iptr_++;
|
||||
|
||||
switch(ch)
|
||||
{
|
||||
case ',': return token::comma;
|
||||
case '/': return token::backslash;
|
||||
case '=': return token::equal;
|
||||
case '>':
|
||||
format_state_ = false;
|
||||
return token::tag_end;
|
||||
case '"':
|
||||
//Here is a string and all the meta characters will be ignored except "
|
||||
{
|
||||
const nana::char_t * str = iptr_;
|
||||
|
||||
while((iptr_ != endptr_) && (*iptr_ != '"'))
|
||||
++iptr_;
|
||||
|
||||
idstr_.assign(str, iptr_++);
|
||||
}
|
||||
return token::string;
|
||||
case '(':
|
||||
_m_eat_whitespace();
|
||||
if((iptr_ < endptr_) && _m_is_idstr_element(*iptr_))
|
||||
{
|
||||
const nana::char_t * pbegin = iptr_;
|
||||
while((iptr_ < endptr_) && _m_is_idstr_element(*iptr_))
|
||||
++iptr_;
|
||||
|
||||
binary_.first.assign(pbegin, iptr_);
|
||||
|
||||
_m_eat_whitespace();
|
||||
if((iptr_ < endptr_) && (',' == *iptr_))
|
||||
{
|
||||
++iptr_;
|
||||
_m_eat_whitespace();
|
||||
if((iptr_ < endptr_) && _m_is_idstr_element(*iptr_))
|
||||
{
|
||||
pbegin = iptr_;
|
||||
while((iptr_ < endptr_) && _m_is_idstr_element(*iptr_))
|
||||
++iptr_;
|
||||
|
||||
binary_.second.assign(pbegin, iptr_);
|
||||
|
||||
_m_eat_whitespace();
|
||||
if((iptr_ < endptr_) && (')' == *iptr_))
|
||||
{
|
||||
++iptr_;
|
||||
return token::binary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return token::eof;
|
||||
}
|
||||
|
||||
if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || '_' == ch)
|
||||
{
|
||||
--iptr_;
|
||||
//Here is a identifier
|
||||
_m_read_idstr();
|
||||
|
||||
if(STR("font") == idstr_)
|
||||
return token::font;
|
||||
else if(STR("bold") == idstr_)
|
||||
return token::bold;
|
||||
else if(STR("size") == idstr_)
|
||||
return token::size;
|
||||
else if(STR("baseline") == idstr_)
|
||||
return token::baseline;
|
||||
else if(STR("top") == idstr_)
|
||||
return token::top;
|
||||
else if(STR("center") == idstr_)
|
||||
return token::center;
|
||||
else if(STR("bottom") == idstr_)
|
||||
return token::bottom;
|
||||
else if(STR("color") == idstr_)
|
||||
return token::color;
|
||||
else if(STR("image") == idstr_)
|
||||
return token::image;
|
||||
else if(STR("true") == idstr_)
|
||||
return token::_true;
|
||||
else if(STR("url") == idstr_)
|
||||
return token::url;
|
||||
else if(STR("target") == idstr_)
|
||||
return token::target;
|
||||
else if(STR("false") == idstr_)
|
||||
return token::_false;
|
||||
else if(STR("red") == idstr_)
|
||||
return token::red;
|
||||
else if(STR("green") == idstr_)
|
||||
return token::green;
|
||||
else if(STR("blue") == idstr_)
|
||||
return token::blue;
|
||||
else if(STR("white") == idstr_)
|
||||
return token::white;
|
||||
else if(STR("black") == idstr_)
|
||||
return token::black;
|
||||
else if(STR("min_limited") == idstr_)
|
||||
return token::min_limited;
|
||||
else if(STR("max_limited") == idstr_)
|
||||
return token::max_limited;
|
||||
|
||||
return token::string;
|
||||
}
|
||||
|
||||
if('0' <= ch && ch <= '9')
|
||||
{
|
||||
--iptr_;
|
||||
_m_read_number();
|
||||
return token::number;
|
||||
}
|
||||
|
||||
return token::eof;
|
||||
}
|
||||
|
||||
static bool _m_is_idstr_element(nana::char_t ch)
|
||||
{
|
||||
return (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('_' == ch) || ('0' <= ch && ch <= '9'));
|
||||
}
|
||||
|
||||
//Read the identifier.
|
||||
void _m_read_idstr()
|
||||
{
|
||||
const nana::char_t * idstr = iptr_;
|
||||
|
||||
nana::char_t ch;
|
||||
do
|
||||
{
|
||||
ch = *(++iptr_);
|
||||
}
|
||||
while(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('_' == ch) || ('0' <= ch && ch <= '9'));
|
||||
|
||||
idstr_.assign(idstr, iptr_);
|
||||
}
|
||||
|
||||
//Read the number
|
||||
void _m_read_number()
|
||||
{
|
||||
idstr_.clear();
|
||||
|
||||
nana::char_t ch = *iptr_;
|
||||
|
||||
idstr_ += ch;
|
||||
|
||||
//First check the number whether will be a hex number.
|
||||
if('0' == ch)
|
||||
{
|
||||
ch = *++iptr_;
|
||||
if((!('0' <= ch && ch <= '9')) && (ch != 'x' && ch != 'X'))
|
||||
return;
|
||||
|
||||
if(ch == 'x' || ch == 'X')
|
||||
{
|
||||
//Here is a hex number
|
||||
idstr_ += 'x';
|
||||
ch = *++iptr_;
|
||||
while(('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F'))
|
||||
{
|
||||
idstr_ += ch;
|
||||
ch = *++iptr_;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Here is not a hex number
|
||||
idstr_ += ch;
|
||||
}
|
||||
|
||||
ch = *++iptr_;
|
||||
while('0' <= ch && ch <= '9')
|
||||
{
|
||||
idstr_ += ch;
|
||||
ch = *++iptr_;
|
||||
}
|
||||
}
|
||||
|
||||
void _m_eat_whitespace()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
switch(*iptr_)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
++iptr_;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
const nana::char_t * iptr_;
|
||||
const nana::char_t * endptr_;
|
||||
const bool format_enabled_;
|
||||
bool format_state_;
|
||||
|
||||
nana::string idstr_;
|
||||
std::pair<nana::string, nana::string> binary_;
|
||||
|
||||
std::size_t whspace_size_;
|
||||
|
||||
token revert_token_;
|
||||
};
|
||||
|
||||
//The fblock states a format, and a format from which it is inherted
|
||||
struct fblock
|
||||
{
|
||||
struct aligns
|
||||
{
|
||||
enum t
|
||||
{
|
||||
top, center, bottom,
|
||||
baseline
|
||||
};
|
||||
};
|
||||
|
||||
nana::string font;
|
||||
std::size_t font_size;
|
||||
bool bold;
|
||||
bool bold_empty; //bold should be ignored if bold_empty is true
|
||||
aligns::t text_align;
|
||||
nana::color_t bgcolor; //If the color is not specified, it will be ignored, and the system will search for its parent.
|
||||
nana::color_t fgcolor; //ditto
|
||||
|
||||
nana::string target;
|
||||
nana::string url;
|
||||
|
||||
fblock * parent;
|
||||
};
|
||||
|
||||
//The abstruct data class states a data.
|
||||
class data
|
||||
{
|
||||
public:
|
||||
typedef nana::paint::graphics& graph_reference;
|
||||
|
||||
virtual ~data(){}
|
||||
|
||||
virtual bool is_text() const = 0;
|
||||
virtual bool is_whitespace() const = 0;
|
||||
virtual const nana::string& text() const = 0;
|
||||
virtual void measure(graph_reference) = 0;
|
||||
virtual void nontext_render(graph_reference, int x, int y) = 0;
|
||||
virtual const nana::size & size() const = 0;
|
||||
virtual std::size_t ascent() const = 0;
|
||||
};
|
||||
|
||||
|
||||
class data_text
|
||||
: public data
|
||||
{
|
||||
public:
|
||||
data_text(const nana::string& s)
|
||||
: str_(s)
|
||||
{}
|
||||
private:
|
||||
virtual bool is_text() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool is_whitespace() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const nana::string& text() const override
|
||||
{
|
||||
return str_;
|
||||
}
|
||||
|
||||
virtual void measure(graph_reference graph) override
|
||||
{
|
||||
size_ = graph.text_extent_size(str_);
|
||||
unsigned ascent;
|
||||
unsigned descent;
|
||||
unsigned internal_leading;
|
||||
graph.text_metrics(ascent, descent, internal_leading);
|
||||
ascent_ = ascent;
|
||||
}
|
||||
|
||||
virtual void nontext_render(graph_reference, int, int) override
|
||||
{
|
||||
}
|
||||
|
||||
virtual const nana::size & size() const override
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
virtual std::size_t ascent() const override
|
||||
{
|
||||
return ascent_;
|
||||
}
|
||||
private:
|
||||
nana::string str_;
|
||||
nana::size size_;
|
||||
std::size_t ascent_;
|
||||
};
|
||||
|
||||
class data_image
|
||||
: public data
|
||||
{
|
||||
public:
|
||||
data_image(const nana::string& imgpath, const nana::size & sz, std::size_t limited)
|
||||
: image_(imgpath), limited_(limited)
|
||||
{
|
||||
size_ = image_.size();
|
||||
|
||||
if(sz.width != 0 && sz.height != 0)
|
||||
{
|
||||
bool make_fit = false;
|
||||
switch(limited)
|
||||
{
|
||||
case 1:
|
||||
make_fit = (size_.width < sz.width || size_.height < sz.height);
|
||||
break;
|
||||
case 2:
|
||||
make_fit = (size_.width > sz.width || size_.height > sz.height);
|
||||
break;
|
||||
}
|
||||
|
||||
if(make_fit)
|
||||
{
|
||||
nana::size res;
|
||||
nana::fit_zoom(size_, sz, res);
|
||||
size_ = res;
|
||||
}
|
||||
else
|
||||
size_ = sz;
|
||||
}
|
||||
}
|
||||
private:
|
||||
//implement data interface
|
||||
virtual bool is_text() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool is_whitespace() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const nana::string& text() const override
|
||||
{
|
||||
return str_;
|
||||
}
|
||||
|
||||
virtual void measure(graph_reference) override
|
||||
{
|
||||
}
|
||||
|
||||
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));
|
||||
else
|
||||
image_.paste(graph, x, y);
|
||||
}
|
||||
|
||||
virtual const nana::size & size() const override
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
virtual std::size_t ascent() const override
|
||||
{
|
||||
return size_.height;
|
||||
}
|
||||
private:
|
||||
nana::string str_;
|
||||
nana::paint::image image_;
|
||||
nana::size size_;
|
||||
std::size_t limited_;
|
||||
};
|
||||
|
||||
class dstream
|
||||
{
|
||||
struct value
|
||||
{
|
||||
fblock * fblock_ptr;
|
||||
data * data_ptr;
|
||||
};
|
||||
public:
|
||||
typedef std::list<std::deque<value> >::iterator iterator;
|
||||
typedef std::deque<value> linecontainer;
|
||||
|
||||
~dstream()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
for(auto & values: lines_)
|
||||
{
|
||||
for(std::deque<value>::iterator u = values.begin(); u != values.end(); ++u)
|
||||
delete u->data_ptr;
|
||||
}
|
||||
|
||||
lines_.clear();
|
||||
|
||||
for(auto p : fblocks_)
|
||||
delete p;
|
||||
|
||||
fblocks_.clear();
|
||||
}
|
||||
|
||||
void parse(const nana::string& s, bool format_enabled)
|
||||
{
|
||||
close();
|
||||
|
||||
tokenizer tknizer(s, format_enabled);
|
||||
std::stack<fblock*> fstack;
|
||||
|
||||
fstack.push(_m_create_default_fblock());
|
||||
|
||||
while(true)
|
||||
{
|
||||
token tk = tknizer.read();
|
||||
|
||||
switch(tk)
|
||||
{
|
||||
case token::data:
|
||||
_m_data_factory(tk, tknizer.idstr(), fstack.top(), lines_.back());
|
||||
break;
|
||||
case token::endl:
|
||||
lines_.emplace_back();
|
||||
break;
|
||||
case token::tag_begin:
|
||||
_m_parse_format(tknizer, fstack);
|
||||
|
||||
if(attr_image_.path.size())
|
||||
{
|
||||
_m_data_image(fstack.top(), lines_.back());
|
||||
//This fblock just serves the image. So we should restore the pervious fblock
|
||||
fstack.pop();
|
||||
}
|
||||
|
||||
break;
|
||||
case token::format_end:
|
||||
if(fstack.size() > 1)
|
||||
fstack.pop();
|
||||
break;
|
||||
case token::eof:
|
||||
return;
|
||||
default:
|
||||
int * debug = 0; //for debug.
|
||||
*debug = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return lines_.begin();
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return lines_.end();
|
||||
}
|
||||
|
||||
private:
|
||||
void _m_parse_format(tokenizer & tknizer, std::stack<fblock*> & fbstack)
|
||||
{
|
||||
fblock * fp = _m_inhert_from(fbstack.top());
|
||||
|
||||
attr_image_.reset();
|
||||
|
||||
while(true)
|
||||
{
|
||||
switch(tknizer.read())
|
||||
{
|
||||
case token::comma: //Eat the comma, now the comma can be omitted.
|
||||
break;
|
||||
case token::eof:
|
||||
case token::tag_end:
|
||||
fblocks_.push_back(fp);
|
||||
fbstack.push(fp);
|
||||
return;
|
||||
case token::font:
|
||||
if(token::equal != tknizer.read())
|
||||
throw std::runtime_error("");
|
||||
|
||||
if(token::string != tknizer.read())
|
||||
throw std::runtime_error("");
|
||||
|
||||
fp->font = tknizer.idstr();
|
||||
break;
|
||||
case token::size:
|
||||
if(token::equal != tknizer.read())
|
||||
throw std::runtime_error("");
|
||||
|
||||
switch(tknizer.read())
|
||||
{
|
||||
case token::number:
|
||||
fp->font_size = tknizer.number();
|
||||
break;
|
||||
case token::binary:
|
||||
{
|
||||
auto value = tknizer.binary_number();
|
||||
attr_image_.size.width = value.first;
|
||||
attr_image_.size.height = value.second;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
break;
|
||||
case token::color:
|
||||
if(token::equal != tknizer.read())
|
||||
throw std::runtime_error("");
|
||||
|
||||
switch(tknizer.read())
|
||||
{
|
||||
case token::number:
|
||||
fp->fgcolor = tknizer.number();
|
||||
break;
|
||||
case token::red:
|
||||
fp->fgcolor = 0xFF0000;
|
||||
break;
|
||||
case token::green:
|
||||
fp->fgcolor = 0xFF00;
|
||||
break;
|
||||
case token::blue:
|
||||
fp->fgcolor = 0xFF;
|
||||
break;
|
||||
case token::white:
|
||||
fp->fgcolor = 0xFFFFFF;
|
||||
break;
|
||||
case token::black:
|
||||
fp->fgcolor = 0x0;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
break;
|
||||
case token::red: //support the omitting of color.
|
||||
fp->fgcolor = 0xFF0000;
|
||||
break;
|
||||
case token::green: //support the omitting of color.
|
||||
fp->fgcolor = 0xFF00;
|
||||
break;
|
||||
case token::blue: //support the omitting of color.
|
||||
fp->fgcolor = 0xFF;
|
||||
break;
|
||||
case token::white: //support the omitting of color.
|
||||
fp->fgcolor = 0xFFFFFF;
|
||||
break;
|
||||
case token::black: //support the omitting of color.
|
||||
fp->fgcolor = 0x0;
|
||||
break;
|
||||
case token::baseline:
|
||||
fp->text_align = fblock::aligns::baseline;
|
||||
break;
|
||||
case token::top:
|
||||
fp->text_align = fblock::aligns::top;
|
||||
break;
|
||||
case token::center:
|
||||
fp->text_align = fblock::aligns::center;
|
||||
break;
|
||||
case token::bottom:
|
||||
fp->text_align = fblock::aligns::bottom;
|
||||
break;
|
||||
case token::image:
|
||||
if(token::equal != tknizer.read())
|
||||
throw std::runtime_error("");
|
||||
|
||||
if(token::string != tknizer.read())
|
||||
throw std::runtime_error("");
|
||||
|
||||
attr_image_.path = tknizer.idstr();
|
||||
break;
|
||||
case token::min_limited:
|
||||
attr_image_.limited = 1;
|
||||
break;
|
||||
case token::max_limited:
|
||||
attr_image_.limited = 2;
|
||||
break;
|
||||
case token::target:
|
||||
if(token::equal != tknizer.read())
|
||||
throw std::runtime_error("error: a '=' is required behind 'target'");
|
||||
|
||||
if(token::string != tknizer.read())
|
||||
throw std::runtime_error("error: the value of 'target' should be a string");
|
||||
|
||||
fp->target = tknizer.idstr();
|
||||
break;
|
||||
case token::url:
|
||||
if(token::equal != tknizer.read())
|
||||
throw std::runtime_error("error: a '=' is required behind 'url'");
|
||||
|
||||
if(token::string != tknizer.read())
|
||||
throw std::runtime_error("error: the value of 'url' should be a string");
|
||||
|
||||
fp->url = tknizer.idstr();
|
||||
break;
|
||||
case token::bold:
|
||||
{
|
||||
token tk = tknizer.read();
|
||||
if(token::equal == tk)
|
||||
{
|
||||
switch(tknizer.read())
|
||||
{
|
||||
case token::_true:
|
||||
fp->bold = true;
|
||||
break;
|
||||
case token::_false:
|
||||
fp->bold = false;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tknizer.push(tk);
|
||||
fp->bold = true;
|
||||
}
|
||||
fp->bold_empty = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fblock* _m_create_default_fblock()
|
||||
{
|
||||
//Make sure that there is not a fblock is created.
|
||||
if(fblocks_.size())
|
||||
return fblocks_.front();
|
||||
|
||||
//Create a default fblock.
|
||||
fblock * fbp = new fblock;
|
||||
|
||||
fbp->font_size = 0xFFFFFFFF;
|
||||
fbp->bold = false;
|
||||
fbp->bold_empty = true;
|
||||
fbp->text_align = fblock::aligns::baseline;
|
||||
|
||||
//Refer to the definition for the color specification.
|
||||
fbp->bgcolor = 0xFFFFFFFF;
|
||||
fbp->fgcolor = 0xFFFFFFFF;
|
||||
|
||||
fbp->parent = nullptr;
|
||||
|
||||
fblocks_.push_back(fbp);
|
||||
lines_.emplace_back();
|
||||
|
||||
return fbp;
|
||||
}
|
||||
|
||||
fblock * _m_inhert_from(fblock* fp)
|
||||
{
|
||||
fblock * fbp = new fblock;
|
||||
|
||||
fbp->font = fp->font;
|
||||
fbp->font_size = fp->font_size;
|
||||
fbp->bold = fp->bold;
|
||||
fbp->bold_empty = fp->bold_empty;
|
||||
fbp->text_align = fp->text_align;
|
||||
|
||||
fbp->bgcolor = fp->bgcolor;
|
||||
fbp->fgcolor = fp->fgcolor;
|
||||
|
||||
fbp->target = fp->target;
|
||||
|
||||
fbp->parent = fp;
|
||||
|
||||
return fbp;
|
||||
}
|
||||
|
||||
void _m_data_factory(token tk, const nana::string& idstr, fblock* fp, std::deque<value>& line)
|
||||
{
|
||||
value v;
|
||||
v.fblock_ptr = fp;
|
||||
|
||||
switch(tk)
|
||||
{
|
||||
case token::data:
|
||||
v.data_ptr = new data_text(idstr);
|
||||
break;
|
||||
default:
|
||||
int * debug = 0; //for debug
|
||||
*debug = 0;
|
||||
}
|
||||
|
||||
line.push_back(v);
|
||||
}
|
||||
|
||||
void _m_data_image(fblock* fp, std::deque<value>& line)
|
||||
{
|
||||
value v;
|
||||
v.fblock_ptr = fp;
|
||||
|
||||
v.data_ptr = new data_image(attr_image_.path, attr_image_.size, attr_image_.limited);
|
||||
|
||||
line.push_back(v);
|
||||
}
|
||||
|
||||
private:
|
||||
bool format_enabled_;
|
||||
std::vector<fblock*> fblocks_;
|
||||
std::list<std::deque<value> > lines_;
|
||||
|
||||
struct attr_image_tag
|
||||
{
|
||||
nana::string path;
|
||||
nana::size size;
|
||||
std::size_t limited;
|
||||
|
||||
void reset()
|
||||
{
|
||||
path.clear();
|
||||
size.width = size.height = 0;
|
||||
limited = 0;
|
||||
}
|
||||
}attr_image_;
|
||||
};
|
||||
}//end namespace skeletons
|
||||
}//end namespace widgets
|
||||
}//end namepsace nana
|
||||
#endif //NANA_GUI_WIDGETS_SKELETONS_TEXT_TOKEN_STREAM
|
||||
539
include/nana/gui/widgets/skeletons/textbase.hpp
Normal file
539
include/nana/gui/widgets/skeletons/textbase.hpp
Normal file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* A textbase class 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/gui/widgets/skeletons/textbase.hpp
|
||||
* @description: This class manages the multi-line text and provides some operation on text
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP
|
||||
#define NANA_GUI_WIDGET_DETAIL_TEXTBASE_HPP
|
||||
|
||||
#include <nana/charset.hpp>
|
||||
#include <nana/basic_types.hpp>
|
||||
#include <nana/traits.hpp>
|
||||
#include "textbase_export_interface.hpp"
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace widgets
|
||||
{
|
||||
namespace skeletons
|
||||
{
|
||||
template<typename CharT>
|
||||
class textbase
|
||||
: public ::nana::noncopyable
|
||||
{
|
||||
public:
|
||||
typedef CharT char_type;
|
||||
typedef std::basic_string<CharT> string_type;
|
||||
typedef typename string_type::size_type size_type;
|
||||
|
||||
textbase()
|
||||
{
|
||||
attr_max_.reset();
|
||||
//Insert an empty string for the first line of empty text.
|
||||
text_cont_.emplace_back();
|
||||
}
|
||||
|
||||
void set_event_agent(textbase_event_agent_interface * evt)
|
||||
{
|
||||
evt_agent_ = evt;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return (text_cont_.empty() ||
|
||||
((text_cont_.size() == 1) && (text_cont_[0].empty())));
|
||||
}
|
||||
|
||||
bool load(const nana::char_t* fs)
|
||||
{
|
||||
if (nullptr == fs)
|
||||
return false;
|
||||
|
||||
std::string fs_mbs = nana::charset(fs);
|
||||
std::ifstream ifs(fs_mbs.data());
|
||||
if (!ifs)
|
||||
return false;
|
||||
|
||||
ifs.seekg(0, std::ios::end);
|
||||
std::size_t bytes = static_cast<std::size_t>(ifs.tellg());
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
|
||||
if(bytes >= 2)
|
||||
{
|
||||
int ch = ifs.get();
|
||||
if(0xEF == ch && bytes >= 3)
|
||||
{
|
||||
//UTF8
|
||||
ch = ifs.get();
|
||||
if(0xBB == ch && 0xBF == ifs.get())
|
||||
{
|
||||
ifs.close();
|
||||
return load(fs, nana::unicode::utf8);
|
||||
}
|
||||
}
|
||||
else if(0xFF == ch)
|
||||
{
|
||||
if(0xFE == ifs.get())
|
||||
{
|
||||
//UTF16,UTF32
|
||||
if(bytes >= 4)
|
||||
{
|
||||
if(ifs.get() == 0 && ifs.get() == 0)
|
||||
{
|
||||
ifs.close();
|
||||
return load(fs, nana::unicode::utf32);
|
||||
}
|
||||
}
|
||||
ifs.close();
|
||||
return load(fs, nana::unicode::utf16);
|
||||
}
|
||||
}
|
||||
else if(0xFE == ch)
|
||||
{
|
||||
if(ifs.get() == 0xFF)
|
||||
{
|
||||
//UTF16(big-endian)
|
||||
ifs.close();
|
||||
return load(fs, nana::unicode::utf16);
|
||||
}
|
||||
}
|
||||
else if(0 == ch)
|
||||
{
|
||||
if(bytes >= 4 && ifs.get() == 0)
|
||||
{
|
||||
ch = ifs.get();
|
||||
if(0xFE == ch && ifs.get() == 0xFF)
|
||||
{
|
||||
//UTF32(big_endian)
|
||||
ifs.close();
|
||||
return load(fs, nana::unicode::utf32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ifs.clear();
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
|
||||
text_cont_.clear(); //Clear only if the file can be opened.
|
||||
attr_max_.reset();
|
||||
|
||||
std::string str_mbs;
|
||||
while(ifs.good())
|
||||
{
|
||||
std::getline(ifs, str_mbs);
|
||||
text_cont_.emplace_back(nana::charset(str_mbs));
|
||||
if(text_cont_.back().size() > attr_max_.size)
|
||||
{
|
||||
attr_max_.size = text_cont_.back().size();
|
||||
attr_max_.line = text_cont_.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
_m_saved(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void byte_order_translate_2bytes(std::string& str)
|
||||
{
|
||||
char * s = const_cast<char*>(str.c_str());
|
||||
char * end = s + str.size();
|
||||
for(; s < end; s += 2)
|
||||
{
|
||||
char c = *s;
|
||||
*s = *(s + 1);
|
||||
*(s + 1) = c;
|
||||
}
|
||||
}
|
||||
|
||||
static void byte_order_translate_4bytes(std::string& str)
|
||||
{
|
||||
char * s = const_cast<char*>(str.c_str());
|
||||
char * end = s + str.size();
|
||||
for(; s < end; s += 4)
|
||||
{
|
||||
char c = *s;
|
||||
*s = *(s + 3);
|
||||
*(s + 3) = c;
|
||||
|
||||
c = *(s + 1);
|
||||
*(s + 1) = *(s + 2);
|
||||
*(s + 2) = c;
|
||||
}
|
||||
}
|
||||
|
||||
bool load(const nana::char_t * fs, nana::unicode encoding)
|
||||
{
|
||||
if (nullptr == fs)
|
||||
return false;
|
||||
|
||||
std::string fs_mbs = nana::charset(fs);
|
||||
std::ifstream ifs(fs_mbs.data());
|
||||
|
||||
if (!ifs)
|
||||
return false;
|
||||
|
||||
std::string str;
|
||||
bool big_endian = true;
|
||||
|
||||
if(ifs.good())
|
||||
{
|
||||
text_cont_.clear(); //Clear only if the file can be opened.
|
||||
attr_max_.reset();
|
||||
|
||||
std::getline(ifs, str);
|
||||
|
||||
std::size_t len_of_BOM = 0;
|
||||
switch(encoding)
|
||||
{
|
||||
case nana::unicode::utf8:
|
||||
len_of_BOM = 3; break;
|
||||
case nana::unicode::utf16:
|
||||
len_of_BOM = 2; break;
|
||||
case nana::unicode::utf32:
|
||||
len_of_BOM = 4; break;
|
||||
default:
|
||||
throw std::runtime_error("Specified a wrong UTF");
|
||||
}
|
||||
|
||||
big_endian = (str[0] == 0x00 || str[0] == char(0xFE));
|
||||
str.erase(0, len_of_BOM);
|
||||
if(big_endian)
|
||||
{
|
||||
if(nana::unicode::utf16 == encoding)
|
||||
byte_order_translate_2bytes(str);
|
||||
else
|
||||
byte_order_translate_4bytes(str);
|
||||
}
|
||||
|
||||
text_cont_.emplace_back(nana::charset(str, encoding));
|
||||
|
||||
attr_max_.size = text_cont_.back().size();
|
||||
attr_max_.line = 0;
|
||||
}
|
||||
|
||||
while(ifs.good())
|
||||
{
|
||||
std::getline(ifs, str);
|
||||
|
||||
if(big_endian)
|
||||
{
|
||||
if(nana::unicode::utf16 == encoding)
|
||||
byte_order_translate_2bytes(str);
|
||||
else
|
||||
byte_order_translate_4bytes(str);
|
||||
}
|
||||
|
||||
text_cont_.emplace_back(nana::charset(str, encoding));
|
||||
if(text_cont_.back().size() > attr_max_.size)
|
||||
{
|
||||
attr_max_.size = text_cont_.back().size();
|
||||
attr_max_.line = text_cont_.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
_m_saved(fs);
|
||||
return true;
|
||||
}
|
||||
|
||||
void store(nana::string fs) const
|
||||
{
|
||||
std::string fs_mbs = nana::charset(fs);
|
||||
std::ofstream ofs(fs_mbs.data(), std::ios::binary);
|
||||
if(ofs && text_cont_.size())
|
||||
{
|
||||
if(text_cont_.size() > 1)
|
||||
{
|
||||
for(auto i = text_cont_.cbegin(), end = text_cont_.cend() - 1; i != end; ++i)
|
||||
{
|
||||
std::string mbs = nana::charset(*i);
|
||||
ofs.write(mbs.c_str(), mbs.size());
|
||||
ofs.write("\r\n", 2);
|
||||
}
|
||||
}
|
||||
std::string mbs = nana::charset(text_cont_.back());
|
||||
ofs.write(mbs.c_str(), mbs.size());
|
||||
_m_saved(std::move(fs));
|
||||
}
|
||||
}
|
||||
|
||||
void store(nana::string fs, nana::unicode encoding) const
|
||||
{
|
||||
std::string fs_mbs = nana::charset(fs);
|
||||
std::ofstream ofs(fs_mbs.data(), std::ios::binary);
|
||||
if(ofs && text_cont_.size())
|
||||
{
|
||||
const char * le_boms[] = {"\xEF\xBB\xBF", "\xFF\xFE", "\xFF\xFE\x0\x0"}; //BOM for little-endian
|
||||
int bytes = 0;
|
||||
switch(encoding)
|
||||
{
|
||||
case nana::unicode::utf8:
|
||||
bytes = 3; break;
|
||||
case nana::unicode::utf16:
|
||||
bytes = 2; break;
|
||||
case nana::unicode::utf32:
|
||||
bytes = 4; break;
|
||||
}
|
||||
|
||||
if(bytes)
|
||||
ofs.write(le_boms[static_cast<int>(encoding)], bytes);
|
||||
|
||||
if(text_cont_.size() > 1)
|
||||
{
|
||||
std::string mbs;
|
||||
for(auto i = text_cont_.cbegin(), end = text_cont_.cend() - 1; i != end; ++i)
|
||||
{
|
||||
mbs = nana::charset(*i).to_bytes(encoding);
|
||||
mbs += "\r\n";
|
||||
ofs.write(mbs.c_str(), static_cast<std::streamsize>(mbs.size()));
|
||||
}
|
||||
}
|
||||
std::string mbs = nana::charset(text_cont_.back()).to_bytes(encoding);
|
||||
ofs.write(mbs.c_str(), static_cast<std::streamsize>(mbs.size()));
|
||||
_m_saved(std::move(fs));
|
||||
}
|
||||
}
|
||||
|
||||
size_type lines() const
|
||||
{
|
||||
return text_cont_.size();
|
||||
}
|
||||
|
||||
const string_type& getline(size_type pos) const
|
||||
{
|
||||
if(pos < text_cont_.size())
|
||||
return text_cont_[pos];
|
||||
|
||||
return nullstr_;
|
||||
}
|
||||
|
||||
std::pair<size_t, size_t> max_line() const
|
||||
{
|
||||
return std::make_pair(attr_max_.line, attr_max_.size);
|
||||
}
|
||||
public:
|
||||
void replace(size_type pos, string_type && text)
|
||||
{
|
||||
if(text_cont_.size() <= pos)
|
||||
{
|
||||
text_cont_.emplace_back(std::move(text));
|
||||
pos = text_cont_.size() - 1;
|
||||
}
|
||||
else
|
||||
text_cont_[pos].swap(text);
|
||||
|
||||
_m_make_max(pos);
|
||||
_m_edited();
|
||||
}
|
||||
|
||||
void insert(upoint pos, string_type && str)
|
||||
{
|
||||
if(pos.y < text_cont_.size())
|
||||
{
|
||||
string_type& lnstr = text_cont_[pos.y];
|
||||
|
||||
if(pos.x < lnstr.size())
|
||||
lnstr.insert(pos.x, str);
|
||||
else
|
||||
lnstr += str;
|
||||
}
|
||||
else
|
||||
{
|
||||
text_cont_.emplace_back(std::move(str));
|
||||
pos.y = static_cast<unsigned>(text_cont_.size() - 1);
|
||||
}
|
||||
|
||||
_m_make_max(pos.y);
|
||||
_m_edited();
|
||||
}
|
||||
|
||||
void insertln(size_type pos, string_type&& str)
|
||||
{
|
||||
if(pos < text_cont_.size())
|
||||
text_cont_.emplace(text_cont_.begin() + pos, std::move(str));
|
||||
else
|
||||
text_cont_.emplace_back(std::move(str));
|
||||
|
||||
_m_make_max(pos);
|
||||
_m_edited();
|
||||
}
|
||||
|
||||
void erase(size_type line, size_type pos, size_type count)
|
||||
{
|
||||
if (line < text_cont_.size())
|
||||
{
|
||||
string_type& lnstr = text_cont_[line];
|
||||
if ((pos == 0) && (count >= lnstr.size()))
|
||||
lnstr.clear();
|
||||
else
|
||||
lnstr.erase(pos, count);
|
||||
|
||||
if (attr_max_.line == line)
|
||||
_m_scan_for_max();
|
||||
|
||||
_m_edited();
|
||||
}
|
||||
}
|
||||
|
||||
bool erase(size_type pos, std::size_t n)
|
||||
{
|
||||
//Bounds checking
|
||||
if ((pos >= text_cont_.size()) || (0 == n))
|
||||
return false;
|
||||
|
||||
if (pos + n > text_cont_.size())
|
||||
n = text_cont_.size() - pos;
|
||||
|
||||
text_cont_.erase(text_cont_.begin() + pos, text_cont_.begin() + (pos + n));
|
||||
|
||||
if (pos <= attr_max_.line && attr_max_.line < pos + n)
|
||||
_m_scan_for_max();
|
||||
else if (pos < attr_max_.line)
|
||||
attr_max_.line -= n;
|
||||
|
||||
_m_edited();
|
||||
return true;
|
||||
}
|
||||
|
||||
void erase_all()
|
||||
{
|
||||
std::deque<string_type>().swap(text_cont_);
|
||||
attr_max_.reset();
|
||||
_m_saved(nana::string());
|
||||
}
|
||||
|
||||
void merge(size_type pos)
|
||||
{
|
||||
if(pos + 1 < text_cont_.size())
|
||||
{
|
||||
text_cont_[pos] += text_cont_[pos + 1];
|
||||
text_cont_.erase(text_cont_.begin() + (pos + 1));
|
||||
_m_make_max(pos);
|
||||
if(pos < attr_max_.line)
|
||||
--attr_max_.line;
|
||||
|
||||
_m_edited();
|
||||
}
|
||||
}
|
||||
|
||||
const nana::string& filename() const
|
||||
{
|
||||
return filename_;
|
||||
}
|
||||
|
||||
bool edited() const
|
||||
{
|
||||
return changed_;
|
||||
}
|
||||
|
||||
void edited_reset()
|
||||
{
|
||||
changed_ = false;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
filename_.clear();
|
||||
changed_ = false;
|
||||
}
|
||||
|
||||
bool saved() const
|
||||
{
|
||||
return ! not_saved();
|
||||
}
|
||||
|
||||
bool not_saved() const
|
||||
{
|
||||
return edited() || filename_.empty();
|
||||
}
|
||||
private:
|
||||
void _m_make_max(std::size_t pos)
|
||||
{
|
||||
const string_type& str = text_cont_[pos];
|
||||
if(str.size() > attr_max_.size)
|
||||
{
|
||||
attr_max_.size = str.size();
|
||||
attr_max_.line = pos;
|
||||
}
|
||||
}
|
||||
|
||||
void _m_scan_for_max()
|
||||
{
|
||||
attr_max_.size = 0;
|
||||
std::size_t n = 0;
|
||||
for(auto & s : text_cont_)
|
||||
{
|
||||
if(s.size() > attr_max_.size)
|
||||
{
|
||||
attr_max_.size = s.size();
|
||||
attr_max_.line = n;
|
||||
}
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
void _m_first_change() const
|
||||
{
|
||||
if (evt_agent_)
|
||||
evt_agent_->first_change();
|
||||
}
|
||||
|
||||
void _m_saved(nana::string && filename) const
|
||||
{
|
||||
if(filename_ != filename)
|
||||
{
|
||||
filename_ = std::move(filename);
|
||||
_m_first_change();
|
||||
}
|
||||
else if(changed_)
|
||||
_m_first_change();
|
||||
|
||||
changed_ = false;
|
||||
}
|
||||
|
||||
void _m_edited()
|
||||
{
|
||||
if(!changed_)
|
||||
{
|
||||
_m_first_change();
|
||||
changed_ = true;
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::deque<string_type> text_cont_;
|
||||
textbase_event_agent_interface* evt_agent_{ nullptr };
|
||||
|
||||
mutable bool changed_{ false };
|
||||
mutable nana::string filename_; //A string for the saved filename.
|
||||
const string_type nullstr_;
|
||||
|
||||
struct attr_max
|
||||
{
|
||||
std::size_t line;
|
||||
std::size_t size;
|
||||
|
||||
void reset()
|
||||
{
|
||||
line = 0;
|
||||
size = 0;
|
||||
}
|
||||
}attr_max_;
|
||||
};
|
||||
|
||||
}//end namespace detail
|
||||
}//end namespace widgets
|
||||
}//end namespace nana
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Definitions of textbase export interfaces
|
||||
* 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/gui/widgets/skeletons/textbase_export_interface.hpp
|
||||
* @description: It is defined outside, some headers like textbox should not include a whole textbase for its ext_evtbase
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_TEXTBASE_EXPORT_INTERFACE_HPP
|
||||
#define NANA_GUI_WIDGET_TEXTBASE_EXPORT_INTERFACE_HPP
|
||||
|
||||
namespace nana{ namespace widgets
|
||||
{
|
||||
namespace skeletons
|
||||
{
|
||||
class textbase_event_agent_interface
|
||||
{
|
||||
public:
|
||||
virtual ~textbase_event_agent_interface() = default;
|
||||
|
||||
virtual void first_change() = 0; ///< An event for the text first change after text has been opened or stored.
|
||||
};
|
||||
}//end namespace skeletons
|
||||
}//end namespace widgets
|
||||
}//end namespace nana
|
||||
#endif //NANA_GUI_WIDGET_TEXTBASE_EXPORT_INTERFACE_HPP
|
||||
142
include/nana/gui/widgets/slider.hpp
Normal file
142
include/nana/gui/widgets/slider.hpp
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* A Slider 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/gui/widgets/slider.hpp
|
||||
*/
|
||||
#ifndef NANA_GUI_WIDGETS_SLIDER_HPP
|
||||
#define NANA_GUI_WIDGETS_SLIDER_HPP
|
||||
#include "widget.hpp"
|
||||
#include <nana/pat/cloneable.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class slider;
|
||||
|
||||
struct arg_slider
|
||||
{
|
||||
slider & widget;
|
||||
};
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace slider
|
||||
{
|
||||
struct slider_events
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_slider> value_changed;
|
||||
};
|
||||
|
||||
enum class seekdir
|
||||
{
|
||||
bilateral, forward, backward
|
||||
};
|
||||
|
||||
class provider
|
||||
{
|
||||
public:
|
||||
virtual ~provider() = 0;
|
||||
virtual nana::string adorn_trace(unsigned vmax, unsigned vadorn) const = 0;
|
||||
};
|
||||
|
||||
class renderer
|
||||
{
|
||||
public:
|
||||
typedef ::nana::paint::graphics & graph_reference;
|
||||
|
||||
struct bar_t
|
||||
{
|
||||
bool horizontal;
|
||||
nana::rectangle r; //the rectangle of bar.
|
||||
unsigned border_size; //border_size of bar.
|
||||
};
|
||||
|
||||
struct slider_t
|
||||
{
|
||||
bool horizontal;
|
||||
int pos;
|
||||
unsigned border;
|
||||
unsigned scale;
|
||||
};
|
||||
|
||||
struct adorn_t
|
||||
{
|
||||
bool horizontal;
|
||||
nana::point bound;
|
||||
int fixedpos;
|
||||
unsigned block;
|
||||
unsigned vcur_scale; //pixels of vcur scale.
|
||||
};
|
||||
|
||||
virtual ~renderer() = 0;
|
||||
|
||||
virtual void background(window, graph_reference, bool isglass) = 0;
|
||||
virtual void adorn(window, graph_reference, const adorn_t&) = 0;
|
||||
virtual void adorn_textbox(window, graph_reference, const nana::string&, const nana::rectangle&) = 0;
|
||||
virtual void bar(window, graph_reference, const bar_t&) = 0;
|
||||
virtual void slider(window, graph_reference, const slider_t&) = 0;
|
||||
};
|
||||
|
||||
class controller;
|
||||
|
||||
class trigger
|
||||
: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
typedef controller controller_t;
|
||||
|
||||
trigger();
|
||||
~trigger();
|
||||
controller_t* ctrl() const;
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void detached() override;
|
||||
void refresh(graph_reference) override;
|
||||
void mouse_down(graph_reference, const arg_mouse&) override;
|
||||
void mouse_up(graph_reference, const arg_mouse&) override;
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||
void resized(graph_reference, const arg_resized&) override;
|
||||
private:
|
||||
controller_t * impl_;
|
||||
};
|
||||
}//end namespace slider
|
||||
}//end namespace drawerbase
|
||||
/// A slider widget wich the user can drag for tracking
|
||||
class slider
|
||||
: public widget_object<category::widget_tag, drawerbase::slider::trigger, drawerbase::slider::slider_events>
|
||||
{
|
||||
public:
|
||||
typedef drawerbase::slider::renderer renderer; ///< The interface for user-defined renderer.
|
||||
typedef drawerbase::slider::provider provider; ///< The interface for user-defined provider.
|
||||
typedef drawerbase::slider::seekdir seekdir; ///< Defines the slider seek direction.
|
||||
|
||||
slider();
|
||||
slider(window, bool visible);
|
||||
slider(window, const rectangle& = rectangle(), bool visible = true);
|
||||
|
||||
void seek(seekdir); ///< Define the direction that user can seek by using mouse.
|
||||
void vertical(bool);
|
||||
bool vertical() const;
|
||||
void vmax(unsigned);
|
||||
unsigned vmax() const;
|
||||
void value(unsigned);
|
||||
unsigned value() const;
|
||||
unsigned move_step(bool forward); ///< Increase or decrease the value of slider.
|
||||
unsigned adorn() const;
|
||||
|
||||
pat::cloneable<renderer>& ext_renderer(); ///< Refers to the current renderer that slider is using.
|
||||
void ext_renderer(const pat::cloneable<renderer>&); ///< Set the current renderer.
|
||||
void ext_provider(const pat::cloneable<provider>&);
|
||||
void transparent(bool);
|
||||
bool transparent() const;
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
332
include/nana/gui/widgets/tabbar.hpp
Normal file
332
include/nana/gui/widgets/tabbar.hpp
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* A Tabbar 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/gui/widgets/tabbar.hpp
|
||||
* @brief: A tabbar contains tab items and toolbox for scrolling, closing, selecting items.
|
||||
*
|
||||
*/
|
||||
#ifndef NANA_GUI_WIDGET_TABBAR_HPP
|
||||
#define NANA_GUI_WIDGET_TABBAR_HPP
|
||||
#include "widget.hpp"
|
||||
#include "../../paint/gadget.hpp"
|
||||
#include <nana/pat/cloneable.hpp>
|
||||
#include <nana/any.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
template<typename T> class tabbar;
|
||||
|
||||
template<typename T>
|
||||
struct arg_tabbar
|
||||
{
|
||||
tabbar<T> & widget;
|
||||
T & value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct arg_tabbar_removed : public arg_tabbar<T>
|
||||
{
|
||||
arg_tabbar_removed(tabbar<T>& wdg, T& v)
|
||||
: arg_tabbar<T>({wdg, v})
|
||||
{}
|
||||
|
||||
bool remove = true;
|
||||
};
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace tabbar
|
||||
{
|
||||
template<typename T>
|
||||
struct tabbar_events
|
||||
: public general_events
|
||||
{
|
||||
typedef T value_type;
|
||||
|
||||
basic_event<arg_tabbar<value_type>> added;
|
||||
basic_event<arg_tabbar<value_type>> activated;
|
||||
basic_event<arg_tabbar<value_type>> removed;
|
||||
};
|
||||
|
||||
class event_agent_interface
|
||||
{
|
||||
public:
|
||||
virtual ~event_agent_interface() = 0;
|
||||
virtual void added(std::size_t) = 0;
|
||||
virtual void activated(std::size_t) = 0;
|
||||
virtual bool removed(std::size_t) = 0;
|
||||
};
|
||||
|
||||
class item_renderer
|
||||
{
|
||||
public:
|
||||
typedef item_renderer item_renderer_type;
|
||||
typedef nana::paint::graphics & graph_reference;
|
||||
enum state_t{disable, normal, highlight, press};
|
||||
|
||||
struct item_t
|
||||
{
|
||||
nana::rectangle r;
|
||||
nana::color_t bgcolor;
|
||||
nana::color_t fgcolor;
|
||||
};
|
||||
|
||||
virtual ~item_renderer() = 0;
|
||||
virtual void background(graph_reference, const nana::rectangle& r, nana::color_t bgcolor) = 0;
|
||||
virtual void item(graph_reference, const item_t&, bool active, state_t) = 0;
|
||||
virtual void close_fly(graph_reference, const nana::rectangle&, bool active, state_t) = 0;
|
||||
|
||||
virtual void add(graph_reference, const nana::rectangle&, state_t) = 0;
|
||||
virtual void close(graph_reference, const nana::rectangle&, state_t) = 0;
|
||||
virtual void back(graph_reference, const nana::rectangle&, state_t) = 0;
|
||||
virtual void next(graph_reference, const nana::rectangle&, state_t) = 0;
|
||||
virtual void list(graph_reference, const nana::rectangle&, state_t) = 0;
|
||||
};
|
||||
|
||||
template<typename T, typename DrawerTrigger>
|
||||
class event_agent
|
||||
: public event_agent_interface
|
||||
{
|
||||
public:
|
||||
typedef ::nana::arg_tabbar<T> arg_tabbar;
|
||||
|
||||
event_agent(::nana::tabbar<T>& tb, DrawerTrigger & dtr)
|
||||
: tabbar_(tb), drawer_trigger_(dtr)
|
||||
{}
|
||||
|
||||
void added(std::size_t pos) override
|
||||
{
|
||||
if(pos != npos)
|
||||
{
|
||||
drawer_trigger_.at_no_bound_check(pos) = T();
|
||||
tabbar_.events().added.emit(arg_tabbar({ tabbar_, tabbar_[pos] }));
|
||||
}
|
||||
}
|
||||
|
||||
void activated(std::size_t pos) override
|
||||
{
|
||||
if(pos != npos)
|
||||
tabbar_.events().activated.emit(arg_tabbar({ tabbar_, tabbar_[pos]}));
|
||||
}
|
||||
|
||||
bool removed(std::size_t pos) override
|
||||
{
|
||||
if (pos != npos)
|
||||
{
|
||||
::nana::arg_tabbar_removed<T> arg(tabbar_, tabbar_[pos]);
|
||||
tabbar_.events().removed.emit(arg);
|
||||
return arg.remove;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
::nana::tabbar<T> & tabbar_;
|
||||
DrawerTrigger& drawer_trigger_;
|
||||
};
|
||||
|
||||
class layouter;
|
||||
|
||||
class trigger
|
||||
: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
enum toolbox_button_t{ButtonAdd, ButtonScroll, ButtonList, ButtonClose};
|
||||
trigger();
|
||||
~trigger();
|
||||
void activate(std::size_t);
|
||||
std::size_t activated() const;
|
||||
nana::any& at(std::size_t) const;
|
||||
nana::any& at_no_bound_check(std::size_t) const;
|
||||
const pat::cloneable<item_renderer> & ext_renderer() const;
|
||||
void ext_renderer(const pat::cloneable<item_renderer>&);
|
||||
void set_event_agent(event_agent_interface*);
|
||||
void push_back(const nana::string&, const nana::any&);
|
||||
std::size_t length() const;
|
||||
bool close_fly(bool);
|
||||
void relate(size_t, window);
|
||||
void tab_color(std::size_t, bool is_bgcolor, nana::color_t);
|
||||
void tab_image(size_t, const nana::paint::image&);
|
||||
void text(std::size_t, const nana::string&);
|
||||
nana::string text(std::size_t) const;
|
||||
bool toolbox_button(toolbox_button_t, bool);
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void detached() override;
|
||||
void refresh(graph_reference) override;
|
||||
void mouse_down(graph_reference, const arg_mouse&) override;
|
||||
void mouse_up(graph_reference, const arg_mouse&) override;
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||
private:
|
||||
layouter * layouter_;
|
||||
};
|
||||
}
|
||||
}//end namespace drawerbase
|
||||
/// Analogous to dividers in a notebook or the labels in a file cabinet
|
||||
template<typename Type>
|
||||
class tabbar
|
||||
: public widget_object<category::widget_tag, drawerbase::tabbar::trigger, drawerbase::tabbar::tabbar_events<Type>>
|
||||
{
|
||||
typedef drawerbase::tabbar::trigger drawer_trigger_t;
|
||||
public:
|
||||
typedef Type value_type; ///< The type of element data which is stored in the tabbar.
|
||||
typedef drawerbase::tabbar::item_renderer item_renderer; ///< A user-defined item renderer should be derived from this interface.
|
||||
|
||||
struct button_add{}; ///< The type identifies the add button of the tabbar's toolbox.
|
||||
struct button_scroll{}; ///< The type identifies the scroll button of the tabbar's toolbox.
|
||||
struct button_list{}; ///< The type identifies the list button of the tabbar's toolbox.
|
||||
struct button_close{}; ///< The type identifies the close button of the tabbar's toolbox.
|
||||
|
||||
/// A template class identifies the buttons of the tabbar<61>s toolbox. Refer to notes for more details.
|
||||
template<typename ButtonAdd = nana::null_type, typename ButtonScroll = nana::null_type, typename ButtonList = nana::null_type, typename ButtonClose = nana::null_type>
|
||||
struct button_container
|
||||
{
|
||||
typedef meta::fixed_type_set<ButtonAdd, ButtonScroll, ButtonList, ButtonClose> type_set;
|
||||
};
|
||||
|
||||
tabbar()
|
||||
{
|
||||
evt_agent_.reset(new drawerbase::tabbar::event_agent<value_type, drawer_trigger_t>(*this, this->get_drawer_trigger()));
|
||||
this->get_drawer_trigger().set_event_agent(evt_agent_.get());
|
||||
}
|
||||
|
||||
tabbar(window wd, bool visible)
|
||||
: tabbar()
|
||||
{
|
||||
this->create(wd, rectangle(), visible);
|
||||
}
|
||||
|
||||
tabbar(window wd, const nana::char_t* text, bool visible)
|
||||
: tabbar(wd, ::nana::string(text), visible)
|
||||
{
|
||||
}
|
||||
|
||||
tabbar(window wd, const nana::string& text, bool visible)
|
||||
: tabbar()
|
||||
{
|
||||
this->create(wd, rectangle(), visible);
|
||||
this->caption(text);
|
||||
}
|
||||
|
||||
tabbar(window wd, const rectangle& r = rectangle(), bool visible = true)
|
||||
: tabbar()
|
||||
{
|
||||
this->create(wd, r, visible);
|
||||
}
|
||||
|
||||
~tabbar()
|
||||
{
|
||||
this->get_drawer_trigger().set_event_agent(nullptr);
|
||||
}
|
||||
|
||||
value_type & operator[](std::size_t pos) const
|
||||
{
|
||||
return static_cast<value_type&>(this->get_drawer_trigger().at_no_bound_check(pos));
|
||||
}
|
||||
|
||||
void activate(std::size_t pos) /// Activates a tab specified by i.
|
||||
{
|
||||
this->get_drawer_trigger().activate(pos);
|
||||
}
|
||||
|
||||
std::size_t activated() const
|
||||
{
|
||||
return this->get_drawer_trigger().activated();
|
||||
}
|
||||
|
||||
value_type & at(std::size_t i) const /// Returns i'th element
|
||||
{
|
||||
return static_cast<value_type&>(this->get_drawer_trigger().at(i));
|
||||
}
|
||||
|
||||
void close_fly(bool fly) /// Draw or not a close button in each tab.
|
||||
{
|
||||
if(this->get_drawer_trigger().close_fly(fly))
|
||||
API::refresh_window(this->handle());
|
||||
}
|
||||
|
||||
pat::cloneable<item_renderer>& ext_renderer() const
|
||||
{
|
||||
return this->get_drawer_trigger().ext_renderer();
|
||||
}
|
||||
|
||||
void ext_renderer(const pat::cloneable<item_renderer>& ir)
|
||||
{
|
||||
this->get_drawer_trigger().ext_renderer(ir);
|
||||
}
|
||||
|
||||
std::size_t length() const /// Returns the number of items.
|
||||
{
|
||||
return this->get_drawer_trigger().length();
|
||||
}
|
||||
|
||||
void push_back(const nana::string& text) /// Append a new item.
|
||||
{
|
||||
auto & t = this->get_drawer_trigger();
|
||||
t.push_back(text, value_type());
|
||||
API::update_window(*this);
|
||||
}
|
||||
|
||||
void relate(std::size_t pos, window wd) /// Binds a window to an item specified by pos, if the item is selected, shows the window, otherwise, hides it.
|
||||
{
|
||||
this->get_drawer_trigger().relate(pos, wd);
|
||||
}
|
||||
|
||||
void tab_bgcolor(std::size_t i, nana::color_t color)
|
||||
{
|
||||
this->get_drawer_trigger().tab_color(i, true, color);
|
||||
}
|
||||
|
||||
void tab_fgcolor(std::size_t i, nana::color_t color)
|
||||
{
|
||||
this->get_drawer_trigger().tab_color(i, false, color);
|
||||
}
|
||||
|
||||
void tab_image(std::size_t i, const nana::paint::image& img)
|
||||
{
|
||||
this->get_drawer_trigger().tab_image(i, img);
|
||||
}
|
||||
/// Sets buttons of the tabbar's toolbox, refer to notes for more details.
|
||||
template<typename Add, typename Scroll, typename List, typename Close>
|
||||
void toolbox(const button_container<Add, Scroll, List, Close>&, bool enable)
|
||||
{
|
||||
typedef typename button_container<Add, Scroll, List, Close>::type_set type_set;
|
||||
auto & tg = this->get_drawer_trigger();
|
||||
bool redraw = false;
|
||||
|
||||
if(type_set::template count<button_add>::value)
|
||||
redraw |= tg.toolbox_button(tg.ButtonAdd, enable);
|
||||
|
||||
if(type_set::template count<button_scroll>::value)
|
||||
redraw |= tg.toolbox_button(tg.ButtonScroll, enable);
|
||||
|
||||
if(type_set::template count<button_list>::value)
|
||||
redraw |= tg.toolbox_button(tg.ButtonList, enable);
|
||||
|
||||
if(type_set::template count<button_close>::value)
|
||||
redraw |= tg.toolbox_button(tg.ButtonClose, enable);
|
||||
|
||||
if(redraw)
|
||||
API::refresh_window(this->handle());
|
||||
}
|
||||
|
||||
void text(std::size_t pos, const nana::string& str) /// Sets the title of the specified item, If pos is invalid, the method throws an std::out_of_range object.
|
||||
{
|
||||
this->get_drawer_trigger().text(pos, str);
|
||||
}
|
||||
|
||||
nana::string text(std::size_t pos) const /// Returns a title of a specified item, If pos is invalid, the method trhows a std::out_of_range object.
|
||||
{
|
||||
return this->get_drawer_trigger().text(pos);
|
||||
}
|
||||
private:
|
||||
std::unique_ptr<drawerbase::tabbar::event_agent<value_type, drawerbase::tabbar::trigger> > evt_agent_;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
189
include/nana/gui/widgets/textbox.hpp
Normal file
189
include/nana/gui/widgets/textbox.hpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* A Textbox 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/gui/widgets/textbox.hpp
|
||||
*/
|
||||
#ifndef NANA_GUI_WIDGET_TEXTBOX_HPP
|
||||
#define NANA_GUI_WIDGET_TEXTBOX_HPP
|
||||
#include <nana/gui/widgets/widget.hpp>
|
||||
#include "skeletons/textbase_export_interface.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class textbox;
|
||||
|
||||
struct arg_textbox
|
||||
{
|
||||
textbox& widget;
|
||||
};
|
||||
|
||||
namespace widgets
|
||||
{
|
||||
namespace skeletons
|
||||
{
|
||||
class text_editor;
|
||||
}
|
||||
}
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace textbox
|
||||
{
|
||||
struct textbox_events
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_textbox> first_change;
|
||||
};
|
||||
|
||||
class event_agent
|
||||
: public widgets::skeletons::textbase_event_agent_interface
|
||||
{
|
||||
public:
|
||||
event_agent(::nana::textbox& wdg);
|
||||
void first_change() override;
|
||||
private:
|
||||
::nana::textbox & widget_;
|
||||
};
|
||||
|
||||
//class drawer
|
||||
class drawer
|
||||
: public drawer_trigger
|
||||
{
|
||||
public:
|
||||
typedef widgets::skeletons::text_editor text_editor;
|
||||
|
||||
drawer();
|
||||
text_editor * editor();
|
||||
const text_editor * editor() const;
|
||||
void set_accept(std::function<bool(nana::char_t)> &&);
|
||||
private:
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void detached() override;
|
||||
void refresh(graph_reference) override;
|
||||
void focus(graph_reference, const arg_focus&) override;
|
||||
void mouse_down(graph_reference, const arg_mouse&) override;
|
||||
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_up(graph_reference, const arg_mouse&) override;
|
||||
void mouse_enter(graph_reference, const arg_mouse&) override;
|
||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||
void key_press(graph_reference, const arg_keyboard&)override;
|
||||
void key_char(graph_reference, const arg_keyboard&) override;
|
||||
void mouse_wheel(graph_reference, const arg_wheel&) override;
|
||||
void resized(graph_reference, const arg_resized&) override;
|
||||
void typeface_changed(graph_reference) override;
|
||||
private:
|
||||
void _m_text_area(unsigned width, unsigned height);
|
||||
void _m_draw_border(graph_reference, nana::color_t bgcolor);
|
||||
private:
|
||||
widget* widget_;
|
||||
struct status_type
|
||||
{
|
||||
bool has_focus; //Indicates whether it has the keyboard focus
|
||||
}status_;
|
||||
|
||||
std::function<bool(nana::char_t)> pred_acceptive_;
|
||||
widgets::skeletons::text_editor * editor_;
|
||||
std::unique_ptr<event_agent> evt_agent_;
|
||||
};
|
||||
}//end namespace textbox
|
||||
}//end namespace drawerbase
|
||||
|
||||
/// Allow users to enter and edit text by typing on the keyboard.
|
||||
class textbox
|
||||
:public widget_object<category::widget_tag, drawerbase::textbox::drawer, drawerbase::textbox::textbox_events>
|
||||
{
|
||||
public:
|
||||
/// The default constructor without creating the widget.
|
||||
textbox();
|
||||
|
||||
/// \brief The construct that creates a widget.
|
||||
/// @param wd A handle to the parent window of the widget being created.
|
||||
/// @param visible specifying the visible after creating.
|
||||
textbox(window, bool visible);
|
||||
|
||||
/// \brief The construct that creates a widget with a specified text.
|
||||
/// @param window A handle to the parent window of the widget being created.
|
||||
/// @param text the text that will be displayed.
|
||||
/// @param visible specifying the visible after creating.
|
||||
textbox(window, const nana::string& text, bool visible = true);
|
||||
|
||||
/// \brief The construct that creates a widget with a specified text.
|
||||
/// @param window A handle to the parent window of the widget being created.
|
||||
/// @param text the text that will be displayed.
|
||||
/// @param visible specifying the visible after creating.
|
||||
textbox(window, const nana::char_t* text, bool visible = true);
|
||||
|
||||
/// \brief The construct that creates a widget.
|
||||
/// @param window A handle to the parent window of the widget being created.
|
||||
/// @param rectangle the size and position of the widget in its parent window coordinate.
|
||||
/// @param visible specifying the visible after creating.
|
||||
textbox(window, const rectangle& = rectangle(), bool visible = true);
|
||||
|
||||
/// \brief Loads a text file. When attempt to load a unicode encoded text file, be sure the file have a BOM header.
|
||||
void load(nana::string file);
|
||||
void store(nana::string file);
|
||||
void store(nana::string file, nana::unicode encoding);
|
||||
textbox& reset(nana::string = {}); ///< discard the old text and set a newtext
|
||||
|
||||
/// The file of last store operation.
|
||||
nana::string filename() const;
|
||||
|
||||
/// Determine whether the text was edited.
|
||||
bool edited() const;
|
||||
|
||||
/// Reset the edited flag to false manually
|
||||
textbox& edited_reset();
|
||||
|
||||
/// Determine whether the changed text has been saved into the file.
|
||||
bool saved() const;
|
||||
|
||||
/// Read the text from a specified line. It returns true for success.
|
||||
bool getline(std::size_t line_index, nana::string&) const;
|
||||
|
||||
/// Appends an string. If `at_caret` is `true`, the string is inserted at the position of caret, otherwise, it is appended at end of the textbox.
|
||||
textbox& append(const nana::string& text, bool at_caret);
|
||||
|
||||
/// Determine wheter the text is line wrapped.
|
||||
bool line_wrapped() const;
|
||||
textbox& line_wrapped(bool);
|
||||
|
||||
/// Determine whether the text is multi-line enabled.
|
||||
bool multi_lines() const;
|
||||
textbox& multi_lines(bool);
|
||||
bool editable() const;
|
||||
textbox& editable(bool);
|
||||
void set_accept(std::function<bool(nana::char_t)>);
|
||||
|
||||
textbox& tip_string(nana::string);
|
||||
|
||||
/// Set a mask character. Text is displayed as mask character if a mask character is set. This is used for hiding some special text, such as password.
|
||||
textbox& mask(nana::char_t);
|
||||
|
||||
/// Returns true if some text is selected.
|
||||
bool selected() const;
|
||||
|
||||
/// Selects/unselects all text.
|
||||
void select(bool);
|
||||
|
||||
void copy() const; ///< Copies the selected text into shared memory, such as clipboard under Windows.
|
||||
void paste(); ///< Pastes the text from shared memory.
|
||||
void del();
|
||||
|
||||
int to_int() const;
|
||||
double to_double() const;
|
||||
textbox& from(int);
|
||||
textbox& from(double);
|
||||
protected:
|
||||
//Overrides widget's virtual functions
|
||||
::nana::string _m_caption() const override;
|
||||
void _m_caption(::nana::string&&) override;
|
||||
void _m_typeface(const paint::font&) override;
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
102
include/nana/gui/widgets/toolbar.hpp
Normal file
102
include/nana/gui/widgets/toolbar.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* A Toolbar 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/gui/widgets/toolbar.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_TOOLBAR_HPP
|
||||
#define NANA_GUI_WIDGET_TOOLBAR_HPP
|
||||
|
||||
#include "widget.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class toolbar;
|
||||
|
||||
struct arg_toolbar
|
||||
{
|
||||
toolbar& widget;
|
||||
std::size_t button;
|
||||
};
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace toolbar
|
||||
{
|
||||
struct toolbar_events
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_toolbar> selected; ///< A mouse click on a control button.
|
||||
basic_event<arg_toolbar> enter; ///< The mouse enters a control button.
|
||||
basic_event<arg_toolbar> leave; ///< The mouse leaves a control button.
|
||||
|
||||
};
|
||||
|
||||
struct item_type;
|
||||
|
||||
class drawer
|
||||
: public drawer_trigger
|
||||
{
|
||||
struct drawer_impl_type;
|
||||
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
|
||||
drawer();
|
||||
~drawer();
|
||||
|
||||
void append(const nana::string&, const nana::paint::image&);
|
||||
void append();
|
||||
bool enable(size_type) const;
|
||||
bool enable(size_type, bool);
|
||||
void scale(unsigned);
|
||||
private:
|
||||
void refresh(graph_reference) override;
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void detached() override;
|
||||
void mouse_move(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_up(graph_reference, const arg_mouse&) override;
|
||||
private:
|
||||
size_type _m_which(int x, int y, bool want_if_disabled) const;
|
||||
void _m_draw_background(nana::color_t);
|
||||
void _m_draw();
|
||||
void _m_owner_sized(const arg_resized&);
|
||||
private:
|
||||
void _m_fill_pixels(item_type*, bool force);
|
||||
private:
|
||||
::nana::toolbar* widget_;
|
||||
::nana::paint::graphics* graph_;
|
||||
drawer_impl_type* impl_;
|
||||
};
|
||||
|
||||
}//end namespace toolbar
|
||||
}//end namespace drawerbase
|
||||
/// Control bar that contains buttons for controlling
|
||||
class toolbar
|
||||
: public widget_object<category::widget_tag, drawerbase::toolbar::drawer, drawerbase::toolbar::toolbar_events>
|
||||
{
|
||||
public:
|
||||
typedef std::size_t size_type; ///< A type to count the number of elements.
|
||||
|
||||
toolbar();
|
||||
toolbar(window, bool visible);
|
||||
toolbar(window, const rectangle& = rectangle(), bool visible = true);
|
||||
|
||||
void append(); ///< Adds a separator.
|
||||
void append(const nana::string& text, const nana::paint::image& img); ///< Adds a control button.
|
||||
void append(const nana::string& text); ///< Adds a control button.
|
||||
bool enable(size_type index) const;
|
||||
void enable(size_type index, bool enable_state);
|
||||
void scale(unsigned s); ///< Sets the scale of control button.
|
||||
};
|
||||
}//end namespace nana
|
||||
#endif
|
||||
440
include/nana/gui/widgets/treebox.hpp
Normal file
440
include/nana/gui/widgets/treebox.hpp
Normal file
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* A Tree Box 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/gui/widgets/treebox.hpp
|
||||
* @brief:
|
||||
* The treebox organizes the nodes by a key string.
|
||||
* The treebox would have a vertical scrollbar if the node
|
||||
* is too many to display. And it does not have a horizontal scrollbar,
|
||||
* the widget will adjust the node's displaying position for fitting.
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGETS_TREEBOX_HPP
|
||||
#define NANA_GUI_WIDGETS_TREEBOX_HPP
|
||||
#include "widget.hpp"
|
||||
#include "detail/compset.hpp"
|
||||
#include <nana/paint/gadget.hpp>
|
||||
#include "detail/tree_cont.hpp"
|
||||
#include <nana/gui/timer.hpp>
|
||||
#include <nana/any.hpp>
|
||||
#include <nana/pat/cloneable.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class treebox;
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace treebox
|
||||
{
|
||||
enum class component
|
||||
{
|
||||
begin, expender = begin, crook, icon, text, bground, end
|
||||
};
|
||||
|
||||
struct node_image_tag
|
||||
{
|
||||
nana::paint::image normal;
|
||||
nana::paint::image hovered;
|
||||
nana::paint::image expanded;
|
||||
};
|
||||
|
||||
struct node_attribute
|
||||
{
|
||||
bool has_children;
|
||||
bool expended;
|
||||
checkstate checked;
|
||||
bool selected;
|
||||
bool mouse_pointed;
|
||||
nana::paint::image icon_normal;
|
||||
nana::paint::image icon_hover;
|
||||
nana::paint::image icon_expanded;
|
||||
nana::string text;
|
||||
};
|
||||
|
||||
typedef widgets::detail::compset<component, node_attribute> compset_interface;
|
||||
typedef widgets::detail::compset_placer<component, node_attribute> compset_placer_interface;
|
||||
|
||||
class renderer_interface
|
||||
{
|
||||
public:
|
||||
typedef drawerbase::treebox::component component;
|
||||
typedef ::nana::paint::graphics& graph_reference;
|
||||
typedef drawerbase::treebox::compset_interface compset_interface;
|
||||
typedef compset_interface::item_attribute_t item_attribute_t;
|
||||
typedef compset_interface::comp_attribute_t comp_attribute_t;
|
||||
|
||||
virtual ~renderer_interface()
|
||||
{}
|
||||
|
||||
virtual void bground(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0;
|
||||
virtual void expander(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0;
|
||||
virtual void crook(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0;
|
||||
virtual void icon(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0;
|
||||
virtual void text(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0;
|
||||
};
|
||||
|
||||
class item_proxy;
|
||||
|
||||
class trigger
|
||||
:public drawer_trigger
|
||||
{
|
||||
template<typename Renderer>
|
||||
struct basic_implement;
|
||||
|
||||
class item_renderer;
|
||||
class item_locator;
|
||||
|
||||
typedef basic_implement<item_renderer> implement;
|
||||
public:
|
||||
struct treebox_node_type
|
||||
{
|
||||
treebox_node_type();
|
||||
treebox_node_type(nana::string);
|
||||
treebox_node_type& operator=(const treebox_node_type&);
|
||||
|
||||
nana::string text;
|
||||
nana::any value;
|
||||
bool expanded;
|
||||
checkstate checked;
|
||||
nana::string img_idstr;
|
||||
};
|
||||
|
||||
struct pseudo_node_type{};
|
||||
|
||||
typedef widgets::detail::tree_cont<treebox_node_type> tree_cont_type;
|
||||
typedef tree_cont_type::node_type node_type;
|
||||
|
||||
trigger();
|
||||
~trigger();
|
||||
|
||||
implement * impl() const;
|
||||
|
||||
void auto_draw(bool);
|
||||
void checkable(bool);
|
||||
bool checkable() const;
|
||||
void check(node_type*, checkstate);
|
||||
bool draw();
|
||||
|
||||
const tree_cont_type & tree() const;
|
||||
tree_cont_type & tree();
|
||||
|
||||
void renderer(::nana::pat::cloneable<renderer_interface>&&);
|
||||
const ::nana::pat::cloneable<renderer_interface>& renderer() const;
|
||||
void placer(::nana::pat::cloneable<compset_placer_interface>&&);
|
||||
const ::nana::pat::cloneable<compset_placer_interface>& placer() const;
|
||||
|
||||
nana::any & value(node_type*) const;
|
||||
node_type* insert(node_type*, const nana::string& key, nana::string&&);
|
||||
node_type* insert(const nana::string& path, nana::string&&);
|
||||
|
||||
bool verify(const void*) const;
|
||||
bool verify_kinship(node_type* parent, node_type* child) const;
|
||||
|
||||
void remove(node_type*);
|
||||
node_type * selected() const;
|
||||
void selected(node_type*);
|
||||
void set_expand(node_type*, bool);
|
||||
void set_expand(const nana::string& path, bool);
|
||||
|
||||
//void image(const nana::string& id, const node_image_tag&);
|
||||
node_image_tag& icon(const nana::string&) const;
|
||||
void icon_erase(const nana::string&);
|
||||
void node_icon(node_type*, const nana::string& id);
|
||||
|
||||
unsigned node_width(const node_type*) const;
|
||||
|
||||
bool rename(node_type*, const nana::char_t* key, const nana::char_t* name);
|
||||
private:
|
||||
//Overrides drawer_trigger methods
|
||||
void attached(widget_reference, graph_reference) override;
|
||||
void refresh(graph_reference) override;
|
||||
void dbl_click(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_move(graph_reference, const arg_mouse&) override;
|
||||
void mouse_wheel(graph_reference, const arg_wheel&) override;
|
||||
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||
void resized(graph_reference, const arg_resized&) override;
|
||||
void key_press(graph_reference, const arg_keyboard&) override;
|
||||
void key_char(graph_reference, const arg_keyboard&) override;
|
||||
private:
|
||||
void _m_deal_adjust();
|
||||
private:
|
||||
implement * const impl_;
|
||||
}; //end class trigger
|
||||
|
||||
|
||||
/// \brief A proxy for accessing the node. The key string is case sensitive.
|
||||
class item_proxy
|
||||
: public std::iterator<std::input_iterator_tag, item_proxy>
|
||||
{
|
||||
public:
|
||||
item_proxy() = default; ///< The default constructor creates an end iterator.
|
||||
|
||||
//Undocumented constructor.
|
||||
item_proxy(trigger*, trigger::node_type*);
|
||||
|
||||
/// Append a child.
|
||||
item_proxy append(const nana::string& key, nana::string name);
|
||||
|
||||
/// Append a child with a specified value (user object.).
|
||||
template<typename T>
|
||||
item_proxy append(const nana::string& key, nana::string name, const T&t)
|
||||
{
|
||||
item_proxy ip = append(key, std::move(name));
|
||||
if(false == ip.empty())
|
||||
ip.value(t);
|
||||
return ip;
|
||||
}
|
||||
|
||||
/// Return true if the proxy does not refer to a node, as an end iterator.
|
||||
bool empty() const;
|
||||
|
||||
/// \brief Return the distance between the ROOT node and this node.
|
||||
/// @return only available when emtpy() is false.
|
||||
std::size_t level() const;
|
||||
|
||||
/// Return the check state
|
||||
bool checked() const;
|
||||
|
||||
/// Set the check state, and it returns itself.
|
||||
item_proxy& check(bool);
|
||||
|
||||
/// Return true when the node is expanded \todo change to expanded ??
|
||||
bool expanded() const;
|
||||
|
||||
/// Expand/Shrink children of the node, and returns itself. \todo change to expand ??
|
||||
item_proxy& expand(bool);
|
||||
|
||||
/// Return true when the node is selected.
|
||||
bool selected() const;
|
||||
|
||||
/// Select the node, and returns itself..
|
||||
item_proxy& select(bool);
|
||||
|
||||
/// Return the icon.
|
||||
const nana::string& icon() const;
|
||||
|
||||
/// Set the icon, and returns itself..
|
||||
item_proxy& icon(const nana::string& id);
|
||||
|
||||
/// Return the text.
|
||||
const nana::string& text() const;
|
||||
|
||||
/// Set a new key, and returns itself..
|
||||
item_proxy& key(const nana::string& s);
|
||||
|
||||
/// Return the key.
|
||||
const nana::string& key() const;
|
||||
|
||||
/// Set the text, and returns itself.
|
||||
item_proxy& text(const nana::string&);
|
||||
|
||||
std::size_t size() const; ///< Returns the number of child nodes.
|
||||
|
||||
/// Return the first child of the node.
|
||||
item_proxy child() const;
|
||||
|
||||
/// Return the owner of the node.
|
||||
item_proxy owner() const;
|
||||
|
||||
/// Return the sibling of the node.
|
||||
item_proxy sibling() const;
|
||||
|
||||
/// Return the first child of the node
|
||||
item_proxy begin() const;
|
||||
|
||||
/// An end node.
|
||||
item_proxy end() const;
|
||||
|
||||
/// Makes an action for each sub item recursively, returns the item that stops the action where action returns false.
|
||||
item_proxy visit_recursively(std::function<bool(item_proxy)> action);
|
||||
|
||||
bool operator==(const nana::string& s) const; ///< Compare the text of node with s.
|
||||
bool operator==(const char* s ) const; ///< Compare the text of node with s.
|
||||
bool operator==(const wchar_t* s ) const; ///< Compare the text of node with s.
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy& operator=(const item_proxy&);
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy & operator++();
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy operator++(int);
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy& operator*();
|
||||
|
||||
/// Behavior of Iterator
|
||||
const item_proxy& operator*() const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
item_proxy* operator->();
|
||||
|
||||
/// Behavior of Iterator
|
||||
const item_proxy* operator->() const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
bool operator==(const item_proxy&) const;
|
||||
|
||||
/// Behavior of Iterator
|
||||
bool operator!=(const item_proxy&) const;
|
||||
|
||||
template<typename T>
|
||||
T * value_ptr() const
|
||||
{
|
||||
return _m_value().get<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& value() const
|
||||
{
|
||||
T* p = _m_value().get<T>();
|
||||
if(nullptr == p)
|
||||
throw std::runtime_error("treebox::value<T>() Invalid type of value.");
|
||||
return *p;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
item_proxy & value(const T& t)
|
||||
{
|
||||
_m_value() = t;
|
||||
return *this;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
item_proxy & value(T&& t)
|
||||
{
|
||||
_m_value() = std::move(t);
|
||||
return *this;
|
||||
};
|
||||
|
||||
// Undocumentated methods for internal use
|
||||
trigger::node_type * _m_node() const;
|
||||
private:
|
||||
nana::any& _m_value();
|
||||
const nana::any& _m_value() const;
|
||||
private:
|
||||
trigger * trigger_{nullptr};
|
||||
trigger::node_type * node_{nullptr};
|
||||
};//end class item_proxy
|
||||
}//end namespace treebox
|
||||
}//end namespace drawerbase
|
||||
|
||||
struct arg_treebox
|
||||
{
|
||||
treebox& widget;
|
||||
drawerbase::treebox::item_proxy & item;
|
||||
bool operated;
|
||||
};
|
||||
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace treebox
|
||||
{
|
||||
struct treebox_events
|
||||
: public general_events
|
||||
{
|
||||
basic_event<arg_treebox> expanded;
|
||||
basic_event<arg_treebox> checked;
|
||||
basic_event<arg_treebox> selected;
|
||||
basic_event<arg_treebox> hovered;
|
||||
};
|
||||
}//end namespace treebox
|
||||
}//end namespace drawerbase
|
||||
|
||||
/// Displays a hierarchical list of items, such as the files and directories on a disk.
|
||||
class treebox
|
||||
:public widget_object < category::widget_tag, drawerbase::treebox::trigger, drawerbase::treebox::treebox_events>
|
||||
{
|
||||
public:
|
||||
/// A type refers to the item and also used to iterate through the node.
|
||||
typedef drawerbase::treebox::item_proxy item_proxy;
|
||||
|
||||
typedef drawerbase::treebox::node_image_tag node_image_type;
|
||||
|
||||
/// The interface of treebox item renderer
|
||||
typedef drawerbase::treebox::renderer_interface renderer_interface;
|
||||
|
||||
/// The interface of treebox compset_placer
|
||||
typedef drawerbase::treebox::compset_placer_interface compset_placer_interface;
|
||||
|
||||
/// The default constructor without creating the widget.
|
||||
treebox();
|
||||
|
||||
/// \brief The construct that creates a widget.
|
||||
/// @param wd A handle to the parent window of the widget being created.
|
||||
/// @param visible specifying the visible after creating.
|
||||
treebox(window wd, bool visible);
|
||||
|
||||
/// \brief The construct that creates a widget.
|
||||
/// @param wd A handle to the parent window of the widget being created.
|
||||
/// @param r the size and position of the widget in its parent window coordinate.
|
||||
/// @param visible specifying the visible after creating.
|
||||
treebox(window, const nana::rectangle& = rectangle(), bool visible = true);
|
||||
|
||||
template<typename ItemRenderer>
|
||||
treebox & renderer(const ItemRenderer & rd)
|
||||
{
|
||||
get_drawer_trigger().renderer(::nana::pat::cloneable<renderer_interface>(rd));
|
||||
return *this;
|
||||
}
|
||||
|
||||
const nana::pat::cloneable<renderer_interface> & renderer() const;
|
||||
|
||||
template<typename Placer>
|
||||
treebox & placer(const Placer & r)
|
||||
{
|
||||
get_drawer_trigger().placer(::nana::pat::cloneable<compset_placer_interface>(r));
|
||||
return *this;
|
||||
}
|
||||
|
||||
const nana::pat::cloneable<compset_placer_interface> & placer() const;
|
||||
|
||||
/// \brief Eanble the widget to be draws automatically when it is operated.
|
||||
/// @param bool whether to enable.
|
||||
void auto_draw(bool);
|
||||
|
||||
/// \brief Enable the checkbox for each item of the widget.
|
||||
/// @param bool wheter to enable.
|
||||
treebox & checkable(bool enable);
|
||||
|
||||
/// Determinte whether the checkbox is enabled.
|
||||
bool checkable() const;
|
||||
|
||||
treebox& icon(const nana::string& id, const node_image_type& node_img);
|
||||
|
||||
node_image_type& icon(const nana::string& id) const;
|
||||
|
||||
void icon_erase(const nana::string& id);
|
||||
|
||||
item_proxy find(const nana::string& keypath); ///< Find an item though a specified keypath.
|
||||
|
||||
/// Inserts a new node to treebox, but if the keypath exists returns the existing node.
|
||||
item_proxy insert(const nana::string& path_key, ///< specifies the node hierarchical
|
||||
nana::string title ///< used for displaying
|
||||
);
|
||||
|
||||
/// Inserts a new node to treebox, but if the keypath exists returns the existing node.
|
||||
item_proxy insert( item_proxy pos, ///< the parent item node
|
||||
const nana::string& key, ///< specifies the new node
|
||||
nana::string title ///< used for displaying.
|
||||
);
|
||||
item_proxy erase(item_proxy i);
|
||||
|
||||
void erase(const nana::string& keypath);
|
||||
|
||||
nana::string make_key_path(item_proxy i, const nana::string& splitter) const;///<returns the key path
|
||||
item_proxy selected() const;
|
||||
};//end class treebox
|
||||
}//end namespace nana
|
||||
#endif
|
||||
499
include/nana/gui/widgets/widget.hpp
Normal file
499
include/nana/gui/widgets/widget.hpp
Normal file
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
* The fundamental widget class 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/gui/widgets/widget.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WIDGET_HPP
|
||||
#define NANA_GUI_WIDGET_HPP
|
||||
#include <nana/traits.hpp>
|
||||
#include "../basis.hpp"
|
||||
#include "../programming_interface.hpp"
|
||||
#include <nana/internationalization.hpp>
|
||||
#include <nana/gui/detail/drawer.hpp>
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class drawer_trigger;
|
||||
|
||||
/// Abstract class for defining the capacity interface.
|
||||
class widget
|
||||
: nana::noncopyable, nana::nonmovable
|
||||
{
|
||||
typedef void(*dummy_bool_type)(widget* (*)(const widget&));
|
||||
public:
|
||||
virtual ~widget();
|
||||
virtual window handle() const = 0; ///< Returns the handle of window, returns 0 if window is not created.
|
||||
bool empty() const; ///< Determines whether the manipulator is handling a window.
|
||||
void close();
|
||||
|
||||
window parent() const;
|
||||
|
||||
nana::string caption() const;
|
||||
void caption(nana::string);
|
||||
|
||||
template<typename ...Args>
|
||||
void i18n(std::string msgid, Args&&... args)
|
||||
{
|
||||
_m_caption(nana::internationalization().get(msgid, std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
void i18n(i18n_eval);
|
||||
|
||||
void cursor(nana::cursor);
|
||||
nana::cursor cursor() const; ///< Retrieves the shape of cursor
|
||||
|
||||
void typeface(const paint::font& font);
|
||||
paint::font typeface() const;
|
||||
|
||||
bool enabled() const; ///< Determines whether the window is enabled for mouse and keyboard input.
|
||||
void enabled(bool);
|
||||
|
||||
void enable_dropfiles(bool); ///< Enables/Disables a window to accept dropped files.
|
||||
|
||||
void focus();
|
||||
bool focused() const;
|
||||
|
||||
void show(); ///< Sets the window visible.
|
||||
void hide(); ///< Sets the window invisible.
|
||||
bool visible() const;
|
||||
|
||||
nana::size size() const;
|
||||
void size(const nana::size&);
|
||||
|
||||
point pos() const;
|
||||
void move(int x, int y);
|
||||
void move(const rectangle&);
|
||||
|
||||
void foreground(nana::color_t);
|
||||
nana::color_t foreground() const;
|
||||
void background(nana::color_t);
|
||||
nana::color_t background() const;
|
||||
|
||||
general_events& events() const;
|
||||
|
||||
void umake_event(event_handle eh) const; ///< Deletes an event callback by a handle.
|
||||
widget& tooltip(const nana::string&);
|
||||
|
||||
operator dummy_bool_type() const;
|
||||
operator window() const;
|
||||
protected:
|
||||
//protected members, a derived class must call this implementation if it overrides an implementation
|
||||
virtual void _m_complete_creation();
|
||||
|
||||
virtual general_events& _m_get_general_events() const = 0;
|
||||
virtual nana::string _m_caption() const;
|
||||
virtual void _m_caption(nana::string&&);
|
||||
virtual nana::cursor _m_cursor() const;
|
||||
virtual void _m_cursor(nana::cursor);
|
||||
virtual void _m_close();
|
||||
virtual bool _m_enabled() const;
|
||||
virtual void _m_enabled(bool);
|
||||
virtual bool _m_show(bool);
|
||||
virtual bool _m_visible() const;
|
||||
virtual void _m_size(const nana::size&);
|
||||
virtual void _m_move(int x, int y);
|
||||
virtual void _m_move(const rectangle&);
|
||||
|
||||
virtual void _m_typeface(const nana::paint::font& font);
|
||||
virtual nana::paint::font _m_typeface() const;
|
||||
|
||||
virtual void _m_foreground(nana::color_t);
|
||||
virtual nana::color_t _m_foreground() const;
|
||||
virtual void _m_background(nana::color_t);
|
||||
virtual nana::color_t _m_background() const;
|
||||
};
|
||||
|
||||
/// Base class of all the classes defined as a widget window. Defaultly a widget_tag
|
||||
template<typename Category, typename DrawerTrigger, typename Events = nana::general_events>
|
||||
class widget_object: public widget
|
||||
{
|
||||
protected:
|
||||
typedef DrawerTrigger drawer_trigger_t;
|
||||
public:
|
||||
widget_object()
|
||||
: events_(std::make_shared<Events>())
|
||||
{}
|
||||
|
||||
~widget_object()
|
||||
{
|
||||
if(handle_)
|
||||
API::close_window(handle_);
|
||||
}
|
||||
|
||||
Events& events() const
|
||||
{
|
||||
return *events_;
|
||||
}
|
||||
|
||||
bool create(window parent_wd, bool visible) ///< Creates a no-size (zero-size) widget. in a widget/root window specified by parent_wd.
|
||||
{
|
||||
return create(parent_wd, rectangle(), visible);
|
||||
}
|
||||
|
||||
bool create(window parent_wd, const rectangle & r = rectangle(), bool visible = true) ///< in a widget/root window specified by parent_wd.
|
||||
{
|
||||
if(parent_wd && this->empty())
|
||||
{
|
||||
handle_ = API::dev::create_widget(parent_wd, r, this);
|
||||
API::dev::set_events(handle_, events_);
|
||||
API::dev::attach_signal(handle_, *this, &widget_object::signal);
|
||||
API::dev::attach_drawer(*this, trigger_);
|
||||
if(visible)
|
||||
API::show_window(handle_, true);
|
||||
|
||||
this->_m_complete_creation();
|
||||
}
|
||||
return (this->empty() == false);
|
||||
}
|
||||
|
||||
window handle() const override
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
widget_object& borderless(bool enable)
|
||||
{
|
||||
API::widget_borderless(handle_, enable);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool borderless() const
|
||||
{
|
||||
return API::widget_borderless(handle_);
|
||||
}
|
||||
protected:
|
||||
DrawerTrigger& get_drawer_trigger()
|
||||
{
|
||||
return trigger_;
|
||||
}
|
||||
|
||||
const DrawerTrigger& get_drawer_trigger() const
|
||||
{
|
||||
return trigger_;
|
||||
}
|
||||
private:
|
||||
void signal(detail::signals::code code, const detail::signals& sig)
|
||||
{
|
||||
typedef detail::signals::code codes;
|
||||
switch(code)
|
||||
{
|
||||
case codes::caption:
|
||||
this->_m_caption(sig.info.caption);
|
||||
break;
|
||||
case codes::read_caption:
|
||||
*sig.info.str = this->_m_caption();
|
||||
break;
|
||||
case codes::destroy:
|
||||
handle_ = nullptr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
general_events& _m_get_general_events() const
|
||||
{
|
||||
return *events_;
|
||||
}
|
||||
private:
|
||||
window handle_{nullptr};
|
||||
DrawerTrigger trigger_;
|
||||
std::shared_ptr<Events> events_;
|
||||
};//end class widget_object
|
||||
|
||||
/// Base class of all the classes defined as a non-graphics-buffer widget window. The second template parameter DrawerTrigger is always ignored.\see nana::panel
|
||||
template<typename DrawerTrigger, typename Events>
|
||||
class widget_object<category::lite_widget_tag, DrawerTrigger, Events>: public widget
|
||||
{
|
||||
protected:
|
||||
typedef DrawerTrigger drawer_trigger_t;
|
||||
public:
|
||||
|
||||
widget_object()
|
||||
: events_(std::make_shared<Events>())
|
||||
{}
|
||||
|
||||
~widget_object()
|
||||
{
|
||||
if(handle_)
|
||||
API::close_window(handle_);
|
||||
}
|
||||
|
||||
Events& events() const
|
||||
{
|
||||
return *events_;
|
||||
}
|
||||
|
||||
bool create(window parent_wd, bool visible) ///< Creates a no-size (zero-size) widget. in a widget/root window specified by parent_wd.
|
||||
{
|
||||
return create(parent_wd, rectangle(), visible);
|
||||
}
|
||||
|
||||
bool create(window parent_wd, const rectangle& r = rectangle(), bool visible = true) ///< in a widget/root window specified by parent_wd.
|
||||
{
|
||||
if(parent_wd && this->empty())
|
||||
{
|
||||
handle_ = API::dev::create_lite_widget(parent_wd, r, this);
|
||||
API::dev::set_events(handle_, events_);
|
||||
if(visible)
|
||||
API::show_window(handle_, true);
|
||||
this->_m_complete_creation();
|
||||
}
|
||||
return (this->empty() == false);
|
||||
}
|
||||
|
||||
window handle() const
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
private:
|
||||
void signal(detail::signals::code code, const detail::signals& sig)
|
||||
{
|
||||
typedef detail::signals::code codes;
|
||||
switch(code)
|
||||
{
|
||||
case codes::caption:
|
||||
this->_m_caption(sig.info.caption);
|
||||
break;
|
||||
case codes::read_caption:
|
||||
*sig.info.str = this->_m_caption();
|
||||
break;
|
||||
case codes::destroy:
|
||||
handle_ = nullptr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
general_events& _m_get_general_events() const
|
||||
{
|
||||
return *events_;
|
||||
}
|
||||
private:
|
||||
window handle_{nullptr};
|
||||
std::shared_ptr<Events> events_;
|
||||
};//end class widget_object
|
||||
|
||||
|
||||
/// Base class of all the classes defined as a root window. \see nana::form
|
||||
template<typename DrawerTrigger, typename Events>
|
||||
class widget_object<category::root_tag, DrawerTrigger, Events>: public widget
|
||||
{
|
||||
protected:
|
||||
typedef DrawerTrigger drawer_trigger_t;
|
||||
public:
|
||||
|
||||
widget_object()
|
||||
{
|
||||
handle_ = API::dev::create_window(nullptr, false, API::make_center(300, 150), appearance(), this);
|
||||
_m_bind_and_attach();
|
||||
}
|
||||
|
||||
widget_object(const rectangle& r, const appearance& apr = appearance())
|
||||
{
|
||||
handle_ = API::dev::create_window(nullptr, false, r, apr, this);
|
||||
_m_bind_and_attach();
|
||||
}
|
||||
|
||||
widget_object(window owner, bool nested, const rectangle& r = rectangle(), const appearance& apr = appearance())
|
||||
{
|
||||
handle_ = API::dev::create_window(owner, nested, r, apr, this);
|
||||
_m_bind_and_attach();
|
||||
}
|
||||
|
||||
~widget_object()
|
||||
{
|
||||
if(handle_)
|
||||
API::close_window(handle_);
|
||||
}
|
||||
|
||||
Events& events() const
|
||||
{
|
||||
return *events_;
|
||||
}
|
||||
|
||||
void activate()
|
||||
{
|
||||
API::activate_window(handle_);
|
||||
}
|
||||
|
||||
void bring_to_top()
|
||||
{
|
||||
API::bring_to_top(handle_);
|
||||
}
|
||||
|
||||
window handle() const
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
native_window_type native_handle() const
|
||||
{
|
||||
return API::root(handle_);
|
||||
}
|
||||
|
||||
window owner() const
|
||||
{
|
||||
return API::get_owner_window(handle_);
|
||||
}
|
||||
|
||||
void icon(const nana::paint::image& ico)
|
||||
{
|
||||
API::window_icon(handle_, ico);
|
||||
}
|
||||
|
||||
void restore()
|
||||
{
|
||||
API::restore_window(handle_);
|
||||
}
|
||||
|
||||
void zoom(bool ask_for_max)
|
||||
{
|
||||
API::zoom_window(handle_, ask_for_max);
|
||||
}
|
||||
|
||||
bool is_zoomed(bool ask_for_max) const
|
||||
{
|
||||
return API::is_window_zoomed(handle_, ask_for_max);
|
||||
}
|
||||
protected:
|
||||
DrawerTrigger& get_drawer_trigger()
|
||||
{
|
||||
return trigger_;
|
||||
}
|
||||
|
||||
const DrawerTrigger& get_drawer_trigger() const
|
||||
{
|
||||
return trigger_;
|
||||
}
|
||||
private:
|
||||
void signal(detail::signals::code code, const detail::signals& sig)
|
||||
{
|
||||
typedef detail::signals::code codes;
|
||||
switch(code)
|
||||
{
|
||||
case codes::caption:
|
||||
this->_m_caption(sig.info.caption);
|
||||
break;
|
||||
case codes::read_caption:
|
||||
*sig.info.str = this->_m_caption();
|
||||
break;
|
||||
case codes::destroy:
|
||||
handle_ = nullptr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _m_bind_and_attach()
|
||||
{
|
||||
events_ = std::make_shared<Events>();
|
||||
API::dev::set_events(handle_, events_);
|
||||
API::dev::attach_signal(handle_, *this, &widget_object::signal);
|
||||
API::dev::attach_drawer(*this, trigger_);
|
||||
}
|
||||
|
||||
general_events& _m_get_general_events() const
|
||||
{
|
||||
return *events_;
|
||||
}
|
||||
private:
|
||||
window handle_;
|
||||
DrawerTrigger trigger_;
|
||||
std::shared_ptr<Events> events_;
|
||||
};//end class widget_object<root_tag>
|
||||
|
||||
/// Base class of all the classes defined as a frame window. \see nana::frame
|
||||
template<typename Drawer, typename Events>
|
||||
class widget_object<category::frame_tag, Drawer, Events>: public widget{};
|
||||
|
||||
/// Especialization. Base class of all the classes defined as a frame window. \see nana::frame
|
||||
template<typename Events>
|
||||
class widget_object<category::frame_tag, int, Events>: public widget
|
||||
{
|
||||
protected:
|
||||
typedef int drawer_trigger_t;
|
||||
public:
|
||||
widget_object()
|
||||
: events_(std::make_shared<Events>())
|
||||
{}
|
||||
|
||||
~widget_object()
|
||||
{
|
||||
if(handle_)
|
||||
API::close_window(handle_);
|
||||
}
|
||||
|
||||
Events& events() const
|
||||
{
|
||||
return *events_;
|
||||
}
|
||||
|
||||
bool create(window parent_wd, bool visible) ///< Creates a no-size (zero-size) widget. in a widget/root window specified by parent_wd.
|
||||
{
|
||||
return create(parent_wd, rectangle(), visible);
|
||||
}
|
||||
/// Creates in a widget/root window specified by parent_wd.
|
||||
bool create(window parent_wd, const rectangle& r = rectangle(), bool visible = true)
|
||||
{
|
||||
if(parent_wd && this->empty())
|
||||
{
|
||||
handle_ = API::dev::create_frame(parent_wd, r, this);
|
||||
API::dev::set_events(handle_, events_);
|
||||
API::dev::attach_signal(handle_, *this, &widget_object::signal);
|
||||
API::show_window(handle_, visible);
|
||||
this->_m_complete_creation();
|
||||
}
|
||||
return (this->empty() == false);
|
||||
}
|
||||
|
||||
window handle() const
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
private:
|
||||
virtual drawer_trigger* get_drawer_trigger()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void signal(detail::signals::code code, const detail::signals& sig)
|
||||
{
|
||||
typedef detail::signals::code codes;
|
||||
switch(code)
|
||||
{
|
||||
case codes::caption:
|
||||
this->_m_caption(sig.info.caption);
|
||||
break;
|
||||
case codes::read_caption:
|
||||
*sig.info.str = this->_m_caption();
|
||||
break;
|
||||
case codes::destroy:
|
||||
handle_ = nullptr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
general_events& _m_get_general_events() const
|
||||
{
|
||||
return *events_;
|
||||
}
|
||||
private:
|
||||
window handle_{nullptr};
|
||||
std::shared_ptr<Events> events_;
|
||||
};//end class widget_object<category::frame_tag>
|
||||
}//end namespace nana
|
||||
#endif
|
||||
45
include/nana/gui/wvl.hpp
Normal file
45
include/nana/gui/wvl.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Nana GUI Library Definition
|
||||
* Copyright(C) 2003-2013 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/wvl.hpp
|
||||
* @description:
|
||||
* the header file contains the files required for running of Nana.GUI
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_WVL_HPP
|
||||
#define NANA_GUI_WVL_HPP
|
||||
|
||||
#include "programming_interface.hpp"
|
||||
#include "widgets/form.hpp"
|
||||
#include "drawing.hpp"
|
||||
#include "msgbox.hpp"
|
||||
#include "../exceptions.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
template<typename Form, bool IsMakeVisible = true>
|
||||
class form_loader
|
||||
{
|
||||
public:
|
||||
template<typename... Args>
|
||||
Form & operator()(Args &&... args) const
|
||||
{
|
||||
Form* res = detail::bedrock::instance().rt_manager.create_form<Form>(std::forward<Args>(args)...);
|
||||
if (nullptr == res)
|
||||
throw nana::bad_window("form_loader.operator(): failed to create a window");
|
||||
|
||||
if (IsMakeVisible) res->show();
|
||||
|
||||
return *res;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void exec();
|
||||
}//end namespace nana
|
||||
#endif
|
||||
211
include/nana/internationalization.hpp
Normal file
211
include/nana/internationalization.hpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* An Implementation of i18n
|
||||
* 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/internationalization.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_INTERNATIONALIZATION_HPP
|
||||
#define NANA_INTERNATIONALIZATION_HPP
|
||||
#include "basic_types.hpp"
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
class internationalization
|
||||
{
|
||||
friend class i18n_eval;
|
||||
public:
|
||||
void load(const std::string& file);
|
||||
void load_utf8(const std::string& file);
|
||||
|
||||
template<typename ...Args>
|
||||
nana::string get(std::string msgid_utf8, Args&&... args) const
|
||||
{
|
||||
std::vector<nana::string> arg_strs;
|
||||
_m_fetch_args(arg_strs, std::forward<Args>(args)...);
|
||||
|
||||
nana::string msgstr;
|
||||
if (_m_get(msgid_utf8, msgstr))
|
||||
_m_replace_args(msgstr, &arg_strs);
|
||||
return msgstr;
|
||||
}
|
||||
|
||||
nana::string get(std::string msgid_utf8) const;
|
||||
void set(std::string msgid_utf8, nana::string msgstr);
|
||||
|
||||
template<typename ...Args>
|
||||
nana::string operator()(std::string msgid_utf8, Args&&... args) const
|
||||
{
|
||||
return get(msgid_utf8, std::forward<Args>(args)...);
|
||||
}
|
||||
private:
|
||||
bool _m_get(std::string& msgid, nana::string& msgstr) const;
|
||||
void _m_replace_args(nana::string& str, std::vector<nana::string> * arg_strs) const;
|
||||
|
||||
void _m_fetch_args(std::vector<nana::string>&) const //Termination of _m_fetch_args
|
||||
{}
|
||||
|
||||
template<typename Arg>
|
||||
void _m_fetch_args(std::vector<nana::string>& v, Arg&& arg) const
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << arg;
|
||||
v.emplace_back(ss.str());
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
void _m_fetch_args(std::vector<nana::string>& v, const char* arg, Args&&... args) const
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << nana::string(nana::charset(arg));
|
||||
v.emplace_back(ss.str());
|
||||
|
||||
_m_fetch_args(v, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
void _m_fetch_args(std::vector<nana::string>& v, const std::string& arg, Args&&... args) const
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << nana::string(nana::charset(arg));
|
||||
v.emplace_back(ss.str());
|
||||
|
||||
_m_fetch_args(v, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
void _m_fetch_args(std::vector<nana::string>& v, std::string& arg, Args&&... args) const
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << nana::string(nana::charset(arg));
|
||||
v.emplace_back(ss.str());
|
||||
|
||||
_m_fetch_args(v, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
void _m_fetch_args(std::vector<nana::string>& v, std::string&& arg, Args&&... args) const
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << nana::string(nana::charset(arg));
|
||||
v.emplace_back(ss.str());
|
||||
|
||||
_m_fetch_args(v, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename Arg, typename ...Args>
|
||||
void _m_fetch_args(std::vector<nana::string>& v, Arg&& arg, Args&&... args) const
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << arg;
|
||||
v.emplace_back(ss.str());
|
||||
|
||||
_m_fetch_args(v, std::forward<Args>(args)...);
|
||||
}
|
||||
};//end class internationalization
|
||||
|
||||
class i18n_eval
|
||||
{
|
||||
class eval_arg
|
||||
{
|
||||
public:
|
||||
virtual ~eval_arg() = default;
|
||||
virtual nana::string eval() const = 0;
|
||||
virtual std::unique_ptr<eval_arg> clone() const = 0;
|
||||
};
|
||||
|
||||
class arg_string;
|
||||
class arg_eval;
|
||||
|
||||
template<typename Return>
|
||||
class arg_function
|
||||
{
|
||||
public:
|
||||
arg_function(std::function<Return()> fn)
|
||||
: fn_(fn)
|
||||
{}
|
||||
|
||||
nana::string eval() const override
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << fn_();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::unique_ptr<eval_arg> clone() const override
|
||||
{
|
||||
return std::unique_ptr<eval_arg>(new arg_function(*this));
|
||||
}
|
||||
private:
|
||||
std::function<Return()> fn_;
|
||||
};
|
||||
public:
|
||||
i18n_eval() = default;
|
||||
|
||||
template<typename ...Args>
|
||||
i18n_eval(std::string msgid_utf8, Args&&... args)
|
||||
: msgid_(std::move(msgid_utf8))
|
||||
{
|
||||
_m_fetch_args(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
i18n_eval(const i18n_eval&);
|
||||
|
||||
//Workaround for VC2013, becuase it can't specified a default explicit move-constructor
|
||||
i18n_eval(i18n_eval&&); //= default
|
||||
|
||||
i18n_eval& operator=(const i18n_eval&);
|
||||
i18n_eval& operator=(i18n_eval&& rhs);
|
||||
|
||||
nana::string operator()() const;
|
||||
private:
|
||||
void _m_fetch_args(){} //Termination of _m_fetch_args
|
||||
|
||||
template<typename Arg, typename ...Args>
|
||||
void _m_fetch_args(Arg&& arg, Args&&... args)
|
||||
{
|
||||
_m_add_args(std::forward<Arg>(arg));
|
||||
_m_fetch_args(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
void _m_add_args(Arg&& arg)
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << arg;
|
||||
_m_add_args(ss.str());
|
||||
}
|
||||
|
||||
template<typename Return>
|
||||
void _m_add_args(std::function<Return()> fn)
|
||||
{
|
||||
args_.emplace_back(new arg_function<Return>(fn));
|
||||
}
|
||||
|
||||
void _m_add_args(i18n_eval&);
|
||||
void _m_add_args(const i18n_eval&);
|
||||
void _m_add_args(i18n_eval&&);
|
||||
|
||||
void _m_add_args(std::string&);
|
||||
void _m_add_args(const std::string&);
|
||||
void _m_add_args(std::string&&);
|
||||
|
||||
void _m_add_args(std::wstring&);
|
||||
void _m_add_args(const std::wstring&);
|
||||
void _m_add_args(std::wstring&&);
|
||||
private:
|
||||
std::string msgid_;
|
||||
std::vector<std::unique_ptr<eval_arg>> args_;
|
||||
};//end class i18n_eval;
|
||||
}
|
||||
|
||||
#endif//NANA_I18N_HPP
|
||||
123
include/nana/key_type.hpp
Normal file
123
include/nana/key_type.hpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* A Key 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/key_type.hpp
|
||||
*/
|
||||
#ifndef NANA_KEY_TYPE_HPP
|
||||
#define NANA_KEY_TYPE_HPP
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class key_interface
|
||||
{
|
||||
public:
|
||||
virtual ~key_interface(){}
|
||||
|
||||
virtual bool same_type(const key_interface*) const = 0;
|
||||
virtual bool compare(const key_interface*) const = 0;
|
||||
}; //end class key_interface
|
||||
|
||||
//Use less compare for equal compare
|
||||
inline bool pred_equal_by_less(const key_interface * left, const key_interface* right)
|
||||
{
|
||||
return (left->compare(right) == false) && (right->compare(left) == false);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct type_escape
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct type_escape<char*>
|
||||
{
|
||||
typedef std::string type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct type_escape<const char*>
|
||||
{
|
||||
typedef std::string type;
|
||||
};
|
||||
|
||||
template<int Size>
|
||||
struct type_escape<char[Size]>
|
||||
{
|
||||
typedef std::string type;
|
||||
};
|
||||
|
||||
template<int Size>
|
||||
struct type_escape<const char[Size]>
|
||||
{
|
||||
typedef std::string type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct type_escape<wchar_t*>
|
||||
{
|
||||
typedef std::wstring type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct type_escape<const wchar_t*>
|
||||
{
|
||||
typedef std::wstring type;
|
||||
};
|
||||
|
||||
template<int Size>
|
||||
struct type_escape<wchar_t[Size]>
|
||||
{
|
||||
typedef std::wstring type;
|
||||
};
|
||||
|
||||
template<int Size>
|
||||
struct type_escape<const wchar_t[Size]>
|
||||
{
|
||||
typedef std::wstring type;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T, typename Compare>
|
||||
class key
|
||||
: public detail::key_interface
|
||||
{
|
||||
public:
|
||||
typedef detail::key_interface key_interface;
|
||||
typedef T key_type;
|
||||
|
||||
key(const key_type& k)
|
||||
: key_object_(k)
|
||||
{}
|
||||
|
||||
key(key_type&& k)
|
||||
: key_object_(std::move(k))
|
||||
{
|
||||
}
|
||||
public:
|
||||
//implement key_interface methods
|
||||
bool same_type(const key_interface * p) const override
|
||||
{
|
||||
return (nullptr != dynamic_cast<const key*>(p));
|
||||
}
|
||||
|
||||
bool compare(const key_interface* p) const override
|
||||
{
|
||||
auto rhs = dynamic_cast<const key*>(p);
|
||||
return rhs && compare_(key_object_, rhs->key_object_);
|
||||
}
|
||||
private:
|
||||
Compare compare_;
|
||||
key_type key_object_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
359
include/nana/paint/detail/image_bmp.hpp
Normal file
359
include/nana/paint/detail/image_bmp.hpp
Normal file
@@ -0,0 +1,359 @@
|
||||
#ifndef NANA_PAINT_DETAIL_IMAGE_BMP_HPP
|
||||
#define NANA_PAINT_DETAIL_IMAGE_BMP_HPP
|
||||
|
||||
#include "image_impl_interface.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace nana{ namespace paint
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#ifndef NANA_WINDOWS
|
||||
struct bitmap_file_header
|
||||
{
|
||||
unsigned short bfType;
|
||||
unsigned long bfSize;
|
||||
unsigned short bfReserved1;
|
||||
unsigned short bfReserved2;
|
||||
unsigned long bfOffBits;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct bitmap_info_header {
|
||||
unsigned long biSize;
|
||||
long biWidth;
|
||||
long biHeight;
|
||||
unsigned short biPlanes;
|
||||
unsigned short biBitCount;
|
||||
unsigned long biCompression;
|
||||
unsigned long biSizeImage;
|
||||
long biXPelsPerMeter;
|
||||
long biYPelsPerMeter;
|
||||
unsigned long biClrUsed;
|
||||
unsigned long biClrImportant;
|
||||
}__attribute__((packed));
|
||||
|
||||
struct rgb_quad
|
||||
{
|
||||
unsigned char rgbBlue;
|
||||
unsigned char rgbGreen;
|
||||
unsigned char rgbRed;
|
||||
unsigned char rgbReserved;
|
||||
};
|
||||
|
||||
struct bitmap_info
|
||||
{
|
||||
bitmap_info_header bmiHeader;
|
||||
rgb_quad bmiColors[1];
|
||||
}__attribute__((packed));
|
||||
#else
|
||||
typedef BITMAPFILEHEADER bitmap_file_header;
|
||||
typedef BITMAPINFO bitmap_info;
|
||||
typedef RGBQUAD rgb_quad;
|
||||
#endif
|
||||
|
||||
class image_bmp
|
||||
:public image::image_impl_interface
|
||||
{
|
||||
public:
|
||||
image_bmp(){}
|
||||
|
||||
~image_bmp()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
||||
bool open(const nana::char_t* filename)
|
||||
{
|
||||
if(nullptr == filename) return false;
|
||||
std::ifstream ifs;
|
||||
#if defined(NANA_UNICODE)
|
||||
ifs.open(static_cast<std::string>(nana::charset(filename)).c_str(), std::ios::binary);
|
||||
#else
|
||||
ifs.open(filename, std::ios::binary);
|
||||
#endif
|
||||
if(ifs)
|
||||
{
|
||||
ifs.seekg(0, std::ios::end);
|
||||
auto size = ifs.tellg();
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
|
||||
if(size <= static_cast<int>(sizeof(bitmap_file_header)))
|
||||
return false;
|
||||
|
||||
std::unique_ptr<char[]> buffer(new char[static_cast<int>(size)]);
|
||||
|
||||
ifs.read(buffer.get(), size);
|
||||
if(size == ifs.gcount())
|
||||
{
|
||||
bitmap_file_header * header = reinterpret_cast<bitmap_file_header*>(buffer.get());
|
||||
if((header->bfType == 0x4D42) && (static_cast<std::streamsize>(header->bfSize) == size))
|
||||
{
|
||||
unsigned char* bits = reinterpret_cast<unsigned char*>(buffer.get() + header->bfOffBits);
|
||||
bitmap_info * info = reinterpret_cast<bitmap_info *>(header + 1);
|
||||
|
||||
//Bitmap file is 4byte-aligned for each line.
|
||||
std::size_t bytes_per_line;
|
||||
const std::size_t height_pixels = abs(info->bmiHeader.biHeight);
|
||||
if(0 == info->bmiHeader.biSizeImage)
|
||||
bytes_per_line = (((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) & ~31) >> 3);
|
||||
else
|
||||
bytes_per_line = info->bmiHeader.biSizeImage / height_pixels;
|
||||
|
||||
pixbuf_.open(info->bmiHeader.biWidth, height_pixels);
|
||||
|
||||
pixel_rgb_t * d = pixbuf_.raw_ptr(0);
|
||||
|
||||
if(16 <= info->bmiHeader.biBitCount)
|
||||
{
|
||||
pixbuf_.put(bits, info->bmiHeader.biWidth, height_pixels, info->bmiHeader.biBitCount, bytes_per_line, (info->bmiHeader.biHeight < 0));
|
||||
}
|
||||
else if(8 == info->bmiHeader.biBitCount)
|
||||
{
|
||||
const pixel_rgb_t * const lend = d + info->bmiHeader.biWidth * height_pixels;
|
||||
|
||||
if(info->bmiHeader.biHeight < 0)
|
||||
{
|
||||
const unsigned char* s = bits;
|
||||
while(d < lend)
|
||||
{
|
||||
pixel_rgb_t * d_p = d;
|
||||
pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth;
|
||||
const unsigned char * s_p = s;
|
||||
while(d_p != dpend)
|
||||
{
|
||||
rgb_quad & rgb = info->bmiColors[*s_p++];
|
||||
d_p->u.element.red = rgb.rgbRed;
|
||||
d_p->u.element.green = rgb.rgbGreen;
|
||||
d_p->u.element.blue = rgb.rgbBlue;
|
||||
d_p->u.element.alpha_channel = rgb.rgbReserved;
|
||||
++d_p;
|
||||
}
|
||||
d = dpend;
|
||||
s += bytes_per_line;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned char* s = bits + bytes_per_line * (height_pixels - 1);
|
||||
while(d < lend)
|
||||
{
|
||||
pixel_rgb_t * d_p = d;
|
||||
pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth;
|
||||
const unsigned char * s_p = s;
|
||||
while(d_p != dpend)
|
||||
{
|
||||
rgb_quad & rgb = info->bmiColors[*s_p++];
|
||||
d_p->u.element.red = rgb.rgbRed;
|
||||
d_p->u.element.green = rgb.rgbGreen;
|
||||
d_p->u.element.blue = rgb.rgbBlue;
|
||||
d_p->u.element.alpha_channel = rgb.rgbReserved;
|
||||
++d_p;
|
||||
}
|
||||
d = dpend;
|
||||
s -= bytes_per_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(4 == info->bmiHeader.biBitCount)
|
||||
{
|
||||
const pixel_rgb_t * const lend = d + info->bmiHeader.biWidth * height_pixels;
|
||||
if(info->bmiHeader.biHeight < 0)
|
||||
{
|
||||
const unsigned char* s = bits;
|
||||
while(d < lend)
|
||||
{
|
||||
pixel_rgb_t * d_p = d;
|
||||
pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth;
|
||||
unsigned index = 0;
|
||||
while(d_p != dpend)
|
||||
{
|
||||
rgb_quad & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4];
|
||||
|
||||
d_p->u.element.red = rgb.rgbRed;
|
||||
d_p->u.element.green = rgb.rgbGreen;
|
||||
d_p->u.element.blue = rgb.rgbBlue;
|
||||
d_p->u.element.alpha_channel = rgb.rgbReserved;
|
||||
++d_p;
|
||||
++index;
|
||||
}
|
||||
d = dpend;
|
||||
s += bytes_per_line;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned char* s = bits + bytes_per_line * (height_pixels - 1);
|
||||
while(d < lend)
|
||||
{
|
||||
pixel_rgb_t * d_p = d;
|
||||
pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth;
|
||||
|
||||
unsigned index = 0;
|
||||
while(d_p != dpend)
|
||||
{
|
||||
rgb_quad & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4];
|
||||
|
||||
d_p->u.element.red = rgb.rgbRed;
|
||||
d_p->u.element.green = rgb.rgbGreen;
|
||||
d_p->u.element.blue = rgb.rgbBlue;
|
||||
d_p->u.element.alpha_channel = rgb.rgbReserved;
|
||||
++d_p;
|
||||
++index;
|
||||
}
|
||||
d = dpend;
|
||||
s -= bytes_per_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(2 == info->bmiHeader.biBitCount)
|
||||
{
|
||||
const pixel_rgb_t * const lend = d + info->bmiHeader.biWidth * height_pixels;
|
||||
if(info->bmiHeader.biHeight < 0)
|
||||
{
|
||||
const unsigned char* s = bits;
|
||||
while(d < lend)
|
||||
{
|
||||
pixel_rgb_t * d_p = d;
|
||||
pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth;
|
||||
unsigned index = 0;
|
||||
while(d_p != dpend)
|
||||
{
|
||||
unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2
|
||||
rgb_quad& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift))>>shift];
|
||||
|
||||
d_p->u.element.red = rgb.rgbRed;
|
||||
d_p->u.element.green = rgb.rgbGreen;
|
||||
d_p->u.element.blue = rgb.rgbBlue;
|
||||
d_p->u.element.alpha_channel = rgb.rgbReserved;
|
||||
++d_p;
|
||||
++index;
|
||||
}
|
||||
d = dpend;
|
||||
s += bytes_per_line;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned char* s = bits + bytes_per_line * (height_pixels - 1);
|
||||
while(d < lend)
|
||||
{
|
||||
pixel_rgb_t * d_p = d;
|
||||
pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth;
|
||||
|
||||
unsigned index = 0;
|
||||
while(d_p != dpend)
|
||||
{
|
||||
unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2
|
||||
rgb_quad& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift))>>shift];
|
||||
|
||||
d_p->u.element.red = rgb.rgbRed;
|
||||
d_p->u.element.green = rgb.rgbGreen;
|
||||
d_p->u.element.blue = rgb.rgbBlue;
|
||||
d_p->u.element.alpha_channel = rgb.rgbReserved;
|
||||
++d_p;
|
||||
++index;
|
||||
}
|
||||
d = dpend;
|
||||
s -= bytes_per_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(1 == info->bmiHeader.biBitCount)
|
||||
{
|
||||
const pixel_rgb_t * const lend = d + info->bmiHeader.biWidth * height_pixels;
|
||||
if(info->bmiHeader.biHeight < 0)
|
||||
{
|
||||
const unsigned char* s = bits;
|
||||
while(d < lend)
|
||||
{
|
||||
pixel_rgb_t * d_p = d;
|
||||
pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth;
|
||||
unsigned index = 0;
|
||||
while(d_p != dpend)
|
||||
{
|
||||
unsigned bi = (7 - (index & 7)); //(index % 8)
|
||||
rgb_quad & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi];
|
||||
|
||||
d_p->u.element.red = rgb.rgbRed;
|
||||
d_p->u.element.green = rgb.rgbGreen;
|
||||
d_p->u.element.blue = rgb.rgbBlue;
|
||||
d_p->u.element.alpha_channel = rgb.rgbReserved;
|
||||
++d_p;
|
||||
++index;
|
||||
}
|
||||
d = dpend;
|
||||
s += bytes_per_line;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned char* s = bits + bytes_per_line * (height_pixels - 1);
|
||||
while(d < lend)
|
||||
{
|
||||
pixel_rgb_t * d_p = d;
|
||||
pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth;
|
||||
|
||||
unsigned index = 0;
|
||||
while(d_p != dpend)
|
||||
{
|
||||
unsigned bi = (7 - (index & 7));
|
||||
rgb_quad & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi];
|
||||
|
||||
d_p->u.element.red = rgb.rgbRed;
|
||||
d_p->u.element.green = rgb.rgbGreen;
|
||||
d_p->u.element.blue = rgb.rgbBlue;
|
||||
d_p->u.element.alpha_channel = rgb.rgbReserved;
|
||||
++d_p;
|
||||
++index;
|
||||
}
|
||||
d = dpend;
|
||||
s -= bytes_per_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (false == pixbuf_.empty());
|
||||
}
|
||||
|
||||
bool alpha_channel() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return pixbuf_.empty();
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
pixbuf_.close();
|
||||
}
|
||||
|
||||
nana::size size() const
|
||||
{
|
||||
return pixbuf_.size();
|
||||
}
|
||||
|
||||
void paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const
|
||||
{
|
||||
if(graph && pixbuf_)
|
||||
pixbuf_.paste(src_r, graph.handle(), x, y);
|
||||
}
|
||||
|
||||
void stretch(const nana::rectangle& src_r, graph_reference graph, const nana::rectangle& r) const
|
||||
{
|
||||
if(graph && pixbuf_)
|
||||
pixbuf_.stretch(src_r, graph.handle(), r);
|
||||
}
|
||||
private:
|
||||
nana::paint::pixel_buffer pixbuf_;
|
||||
};//end class bmpfile
|
||||
}//end namespace detail
|
||||
}//end namespace paint
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
43
include/nana/paint/detail/image_ico.hpp
Normal file
43
include/nana/paint/detail/image_ico.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef NANA_PAINT_DETAIL_IMAGE_ICO_HPP
|
||||
#define NANA_PAINT_DETAIL_IMAGE_ICO_HPP
|
||||
|
||||
#include "image_impl_interface.hpp"
|
||||
|
||||
namespace nana{ namespace paint
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class image_ico
|
||||
:public image::image_impl_interface
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
struct handle_deleter
|
||||
{
|
||||
void operator()(HICON* handle) const;
|
||||
};//end struct handle_deleter
|
||||
typedef std::shared_ptr<HICON> ptr_t;
|
||||
#else
|
||||
typedef std::shared_ptr<int*> ptr_t;
|
||||
#endif
|
||||
public:
|
||||
image_ico(bool is_ico);
|
||||
|
||||
bool open(const nana::char_t* filename);
|
||||
bool alpha_channel() const;
|
||||
bool empty() const;
|
||||
void close();
|
||||
nana::size size() const;
|
||||
virtual void paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const;
|
||||
virtual void stretch(const nana::rectangle&, graph_reference graph, const nana::rectangle& r) const;
|
||||
|
||||
const ptr_t & ptr() const;
|
||||
private:
|
||||
const bool is_ico_;
|
||||
nana::size size_;
|
||||
ptr_t ptr_;
|
||||
};//end class image_ico
|
||||
}
|
||||
}//end namespace paint
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
29
include/nana/paint/detail/image_impl_interface.hpp
Normal file
29
include/nana/paint/detail/image_impl_interface.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef NANA_PAINT_DETAIL_IMAGE_IMPL_INTERFACE_HPP
|
||||
#define NANA_PAINT_DETAIL_IMAGE_IMPL_INTERFACE_HPP
|
||||
|
||||
#include "../image.hpp"
|
||||
|
||||
namespace nana{ namespace paint{
|
||||
|
||||
// class image::image_impl_interface
|
||||
// the nana::image refers to an object of image::image_impl_interface by nana::refer. Employing nana::refer to refer the image::implement_t object indirectly is used
|
||||
// for saving the memory that sharing the same image resource with many nana::image objects.
|
||||
class image::image_impl_interface
|
||||
: private nana::noncopyable
|
||||
{
|
||||
image_impl_interface& operator=(const image_impl_interface& rhs);
|
||||
public:
|
||||
typedef nana::paint::graphics& graph_reference;
|
||||
virtual ~image_impl_interface() = 0; //The destructor is defined in ../image.cpp
|
||||
virtual bool open(const nana::char_t* filename) = 0;
|
||||
virtual bool alpha_channel() const = 0;
|
||||
virtual bool empty() const = 0;
|
||||
virtual void close() = 0;
|
||||
virtual nana::size size() const = 0;
|
||||
virtual void paste(const nana::rectangle& src_r, graph_reference dst, int x, int y) const = 0;
|
||||
virtual void stretch(const nana::rectangle& src_r, graph_reference dst, const nana::rectangle& r) const = 0;
|
||||
};//end class image::image_impl_interface
|
||||
}//end namespace paint
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
188
include/nana/paint/detail/image_png.hpp
Normal file
188
include/nana/paint/detail/image_png.hpp
Normal file
@@ -0,0 +1,188 @@
|
||||
#ifndef NANA_PAINT_DETAIL_IMAGE_PNG_HPP
|
||||
#define NANA_PAINT_DETAIL_IMAGE_PNG_HPP
|
||||
|
||||
#include "image_impl_interface.hpp"
|
||||
|
||||
//Separate the libpng from the package that system provides.
|
||||
#if defined(NANA_LIBPNG)
|
||||
#include <nana/extrlib/png.h>
|
||||
#else
|
||||
#include <png.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../pixel_buffer.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint{ namespace detail{
|
||||
|
||||
class image_png
|
||||
: public image::image_impl_interface
|
||||
{
|
||||
public:
|
||||
image_png()
|
||||
{
|
||||
}
|
||||
|
||||
bool open(const nana::char_t* png_file)
|
||||
{
|
||||
#ifdef NANA_UNICODE
|
||||
FILE * fp = ::fopen(static_cast<std::string>(nana::charset(png_file)).c_str(), "rb");
|
||||
#else
|
||||
FILE* fp = ::fopen(png_file, "rb");
|
||||
#endif
|
||||
if(nullptr == fp) return false;
|
||||
|
||||
bool is_opened = false;
|
||||
|
||||
png_byte png_sig[8];
|
||||
::fread(png_sig, 1, 8, fp);
|
||||
|
||||
//Test whether the file is a png.
|
||||
if(0 == png_sig_cmp(png_sig, 0, 8))
|
||||
{
|
||||
png_structp png_ptr = ::png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
|
||||
if(png_ptr)
|
||||
{
|
||||
png_infop info_ptr = ::png_create_info_struct(png_ptr);
|
||||
|
||||
if(info_ptr)
|
||||
{
|
||||
if(!setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
//The following codes may longjmp while init_io error.
|
||||
::png_init_io(png_ptr, fp);
|
||||
::png_set_sig_bytes(png_ptr, 8);
|
||||
::png_read_info(png_ptr, info_ptr);
|
||||
|
||||
const int png_width = ::png_get_image_width(png_ptr, info_ptr);
|
||||
const int png_height = ::png_get_image_height(png_ptr, info_ptr);
|
||||
png_byte color_type = ::png_get_color_type(png_ptr, info_ptr);
|
||||
|
||||
::png_set_interlace_handling(png_ptr);
|
||||
::png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
//The following codes may longjmp while image_read error.
|
||||
png_bytep * row_ptrs = new png_bytep[png_height];
|
||||
const std::size_t png_rowbytes = ::png_get_rowbytes(png_ptr, info_ptr);
|
||||
|
||||
pixbuf_.open(png_width, png_height);
|
||||
|
||||
const bool is_alpha_enabled = ((PNG_COLOR_MASK_ALPHA & color_type) != 0);
|
||||
pixbuf_.alpha_channel(is_alpha_enabled);
|
||||
|
||||
if(is_alpha_enabled && (png_rowbytes == png_width * sizeof(pixel_rgb_t)))
|
||||
{
|
||||
for(int i = 0; i < png_height; ++i)
|
||||
row_ptrs[i] = reinterpret_cast<png_bytep>(pixbuf_.raw_ptr(i));
|
||||
|
||||
::png_read_image(png_ptr, row_ptrs);
|
||||
::png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
|
||||
|
||||
for (int i = 0; i < png_height; ++i)
|
||||
{
|
||||
auto p = pixbuf_.raw_ptr(i);
|
||||
for (int u = 0; u < png_width; ++u)
|
||||
{
|
||||
auto t = p[u].u.element.red;
|
||||
p[u].u.element.red = p[u].u.element.blue;
|
||||
p[u].u.element.blue = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
png_byte * png_pixbuf = new png_byte[png_height * png_rowbytes];
|
||||
|
||||
for(int i = 0; i < png_height; ++i)
|
||||
row_ptrs[i] = reinterpret_cast<png_bytep>(png_pixbuf + png_rowbytes * i);
|
||||
|
||||
::png_read_image(png_ptr, row_ptrs);
|
||||
::png_destroy_read_struct(&png_ptr, &info_ptr, 0);
|
||||
|
||||
std::size_t png_pixel_bytes = png_rowbytes / png_width;
|
||||
|
||||
pixel_rgb_t * rgb_row_ptr = pixbuf_.raw_ptr(0);
|
||||
for(int y = 0; y < png_height; ++y)
|
||||
{
|
||||
png_bytep png_ptr = row_ptrs[y];
|
||||
|
||||
pixel_rgb_t * rgb_end = rgb_row_ptr + png_width;
|
||||
|
||||
if(is_alpha_enabled)
|
||||
{
|
||||
for(pixel_rgb_t * i = rgb_row_ptr; i < rgb_end; ++i)
|
||||
{
|
||||
i->u.element.red = png_ptr[0];
|
||||
i->u.element.green = png_ptr[1];
|
||||
i->u.element.blue = png_ptr[2];
|
||||
i->u.element.alpha_channel = png_ptr[3];
|
||||
png_ptr += png_pixel_bytes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(pixel_rgb_t * i = rgb_row_ptr; i < rgb_end; ++i)
|
||||
{
|
||||
i->u.element.red = png_ptr[0];
|
||||
i->u.element.green = png_ptr[1];
|
||||
i->u.element.blue = png_ptr[2];
|
||||
i->u.element.alpha_channel = 255;
|
||||
png_ptr += png_pixel_bytes;
|
||||
}
|
||||
}
|
||||
rgb_row_ptr = rgb_end;
|
||||
}
|
||||
|
||||
delete [] png_pixbuf;
|
||||
}
|
||||
delete [] row_ptrs;
|
||||
is_opened = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::fclose(fp);
|
||||
return is_opened;
|
||||
}
|
||||
|
||||
bool alpha_channel() const
|
||||
{
|
||||
return pixbuf_.alpha_channel();
|
||||
}
|
||||
|
||||
virtual bool empty() const
|
||||
{
|
||||
return pixbuf_.empty();
|
||||
}
|
||||
|
||||
virtual void close()
|
||||
{
|
||||
pixbuf_.close();
|
||||
}
|
||||
|
||||
virtual nana::size size() const
|
||||
{
|
||||
return pixbuf_.size();
|
||||
}
|
||||
|
||||
void paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const
|
||||
{
|
||||
pixbuf_.paste(src_r, graph.handle(), x, y);
|
||||
}
|
||||
|
||||
void stretch(const nana::rectangle& src_r, graph_reference dst, const nana::rectangle& r) const
|
||||
{
|
||||
pixbuf_.stretch(src_r, dst.handle(), r);
|
||||
}
|
||||
private:
|
||||
nana::paint::pixel_buffer pixbuf_;
|
||||
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace paint
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
127
include/nana/paint/detail/image_process_provider.hpp
Normal file
127
include/nana/paint/detail/image_process_provider.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#ifndef NANA_PAINT_IMAGE_PROCESS_PROVIDER_HPP
|
||||
#define NANA_PAINT_IMAGE_PROCESS_PROVIDER_HPP
|
||||
#include <nana/pat/cloneable.hpp>
|
||||
#include <nana/paint/image_process_interface.hpp>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class image_process_provider
|
||||
: nana::noncopyable
|
||||
{
|
||||
image_process_provider();
|
||||
|
||||
struct stretch_tag
|
||||
{
|
||||
typedef paint::image_process::stretch_interface interface_t;
|
||||
typedef pat::mutable_cloneable<interface_t> cloneable_t;
|
||||
typedef std::map<std::string, cloneable_t> table_t;
|
||||
|
||||
table_t table;
|
||||
interface_t* employee;
|
||||
}stretch_;
|
||||
|
||||
struct alpha_blend_tag
|
||||
{
|
||||
typedef paint::image_process::alpha_blend_interface interface_t;
|
||||
typedef pat::mutable_cloneable<interface_t> cloneable_t;
|
||||
typedef std::map<std::string, cloneable_t> table_t;
|
||||
|
||||
table_t table;
|
||||
interface_t * employee;
|
||||
}alpha_blend_;
|
||||
|
||||
struct blend_tag
|
||||
{
|
||||
typedef paint::image_process::blend_interface interface_t;
|
||||
typedef pat::mutable_cloneable<interface_t> cloneable_t;
|
||||
typedef std::map<std::string, cloneable_t> table_t;
|
||||
|
||||
table_t table;
|
||||
interface_t * employee;
|
||||
}blend_;
|
||||
|
||||
struct line_tag
|
||||
{
|
||||
typedef paint::image_process::line_interface interface_t;
|
||||
typedef pat::mutable_cloneable<interface_t> cloneable_t;
|
||||
typedef std::map<std::string, cloneable_t> table_t;
|
||||
|
||||
table_t table;
|
||||
interface_t * employee;
|
||||
}line_;
|
||||
|
||||
struct blur_tag
|
||||
{
|
||||
typedef paint::image_process::blur_interface interface_t;
|
||||
typedef pat::mutable_cloneable<interface_t> cloneable_t;
|
||||
typedef std::map<std::string, cloneable_t> table_t;
|
||||
|
||||
table_t table;
|
||||
interface_t * employee;
|
||||
}blur_;
|
||||
public:
|
||||
|
||||
static image_process_provider & instance();
|
||||
|
||||
stretch_tag & ref_stretch_tag();
|
||||
paint::image_process::stretch_interface * const * stretch() const;
|
||||
paint::image_process::stretch_interface * ref_stretch(const std::string& name) const;
|
||||
|
||||
alpha_blend_tag & ref_alpha_blend_tag();
|
||||
paint::image_process::alpha_blend_interface * const * alpha_blend() const;
|
||||
paint::image_process::alpha_blend_interface * ref_alpha_blend(const std::string& name) const;
|
||||
|
||||
blend_tag & ref_blend_tag();
|
||||
paint::image_process::blend_interface * const * blend() const;
|
||||
paint::image_process::blend_interface * ref_blend(const std::string& name) const;
|
||||
|
||||
line_tag & ref_line_tag();
|
||||
paint::image_process::line_interface * const * line() const;
|
||||
paint::image_process::line_interface * ref_line(const std::string& name) const;
|
||||
|
||||
blur_tag & ref_blur_tag();
|
||||
paint::image_process::blur_interface * const * blur() const;
|
||||
paint::image_process::blur_interface * ref_blur(const std::string& name) const;
|
||||
public:
|
||||
template<typename Tag>
|
||||
void set(Tag & tag, const std::string& name)
|
||||
{
|
||||
auto i = tag.table.find(name);
|
||||
if(i != tag.table.end())
|
||||
tag.employee = &(*(i->second));
|
||||
}
|
||||
|
||||
//add
|
||||
//@brief: The add operation is successful if the name does not exist.
|
||||
// it does not replace the existing object by new object, becuase this
|
||||
// feature is thread safe and efficiency.
|
||||
template<typename ImageProcessor, typename Tag>
|
||||
void add(Tag & tag, const std::string& name)
|
||||
{
|
||||
if(tag.table.count(name) == 0)
|
||||
{
|
||||
typedef typename Tag::cloneable_t cloneable_t;
|
||||
auto & obj = tag.table[name];
|
||||
obj = cloneable_t(ImageProcessor());
|
||||
if(nullptr == tag.employee)
|
||||
tag.employee = &(*obj);
|
||||
}
|
||||
}
|
||||
private:
|
||||
template<typename Tag>
|
||||
typename Tag::interface_t* _m_read(const Tag& tag, const std::string& name) const
|
||||
{
|
||||
auto i = tag.table.find(name);
|
||||
return (i != tag.table.end() ? &(*i->second) : tag.employee);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}//end namespace nana
|
||||
#endif
|
||||
676
include/nana/paint/detail/image_processor.hpp
Normal file
676
include/nana/paint/detail/image_processor.hpp
Normal file
@@ -0,0 +1,676 @@
|
||||
/*
|
||||
* Image Processor Algorithm 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/paint/detail/image_processor.hpp
|
||||
* @brief: This header file implements the algorithms of image processor
|
||||
*
|
||||
* DON'T INCLUDE THIS HEADER FILE DIRECTLY TO YOUR SOURCE FILE.
|
||||
*/
|
||||
|
||||
#ifndef NANA_PAINT_DETAIL_IMAGE_PROCESSOR_HPP
|
||||
#define NANA_PAINT_DETAIL_IMAGE_PROCESSOR_HPP
|
||||
#include "../image_process_interface.hpp"
|
||||
#include <nana/paint/pixel_buffer.hpp>
|
||||
#include <nana/paint/detail/native_paint_interface.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace algorithms
|
||||
{
|
||||
class proximal_interoplation
|
||||
: public image_process::stretch_interface
|
||||
{
|
||||
void process(const paint::pixel_buffer& s_pixbuf, const nana::rectangle& r_src, paint::pixel_buffer & pixbuf, const nana::rectangle& r_dst) const
|
||||
{
|
||||
const auto bytes_per_line = s_pixbuf.bytes_per_line();
|
||||
|
||||
double rate_x = double(r_src.width) / r_dst.width;
|
||||
double rate_y = double(r_src.height) / r_dst.height;
|
||||
|
||||
pixel_rgb_t * s_raw_pixbuf = s_pixbuf.raw_ptr(0);
|
||||
|
||||
if(s_pixbuf.alpha_channel())
|
||||
{
|
||||
for(std::size_t row = 0; row < r_dst.height; ++row)
|
||||
{
|
||||
const pixel_rgb_t * s_line = pixel_at(s_raw_pixbuf, (static_cast<int>(row * rate_y) + r_src.y) * bytes_per_line);
|
||||
pixel_rgb_t * i = pixbuf.raw_ptr(r_dst.y + row);
|
||||
|
||||
for(std::size_t x = 0; x < r_dst.width; ++x, ++i)
|
||||
{
|
||||
const pixel_rgb_t * s = s_line + static_cast<int>(x * rate_x) + r_src.x;
|
||||
if(0 == s->u.element.alpha_channel)
|
||||
continue;
|
||||
|
||||
if(s->u.element.alpha_channel != 255)
|
||||
{
|
||||
i->u.element.red = unsigned(i->u.element.red * (255 - s->u.element.alpha_channel) + s->u.element.red * s->u.element.alpha_channel) / 255;
|
||||
i->u.element.green = unsigned(i->u.element.green * (255 - s->u.element.alpha_channel) + s->u.element.green * s->u.element.alpha_channel) / 255;
|
||||
i->u.element.blue = unsigned(i->u.element.blue * (255 - s->u.element.alpha_channel) + s->u.element.blue * s->u.element.alpha_channel) / 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned alpha_chn = i->u.element.alpha_channel;
|
||||
*i = *s;
|
||||
i->u.element.alpha_channel = alpha_chn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(std::size_t row = 0; row < r_dst.height; ++row)
|
||||
{
|
||||
const pixel_rgb_t * s_line = pixel_at(s_raw_pixbuf, (static_cast<int>(row * rate_y) + r_src.y) * bytes_per_line);
|
||||
pixel_rgb_t * i = pixbuf.raw_ptr(r_dst.y + row);
|
||||
|
||||
for(std::size_t x = 0; x < r_dst.width; ++x, ++i)
|
||||
*i = s_line[static_cast<int>(x * rate_x) + r_src.x];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class bilinear_interoplation
|
||||
: public image_process::stretch_interface
|
||||
{
|
||||
struct x_u_table_tag
|
||||
{
|
||||
int x;
|
||||
int iu;
|
||||
int iu_minus_coef;
|
||||
};
|
||||
|
||||
void process(const paint::pixel_buffer & s_pixbuf, const nana::rectangle& r_src, paint::pixel_buffer & pixbuf, const nana::rectangle& r_dst) const
|
||||
{
|
||||
const auto s_bytes_per_line = s_pixbuf.bytes_per_line();
|
||||
|
||||
const int shift_size = 8;
|
||||
const std::size_t coef = 1 << shift_size;
|
||||
const int double_shift_size = shift_size << 1;
|
||||
|
||||
double rate_x = double(r_src.width) / r_dst.width;
|
||||
double rate_y = double(r_src.height) / r_dst.height;
|
||||
|
||||
const int right_bound = static_cast<int>(r_src.width) - 1 + r_src.x;
|
||||
|
||||
const nana::pixel_rgb_t * s_raw_pixel_buffer = s_pixbuf.raw_ptr(0);
|
||||
|
||||
const int bottom = r_src.y + static_cast<int>(r_src.height - 1);
|
||||
|
||||
x_u_table_tag * x_u_table = new x_u_table_tag[r_dst.width];
|
||||
|
||||
for(std::size_t x = 0; x < r_dst.width; ++x)
|
||||
{
|
||||
double u = (int(x) + 0.5) * rate_x - 0.5;
|
||||
x_u_table_tag el;
|
||||
el.x = r_src.x;
|
||||
if(u < 0)
|
||||
{
|
||||
u = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ipart = static_cast<int>(u);
|
||||
el.x += ipart;
|
||||
u -= ipart;
|
||||
}
|
||||
el.iu = static_cast<int>(u * coef);
|
||||
el.iu_minus_coef = coef - el.iu;
|
||||
x_u_table[x] = el;
|
||||
}
|
||||
|
||||
const bool is_alpha_channel = s_pixbuf.alpha_channel();
|
||||
|
||||
for(std::size_t row = 0; row < r_dst.height; ++row)
|
||||
{
|
||||
double v = (int(row) + 0.5) * rate_y - 0.5;
|
||||
int sy = r_src.y;
|
||||
if(v < 0)
|
||||
{
|
||||
v = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ipart = static_cast<int>(v);
|
||||
sy += ipart;
|
||||
v -= ipart;
|
||||
}
|
||||
|
||||
std::size_t iv = static_cast<size_t>(v * coef);
|
||||
const std::size_t iv_minus_coef = coef - iv;
|
||||
|
||||
const nana::pixel_rgb_t * s_line = pixel_at(s_raw_pixel_buffer, sy * s_bytes_per_line);
|
||||
const nana::pixel_rgb_t * next_s_line = pixel_at(s_line, (sy < bottom ? s_bytes_per_line : 0));
|
||||
|
||||
nana::pixel_rgb_t col0;
|
||||
nana::pixel_rgb_t col1;
|
||||
nana::pixel_rgb_t col2;
|
||||
nana::pixel_rgb_t col3;
|
||||
|
||||
pixel_rgb_t * i = pixbuf.raw_ptr(row + r_dst.y) + r_dst.x;
|
||||
|
||||
if(is_alpha_channel)
|
||||
{
|
||||
for(std::size_t x = 0; x < r_dst.width; ++x, ++i)
|
||||
{
|
||||
x_u_table_tag el = x_u_table[x];
|
||||
|
||||
col0 = s_line[el.x];
|
||||
col1 = next_s_line[el.x];
|
||||
|
||||
if(el.x < right_bound)
|
||||
{
|
||||
col2 = s_line[el.x + 1];
|
||||
col3 = next_s_line[el.x + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
col2 = col0;
|
||||
col3 = col1;
|
||||
}
|
||||
|
||||
std::size_t coef0 = el.iu_minus_coef * iv_minus_coef;
|
||||
std::size_t coef1 = el.iu_minus_coef * iv;
|
||||
std::size_t coef2 = el.iu * iv_minus_coef;
|
||||
std::size_t coef3 = el.iu * iv;
|
||||
|
||||
unsigned alpha_chn = static_cast<unsigned>((coef0 * col0.u.element.alpha_channel + coef1 * col1.u.element.alpha_channel + (coef2 * col2.u.element.alpha_channel + coef3 * col3.u.element.alpha_channel)) >> double_shift_size);
|
||||
unsigned s_red = static_cast<unsigned>((coef0 * col0.u.element.red + coef1 * col1.u.element.red + (coef2 * col2.u.element.red + coef3 * col3.u.element.red)) >> double_shift_size);
|
||||
unsigned s_green = static_cast<unsigned>((coef0 * col0.u.element.green + coef1 * col1.u.element.green + (coef2 * col2.u.element.green + coef3 * col3.u.element.green)) >> double_shift_size);
|
||||
unsigned s_blue = static_cast<unsigned>((coef0 * col0.u.element.blue + coef1 * col1.u.element.blue + (coef2 * col2.u.element.blue + coef3 * col3.u.element.blue)) >> double_shift_size);
|
||||
|
||||
if(alpha_chn)
|
||||
{
|
||||
if(alpha_chn != 255)
|
||||
{
|
||||
i->u.element.red = unsigned(i->u.element.red * (255 - alpha_chn) + s_red * alpha_chn) / 255;
|
||||
i->u.element.green = unsigned(i->u.element.green * (255 - alpha_chn) + s_green * alpha_chn) / 255;
|
||||
i->u.element.blue = unsigned(i->u.element.blue * (255 - alpha_chn) + s_blue * alpha_chn) / 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
i->u.element.red = s_red;
|
||||
i->u.element.green = s_green;
|
||||
i->u.element.blue = s_blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(std::size_t x = 0; x < r_dst.width; ++x, ++i)
|
||||
{
|
||||
x_u_table_tag el = x_u_table[x];
|
||||
|
||||
col0 = s_line[el.x];
|
||||
col1 = next_s_line[el.x];
|
||||
|
||||
if(el.x < right_bound)
|
||||
{
|
||||
col2 = s_line[el.x + 1];
|
||||
col3 = next_s_line[el.x + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
col2 = col0;
|
||||
col3 = col1;
|
||||
}
|
||||
|
||||
std::size_t coef0 = el.iu_minus_coef * iv_minus_coef;
|
||||
std::size_t coef1 = el.iu_minus_coef * iv;
|
||||
std::size_t coef2 = el.iu * iv_minus_coef;
|
||||
std::size_t coef3 = el.iu * iv;
|
||||
|
||||
i->u.element.red = static_cast<unsigned>((coef0 * col0.u.element.red + coef1 * col1.u.element.red + (coef2 * col2.u.element.red + coef3 * col3.u.element.red)) >> double_shift_size);
|
||||
i->u.element.green = static_cast<unsigned>((coef0 * col0.u.element.green + coef1 * col1.u.element.green + (coef2 * col2.u.element.green + coef3 * col3.u.element.green)) >> double_shift_size);
|
||||
i->u.element.blue = static_cast<unsigned>((coef0 * col0.u.element.blue + coef1 * col1.u.element.blue + (coef2 * col2.u.element.blue + coef3 * col3.u.element.blue)) >> double_shift_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete [] x_u_table;
|
||||
}
|
||||
};
|
||||
|
||||
//alpha_blend
|
||||
class alpha_blend
|
||||
: public image_process::alpha_blend_interface
|
||||
{
|
||||
//process
|
||||
virtual void process(const paint::pixel_buffer& s_pixbuf, const nana::rectangle& s_r, paint::pixel_buffer& d_pixbuf, const nana::point& d_pos) const
|
||||
{
|
||||
nana::pixel_rgb_t * d_rgb = d_pixbuf.at(d_pos);
|
||||
nana::pixel_rgb_t * s_rgb = s_pixbuf.raw_ptr(s_r.y) + s_r.x;
|
||||
if(d_rgb && s_rgb)
|
||||
{
|
||||
const unsigned rest = s_r.width & 0x3;
|
||||
const unsigned length_align4 = s_r.width - rest;
|
||||
|
||||
std::size_t d_step_bytes = d_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_rgb_t);
|
||||
std::size_t s_step_bytes = s_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_rgb_t);
|
||||
for(unsigned line = 0; line < s_r.height; ++line)
|
||||
{
|
||||
pixel_rgb_t* end = d_rgb + length_align4;
|
||||
for(; d_rgb < end; d_rgb += 4, s_rgb += 4)
|
||||
{
|
||||
//0
|
||||
if(s_rgb->u.element.alpha_channel)
|
||||
{
|
||||
if(s_rgb->u.element.alpha_channel != 255)
|
||||
{
|
||||
d_rgb->u.element.red = unsigned(d_rgb->u.element.red * (255 - s_rgb[0].u.element.alpha_channel) + s_rgb[0].u.element.red * s_rgb[0].u.element.alpha_channel) / 255;
|
||||
d_rgb->u.element.green = unsigned(d_rgb->u.element.green * (255 - s_rgb[0].u.element.alpha_channel) + s_rgb[0].u.element.green * s_rgb[0].u.element.alpha_channel) / 255;
|
||||
d_rgb->u.element.blue = unsigned(d_rgb->u.element.blue * (255 - s_rgb[0].u.element.alpha_channel) + s_rgb[0].u.element.blue * s_rgb[0].u.element.alpha_channel) / 255;
|
||||
}
|
||||
else
|
||||
*d_rgb = *s_rgb;
|
||||
}
|
||||
|
||||
//1
|
||||
if(s_rgb[1].u.element.alpha_channel)
|
||||
{
|
||||
if(s_rgb[1].u.element.alpha_channel != 255)
|
||||
{
|
||||
d_rgb[1].u.element.red = unsigned(d_rgb[1].u.element.red * (255 - s_rgb[1].u.element.alpha_channel) + s_rgb[1].u.element.red * s_rgb[1].u.element.alpha_channel) / 255;
|
||||
d_rgb[1].u.element.green = unsigned(d_rgb[1].u.element.green * (255 - s_rgb[1].u.element.alpha_channel) + s_rgb[1].u.element.green * s_rgb[1].u.element.alpha_channel) / 255;
|
||||
d_rgb[1].u.element.blue = unsigned(d_rgb[1].u.element.blue * (255 - s_rgb[1].u.element.alpha_channel) + s_rgb[1].u.element.blue * s_rgb[1].u.element.alpha_channel) / 255;
|
||||
}
|
||||
else
|
||||
d_rgb[1] = s_rgb[1];
|
||||
}
|
||||
|
||||
//2
|
||||
if(s_rgb[2].u.element.alpha_channel)
|
||||
{
|
||||
if(s_rgb[2].u.element.alpha_channel != 255)
|
||||
{
|
||||
d_rgb[2].u.element.red = unsigned(d_rgb[2].u.element.red * (255 - s_rgb[2].u.element.alpha_channel) + s_rgb[2].u.element.red * s_rgb[2].u.element.alpha_channel) / 255;
|
||||
d_rgb[2].u.element.green = unsigned(d_rgb[2].u.element.green * (255 - s_rgb[2].u.element.alpha_channel) + s_rgb[2].u.element.green * s_rgb[2].u.element.alpha_channel) / 255;
|
||||
d_rgb[2].u.element.blue = unsigned(d_rgb[2].u.element.blue * (255 - s_rgb[2].u.element.alpha_channel) + s_rgb[2].u.element.blue * s_rgb[2].u.element.alpha_channel) / 255;
|
||||
}
|
||||
else
|
||||
d_rgb[2] = s_rgb[2];
|
||||
}
|
||||
|
||||
//3
|
||||
if(s_rgb[3].u.element.alpha_channel)
|
||||
{
|
||||
if(s_rgb[3].u.element.alpha_channel != 255)
|
||||
{
|
||||
d_rgb[3].u.element.red = unsigned(d_rgb[3].u.element.red * (255 - s_rgb[3].u.element.alpha_channel) + s_rgb[3].u.element.red * s_rgb[3].u.element.alpha_channel) / 255;
|
||||
d_rgb[3].u.element.green = unsigned(d_rgb[3].u.element.green * (255 - s_rgb[3].u.element.alpha_channel) + s_rgb[3].u.element.green * s_rgb[3].u.element.alpha_channel) / 255;
|
||||
d_rgb[3].u.element.blue = unsigned(d_rgb[3].u.element.blue * (255 - s_rgb[3].u.element.alpha_channel) + s_rgb[3].u.element.blue * s_rgb[3].u.element.alpha_channel) / 255;
|
||||
}
|
||||
else
|
||||
d_rgb[3] = s_rgb[3];
|
||||
}
|
||||
}
|
||||
|
||||
const pixel_rgb_t * s_end = s_rgb + rest;
|
||||
for(auto i = s_rgb; i != s_end; ++i)
|
||||
{
|
||||
if(i->u.element.alpha_channel)
|
||||
{
|
||||
if(i->u.element.alpha_channel != 255)
|
||||
{
|
||||
d_rgb[3].u.element.red = unsigned(d_rgb[3].u.element.red * (255 - i->u.element.alpha_channel) + i->u.element.red * i->u.element.alpha_channel) / 255;
|
||||
d_rgb[3].u.element.green = unsigned(d_rgb[3].u.element.green * (255 - i->u.element.alpha_channel) + i->u.element.green * i->u.element.alpha_channel) / 255;
|
||||
d_rgb[3].u.element.blue = unsigned(d_rgb[3].u.element.blue * (255 - i->u.element.alpha_channel) + i->u.element.blue * i->u.element.alpha_channel) / 255;
|
||||
}
|
||||
else
|
||||
d_rgb[3] = *i;
|
||||
}
|
||||
}
|
||||
d_rgb = pixel_at(d_rgb, d_step_bytes);
|
||||
s_rgb = pixel_at(s_rgb, s_step_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//blend
|
||||
class blend
|
||||
: public image_process::blend_interface
|
||||
{
|
||||
//process
|
||||
virtual void process(const paint::pixel_buffer& s_pixbuf, const nana::rectangle& s_r, paint::pixel_buffer& d_pixbuf, const nana::point& d_pos, double fade_rate) const
|
||||
{
|
||||
nana::pixel_rgb_t * d_rgb = d_pixbuf.raw_ptr(d_pos.y) + d_pos.x;
|
||||
nana::pixel_rgb_t * s_rgb = s_pixbuf.raw_ptr(s_r.y) + s_r.x;
|
||||
|
||||
if(d_rgb && s_rgb)
|
||||
{
|
||||
unsigned char* tablebuf = detail::alloc_fade_table(fade_rate);//new unsigned char[0x100 * 2];
|
||||
unsigned char* d_table = tablebuf;
|
||||
unsigned char* s_table = d_table + 0x100;
|
||||
|
||||
const unsigned rest = s_r.width & 0x3;
|
||||
const unsigned length_align4 = s_r.width - rest;
|
||||
|
||||
std::size_t d_step_bytes = d_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_rgb_t);
|
||||
std::size_t s_step_bytes = s_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_rgb_t);
|
||||
for(unsigned line = 0; line < s_r.height; ++line)
|
||||
{
|
||||
pixel_rgb_t* end = d_rgb + length_align4;
|
||||
for(; d_rgb < end; d_rgb += 4, s_rgb += 4)
|
||||
{
|
||||
//0
|
||||
d_rgb[0].u.element.red = unsigned(d_table[d_rgb[0].u.element.red] + s_table[s_rgb[0].u.element.red]);
|
||||
d_rgb[0].u.element.green = unsigned(d_table[d_rgb[0].u.element.green] + s_table[s_rgb[0].u.element.green]);
|
||||
d_rgb[0].u.element.blue = unsigned(d_table[d_rgb[0].u.element.blue] + s_table[s_rgb[0].u.element.blue]);
|
||||
|
||||
//1
|
||||
d_rgb[1].u.element.red = unsigned(d_table[d_rgb[1].u.element.red] + s_table[s_rgb[1].u.element.red]);
|
||||
d_rgb[1].u.element.green = unsigned(d_table[d_rgb[1].u.element.green] + s_table[s_rgb[1].u.element.green]);
|
||||
d_rgb[1].u.element.blue = unsigned(d_table[d_rgb[1].u.element.blue] + s_table[s_rgb[1].u.element.blue]);
|
||||
|
||||
//2
|
||||
d_rgb[2].u.element.red = unsigned(d_table[d_rgb[2].u.element.red] + s_table[s_rgb[2].u.element.red]);
|
||||
d_rgb[2].u.element.green = unsigned(d_table[d_rgb[2].u.element.green] + s_table[s_rgb[2].u.element.green]);
|
||||
d_rgb[2].u.element.blue = unsigned(d_table[d_rgb[2].u.element.blue] + s_table[s_rgb[2].u.element.blue]);
|
||||
|
||||
//3
|
||||
d_rgb[3].u.element.red = unsigned(d_table[d_rgb[3].u.element.red] + s_table[s_rgb[3].u.element.red]);
|
||||
d_rgb[3].u.element.green = unsigned(d_table[d_rgb[3].u.element.green] + s_table[s_rgb[3].u.element.green]);
|
||||
d_rgb[3].u.element.blue = unsigned(d_table[d_rgb[3].u.element.blue] + s_table[s_rgb[3].u.element.blue]);
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < rest; ++i)
|
||||
{
|
||||
d_rgb[i].u.element.red = unsigned(d_table[d_rgb[i].u.element.red] + s_table[s_rgb[i].u.element.red]);
|
||||
d_rgb[i].u.element.green = unsigned(d_table[d_rgb[i].u.element.green] + s_table[s_rgb[i].u.element.green]);
|
||||
d_rgb[i].u.element.blue = unsigned(d_table[d_rgb[i].u.element.blue] + s_table[s_rgb[i].u.element.blue]);
|
||||
}
|
||||
d_rgb = pixel_at(d_rgb, d_step_bytes);
|
||||
s_rgb = pixel_at(s_rgb, s_step_bytes);
|
||||
}
|
||||
detail::free_fade_table(tablebuf);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//class line
|
||||
class bresenham_line
|
||||
: public image_process::line_interface
|
||||
{
|
||||
virtual void process(paint::pixel_buffer & pixbuf, const nana::point& pos_beg, const nana::point& pos_end, nana::color_t color, double fade_rate) const
|
||||
{
|
||||
const std::size_t bytes_pl = pixbuf.bytes_per_line();
|
||||
unsigned char * fade_table = nullptr;
|
||||
nana::pixel_rgb_t rgb_imd;
|
||||
if(fade_rate != 0.0)
|
||||
{
|
||||
fade_table = detail::alloc_fade_table(1 - fade_rate);
|
||||
rgb_imd.u.color = color;
|
||||
rgb_imd = detail::fade_color_intermedia(rgb_imd, fade_table);
|
||||
}
|
||||
|
||||
nana::pixel_rgb_t * i = pixel_at(pixbuf.raw_ptr(0), pos_beg.y * bytes_pl) + pos_beg.x;
|
||||
|
||||
auto delta = pos_end - pos_beg;
|
||||
|
||||
int step_bytes;
|
||||
if(delta.y < 0)
|
||||
{
|
||||
delta.y = -delta.y;
|
||||
step_bytes = -static_cast<int>(bytes_pl);
|
||||
}
|
||||
else
|
||||
step_bytes = static_cast<int>(bytes_pl);
|
||||
|
||||
if(delta.x == delta.y)
|
||||
{
|
||||
step_bytes += sizeof(pixel_rgb_t);
|
||||
++delta.x;
|
||||
|
||||
if(fade_table)
|
||||
{
|
||||
for(int x = 0; x < delta.x; ++x)
|
||||
{
|
||||
*i = detail::fade_color_by_intermedia(*i, rgb_imd, fade_table);
|
||||
i = pixel_at(i, step_bytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int x = 0; x < delta.x; ++x)
|
||||
{
|
||||
i->u.color = color;
|
||||
i = pixel_at(i, step_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int dx_2 = delta.x << 1;
|
||||
int dy_2 = delta.y << 1;
|
||||
if(delta.x > delta.y)
|
||||
{
|
||||
int error = dy_2 - delta.x;
|
||||
++delta.x; //Include the end poing
|
||||
|
||||
if(fade_table)
|
||||
{
|
||||
for(int x = 0; x < delta.x; ++x)
|
||||
{
|
||||
*i = detail::fade_color_by_intermedia(*i, rgb_imd, fade_table);
|
||||
if(error >= 0)
|
||||
{
|
||||
error -= dx_2;
|
||||
i = pixel_at(i, step_bytes);
|
||||
}
|
||||
error += dy_2;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int x = 0; x < delta.x; ++x)
|
||||
{
|
||||
i->u.color = color;
|
||||
if(error >= 0)
|
||||
{
|
||||
error -= dx_2;
|
||||
i = pixel_at(i, step_bytes);
|
||||
}
|
||||
error += dy_2;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int error = dx_2 - delta.y;
|
||||
++delta.y; //Include the end point
|
||||
|
||||
if(fade_table)
|
||||
{
|
||||
for (int y = 0; y < delta.y; ++y)
|
||||
{
|
||||
*i = detail::fade_color_by_intermedia(*i, rgb_imd, fade_table);
|
||||
if(error >= 0)
|
||||
{
|
||||
error -= dy_2;
|
||||
++i;
|
||||
}
|
||||
error += dx_2;
|
||||
i = pixel_at(i, step_bytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int y = 0; y < delta.y; ++y)
|
||||
{
|
||||
i->u.color = color;
|
||||
if(error >= 0)
|
||||
{
|
||||
error -= dy_2;
|
||||
++i;
|
||||
}
|
||||
error += dx_2;
|
||||
i = pixel_at(i, step_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
detail::free_fade_table(fade_table);
|
||||
}
|
||||
};
|
||||
|
||||
class superfast_blur
|
||||
: public image_process::blur_interface
|
||||
{
|
||||
void process(pixel_buffer& pixbuf, const nana::rectangle& area, std::size_t u_radius) const
|
||||
{
|
||||
int radius = static_cast<int>(u_radius);
|
||||
int w = area.width;
|
||||
int h = area.height;
|
||||
int wm = w - 1;
|
||||
int hm = h - 1;
|
||||
int wh = w * h;
|
||||
int div = (radius << 1) + 1;
|
||||
|
||||
int large_edge = (w > h ? w : h);
|
||||
const int div_256 = div * 256;
|
||||
|
||||
std::unique_ptr<int[]> all_table(new int[(wh << 1) + wh + (large_edge << 1) + div_256]);
|
||||
|
||||
|
||||
int * r = all_table.get();
|
||||
int * g = r + wh;
|
||||
int * b = g + wh;
|
||||
|
||||
int * vmin = b + wh;
|
||||
int * vmax = vmin + large_edge;
|
||||
|
||||
int * dv = vmax + large_edge;
|
||||
int end_div = div - 1;
|
||||
for(int i = 0, *dv_block = dv; i < 256; ++i)
|
||||
{
|
||||
for(int u = 0; u < end_div; u += 2)
|
||||
{
|
||||
dv_block[u] = i;
|
||||
dv_block[u + 1] = i;
|
||||
}
|
||||
dv_block[div - 1] = i;
|
||||
dv_block += div;
|
||||
}
|
||||
|
||||
auto linepix = pixbuf.raw_ptr(area.y) + area.x;
|
||||
|
||||
int yi = 0;
|
||||
for(int y = 0; y < h; ++y)
|
||||
{
|
||||
int sum_r = 0, sum_g = 0, sum_b = 0;
|
||||
if(radius <= wm)
|
||||
{
|
||||
for(int i = - radius; i <= radius; ++i)
|
||||
{
|
||||
nana::pixel_rgb_t px = linepix[(i > 0 ? i : 0)];
|
||||
sum_r += px.u.element.red;
|
||||
sum_g += px.u.element.green;
|
||||
sum_b += px.u.element.blue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = - radius; i <= radius; ++i)
|
||||
{
|
||||
nana::pixel_rgb_t px = linepix[std::min(wm, (i > 0 ? i : 0))];
|
||||
sum_r += px.u.element.red;
|
||||
sum_g += px.u.element.green;
|
||||
sum_b += px.u.element.blue;
|
||||
}
|
||||
}
|
||||
|
||||
for(int x = 0; x < w; ++x)
|
||||
{
|
||||
r[yi] = dv[sum_r];
|
||||
g[yi] = dv[sum_g];
|
||||
b[yi] = dv[sum_b];
|
||||
|
||||
if(0 == y)
|
||||
{
|
||||
vmin[x] = std::min(x + radius + 1, wm);
|
||||
vmax[x] = std::max(x - radius, 0);
|
||||
}
|
||||
|
||||
nana::pixel_rgb_t p1 = linepix[vmin[x]];
|
||||
nana::pixel_rgb_t p2 = linepix[vmax[x]];
|
||||
|
||||
sum_r += p1.u.element.red - p2.u.element.red;
|
||||
sum_g += p1.u.element.green - p2.u.element.green;
|
||||
sum_b += p1.u.element.blue - p2.u.element.blue;
|
||||
++yi;
|
||||
}
|
||||
linepix = pixbuf.raw_ptr(area.y + y) + area.x;
|
||||
}
|
||||
|
||||
const int yp_init = -radius * w;
|
||||
|
||||
const std::size_t bytes_pl = pixbuf.bytes_per_line();
|
||||
for(int x = 0; x < w; ++x)
|
||||
{
|
||||
int sum_r = 0, sum_g = 0, sum_b = 0;
|
||||
|
||||
int yp = yp_init;
|
||||
for(int i = -radius; i <= radius; ++i)
|
||||
{
|
||||
if(yp < 1)
|
||||
{
|
||||
sum_r += r[x];
|
||||
sum_g += g[x];
|
||||
sum_b += b[x];
|
||||
}
|
||||
else
|
||||
{
|
||||
int yi = yp + x;
|
||||
sum_r += r[yi];
|
||||
sum_g += g[yi];
|
||||
sum_b += b[yi];
|
||||
}
|
||||
yp += w;
|
||||
}
|
||||
|
||||
linepix = pixbuf.raw_ptr(area.y) + x;
|
||||
|
||||
for(int y = 0; y < h; ++y)
|
||||
{
|
||||
linepix->u.color = 0xFF000000 | (dv[sum_r] << 16) | (dv[sum_g] << 8) | dv[sum_b];
|
||||
if(x == 0)
|
||||
{
|
||||
vmin[y] = std::min(y + radius + 1, hm) * w;
|
||||
vmax[y] = std::max(y - radius, 0) * w;
|
||||
}
|
||||
|
||||
int pt1 = x + vmin[y];
|
||||
int pt2 = x + vmax[y];
|
||||
|
||||
sum_r += r[pt1] - r[pt2];
|
||||
sum_g += g[pt1] - g[pt2];
|
||||
sum_b += b[pt1] - b[pt2];
|
||||
|
||||
linepix = pixel_at(linepix, bytes_pl);
|
||||
}
|
||||
}
|
||||
}
|
||||
};//end class superfast_blur
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
42
include/nana/paint/detail/native_paint_interface.hpp
Normal file
42
include/nana/paint/detail/native_paint_interface.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Platform Implementation
|
||||
* Copyright(C) 2003-2013 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/paint/detail/native_paint_interface.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_PAINT_DETAIL_PLATFORM_HPP
|
||||
#define NANA_PAINT_DETAIL_PLATFORM_HPP
|
||||
#include <nana/basic_types.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
nana::size drawable_size(drawable_type);
|
||||
|
||||
unsigned char * alloc_fade_table(double fade_rate);
|
||||
void free_fade_table(const unsigned char*);
|
||||
|
||||
//color = bgcolor * fade_rate + fgcolor * (1 - fade_rate);
|
||||
nana::pixel_rgb_t fade_color(nana::pixel_rgb_t bgcolor, nana::pixel_rgb_t fgcolor, double fade_rate);
|
||||
nana::pixel_rgb_t fade_color(nana::pixel_rgb_t bgcolor, nana::pixel_rgb_t fgcolor, const unsigned char* const fade_table);
|
||||
nana::pixel_rgb_t fade_color_intermedia(nana::pixel_rgb_t fgcolor, const unsigned char* fade_table);
|
||||
nana::pixel_rgb_t fade_color_by_intermedia(nana::pixel_rgb_t bgcolor, nana::pixel_rgb_t fgcolor_intermedia, const unsigned char* const fade_table);
|
||||
|
||||
void blend(drawable_type dw, const nana::rectangle& r, nana::color_t, double fade_rate);
|
||||
|
||||
nana::size raw_text_extent_size(drawable_type, const nana::char_t*, std::size_t len);
|
||||
nana::size text_extent_size(drawable_type, const nana::char_t*, std::size_t len);
|
||||
void draw_string(drawable_type, int x, int y, const nana::char_t *, std::size_t len);
|
||||
}//end namespace detail
|
||||
}//end namespace paint
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
38
include/nana/paint/gadget.hpp
Normal file
38
include/nana/paint/gadget.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Graphics Gadget Implementation
|
||||
* Copyright(C) 2003-2013 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/paint/gadget.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_PAINT_GADGET_HPP
|
||||
#define NANA_PAINT_GADGET_HPP
|
||||
#include "graphics.hpp"
|
||||
#include "image.hpp"
|
||||
#include <nana/basic_types.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
namespace gadget
|
||||
{
|
||||
struct directions
|
||||
{
|
||||
enum t{to_east, to_southeast, to_south, to_southwest, to_west, to_northwest, to_north, to_northeast};
|
||||
};
|
||||
|
||||
void arrow_16_pixels(nana::paint::graphics&, int x, int y, unsigned color, uint32_t style, directions::t direction);
|
||||
void close_16_pixels(nana::paint::graphics&, int x, int y, uint32_t style, uint32_t color);
|
||||
void cross(nana::paint::graphics&, int x, int y, uint32_t size, uint32_t thickness, nana::color_t color);
|
||||
|
||||
}//end namespace gadget
|
||||
|
||||
}//end namespace paint
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
166
include/nana/paint/graphics.hpp
Normal file
166
include/nana/paint/graphics.hpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Paint Graphics Implementation
|
||||
* Copyright(C) 2003-2013 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/paint/graphics.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_PAINT_GRAPHICS_HPP
|
||||
#define NANA_PAINT_GRAPHICS_HPP
|
||||
|
||||
#include "../basic_types.hpp"
|
||||
#include "../gui/basis.hpp"
|
||||
#include "pixel_buffer.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct native_font_signature;
|
||||
}// end namespace detail
|
||||
|
||||
typedef detail::native_font_signature* native_font_type;
|
||||
|
||||
class font
|
||||
{
|
||||
friend class graphics;
|
||||
public:
|
||||
font();
|
||||
font(drawable_type);
|
||||
font(const font&);
|
||||
font(const char_t* name, unsigned size, bool bold = false, bool italic = false, bool underline = false, bool strike_out = false);
|
||||
~font();
|
||||
bool empty() const;
|
||||
void make(const char_t* name, unsigned size, bool bold = false, bool italic = false, bool underline = false, bool strike_out = false);
|
||||
void make_raw(const char_t*, unsigned height, unsigned weight, bool italic, bool underline, bool strike_out);
|
||||
|
||||
void set_default() const;
|
||||
::nana::string name() const;
|
||||
unsigned size() const;
|
||||
bool bold() const;
|
||||
unsigned height() const;
|
||||
unsigned weight() const;
|
||||
bool italic() const;
|
||||
native_font_type handle() const;
|
||||
void release();
|
||||
|
||||
font& operator=(const font&);
|
||||
bool operator==(const font&) const;
|
||||
bool operator!=(const font&) const;
|
||||
private:
|
||||
struct impl_type;
|
||||
impl_type * impl_;
|
||||
};
|
||||
|
||||
/// \brief off-screen resource defined as ref-counting, can refer one resource
|
||||
///
|
||||
/// Load a bitmap into a graphics:
|
||||
/// \code
|
||||
/// nana::paint::graphics graph;
|
||||
/// nana::paint::image img("C:\\ABitmap.bmp");
|
||||
/// img.paste(graph, 0, 0); //graph may create if it is empty
|
||||
/// \endcode
|
||||
class graphics
|
||||
{
|
||||
public:
|
||||
typedef ::nana::native_window_type native_window_type;
|
||||
|
||||
graphics();
|
||||
graphics(unsigned width, unsigned height); ///< size in pixel
|
||||
graphics(const ::nana::size&); ///< size in pixel
|
||||
graphics(const graphics&); ///< the resource is not copyed, the two graphics objects refer to the *SAME* resource
|
||||
graphics& operator=(const graphics&);
|
||||
bool changed() const; ///< Returns true if the graphics object is operated
|
||||
bool empty() const; ///< Returns true if the graphics object does not refer to any resource.
|
||||
operator const void*() const;
|
||||
|
||||
drawable_type handle() const;
|
||||
const void* pixmap() const;
|
||||
const void* context() const;
|
||||
void make(unsigned width, unsigned height); ///< Creates a bitmap resource that size is width by height in pixel
|
||||
void resize(unsigned width, unsigned height);
|
||||
void typeface(const font&); ///< Selects a specified font type into the graphics object.
|
||||
font typeface() const;
|
||||
::nana::size text_extent_size(const char_t*) const; ///< Computes the width and height of the specified string of text.
|
||||
::nana::size text_extent_size(const string&) const; ///< Computes the width and height of the specified string of text.
|
||||
::nana::size text_extent_size(const char_t*, std::size_t length) const; ///< Computes the width and height of the specified string of text with the specified length.
|
||||
::nana::size text_extent_size(const string&, std::size_t length) const; ///< Computes the width and height of the specified string of text with the specified length.
|
||||
::nana::size glyph_extent_size(const char_t*, std::size_t length, std::size_t begin, std::size_t end) const;
|
||||
::nana::size glyph_extent_size(const string&, std::size_t length, std::size_t begin, std::size_t end) const;
|
||||
bool glyph_pixels(const char_t *, std::size_t length, unsigned* pxbuf) const;
|
||||
::nana::size bidi_extent_size(const string&) const;
|
||||
|
||||
bool text_metrics(unsigned & ascent, unsigned& descent, unsigned& internal_leading) const;
|
||||
|
||||
unsigned bidi_string(int x, int y, color_t, const char_t *, std::size_t len);
|
||||
void string(int x, int y, color_t, const ::nana::string&, std::size_t len);
|
||||
void string(int x, int y, color_t, const ::nana::string&);
|
||||
void string(int x, int y, color_t, const char_t*, std::size_t len);
|
||||
void string(int x, int y, color_t, const char_t*);
|
||||
|
||||
void set_pixel(int x, int y, color_t);
|
||||
void rectangle(int x, int y, unsigned width, unsigned height, color_t, bool solid);
|
||||
void rectangle(color_t, bool solid);
|
||||
void rectangle(const ::nana::rectangle&, color_t, bool solid);
|
||||
void rectangle_line(const ::nana::rectangle&, color_t left, color_t top, color_t right, color_t bottom);
|
||||
void round_rectangle(int x, int y, unsigned width, unsigned height, unsigned radius_x, unsigned radius_y, color_t, bool solid, color_t color_if_solid);
|
||||
void round_rectangle(const ::nana::rectangle&, unsigned radius_x, unsigned radius_y, color_t, bool solid, color_t color_if_solid);
|
||||
void shadow_rectangle(const ::nana::rectangle&, color_t beg_color, color_t end_color, bool vertical);
|
||||
void shadow_rectangle(int x, int y, unsigned width, unsigned height, color_t beg_color, color_t end_color, bool vertical); ///< Draws a width and height rectangle at (x, y) and the color in range of [begin, end]
|
||||
|
||||
void line(int x1, int y1, int x2, int y2, color_t); ///< Draws a line from point (x1, y1) to point (x2, y2) in the specified color.
|
||||
void line(const point& beg, const point& end, color_t);
|
||||
void lines(const point* points, std::size_t n_of_points, color_t);
|
||||
void line_begin(int x, int y);
|
||||
void line_to(int x, int y, color_t);
|
||||
|
||||
void bitblt(int x, int y, const graphics& source); ///< Transfers the source to the specified point.
|
||||
void bitblt(const ::nana::rectangle& r_dst, native_window_type src); ///< Transfers the color data corresponding to r_dst from the src window to this graphics.
|
||||
void bitblt(const ::nana::rectangle& r_dst, native_window_type src, const point& p_src); ///< Transfers the color data corresponding to r_dst from the src window at point p_src to this graphics.
|
||||
void bitblt(const ::nana::rectangle& r_dst, const graphics& src); ///< Transfers the color data corresponding to r_dst from the src graphics to this graphics.
|
||||
void bitblt(const ::nana::rectangle& r_dst, const graphics& src, const point& p_src);///< Transfers the color data corresponding to r_dst from the src graphics at point p_src to this graphics.
|
||||
|
||||
void blend(const ::nana::rectangle& s_r, graphics& dst, const point& d_pos, double fade_rate) const;///< blends with the dst object.
|
||||
void blend(const ::nana::rectangle& r, color_t, double fade_rate); ///< blends the specifed block width the specified color.
|
||||
|
||||
void blur(const ::nana::rectangle& r, std::size_t radius); ///< Blur process.
|
||||
|
||||
void paste(graphics& dst, int x, int y) const; ///< Paste the graphics object into the dest at (x, y)
|
||||
void paste(native_window_type dst, const ::nana::rectangle&, int sx, int sy) const; ///< Paste the graphics object into a platform-dependent window at (x, y)
|
||||
void paste(native_window_type dst, int dx, int dy, unsigned width, unsigned height, int sx, int sy) const;
|
||||
void paste(drawable_type dst, int x, int y) const;
|
||||
void paste(const ::nana::rectangle& r_src, graphics& dst, int x, int y) const;
|
||||
void rgb_to_wb(); ///< Transform a color graphics into black&white.
|
||||
|
||||
void stretch(const ::nana::rectangle& src_r, graphics& dst, const ::nana::rectangle& r) const;
|
||||
void stretch(graphics& dst, const ::nana::rectangle& r) const;
|
||||
|
||||
void flush();
|
||||
|
||||
unsigned width() const;
|
||||
unsigned height() const; ///< Returns the height of the off-screen buffer.
|
||||
::nana::size size() const;
|
||||
void setsta(); ///< Clears the status if the graphics object had been changed
|
||||
void release();
|
||||
void save_as_file(const char*);
|
||||
|
||||
static color_t mix(color_t colorX, color_t colorY, double persent);
|
||||
private:
|
||||
std::shared_ptr< ::nana::detail::drawable_impl_type> dwptr_;
|
||||
font font_shadow_;
|
||||
drawable_type handle_;
|
||||
::nana::size size_;
|
||||
pixel_buffer pxbuf_;
|
||||
bool changed_;
|
||||
};
|
||||
}//end namespace paint
|
||||
} //end namespace nana
|
||||
#endif
|
||||
|
||||
54
include/nana/paint/image.hpp
Normal file
54
include/nana/paint/image.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Paint Image Implementation
|
||||
* Copyright(C) 2003-2013 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/paint/image.hpp
|
||||
* @description: class image is used for load an image file into memory.
|
||||
*/
|
||||
|
||||
#ifndef NANA_PAINT_IMAGE_HPP
|
||||
#define NANA_PAINT_IMAGE_HPP
|
||||
|
||||
#include "graphics.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
/// load a picture file
|
||||
class image
|
||||
{
|
||||
friend class image_accessor;
|
||||
typedef bool (image::* unspecified_bool_t)() const;
|
||||
public:
|
||||
class image_impl_interface;
|
||||
|
||||
image();
|
||||
image(const image&);
|
||||
image(image&&);
|
||||
image(const nana::char_t* file);
|
||||
image(const nana::string& filename);
|
||||
~image();
|
||||
image& operator=(const image& rhs);
|
||||
image& operator=(image&&);
|
||||
bool open(const nana::string& filename);
|
||||
bool empty() const;
|
||||
operator unspecified_bool_t() const;
|
||||
void close();
|
||||
nana::size size() const;
|
||||
void paste(graphics& dst, int x, int y) const;
|
||||
void paste(const nana::rectangle& r_src, graphics& dst, const point& p_dst) const;///< Paste the area of picture specified by r_src into the destination graphics specified by dst at position p_dst.
|
||||
void stretch(const nana::rectangle& r_src, graphics& dst, const nana::rectangle& r_dst) const;///<Paste the picture into the dst, stretching or compressing the picture to fit the given area.
|
||||
private:
|
||||
std::shared_ptr<image_impl_interface> image_ptr_;
|
||||
};//end class image
|
||||
|
||||
}//end namespace paint
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
85
include/nana/paint/image_process_interface.hpp
Normal file
85
include/nana/paint/image_process_interface.hpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Image Processing Interfaces
|
||||
* Copyright(C) 2003-2013 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/paint/image_process_interface.hpp
|
||||
*/
|
||||
|
||||
#ifndef NANA_PAINT_IMAGE_PROCESS_INTERFACE_HPP
|
||||
#define NANA_PAINT_IMAGE_PROCESS_INTERFACE_HPP
|
||||
|
||||
#include <nana/basic_types.hpp>
|
||||
#include <nana/paint/pixel_buffer.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{ /// Image Processing Algorithm Interfaces
|
||||
namespace image_process
|
||||
{ /// The interface of stretch algorithm.
|
||||
class stretch_interface
|
||||
{
|
||||
public:
|
||||
virtual ~stretch_interface() = 0;
|
||||
/// Copies the image from a source rectangle into a destination rectangle, stretching or compressing the image to fit the dimensions of the destination rectangle in destination(d_pixbuf).
|
||||
virtual void process(const paint::pixel_buffer & s_pixbuf,
|
||||
const nana::rectangle& source_rectangle,
|
||||
paint::pixel_buffer & d_pixbuf,
|
||||
const nana::rectangle& destination_rectangle
|
||||
) const = 0;
|
||||
};
|
||||
|
||||
class alpha_blend_interface
|
||||
{
|
||||
public:
|
||||
virtual ~alpha_blend_interface() = 0;
|
||||
virtual void process(const paint::pixel_buffer& s_pixbuf, const nana::rectangle& s_r, paint::pixel_buffer& d_pixbuf, const point& d_pos) const = 0;
|
||||
};
|
||||
/// The interface of a blend algorithm.
|
||||
class blend_interface
|
||||
{
|
||||
public:
|
||||
virtual ~blend_interface() = 0;
|
||||
/// \brief Blends two images with specified area and blend rate.
|
||||
///
|
||||
/// Semantics: \code dest_pixbuf = dest_pixbuf * fade_rate + scr_pixbuf * (1 - fade_rate); \endcode
|
||||
/// The area is always valid, it is calculated by Nana before passing to the algorithm. So the area could be applied without a check.
|
||||
virtual void process( const paint::pixel_buffer& src_pixbuf,
|
||||
const nana::rectangle& src_area,
|
||||
paint::pixel_buffer& dest_pixbuf,
|
||||
const nana::point& dest_pos,
|
||||
double fade_rate ///< blend rate in the range of [0, 1]
|
||||
) const = 0;
|
||||
};
|
||||
/// The interface of line algorithm.
|
||||
class line_interface
|
||||
{
|
||||
public:
|
||||
virtual ~line_interface() = 0;
|
||||
|
||||
/// \brief Draws a line
|
||||
///
|
||||
/// Semantics: \code pixbuf = pixbuf * (1 - fade_rate) + color * fade_rate \endcode
|
||||
/// The two points are calculated by Nana, they are always valid, and pos_beg.x <= pos_end.x
|
||||
virtual void process(paint::pixel_buffer & pixbuf,
|
||||
const nana::point& pos_beg, ///< left point
|
||||
const nana::point& pos_end, ///< right point
|
||||
nana::color_t color,
|
||||
double fade_rate ///< blend rate in the range of [0, 1] If not 0, the line is blended to the pixbuf
|
||||
) const = 0;
|
||||
};
|
||||
|
||||
class blur_interface
|
||||
{
|
||||
public:
|
||||
virtual ~blur_interface() = 0;
|
||||
virtual void process(paint::pixel_buffer&, const nana::rectangle& r, std::size_t radius) const = 0;
|
||||
};
|
||||
}
|
||||
}//end namespace paint
|
||||
}//end namespace nana
|
||||
#endif
|
||||
71
include/nana/paint/image_process_selector.hpp
Normal file
71
include/nana/paint/image_process_selector.hpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef NANA_PAINT_IMAGE_PROCESS_SELECTOR_HPP
|
||||
#define NANA_PAINT_IMAGE_PROCESS_SELECTOR_HPP
|
||||
#include "detail/image_process_provider.hpp"
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace paint
|
||||
{
|
||||
namespace image_process
|
||||
{ /// Configure the image processing algorithms.
|
||||
class selector
|
||||
{
|
||||
public:
|
||||
/// Selects an image processor through a specified name.
|
||||
/*! if users give a non-existing name for choosing an image processor,
|
||||
the call succeed, but no image processor would be replaced.
|
||||
*/
|
||||
void stretch(const std::string& name);
|
||||
/// Inserts a new user-defined image processor for stretch.
|
||||
template<typename ImageProcessor>
|
||||
void add_stretch(const std::string& name)
|
||||
{
|
||||
detail::image_process_provider & p = detail::image_process_provider::instance();
|
||||
p.add<ImageProcessor>(p.ref_stretch_tag(), name);
|
||||
}
|
||||
|
||||
/// Selects an image process through a specified name.
|
||||
void alpha_blend(const std::string& name);
|
||||
/// Inserts a new user defined image process for alpha blend.
|
||||
template<typename ImageProcessor>
|
||||
void add_alpha_blend(const std::string& name)
|
||||
{
|
||||
detail::image_process_provider& p = detail::image_process_provider::instance();
|
||||
p.add<ImageProcessor>(p.ref_alpha_blend_tag(), name);
|
||||
}
|
||||
|
||||
/// Selects an image processor blend through a specified name.
|
||||
void blend(const std::string& name);
|
||||
/// Inserts a new user-defined image processor for blend.
|
||||
template<typename ImageProcessor>
|
||||
void add_blend(const std::string& name)
|
||||
{
|
||||
detail::image_process_provider& p = detail::image_process_provider::instance();
|
||||
p.add<ImageProcessor>(p.ref_blend_tag(), name);
|
||||
}
|
||||
|
||||
/// Selects an image processor through a specified name.
|
||||
void line(const std::string& name);
|
||||
/// Inserts a new user-defined image processor for line.
|
||||
template<typename ImageProcessor>
|
||||
void add_line(const std::string& name)
|
||||
{
|
||||
detail::image_process_provider & p = detail::image_process_provider::instance();
|
||||
p.add<ImageProcessor>(p.ref_line_tag(), name);
|
||||
}
|
||||
|
||||
/// blur - Selects an image procssor through a specified name.
|
||||
void blur(const std::string& name);
|
||||
/// Inserts a new user-defined image process for blur.
|
||||
template<typename ImageProcessor>
|
||||
void add_blur(const std::string& name)
|
||||
{
|
||||
detail::image_process_provider & p = detail::image_process_provider::instance();
|
||||
p.add<ImageProcessor>(p.ref_blur_tag(), name);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user