add some missing files, refactor group

This commit is contained in:
Jinhao 2015-07-13 04:57:01 +08:00
parent 1eb76307e4
commit e788c57512
5 changed files with 674 additions and 45 deletions

View File

@ -18,10 +18,7 @@
#define NANA_GUI_WIDGETS_GROUP_HPP
#include <nana/gui/place.hpp>
#include <nana/gui/widgets/button.hpp>
#include <nana/gui/widgets/panel.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/drawing.hpp>
namespace nana{
class group
@ -29,19 +26,26 @@ namespace nana{
{
place plc_outer{*this};
panel<false> content {*this};
label titel/* {*this}*/;
place plc_inner{content};
unsigned int gap;
struct implement;
public:
group( window parent, ///<
string titel_ ={STR("")}, ///<
std::wstring titel_ ={STR("")}, ///<
bool format =false, ///< Use a formated label?
unsigned gap =2, ///< betwen the content and the external limit
rectangle r ={} ///<
);
~group();
place& plc (){ return plc_inner; }
window inner(){ return content; }
label& lbl (){ return titel; }
private:
::nana::string _m_caption() const override;
void _m_caption(::nana::string&&) override;
private:
std::unique_ptr<implement> impl_;
};
}//end namespace nana

View File

@ -9,55 +9,78 @@
*
* @file: nana/gui/widgets/group.cpp
*
* @contributors: Stefan Pfeifer (st-321), Jinhao, Ariel Vina-Rodriguez (qPCR4vir)
* @Author: Stefan Pfeifer(st-321), Ariel Vina-Rodriguez (qPCR4vir)
*
* @brief group is a widget used to visually group and layout other widgets.
*/
#include <nana/gui/widgets/group.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/drawing.hpp>
namespace nana{
group::group( window parent, ///<
string titel_ /*={}*/, ///<
bool format /*=false*/, ///<
unsigned gap /*=2*/, ///<
rectangle r /*={} */ ///<
struct group::implement
{
label caption;
};
group::group( window parent, ///<
std::wstring titel_ /*={}*/, ///<
bool format /*=false*/, ///<
unsigned gap /*=2*/, ///<
rectangle r /*={} */ ///<
)
: panel (parent, r),
titel (*this, titel_)
{
titel.format(format);
::nana::size sz = titel.measure(1000);
std::stringstream ft;
: panel (parent, r),
impl_(new implement)
{
impl_->caption.create(*this);
impl_->caption.format(format);
::nana::size sz = impl_->caption.measure(1000);
std::stringstream ft;
ft << "vert margin=[0," << gap << "," << gap << "," << gap << "]"
<< " <weight=" << sz.height << " <weight=5> <titel weight=" << sz.width+1 << "> >"
<< " <content>";
plc_outer.div(ft.str().c_str());
plc_outer["titel" ] << impl_->caption;
plc_outer["content"] << content;
plc_outer.collocate();
color pbg = API::bgcolor( parent);
impl_->caption.bgcolor(pbg.blend(colors::black, 0.975) );
color bg=pbg.blend(colors::black, 0.950 );
bgcolor(pbg);
content.bgcolor(bg);
drawing dw(*this);
// This drawing function is owner by the onwer of dw (the outer panel of the group widget), not by dw !!
dw.draw([gap, sz, bg, pbg](paint::graphics& graph)
{
graph.rectangle(true, pbg);
graph.round_rectangle(rectangle(point(gap - 1, sz.height / 2),
nana::size(graph.width() - 2 * (gap - 1), graph.height() - sz.height / 2 - (gap - 1))
),
3, 3, colors::gray_border, true, bg);
});
}
ft << "vertical margin=[0," << gap << "," << gap << "," << gap << "]"
<< " <weight=" << sz.height << " <weight=5> <titel weight=" << sz.width+1 << "> >"
<< " <content>";
plc_outer.div(ft.str().c_str());
group::~group()
{
}
plc_outer["titel" ] << titel;
plc_outer["content"] << content;
plc_outer.collocate();
color pbg = API::bgcolor( parent);
titel.bgcolor(pbg.blend(colors::black, 0.975) );
color bg=pbg.blend(colors::black, 0.950 );
bgcolor(pbg);
content.bgcolor(bg);
drawing dw(*this);
// This drawing function is owner by the onwer of dw (the outer panel of the group widget), not by dw !!
dw.draw([gap,sz,bg,pbg](paint::graphics& graph)
{
graph.rectangle(true, pbg);
graph.round_rectangle(rectangle( point ( gap-1 , sz.height/2 ),
nana::size (graph.width()-2*(gap-1), graph.height()-sz.height/2-(gap-1))
),
3,3, colors::gray_border, true, bg);
});
}
::nana::string group::_m_caption() const
{
return impl_->caption.caption();
}
void group::_m_caption(::nana::string&& str)
{
return impl_->caption.caption(std::move(str));
}
}//end namespace nana

View File

@ -0,0 +1,371 @@
/*
* Bitmap Format Graphics Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/paint/detail/image_bmp.hpp
* @contributors: Ryan Gonzalez
*/
#ifndef NANA_PAINT_DETAIL_IMAGE_BMP_HPP
#define NANA_PAINT_DETAIL_IMAGE_BMP_HPP
#include <nana/paint/detail/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) override
{
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 = std::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);
auto 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 auto lend = d + info->bmiHeader.biWidth * height_pixels;
if(info->bmiHeader.biHeight < 0)
{
auto s = bits;
while(d < lend)
{
auto d_p = d;
auto dpend = d_p + info->bmiHeader.biWidth;
auto s_p = s;
while(d_p != dpend)
{
rgb_quad & rgb = info->bmiColors[*s_p++];
d_p->element.red = rgb.rgbRed;
d_p->element.green = rgb.rgbGreen;
d_p->element.blue = rgb.rgbBlue;
d_p->element.alpha_channel = rgb.rgbReserved;
++d_p;
}
d = dpend;
s += bytes_per_line;
}
}
else
{
const auto* s = bits + bytes_per_line * (height_pixels - 1);
while(d < lend)
{
auto d_p = d;
auto* const dpend = d_p + info->bmiHeader.biWidth;
const auto * s_p = s;
while(d_p != dpend)
{
rgb_quad & rgb = info->bmiColors[*s_p++];
d_p->element.red = rgb.rgbRed;
d_p->element.green = rgb.rgbGreen;
d_p->element.blue = rgb.rgbBlue;
d_p->element.alpha_channel = rgb.rgbReserved;
++d_p;
}
d = dpend;
s -= bytes_per_line;
}
}
}
else if(4 == info->bmiHeader.biBitCount)
{
const auto * const lend = d + info->bmiHeader.biWidth * height_pixels;
if(info->bmiHeader.biHeight < 0)
{
const unsigned char* s = bits;
while(d < lend)
{
auto d_p = d;
auto * 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->element.red = rgb.rgbRed;
d_p->element.green = rgb.rgbGreen;
d_p->element.blue = rgb.rgbBlue;
d_p->element.alpha_channel = rgb.rgbReserved;
++d_p;
++index;
}
d = dpend;
s += bytes_per_line;
}
}
else
{
const auto* s = bits + bytes_per_line * (height_pixels - 1);
while(d < lend)
{
auto d_p = d;
auto * 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->element.red = rgb.rgbRed;
d_p->element.green = rgb.rgbGreen;
d_p->element.blue = rgb.rgbBlue;
d_p->element.alpha_channel = rgb.rgbReserved;
++d_p;
++index;
}
d = dpend;
s -= bytes_per_line;
}
}
}
else if(2 == info->bmiHeader.biBitCount)
{
const auto * const lend = d + info->bmiHeader.biWidth * height_pixels;
if(info->bmiHeader.biHeight < 0)
{
const unsigned char* s = bits;
while(d < lend)
{
auto d_p = d;
auto * 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->element.red = rgb.rgbRed;
d_p->element.green = rgb.rgbGreen;
d_p->element.blue = rgb.rgbBlue;
d_p->element.alpha_channel = rgb.rgbReserved;
++d_p;
++index;
}
d = dpend;
s += bytes_per_line;
}
}
else
{
const auto* s = bits + bytes_per_line * (height_pixels - 1);
while(d < lend)
{
auto d_p = d;
auto * 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->element.red = rgb.rgbRed;
d_p->element.green = rgb.rgbGreen;
d_p->element.blue = rgb.rgbBlue;
d_p->element.alpha_channel = rgb.rgbReserved;
++d_p;
++index;
}
d = dpend;
s -= bytes_per_line;
}
}
}
else if(1 == info->bmiHeader.biBitCount)
{
const auto * const lend = d + info->bmiHeader.biWidth * height_pixels;
if(info->bmiHeader.biHeight < 0)
{
const auto* s = bits;
while(d < lend)
{
auto d_p = d;
auto * 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->element.red = rgb.rgbRed;
d_p->element.green = rgb.rgbGreen;
d_p->element.blue = rgb.rgbBlue;
d_p->element.alpha_channel = rgb.rgbReserved;
++d_p;
++index;
}
d = dpend;
s += bytes_per_line;
}
}
else
{
const auto* s = bits + bytes_per_line * (height_pixels - 1);
while(d < lend)
{
auto d_p = d;
auto * 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->element.red = rgb.rgbRed;
d_p->element.green = rgb.rgbGreen;
d_p->element.blue = rgb.rgbBlue;
d_p->element.alpha_channel = rgb.rgbReserved;
++d_p;
++index;
}
d = dpend;
s -= bytes_per_line;
}
}
}
}
}
}
return (false == pixbuf_.empty());
}
bool alpha_channel() const override
{
return false;
}
bool empty() const override
{
return pixbuf_.empty();
}
void close() override
{
pixbuf_.close();
}
nana::size size() const override
{
return pixbuf_.size();
}
void paste(const nana::rectangle& src_r, graph_reference graph, const point& p_dst) const override
{
if(graph && pixbuf_)
pixbuf_.paste(src_r, graph.handle(), p_dst);
}
void stretch(const nana::rectangle& src_r, graph_reference graph, const nana::rectangle& r) const override
{
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

View File

@ -0,0 +1,43 @@
#ifndef NANA_PAINT_DETAIL_IMAGE_ICO_HPP
#define NANA_PAINT_DETAIL_IMAGE_ICO_HPP
#include <nana/paint/detail/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) override;
bool alpha_channel() const override;
bool empty() const override;
void close() override;
nana::size size() const override;
virtual void paste(const nana::rectangle& src_r, graph_reference graph, const point& p_dst) const override;
virtual void stretch(const nana::rectangle&, graph_reference graph, const nana::rectangle& r) const override;
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

View File

@ -0,0 +1,188 @@
#ifndef NANA_PAINT_DETAIL_IMAGE_PNG_HPP
#define NANA_PAINT_DETAIL_IMAGE_PNG_HPP
#include <nana/paint/detail/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 <nana/paint/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) override
{
#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_argb_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].element.red;
p[u].element.red = p[u].element.blue;
p[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_argb_t * rgb_row_ptr = pixbuf_.raw_ptr(0);
for(int y = 0; y < png_height; ++y)
{
png_bytep png_ptr = row_ptrs[y];
pixel_argb_t * rgb_end = rgb_row_ptr + png_width;
if(is_alpha_enabled)
{
for(pixel_argb_t * i = rgb_row_ptr; i < rgb_end; ++i)
{
i->element.red = png_ptr[0];
i->element.green = png_ptr[1];
i->element.blue = png_ptr[2];
i->element.alpha_channel = png_ptr[3];
png_ptr += png_pixel_bytes;
}
}
else
{
for(pixel_argb_t * i = rgb_row_ptr; i < rgb_end; ++i)
{
i->element.red = png_ptr[0];
i->element.green = png_ptr[1];
i->element.blue = png_ptr[2];
i->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 override
{
return pixbuf_.alpha_channel();
}
virtual bool empty() const override
{
return pixbuf_.empty();
}
virtual void close() override
{
pixbuf_.close();
}
virtual nana::size size() const override
{
return pixbuf_.size();
}
void paste(const nana::rectangle& src_r, graph_reference graph, const point& p_dst) const override
{
pixbuf_.paste(src_r, graph.handle(), p_dst);
}
void stretch(const nana::rectangle& src_r, graph_reference dst, const nana::rectangle& r) const override
{
pixbuf_.stretch(src_r, dst.handle(), r);
}
private:
nana::paint::pixel_buffer pixbuf_;
};
}//end namespace detail
}//end namespace paint
}//end namespace nana
#endif