From d13677f703988023df7e7d16d2723106a394febb Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Sun, 12 Apr 2015 23:45:02 +0200 Subject: [PATCH 1/7] add empty group files --- build/vc2013/nana.vcxproj | 123 +++++++++ build/vc2013/nana.vcxproj.filters | 410 +++++++++++++++++++++++++++++ include/nana/gui/widgets/group.hpp | 37 +++ source/gui/widgets/group.cpp | 25 ++ 4 files changed, 595 insertions(+) create mode 100644 include/nana/gui/widgets/group.hpp create mode 100644 source/gui/widgets/group.cpp diff --git a/build/vc2013/nana.vcxproj b/build/vc2013/nana.vcxproj index 7e216758..62b7f037 100644 --- a/build/vc2013/nana.vcxproj +++ b/build/vc2013/nana.vcxproj @@ -213,6 +213,7 @@ + @@ -247,6 +248,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/vc2013/nana.vcxproj.filters b/build/vc2013/nana.vcxproj.filters index f0f82981..d04ac84d 100644 --- a/build/vc2013/nana.vcxproj.filters +++ b/build/vc2013/nana.vcxproj.filters @@ -58,6 +58,51 @@ {e95b4a72-643f-4416-af95-b0bbaf7f0c57} + + {d421a05b-b868-4c3d-bdac-ff57d09f8d07} + + + {64c22f90-dce2-40dc-be98-edc9fe8951e8} + + + {91301ff5-79ac-40cc-a6db-bca2097ea763} + + + {81c62a28-ef5f-43f7-a6ce-e6c186cb411a} + + + {4a1db6f0-a4ee-4514-8e89-54ef9d52e3b8} + + + {c92e890a-ffd5-4efd-8b37-78ed9bbea1e1} + + + {63401f37-26a3-423e-87e6-6840344c3056} + + + {61385c08-f06b-4cf3-8e05-9b47d546164b} + + + {e9eadc97-4a14-4a4e-bb52-52d3a20e2693} + + + {5667eac1-0887-4936-9502-eac4dd8c1c1d} + + + {e6c4a4d9-b4b5-4c56-bb2a-486f3f777ecb} + + + {ac132633-f80c-4983-8e47-fa7fc17f666e} + + + {ee3e9e63-7221-409e-9659-25864e576e16} + + + {ef87057b-dff2-40aa-a05e-9dcd0b335c30} + + + {8ea232cf-bd7c-47e3-a694-6a8898b677d7} + @@ -300,5 +345,370 @@ Source Files\nana\gui\widgets + + Source Files\nana\gui\widgets + + + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\widgets + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui\detail + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui + + + Header Files\gui\widgets\detail + + + Header Files\gui\widgets\detail + + + Header Files\gui\widgets\skeletons + + + Header Files\gui\widgets\skeletons + + + Header Files\gui\widgets\skeletons + + + Header Files\gui\widgets\skeletons + + + Header Files\gui\widgets\skeletons + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\detail\linux_X11 + + + Header Files\detail\linux_X11 + + + Header Files\detail\linux_X11 + + + Header Files\detail\win32 + + + Header Files\extrlib + + + Header Files\extrlib + + + Header Files\extrlib + + + Header Files\extrlib + + + Header Files\filesystem + + + Header Files\filesystem + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\paint\detail + + + Header Files\pat + + + Header Files\system + + + Header Files\system + + + Header Files\system + + + Header Files\system + + + Header Files\threads + + + Header Files\gui\widgets + \ No newline at end of file diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp new file mode 100644 index 00000000..d876becb --- /dev/null +++ b/include/nana/gui/widgets/group.hpp @@ -0,0 +1,37 @@ +/** + * A group widget implementation + * Nana C++ Library(http://www.nanaro.org) + * Copyright(C) 2015 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file: nana/gui/widgets/group.hpp + * + * @contributors: Stefan Pfeifer (st-321), Jinhao, Ariel Vina-Rodriguez (qPCR4vir) + * + * @brief group is a widget used to visually group and layout other widgets. + */ + +#ifndef NANA_GUI_WIDGETS_GROUP_HPP +#define NANA_GUI_WIDGETS_GROUP_HPP + +#include +#include +#include +#include +#include + +namespace nana{ + class group + : public panel + { + + + }; + + + +}//end namespace nana +#endif diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp new file mode 100644 index 00000000..e0958124 --- /dev/null +++ b/source/gui/widgets/group.cpp @@ -0,0 +1,25 @@ +/** + * A group widget implementation + * Nana C++ Library(http://www.nanaro.org) + * Copyright(C) 2015 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file: nana/gui/widgets/group.cpp + * + * @contributors: Stefan Pfeifer (st-321), Jinhao, Ariel Vina-Rodriguez (qPCR4vir) + * + * @brief group is a widget used to visually group and layout other widgets. + */ + + +#include + +namespace nana{ + + + +}//end namespace nana + From ae2a2aeec4a8fa271236f2e3e0fe7c89b68e3b47 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 13 Apr 2015 01:59:30 +0200 Subject: [PATCH 2/7] group with internal panel and place Non tested --- include/nana/gui/widgets/group.hpp | 18 +++++++++++---- source/gui/widgets/group.cpp | 35 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp index d876becb..6cd15af1 100644 --- a/include/nana/gui/widgets/group.hpp +++ b/include/nana/gui/widgets/group.hpp @@ -27,11 +27,21 @@ namespace nana{ class group : public panel { - - + place plc_outer{*this}; + panel content {*this}; + label titel/* {*this}*/; + place plc_inner{content}; + unsigned int gap; + public: + group( widget &owner, ///< + string titel_ ={}, ///< + bool format =false, ///< Use a formated label? + unsigned gap =2, ///< betwen the content and the external limit + rectangle r ={} ///< + ); + place& plc (){ return plc_inner; } + window inner(){ return content; } }; - - }//end namespace nana #endif diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp index e0958124..d613b63d 100644 --- a/source/gui/widgets/group.cpp +++ b/source/gui/widgets/group.cpp @@ -18,8 +18,43 @@ #include namespace nana{ + group::group( widget &owner, ///< + string titel_ /*={}*/, ///< + bool format /*=false*/, ///< + unsigned gap /*=2*/, ///< + rectangle r /*={} */ ///< + ) + : panel (owner, r), + titel (*this, titel_) + { + titel.format(format); + ::nana::size sz = titel.measure(1000); + std::stringstream ft; + ft << "vertical margin=[0," << gap << "," << gap << "," << gap << "]" + << " >" + << " "; + plc_outer.div(ft.str().c_str()); + plc_outer["titel" ] << titel; + plc_outer["content"] << content; + plc_outer.collocate(); + + color obg = owner.bgcolor(); + titel.bgcolor(obg.blend(colors::black, 0.975) ); + color bg=obg.blend(colors::black, 0.950 ); + bgcolor(bg); + + drawing dw(*this); + dw.draw([gap,sz,bg,obg](paint::graphics& graph) + { + graph.rectangle(true, obg); + 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); + }); + } }//end namespace nana From 73e5d3fd8f233700028c4e387012673f26b61cfb Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Mon, 13 Apr 2015 10:53:20 +0200 Subject: [PATCH 3/7] refine group --- include/nana/gui/widgets/group.hpp | 5 +++-- source/gui/widgets/group.cpp | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp index 6cd15af1..19cb6dce 100644 --- a/include/nana/gui/widgets/group.hpp +++ b/include/nana/gui/widgets/group.hpp @@ -33,14 +33,15 @@ namespace nana{ place plc_inner{content}; unsigned int gap; public: - group( widget &owner, ///< - string titel_ ={}, ///< + group( window parent, ///< + string titel_ ={STR("")}, ///< bool format =false, ///< Use a formated label? unsigned gap =2, ///< betwen the content and the external limit rectangle r ={} ///< ); place& plc (){ return plc_inner; } window inner(){ return content; } + label& lbl (){ return titel; } }; }//end namespace nana diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp index d613b63d..b4905afe 100644 --- a/source/gui/widgets/group.cpp +++ b/source/gui/widgets/group.cpp @@ -18,13 +18,13 @@ #include namespace nana{ - group::group( widget &owner, ///< + group::group( window parent, ///< string titel_ /*={}*/, ///< bool format /*=false*/, ///< unsigned gap /*=2*/, ///< rectangle r /*={} */ ///< ) - : panel (owner, r), + : panel (parent, r), titel (*this, titel_) { titel.format(format); @@ -40,15 +40,18 @@ namespace nana{ plc_outer["content"] << content; plc_outer.collocate(); - color obg = owner.bgcolor(); - titel.bgcolor(obg.blend(colors::black, 0.975) ); - color bg=obg.blend(colors::black, 0.950 ); - bgcolor(bg); + 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); - dw.draw([gap,sz,bg,obg](paint::graphics& graph) + + // 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, obg); + 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)) ), From f76258997567625ebea7e2bf9e07d96c0ae1fe25 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 12 Jul 2015 10:56:51 +0800 Subject: [PATCH 4/7] fix newline issue of text_editor --- source/gui/widgets/skeletons/text_editor.cpp | 112 ++++++++++++------- 1 file changed, 70 insertions(+), 42 deletions(-) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 6cc33b51..d7a4533f 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -2534,8 +2534,34 @@ namespace nana{ namespace widgets return true; } + std::size_t eat_endl(const wchar_t* str, std::size_t pos) + { + auto ch = str[pos]; + if (0 == ch) + return pos; + + const wchar_t * endlstr; + switch (ch) + { + case L'\n': + endlstr = L"\n\r"; + break; + case L'\r': + endlstr = L"\r\n"; + break; + default: + return pos; + } + + if (std::memcmp(str + pos, endlstr, sizeof(wchar_t) * 2) == 0) + return pos + 2; + + return pos + 1; + } + bool text_editor::_m_resolve_text(const nana::string& text, std::vector> & lines) { + auto const text_str = text.data(); std::size_t begin = 0; while (true) { @@ -2548,13 +2574,23 @@ namespace nana{ namespace widgets } lines.emplace_back(begin, pos); - begin = text.find_first_not_of(STR("\r\n"), pos + 1); + + pos = eat_endl(text_str, pos); + + begin = text.find_first_not_of(STR("\r\n"), pos); //The number of new lines minus one - const auto chp_end = text.data() + (begin == text.npos ? text.size() : begin); - for (auto chp = text.data() + (pos + 1); chp != chp_end; ++chp) - if (*chp == '\n') + const auto chp_end = text_str + (begin == text.npos ? text.size() : begin); + + for (auto chp = text_str + pos; chp != chp_end; ++chp) + { + auto eats = eat_endl(chp, 0); + if (eats) + { lines.emplace_back(0, 0); + chp += (eats - 1); + } + } if (text.npos == begin) { @@ -2742,50 +2778,43 @@ namespace nana{ namespace widgets const auto str_end = str + len; auto & entities = parser.entities(); - for (auto & ent : entities) + for (auto & ent : entities) + { + const ::nana::char_t* ent_begin = nullptr; + + int ent_off = 0; + if (str <= ent.begin && ent.begin < str_end) { - const ::nana::char_t* ent_begin = nullptr; + ent_begin = ent.begin; + ent_off = std::accumulate(glyphs, glyphs + (ent.begin - str), 0); + } + else if (ent.begin <= str && str < ent.end) + ent_begin = str; - int ent_off = 0; - if (str <= ent.begin && ent.begin < str_end) + if (ent_begin) + { + auto ent_end = (ent.end < str_end ? ent.end : str_end); + auto ent_pixels = std::accumulate(glyphs + (ent_begin - str), glyphs + (ent_end - str), unsigned{}); + + canvas.set_color(ent.scheme->bgcolor.invisible() ? _m_bgcolor() : ent.scheme->bgcolor); + canvas.set_text_color(ent.scheme->fgcolor.invisible() ? fgcolor : ent.scheme->fgcolor); + + canvas.rectangle(true); + + ent_pos.x += ent_off; + if (rtl) { - ent_begin = ent.begin; - ent_off = std::accumulate(glyphs, glyphs + (ent.begin - str), 0); + //draw the whole text if it is a RTL text, because Arbic language is transformable. + canvas.string({}, str, len); + graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas, ::nana::point{ ent_off, 0 }); } - else if (ent.begin <= str && str < ent.end) - ent_begin = str; - - if (ent_begin) + else { - auto ent_end = (ent.end < str_end ? ent.end : str_end); - auto ent_pixels = std::accumulate(glyphs + (ent_begin - str), glyphs + (ent_end - str), unsigned{}); - - if (ent.scheme->bgcolor.invisible()) - canvas.set_color(_m_bgcolor()); - else - canvas.set_color(ent.scheme->bgcolor); - canvas.rectangle(true); - - if (ent.scheme->fgcolor.invisible()) - canvas.set_text_color(fgcolor); - else - canvas.set_text_color(ent.scheme->fgcolor); - - ent_pos.x += ent_off; - - if (rtl) - { - //draw the whole text if it is a RTL text, because Arbic language is transformable. - canvas.string({}, str, len); - graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas, ::nana::point{ ent_off, 0 }); - } - else - { - canvas.string({}, ent_begin, ent_end - ent_begin); - graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas); - } + canvas.string({}, ent_begin, ent_end - ent_begin); + graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas); } } + } } void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& str_pos, const nana::string& str, bool if_mask) const @@ -2797,7 +2826,6 @@ namespace nana{ namespace widgets if (if_mask && mask_char_) mask_str.reset(new nana::string(str.size(), mask_char_)); - auto & linestr = (if_mask && mask_char_ ? *mask_str : str); unicode_bidi bidi; From 1eb76307e4f3500254c98173ba5459597cd84070 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 13 Jul 2015 00:23:54 +0800 Subject: [PATCH 5/7] image::paste throws exception if graphics or image is empty --- include/nana/gui/detail/effects_renderer.hpp | 2 +- .../widgets/skeletons/text_token_stream.hpp | 2 +- include/nana/paint/detail/image_bmp.hpp | 371 ------------------ include/nana/paint/detail/image_ico.hpp | 43 -- .../paint/detail/image_impl_interface.hpp | 2 +- include/nana/paint/detail/image_png.hpp | 188 --------- include/nana/paint/image.hpp | 2 +- include/nana/paint/pixel_buffer.hpp | 6 +- source/gui/animation.cpp | 4 +- source/gui/widgets/button.cpp | 2 +- source/gui/widgets/treebox.cpp | 2 +- .../paint/detail/native_paint_interface.cpp | 10 +- source/paint/graphics.cpp | 6 +- source/paint/image.cpp | 43 +- source/paint/pixel_buffer.cpp | 18 +- 15 files changed, 59 insertions(+), 642 deletions(-) delete mode 100644 include/nana/paint/detail/image_bmp.hpp delete mode 100644 include/nana/paint/detail/image_ico.hpp delete mode 100644 include/nana/paint/detail/image_png.hpp diff --git a/include/nana/gui/detail/effects_renderer.hpp b/include/nana/gui/detail/effects_renderer.hpp index 2937a1d5..2c4522a3 100644 --- a/include/nana/gui/detail/effects_renderer.hpp +++ b/include/nana/gui/detail/effects_renderer.hpp @@ -170,7 +170,7 @@ namespace nana{ pixbuf.pixel(0, r.height - 1, px2); pixbuf.pixel(r.width - 1, r.height - 1, px3); - pixbuf.paste(wd->root, r.x, r.y); + pixbuf.paste(wd->root, { r.x, r.y }); std::vector overlaps; if(window_layer::read_overlaps(wd, visual, overlaps)) diff --git a/include/nana/gui/widgets/skeletons/text_token_stream.hpp b/include/nana/gui/widgets/skeletons/text_token_stream.hpp index beae23ee..eef80358 100644 --- a/include/nana/gui/widgets/skeletons/text_token_stream.hpp +++ b/include/nana/gui/widgets/skeletons/text_token_stream.hpp @@ -576,7 +576,7 @@ namespace nana{ namespace widgets{ namespace skeletons if(size_ != image_.size()) image_.stretch(::nana::rectangle{ image_.size() }, graph, nana::rectangle(x, y, size_.width, size_.height)); else - image_.paste(graph, x, y); + image_.paste(graph, point{ x, y }); } virtual const nana::size & size() const override diff --git a/include/nana/paint/detail/image_bmp.hpp b/include/nana/paint/detail/image_bmp.hpp deleted file mode 100644 index 5397faef..00000000 --- a/include/nana/paint/detail/image_bmp.hpp +++ /dev/null @@ -1,371 +0,0 @@ -/* - * 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 "image_impl_interface.hpp" -#include - -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(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(sizeof(bitmap_file_header))) - return false; - - std::unique_ptr buffer(new char[static_cast(size)]); - - ifs.read(buffer.get(), size); - if(size == ifs.gcount()) - { - bitmap_file_header * header = reinterpret_cast(buffer.get()); - if((header->bfType == 0x4D42) && (static_cast(header->bfSize) == size)) - { - unsigned char* bits = reinterpret_cast(buffer.get() + header->bfOffBits); - bitmap_info * info = reinterpret_cast(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 - { - 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 diff --git a/include/nana/paint/detail/image_ico.hpp b/include/nana/paint/detail/image_ico.hpp deleted file mode 100644 index 8c66d19b..00000000 --- a/include/nana/paint/detail/image_ico.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#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 ptr_t; -#else - typedef std::shared_ptr 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 diff --git a/include/nana/paint/detail/image_impl_interface.hpp b/include/nana/paint/detail/image_impl_interface.hpp index b2a7df50..3d74ce5c 100644 --- a/include/nana/paint/detail/image_impl_interface.hpp +++ b/include/nana/paint/detail/image_impl_interface.hpp @@ -20,7 +20,7 @@ namespace nana{ namespace paint{ 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 paste(const nana::rectangle& src_r, graph_reference dst, const point& p_dst) 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 diff --git a/include/nana/paint/detail/image_png.hpp b/include/nana/paint/detail/image_png.hpp deleted file mode 100644 index 9f54e8ef..00000000 --- a/include/nana/paint/detail/image_png.hpp +++ /dev/null @@ -1,188 +0,0 @@ -#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 -#else - #include -#endif - -#include -#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(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(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_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 - { - 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 diff --git a/include/nana/paint/image.hpp b/include/nana/paint/image.hpp index b335a4fe..2b127586 100644 --- a/include/nana/paint/image.hpp +++ b/include/nana/paint/image.hpp @@ -43,7 +43,7 @@ namespace paint bool alpha() const; nana::size size() const; - void paste(graphics& dst, int x, int y) const; + void paste(graphics& dst, const point& p_dst) 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(tar, pos.x, pos.y); + frmobj.u.oneshot->paste(tar, pos); }); break; case frame::kind::framebuilder: @@ -230,7 +230,7 @@ namespace nana switch(frmobj.type) { case frame::kind::oneshot: - frmobj.u.oneshot->paste(graph, pos.x, pos.y); + frmobj.u.oneshot->paste(graph, pos); break; case frame::kind::framebuilder: if(rebuild_frame) diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index a43c47b4..9a4c676e 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -258,7 +258,7 @@ namespace nana{ namespace drawerbase } if(attr_.icon) - attr_.icon->paste(graph, 3, (gsize.height - icon_sz.height) / 2); + attr_.icon->paste(graph, point{ 3, static_cast(gsize.height - icon_sz.height) / 2 }); } void trigger::_m_draw(graph_reference graph) diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp index 7e026e6c..98578aad 100644 --- a/source/gui/widgets/treebox.cpp +++ b/source/gui/widgets/treebox.cpp @@ -1263,7 +1263,7 @@ namespace nana img->stretch(::nana::rectangle{ size }, graph, attr.area); } else - img->paste(graph, attr.area.x + static_cast(attr.area.width - size.width) / 2, attr.area.y + static_cast(attr.area.height - size.height) / 2); + img->paste(graph, point{ attr.area.x + static_cast(attr.area.width - size.width) / 2, attr.area.y + static_cast(attr.area.height - size.height) / 2 }); } } } diff --git a/source/paint/detail/native_paint_interface.cpp b/source/paint/detail/native_paint_interface.cpp index 05b66977..153ac5f0 100644 --- a/source/paint/detail/native_paint_interface.cpp +++ b/source/paint/detail/native_paint_interface.cpp @@ -100,8 +100,8 @@ namespace detail void blend(drawable_type dw, const rectangle& area, pixel_color_t color, double fade_rate) { - if(fade_rate <= 0) return; - if(fade_rate > 1) fade_rate = 1; + if (fade_rate <= 0) return; + if (fade_rate > 1) fade_rate = 1; rectangle r; if (false == ::nana::overlap(rectangle{ drawable_size(dw) }, area, r)) @@ -114,11 +114,11 @@ namespace detail double lrate = 1 - fade_rate; pixel_buffer pixbuf(dw, r.y, r.height); - for(std::size_t row = 0; row < r.height; ++row) + for (std::size_t row = 0; row < r.height; ++row) { auto i = pixbuf.raw_ptr(row) + r.x; const auto end = i + r.width; - for(; i < end; ++i) + for (; i < end; ++i) { unsigned px_r = ((static_cast((i->value & 0xFF0000) * lrate) + red) & 0xFF0000); unsigned px_g = ((static_cast((i->value & 0xFF00) * lrate) + green) & 0xFF00); @@ -126,7 +126,7 @@ namespace detail i->value = (px_r | px_g | px_b); } } - pixbuf.paste(nana::rectangle(r.x, 0, r.width, r.height), dw, r.x, r.y); + pixbuf.paste(nana::rectangle(r.x, 0, r.width, r.height), dw, point{r.x, r.y}); } nana::size raw_text_extent_size(drawable_type dw, const nana::char_t* text, std::size_t len) diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 76e9aefc..343f4c6f 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -618,7 +618,7 @@ namespace paint { pixel_buffer pixbuf(handle_, 0, 0); pixbuf.blur(r, radius); - pixbuf.paste(handle_, 0, 0); + pixbuf.paste(handle_, point{}); } } @@ -677,7 +677,7 @@ namespace paint } delete [] tablebuf; - pixbuf.paste(handle_, 0, 0); + pixbuf.paste(handle_, point{}); if(changed_ == false) changed_ = true; } } @@ -1074,7 +1074,7 @@ namespace paint if (pxbuf_.open(handle_)) { pxbuf_.gradual_rectangle(rct, from, to, 0.0, vertical); - pxbuf_.paste(handle_, 0, 0); + pxbuf_.paste(handle_, point{}); } #elif defined(NANA_X11) if (nullptr == handle_) return; diff --git a/source/paint/image.cpp b/source/paint/image.cpp index 39aac942..2312c9c6 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -16,14 +16,15 @@ #include #include #include +#include #include #include #if defined(NANA_ENABLE_PNG) - #include + #include "detail/image_png.hpp" #endif -#include -#include +#include "detail/image_bmp.hpp" +#include "detail/image_ico.hpp" namespace nana { @@ -89,12 +90,12 @@ namespace paint return size_; } - void image_ico::paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const + void image_ico::paste(const nana::rectangle& src_r, graph_reference graph, const point& p_dst) const { if(ptr_ && (graph.empty() == false)) { #if defined(NANA_WINDOWS) - ::DrawIconEx(graph.handle()->context, x, y, *ptr_, src_r.width, src_r.height, 0, 0, DI_NORMAL); + ::DrawIconEx(graph.handle()->context, p_dst.x, p_dst.y, *ptr_, src_r.width, src_r.height, 0, 0, DI_NORMAL); #endif } } @@ -260,22 +261,40 @@ namespace paint return (image_ptr_ ? image_ptr_->size() : nana::size()); } - void image::paste(graphics& dst, int x, int y) const + void image::paste(graphics& dst, const point& p_dst) const { - if(image_ptr_) - image_ptr_->paste(::nana::rectangle{ image_ptr_->size() }, dst, x, y); + if(image_ptr_ && !dst.empty()) + image_ptr_->paste(::nana::rectangle{ image_ptr_->size() }, dst, p_dst); + + if (!image_ptr_) + throw std::runtime_error("image is empty"); + + if (dst.empty()) + throw std::invalid_argument("graphics is empty"); } void image::paste(const nana::rectangle& r_src, graphics & dst, const nana::point& p_dst) const { - if(image_ptr_) - image_ptr_->paste(r_src, dst, p_dst.x, p_dst.y); + if(image_ptr_ && !dst.empty()) + image_ptr_->paste(r_src, dst, p_dst); + + if (!image_ptr_) + throw std::runtime_error("image is empty"); + + if (dst.empty()) + throw std::invalid_argument("graphics is empty"); } void image::stretch(const nana::rectangle& r_src, graphics& dst, const nana::rectangle & r_dst) const { - if(image_ptr_) - image_ptr_->stretch(r_src, dst, r_dst); + if(image_ptr_ && !dst.empty()) + image_ptr_->stretch(r_src, dst, r_dst); + + if (!image_ptr_) + throw std::runtime_error("image is empty"); + + if (dst.empty()) + throw std::invalid_argument("graphics is empty"); } //end class image diff --git a/source/paint/pixel_buffer.cpp b/source/paint/pixel_buffer.cpp index 787d2532..e89c3a0e 100644 --- a/source/paint/pixel_buffer.cpp +++ b/source/paint/pixel_buffer.cpp @@ -633,13 +633,13 @@ namespace nana{ namespace paint *reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer + x) + y * sp->bytes_per_line) = px; } - void pixel_buffer::paste(drawable_type drawable, int x, int y) const + void pixel_buffer::paste(drawable_type drawable, const point& p_dst) const { if(storage_) - paste(nana::rectangle(storage_->pixel_size), drawable, x, y); + paste(nana::rectangle(storage_->pixel_size), drawable, p_dst); } - void pixel_buffer::paste(const nana::rectangle& src_r, drawable_type drawable, int x, int y) const + void pixel_buffer::paste(const nana::rectangle& src_r, drawable_type drawable, const point& p_dst) const { auto sp = storage_.get(); if(drawable && sp) @@ -647,7 +647,7 @@ namespace nana{ namespace paint if(sp->alpha_channel) { nana::rectangle s_good_r, d_good_r; - if(overlap(src_r, sp->pixel_size, nana::rectangle(x, y, src_r.width, src_r.height), paint::detail::drawable_size(drawable), s_good_r, d_good_r)) + if(overlap(src_r, sp->pixel_size, nana::rectangle(p_dst.x, p_dst.y, src_r.width, src_r.height), paint::detail::drawable_size(drawable), s_good_r, d_good_r)) { pixel_buffer d_pixbuf; d_pixbuf.attach(drawable, d_good_r); @@ -660,16 +660,16 @@ namespace nana{ namespace paint assign_windows_bitmapinfo(sp->pixel_size, bi); ::SetDIBitsToDevice(drawable->context, - x, y, src_r.width, src_r.height, + p_dst.x, p_dst.y, src_r.width, src_r.height, src_r.x, static_cast(sp->pixel_size.height) - src_r.y - src_r.height, 0, sp->pixel_size.height, sp->raw_pixel_buffer, &bi, DIB_RGB_COLORS); #elif defined(NANA_X11) - sp->put(drawable->pixmap, drawable->context, src_r.x, src_r.y, x, y, src_r.width, src_r.height); + sp->put(drawable->pixmap, drawable->context, src_r.x, src_r.y, p_dst.x, p_dst.y, src_r.width, src_r.height); #endif } } - void pixel_buffer::paste(native_window_type wd, int x, int y) const + void pixel_buffer::paste(native_window_type wd, const point& p_dst) const { auto sp = storage_.get(); if(nullptr == wd || nullptr == sp) return; @@ -681,7 +681,7 @@ namespace nana{ namespace paint assign_windows_bitmapinfo(sp->pixel_size, bi); ::SetDIBitsToDevice(handle, - x, y, sp->pixel_size.width, sp->pixel_size.height, + p_dst.x, p_dst.y, sp->pixel_size.width, sp->pixel_size.height, 0, 0, 0, sp->pixel_size.height, sp->raw_pixel_buffer, &bi, DIB_RGB_COLORS); @@ -690,7 +690,7 @@ namespace nana{ namespace paint #elif defined(NANA_X11) auto & spec = nana::detail::platform_spec::instance(); Display * disp = spec.open_display(); - sp->put(reinterpret_cast(wd), XDefaultGC(disp, XDefaultScreen(disp)), 0, 0, x, y, sp->pixel_size.width, sp->pixel_size.height); + sp->put(reinterpret_cast(wd), XDefaultGC(disp, XDefaultScreen(disp)), 0, 0, p_dst.x, p_dst.y, sp->pixel_size.width, sp->pixel_size.height); #endif } From e788c575125a1adb37ae935656f50988447be9cb Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 13 Jul 2015 04:57:01 +0800 Subject: [PATCH 6/7] add some missing files, refactor group --- include/nana/gui/widgets/group.hpp | 18 +- source/gui/widgets/group.cpp | 99 +++++--- source/paint/detail/image_bmp.hpp | 371 +++++++++++++++++++++++++++++ source/paint/detail/image_ico.hpp | 43 ++++ source/paint/detail/image_png.hpp | 188 +++++++++++++++ 5 files changed, 674 insertions(+), 45 deletions(-) create mode 100644 source/paint/detail/image_bmp.hpp create mode 100644 source/paint/detail/image_ico.hpp create mode 100644 source/paint/detail/image_png.hpp diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp index 19cb6dce..26a0e408 100644 --- a/include/nana/gui/widgets/group.hpp +++ b/include/nana/gui/widgets/group.hpp @@ -18,10 +18,7 @@ #define NANA_GUI_WIDGETS_GROUP_HPP #include -#include #include -#include -#include namespace nana{ class group @@ -29,19 +26,26 @@ namespace nana{ { place plc_outer{*this}; panel 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 impl_; }; }//end namespace nana diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp index b4905afe..e18f0bbd 100644 --- a/source/gui/widgets/group.cpp +++ b/source/gui/widgets/group.cpp @@ -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 +#include +#include 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 << "]" + << " >" + << " "; + 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 << "]" - << " >" - << " "; - 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 diff --git a/source/paint/detail/image_bmp.hpp b/source/paint/detail/image_bmp.hpp new file mode 100644 index 00000000..77f87df2 --- /dev/null +++ b/source/paint/detail/image_bmp.hpp @@ -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 +#include + +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(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(sizeof(bitmap_file_header))) + return false; + + std::unique_ptr buffer(new char[static_cast(size)]); + + ifs.read(buffer.get(), size); + if(size == ifs.gcount()) + { + bitmap_file_header * header = reinterpret_cast(buffer.get()); + if((header->bfType == 0x4D42) && (static_cast(header->bfSize) == size)) + { + unsigned char* bits = reinterpret_cast(buffer.get() + header->bfOffBits); + bitmap_info * info = reinterpret_cast(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 diff --git a/source/paint/detail/image_ico.hpp b/source/paint/detail/image_ico.hpp new file mode 100644 index 00000000..37226431 --- /dev/null +++ b/source/paint/detail/image_ico.hpp @@ -0,0 +1,43 @@ +#ifndef NANA_PAINT_DETAIL_IMAGE_ICO_HPP +#define NANA_PAINT_DETAIL_IMAGE_ICO_HPP + +#include + +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 ptr_t; +#else + typedef std::shared_ptr 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 diff --git a/source/paint/detail/image_png.hpp b/source/paint/detail/image_png.hpp new file mode 100644 index 00000000..cab432cd --- /dev/null +++ b/source/paint/detail/image_png.hpp @@ -0,0 +1,188 @@ +#ifndef NANA_PAINT_DETAIL_IMAGE_PNG_HPP +#define NANA_PAINT_DETAIL_IMAGE_PNG_HPP + +#include + +//Separate the libpng from the package that system provides. +#if defined(NANA_LIBPNG) + #include +#else + #include +#endif + +#include +#include + +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(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(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_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 From 19a44b772b1194813047c8fb7a509b21d0c13f04 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 14 Jul 2015 02:03:42 +0800 Subject: [PATCH 7/7] develop group --- include/nana/filesystem/filesystem.hpp | 5 +-- include/nana/gui/widgets/group.hpp | 41 +++++++++++++---------- source/gui/widgets/group.cpp | 45 ++++++++++++++++++++------ 3 files changed, 63 insertions(+), 28 deletions(-) diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index b00760d2..284faea1 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -1,12 +1,13 @@ /* * A filesystem Implementation - * Copyright(C) 2003 Jinhao(cnjinhao@hotmail.com) + * 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: stdex/filesystem/filesystem.hpp + * @file: nana/filesystem/filesystem.hpp * @description: * file_iterator is a toolkit for applying each file and directory in a * specified path. diff --git a/include/nana/gui/widgets/group.hpp b/include/nana/gui/widgets/group.hpp index 26a0e408..cff1f21e 100644 --- a/include/nana/gui/widgets/group.hpp +++ b/include/nana/gui/widgets/group.hpp @@ -9,7 +9,7 @@ * * @file: nana/gui/widgets/group.hpp * - * @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. */ @@ -21,27 +21,34 @@ #include namespace nana{ - class group - : public panel - { - place plc_outer{*this}; - panel content {*this}; - place plc_inner{content}; - + class group + : public panel + { struct implement; - public: - group( window parent, ///< - std::wstring titel_ ={STR("")}, ///< - bool format =false, ///< Use a formated label? - unsigned gap =2, ///< betwen the content and the external limit - rectangle r ={} ///< - ); + public: + group( window parent, ///< + 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; } + place& get_place(); + + template + Widget* create_child(const char* field, Args && ... args) + { + auto wdg = new Widget(inner(), std::forward(args)...); + _m_add_child(field, wdg); + return wdg; + } + + window inner(); private: + void _m_add_child(const char* field, widget*); + ::nana::string _m_caption() const override; void _m_caption(::nana::string&&) override; private: diff --git a/source/gui/widgets/group.cpp b/source/gui/widgets/group.cpp index e18f0bbd..5b61a9e3 100644 --- a/source/gui/widgets/group.cpp +++ b/source/gui/widgets/group.cpp @@ -23,7 +23,17 @@ namespace nana{ struct group::implement { - label caption; + label caption; + panel content; + place place_outter; + place place_content; + + implement(group* host): + caption(*host), + content(*host), + place_outter(*host), + place_content(content) + {} }; group::group( window parent, ///< @@ -33,28 +43,30 @@ namespace nana{ rectangle r /*={} */ ///< ) : panel (parent, r), - impl_(new implement) + impl_(new implement(this)) { - 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 << "]" + ft << "vert margin=[0," << gap << ","< >" << " "; - plc_outer.div(ft.str().c_str()); + + auto & outter = impl_->place_outter; + + outter.div(ft.str().c_str()); - plc_outer["titel" ] << impl_->caption; - plc_outer["content"] << content; - plc_outer.collocate(); + outter["titel"] << impl_->caption; + outter["content"] << impl_->content; + outter.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); + impl_->content.bgcolor(bg); drawing dw(*this); @@ -73,6 +85,21 @@ namespace nana{ { } + place& group::get_place() + { + return impl_->place_content; + } + + window group::inner() + { + return impl_->content; + } + + void group::_m_add_child(const char* field, widget* wdg) + { + impl_->place_content[field] << wdg->handle(); + } + ::nana::string group::_m_caption() const { return impl_->caption.caption();