├── .gitignore ├── example ├── res │ ├── boost.ico │ └── example.rc ├── cpp17 │ ├── Jamfile.v2 │ ├── p1108.cpp │ └── geometry.cpp ├── to_string.hpp ├── cpp11 │ ├── stacktrace.cpp │ ├── Jamfile.v2 │ ├── hello.cpp │ ├── demo.cpp │ ├── beman.cpp │ ├── minimal.cpp │ ├── beman.html │ ├── bootstrap.cpp │ └── io2d.cpp ├── hello.cpp ├── native.cpp ├── Jamfile.v2 ├── random.cpp ├── timer.cpp ├── thread.cpp ├── lexical_cast.cpp └── spirit.cpp ├── doc ├── doxygen │ ├── images │ │ ├── demo_unity.png │ │ ├── demo_windows7.png │ │ ├── bootstrap_unity.png │ │ ├── demo_windows10.png │ │ ├── demo_windows95.png │ │ ├── demo_windows_xp.png │ │ └── hello_windows7.png │ └── footer.html ├── ui.qbk └── Jamfile.v2 ├── test ├── coord_polygon_test.cpp ├── coord_geometry_test.cpp ├── Jamfile.v2 ├── native_test.cpp ├── log_test.cpp ├── image_test.cpp ├── stream_test.cpp ├── color_test.cpp ├── cache_test.cpp └── font_test.cpp ├── meta └── libraries.json ├── include └── boost │ └── ui │ ├── native │ ├── config.hpp │ ├── all.hpp │ ├── color.hpp │ ├── font.hpp │ ├── string.hpp │ ├── image.hpp │ ├── winmain.cpp │ ├── widget.hpp │ ├── impl │ │ └── canvas.hpp │ └── event.hpp │ ├── def.hpp │ ├── audio.hpp │ ├── locale.hpp │ ├── detail │ ├── memcheck.hpp │ ├── shared_count.hpp │ ├── event.hpp │ └── widget.hpp │ ├── panel.hpp │ ├── dialog.hpp │ ├── event_loop.hpp │ ├── hyperlink.hpp │ ├── group_box.hpp │ ├── color_io.hpp │ ├── canvas.hpp │ ├── thread.hpp │ ├── button.hpp │ ├── frame.hpp │ ├── image_widget.hpp │ ├── web_widget.hpp │ ├── label.hpp │ ├── coord_io.hpp │ ├── notebook.hpp │ ├── line.hpp │ ├── status_bar.hpp │ ├── window.hpp │ ├── image.hpp │ ├── config.hpp │ ├── choice.hpp │ ├── progress_bar.hpp │ ├── list_box.hpp │ ├── slider.hpp │ ├── check_box.hpp │ ├── text_box.hpp │ ├── font.hpp │ └── layout.hpp ├── Jamfile.v2 ├── src ├── audio.cpp ├── res │ └── boost.xpm ├── thread.cpp ├── stream.cpp ├── panel.cpp ├── canvas.cpp ├── locale.cpp ├── line.cpp ├── event_loop.cpp ├── hyperlink.cpp ├── button.cpp ├── dialog.cpp ├── group_box.cpp ├── status_bar.cpp ├── web_widget.cpp ├── window.cpp ├── image_widget.cpp ├── event.cpp ├── label.cpp ├── notebook.cpp ├── strings_box.cpp ├── choice.cpp ├── progress_bar.cpp ├── combo_box.cpp ├── frame.cpp ├── slider.cpp └── list_box.cpp ├── .travis.yml ├── appveyor.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | doc/html/ 2 | doc/ui_reference.xml 3 | -------------------------------------------------------------------------------- /example/res/boost.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kosenko/ui/HEAD/example/res/boost.ico -------------------------------------------------------------------------------- /doc/doxygen/images/demo_unity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kosenko/ui/HEAD/doc/doxygen/images/demo_unity.png -------------------------------------------------------------------------------- /doc/doxygen/images/demo_windows7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kosenko/ui/HEAD/doc/doxygen/images/demo_windows7.png -------------------------------------------------------------------------------- /doc/doxygen/images/bootstrap_unity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kosenko/ui/HEAD/doc/doxygen/images/bootstrap_unity.png -------------------------------------------------------------------------------- /doc/doxygen/images/demo_windows10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kosenko/ui/HEAD/doc/doxygen/images/demo_windows10.png -------------------------------------------------------------------------------- /doc/doxygen/images/demo_windows95.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kosenko/ui/HEAD/doc/doxygen/images/demo_windows95.png -------------------------------------------------------------------------------- /doc/doxygen/images/demo_windows_xp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kosenko/ui/HEAD/doc/doxygen/images/demo_windows_xp.png -------------------------------------------------------------------------------- /doc/doxygen/images/hello_windows7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kosenko/ui/HEAD/doc/doxygen/images/hello_windows7.png -------------------------------------------------------------------------------- /test/coord_polygon_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_USE_POLYGON 7 | 8 | #include "coord_test.cpp" 9 | -------------------------------------------------------------------------------- /meta/libraries.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "ui", 3 | "name": "User Interface", 4 | "authors": [ "Kolya Kosenko" ], 5 | "maintainers": [ "Kolya Kosenko " ], 6 | "description": "Interacts with users through electronic devices", 7 | "category": [ "System", "IO", "Image-processing" ] 8 | } 9 | -------------------------------------------------------------------------------- /example/res/example.rc: -------------------------------------------------------------------------------- 1 | // Windows resources file for examples 2 | // Copyright (c) 2017 Kolya Kosenko 3 | 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // See http://www.boost.org/LICENSE_1_0.txt 6 | 7 | // Application icon (first in the alphabetical order) 8 | aaaaaaaaa ICON "boost.ico" 9 | 10 | #include 11 | -------------------------------------------------------------------------------- /include/boost/ui/native/config.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_CONFIG_HPP 7 | #define BOOST_UI_NATIVE_CONFIG_HPP 8 | 9 | #define wxNO_UNSAFE_WXSTRING_CONV 10 | 11 | #endif // BOOST_UI_NATIVE_CONFIG_HPP 12 | -------------------------------------------------------------------------------- /doc/ui.qbk: -------------------------------------------------------------------------------- 1 | [library Boost.UI 2 | [quickbook 1.6] 3 | [id ui] 4 | [copyright 2017 Kolya Kosenko] 5 | [license 6 | Distributed under the Boost Software License, Version 1.0. 7 | (See accompanying file LICENSE_1_0.txt or copy at 8 | [@http://www.boost.org/LICENSE_1_0.txt]) 9 | ] 10 | ] 11 | 12 | [xinclude ui_reference.xml] 13 | -------------------------------------------------------------------------------- /Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost UI Library Build Jamfile 2 | 3 | # Copyright (c) 2017 Kolya Kosenko 4 | 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # See www.boost.org/LICENSE_1_0.txt 7 | 8 | build-project build ; 9 | build-project test ; 10 | build-project example ; 11 | build-project example/cpp11 ; 12 | build-project example/cpp17 ; 13 | build-project doc ; 14 | -------------------------------------------------------------------------------- /src/audio.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace boost { 15 | namespace ui { 16 | 17 | void beep() 18 | { 19 | wxBell(); 20 | } 21 | 22 | } // namespace ui 23 | } // namespace boost 24 | -------------------------------------------------------------------------------- /test/coord_geometry_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #if defined(__cplusplus) && __cplusplus >= 201703L 7 | 8 | #define BOOST_UI_USE_GEOMETRY 9 | 10 | #include "coord_test.cpp" 11 | 12 | #else 13 | 14 | #include 15 | #include 16 | 17 | int cpp_main(int argc, char* argv[]) 18 | { 19 | return boost::report_errors(); 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /example/cpp17/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost UI Library Build Jamfile 2 | 3 | # Copyright (c) 2018 Kolya Kosenko 4 | 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # See www.boost.org/LICENSE_1_0.txt 7 | 8 | project 9 | : requirements 10 | /boost/ui//boost_ui 11 | windows:gui 12 | ; 13 | 14 | obj winmain : ../../include/boost/ui/native/winmain.cpp ; 15 | obj example_rc : ../res/example.rc ; 16 | 17 | exe geometry : geometry.cpp example_rc winmain ; 18 | exe p1108 : p1108.cpp example_rc winmain ; 19 | -------------------------------------------------------------------------------- /example/to_string.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_EXAMPLE_TO_STRING_HPP 7 | #define BOOST_UI_EXAMPLE_TO_STRING_HPP 8 | 9 | #include 10 | #include 11 | 12 | template 13 | std::string to_string(T value) 14 | { 15 | //return std::to_string(value); 16 | 17 | std::ostringstream ss; 18 | ss << value; 19 | return ss.str(); 20 | } 21 | 22 | #endif // BOOST_UI_EXAMPLE_TO_STRING_HPP 23 | -------------------------------------------------------------------------------- /include/boost/ui/native/all.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_ALL_HPP 7 | #define BOOST_UI_NATIVE_ALL_HPP 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #endif // BOOST_UI_NATIVE_ALL_HPP 19 | -------------------------------------------------------------------------------- /doc/doxygen/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/res/boost.xpm: -------------------------------------------------------------------------------- 1 | static const char* boost_xpm[] = { 2 | "16 16 8 1", 3 | " c None", 4 | ". c #B4E6E6", 5 | "+ c #669ACE", 6 | "@ c #3266B4", 7 | "# c #4C80E6", 8 | "$ c #669AFE", 9 | "% c #329AB4", 10 | "& c #80B4E6", 11 | " ", 12 | " ..... ", 13 | " +@#+$ ", 14 | " .%$+$$. ", 15 | " +@+%$..$.$. ", 16 | " +%@%..#$$$& ", 17 | " +$+.$++$$$. ", 18 | " .....%%$%$$$ ", 19 | " &@%@+.+$+$$#. ", 20 | " @@%@%&.%#+%$ ", 21 | " +%#@+@%.&+$$. ", 22 | " +@@%@%@. ", 23 | " .@@@#@+ ", 24 | " +@@@% ", 25 | " .... ", 26 | " "}; 27 | -------------------------------------------------------------------------------- /include/boost/ui/native/color.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_COLOR_HPP 7 | #define BOOST_UI_NATIVE_COLOR_HPP 8 | 9 | #include 10 | #include 11 | 12 | namespace boost { 13 | namespace ui { 14 | namespace native { 15 | 16 | inline wxColor from_color(const color& c) 17 | { 18 | return wxColor(c.red255(), c.green255(), c.blue255(), c.alpha255()); 19 | } 20 | 21 | } // namespace native 22 | } // namespace ui 23 | } // namespace boost 24 | 25 | #endif // BOOST_UI_NATIVE_COLOR_HPP 26 | -------------------------------------------------------------------------------- /include/boost/ui/def.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file def.hpp @brief Definitions 7 | 8 | #ifndef BOOST_UI_DEF_HPP 9 | #define BOOST_UI_DEF_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | #ifndef DOXYGEN 21 | 22 | struct nullopt_t { 23 | nullopt_t(int) {} 24 | }; 25 | 26 | extern BOOST_UI_DECL nullopt_t nullopt; 27 | 28 | #endif 29 | 30 | } // namespace ui 31 | } // namespace boost 32 | 33 | #endif // BOOST_UI_DEF_HPP 34 | -------------------------------------------------------------------------------- /include/boost/ui/native/font.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_FONT_HPP 7 | #define BOOST_UI_NATIVE_FONT_HPP 8 | 9 | #include 10 | 11 | class wxFont; 12 | 13 | #include 14 | 15 | namespace boost { 16 | namespace ui { 17 | namespace native { 18 | 19 | wxFont from_font(ui::font& f); 20 | const wxFont from_font(const ui::font& f); 21 | ui::font to_font(const wxFont& f); 22 | 23 | } // namespace native 24 | } // namespace ui 25 | } // namespace boost 26 | 27 | #endif // BOOST_UI_NATIVE_FONT_HPP 28 | -------------------------------------------------------------------------------- /include/boost/ui/audio.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file audio.hpp @brief Audio 7 | 8 | #ifndef BOOST_UI_AUDIO_HPP 9 | #define BOOST_UI_AUDIO_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | /// @brief Rings the system bell 21 | /// @see Beep (Wikipedia) 22 | /// @ingroup audio 23 | BOOST_UI_DECL void beep(); 24 | 25 | } // namespace ui 26 | } // namespace boost 27 | 28 | #endif // BOOST_UI_AUDIO_HPP 29 | -------------------------------------------------------------------------------- /include/boost/ui/native/string.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_STRING_HPP 7 | #define BOOST_UI_NATIVE_STRING_HPP 8 | 9 | #include 10 | 11 | #include 12 | 13 | class wxString; 14 | class wxArrayString; 15 | 16 | namespace boost { 17 | namespace ui { 18 | namespace native { 19 | 20 | wxString from_uistring(const uistring& str); 21 | uistring to_uistring(const wxString& str); 22 | wxArrayString from_vector_uistring(const std::vector& arr); 23 | 24 | } // namespace native 25 | } // namespace ui 26 | } // namespace boost 27 | 28 | #endif // BOOST_UI_STRING_HPP 29 | -------------------------------------------------------------------------------- /src/thread.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace boost { 15 | namespace ui { 16 | namespace detail { 17 | 18 | void call_async(const boost::function& fn) 19 | { 20 | #ifdef wxHAS_CALL_AFTER 21 | wxAppConsole* app = wxApp::GetInstance(); 22 | if ( app ) 23 | { 24 | app->CallAfter(fn); 25 | return; 26 | } 27 | #endif 28 | 29 | wxFAIL; 30 | fn(); 31 | } 32 | 33 | } // namespace detail 34 | } // namespace ui 35 | } // namespace boost 36 | -------------------------------------------------------------------------------- /src/stream.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace boost { 16 | namespace ui { 17 | 18 | uiostringstream& uiostringstream::operator<<(float value) 19 | { 20 | m_buffer += native::to_uistring(wxString() << value); 21 | return *this; 22 | } 23 | 24 | uiostringstream& uiostringstream::operator<<(double value) 25 | { 26 | m_buffer += native::to_uistring(wxString() << value); 27 | return *this; 28 | } 29 | 30 | } // namespace ui 31 | } // namespace boost 32 | -------------------------------------------------------------------------------- /example/cpp11/stacktrace.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Show stacktrace in event handler. 7 | 8 | #include 9 | #include 10 | 11 | namespace ui = boost::ui; 12 | 13 | int ui_main() 14 | { 15 | ui::dialog dlg("Boost.Stacktrace + Boost.UI example"); 16 | 17 | ui::button(dlg, "Show &stacktrace") 18 | .on_press([] 19 | { 20 | std::ostringstream info; 21 | info << boost::stacktrace::stacktrace(); 22 | ui::info_dialog(info.str()); 23 | }); 24 | 25 | dlg.show_modal(); 26 | 27 | return 0; 28 | } 29 | 30 | int main(int argc, char* argv[]) 31 | { 32 | return ui::entry(&ui_main, argc, argv); 33 | } 34 | -------------------------------------------------------------------------------- /example/hello.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // "Hello, World" example 7 | // This example creates dialog with one button. When user press button 8 | // informational dialog is shown. 9 | // Code is written in C++03 style. 10 | 11 | #include 12 | 13 | namespace ui = boost::ui; 14 | 15 | void handle_button_press() 16 | { 17 | ui::info_dialog("Hello, C++ World!"); 18 | } 19 | 20 | int ui_main() 21 | { 22 | ui::dialog dlg("Hello, Boost.UI!"); 23 | 24 | ui::button(dlg, "Say &hello") 25 | .on_press(&handle_button_press); 26 | 27 | dlg.show_modal(); 28 | 29 | return 0; 30 | } 31 | 32 | int main(int argc, char* argv[]) 33 | { 34 | return ui::entry(&ui_main, argc, argv); 35 | } 36 | -------------------------------------------------------------------------------- /include/boost/ui/native/image.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_IMAGE_HPP 7 | #define BOOST_UI_NATIVE_IMAGE_HPP 8 | 9 | #include 10 | 11 | class wxBitmap; 12 | 13 | #include 14 | 15 | namespace boost { 16 | namespace ui { 17 | namespace native { 18 | 19 | inline wxBitmap* from_image_ptr(ui::image& img) 20 | { 21 | return static_cast(img.native_handle()); 22 | } 23 | 24 | inline const wxBitmap* from_image_ptr(const ui::image& img) 25 | { 26 | return static_cast(img.native_handle()); 27 | } 28 | 29 | } // namespace native 30 | } // namespace ui 31 | } // namespace boost 32 | 33 | #endif // BOOST_UI_NATIVE_IMAGE_HPP 34 | -------------------------------------------------------------------------------- /test/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost UI Library Build Jamfile 2 | 3 | # Copyright (c) 2017 Kolya Kosenko 4 | 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # See www.boost.org/LICENSE_1_0.txt 7 | 8 | project 9 | : requirements 10 | /boost/ui//boost_ui 11 | ; 12 | 13 | test-suite "ui" : 14 | [ run cache_test.cpp ] 15 | [ run color_test.cpp ] 16 | [ run coord_test.cpp ] 17 | [ run coord_geometry_test.cpp ] 18 | [ run coord_polygon_test.cpp ] 19 | [ run datetime_test.cpp /boost/chrono//boost_chrono ] 20 | [ run font_test.cpp ] 21 | [ run image_test.cpp : : ../example/res/boost.ico ] 22 | [ run log_test.cpp ] 23 | [ run native_test.cpp ] 24 | [ run stream_test.cpp ] 25 | [ run string_test.cpp ] 26 | [ run widget_test.cpp ] 27 | ; 28 | -------------------------------------------------------------------------------- /src/panel.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace boost { 17 | namespace ui { 18 | 19 | class panel::detail_impl : public detail::widget_detail 20 | { 21 | public: 22 | explicit detail_impl(widget& parent) 23 | { 24 | set_native_handle(new wxPanel(native::from_widget(parent))); 25 | } 26 | }; 27 | 28 | panel& panel::create(widget& parent) 29 | { 30 | detail_set_detail_impl(new detail_impl(parent)); 31 | 32 | return *this; 33 | } 34 | 35 | } // namespace ui 36 | } // namespace boost 37 | -------------------------------------------------------------------------------- /src/canvas.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | ui::painter canvas::painter() 21 | { 22 | return ui::painter(get_impl()); 23 | } 24 | 25 | detail::painter_impl* canvas::get_impl() 26 | { 27 | return get_detail_impl(); 28 | } 29 | 30 | canvas& canvas::create(widget& parent) 31 | { 32 | detail_set_detail_impl(new detail::painter_impl(parent)); 33 | 34 | return *this; 35 | } 36 | 37 | } // namespace ui 38 | } // namespace boost 39 | -------------------------------------------------------------------------------- /include/boost/ui/locale.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file locale.hpp @brief Localization 7 | 8 | #ifndef BOOST_UI_LOCALE_HPP 9 | #define BOOST_UI_LOCALE_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Returns the current locale associated with the user interface 23 | /// @ingroup locale 24 | BOOST_UI_DECL std::locale getloc(); 25 | 26 | // @brief Replaces locale associated with the user interface 27 | // @return The locale before the call of this function 28 | // @ingroup locale 29 | //std::locale imbue(const std::locale& loc); 30 | 31 | } // namespace ui 32 | } // namespace boost 33 | 34 | #endif // BOOST_UI_LOCALE_HPP 35 | -------------------------------------------------------------------------------- /include/boost/ui/native/winmain.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_WINMAIN_CPP 7 | #define BOOST_UI_NATIVE_WINMAIN_CPP 8 | 9 | #include 10 | 11 | #if defined(BOOST_WINDOWS) 12 | #if defined(BOOST_UI_SOURCE) && !defined(BOOST_UI_DYN_LINK) \ 13 | || !defined(BOOST_UI_SOURCE) && !defined(BOOST_UI_STATIC_LINK) 14 | 15 | #include 16 | 17 | extern "C" int main(int, char**); 18 | 19 | int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 20 | LPSTR lpCmdLine, int nCmdShow) 21 | { 22 | #ifdef _MSC_VER 23 | return main(__argc, __argv); 24 | #else 25 | // TODO 26 | char* argv[] = { "" }; 27 | return main(1, argv); 28 | #endif 29 | } 30 | 31 | #endif 32 | #endif 33 | 34 | #endif // BOOST_UI_NATIVE_WINMAIN_CPP 35 | -------------------------------------------------------------------------------- /example/cpp11/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost UI Library Build Jamfile 2 | 3 | # Copyright (c) 2017 Kolya Kosenko 4 | 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # See www.boost.org/LICENSE_1_0.txt 7 | 8 | project 9 | : requirements 10 | /boost/ui//boost_ui 11 | windows:gui 12 | ; 13 | 14 | obj winmain : ../../include/boost/ui/native/winmain.cpp ; 15 | obj example_rc : ../res/example.rc ; 16 | 17 | exe hello : hello.cpp example_rc winmain ; 18 | 19 | exe beman : beman.cpp example_rc winmain ; 20 | exe bootstrap : bootstrap.cpp example_rc winmain ; 21 | exe datarep : datarep.cpp example_rc winmain ; 22 | exe io2d : io2d.cpp example_rc winmain ; 23 | exe minimal : minimal.cpp example_rc winmain ; 24 | exe snippet : snippet.cpp example_rc ; 25 | lib dl ; 26 | exe stacktrace : stacktrace.cpp example_rc winmain : linux:dl ; 27 | exe stroustrup : stroustrup.cpp example_rc winmain ; 28 | 29 | exe demo : demo.cpp example_rc winmain ; 30 | -------------------------------------------------------------------------------- /include/boost/ui/detail/memcheck.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_DETAIL_MEMCHECK_HPP 7 | #define BOOST_UI_DETAIL_MEMCHECK_HPP 8 | 9 | #ifndef NDEBUG 10 | #define BOOST_UI_DEBUG_HOOKS 11 | #endif 12 | 13 | namespace boost { 14 | namespace ui { 15 | namespace detail { 16 | 17 | class memcheck 18 | { 19 | public: 20 | memcheck() { inc(); } 21 | explicit memcheck(const memcheck& other) { inc(); } 22 | ~memcheck() { dec(); } 23 | 24 | #ifdef BOOST_UI_DEBUG_HOOKS 25 | static int count() { return s_count; } 26 | #endif 27 | 28 | private: 29 | #ifdef BOOST_UI_DEBUG_HOOKS 30 | void inc() { ++s_count; } 31 | void dec() { --s_count; } 32 | static int s_count; 33 | #else 34 | void inc() {} 35 | void dec() {} 36 | #endif 37 | }; 38 | 39 | } // namespace detail 40 | } // namespace ui 41 | } // namespace boost 42 | 43 | #endif // BOOST_UI_DETAIL_MEMCHECK_HPP 44 | -------------------------------------------------------------------------------- /src/locale.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include // std::runtime_error 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | std::locale getloc() 21 | { 22 | const wxLanguageInfo* info = wxLocale::GetLanguageInfo(wxLocale::GetSystemLanguage()); 23 | wxCHECK_MSG(info, std::locale(), "System language has no valid info"); 24 | 25 | wxString localeName = info->GetLocaleName(); 26 | #ifndef BOOST_WINDOWS 27 | localeName << wxS(".UTF-8"); 28 | #endif 29 | try 30 | { 31 | return std::locale(localeName.ToAscii()); 32 | } 33 | catch(...) 34 | { 35 | wxLogDebug(wxS("Invalid std::locale name: '%s'"), localeName); 36 | return std::locale(); 37 | } 38 | } 39 | 40 | } // namespace ui 41 | } // namespace boost 42 | -------------------------------------------------------------------------------- /include/boost/ui/panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file panel.hpp @brief Panel widget 7 | 8 | #ifndef BOOST_UI_PANEL_HPP 9 | #define BOOST_UI_PANEL_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Widget that hosts other widgets 23 | /// @see Panel (Wikipedia) 24 | /// @ingroup container 25 | 26 | class BOOST_UI_DECL panel : public widget 27 | { 28 | public: 29 | panel() {} 30 | 31 | ///@{ Creates panel widget 32 | explicit panel(panel& other) { create(other); } 33 | explicit panel(widget& parent) { create(parent); } 34 | panel& create(widget& parent); 35 | ///@} 36 | 37 | private: 38 | class detail_impl; 39 | }; 40 | 41 | } // namespace ui 42 | } // namespace boost 43 | 44 | #endif // BOOST_UI_PANEL_HPP 45 | -------------------------------------------------------------------------------- /src/line.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace boost { 17 | namespace ui { 18 | 19 | #if wxUSE_STATLINE 20 | 21 | class line_widget::detail_impl : public detail::widget_detail 22 | { 23 | public: 24 | explicit detail_impl(widget& parent, bool horizontal) 25 | { 26 | set_native_handle(new wxStaticLine(native::from_widget(parent), 27 | wxID_ANY, wxDefaultPosition, wxDefaultSize, 28 | horizontal ? wxLI_HORIZONTAL : wxLI_VERTICAL)); 29 | } 30 | }; 31 | 32 | #endif 33 | 34 | void line_widget::detail_create(widget& parent, bool horizontal) 35 | { 36 | #if wxUSE_STATLINE 37 | detail_set_detail_impl(new detail_impl(parent, horizontal)); 38 | #endif 39 | } 40 | 41 | } // namespace ui 42 | } // namespace boost 43 | -------------------------------------------------------------------------------- /src/event_loop.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace boost { 17 | namespace ui { 18 | 19 | class event_loop::native_impl : public wxEventLoop, private detail::memcheck 20 | { 21 | public: 22 | }; 23 | 24 | bool event_loop::is_running() const 25 | { 26 | if ( !m_loop ) 27 | return false; 28 | 29 | return m_loop->IsRunning(); 30 | } 31 | 32 | void event_loop::run() 33 | { 34 | wxCHECK_RET(!m_loop, "Event loop already runs"); 35 | 36 | boost::scoped_ptr loop(m_loop = new event_loop::native_impl); 37 | m_loop->Run(); 38 | m_loop = NULL; 39 | } 40 | 41 | void event_loop::exit() 42 | { 43 | wxCHECK_RET(m_loop, "Event loop don't run"); 44 | 45 | m_loop->Exit(); 46 | } 47 | 48 | } // namespace ui 49 | } // namespace boost 50 | -------------------------------------------------------------------------------- /include/boost/ui/dialog.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file dialog.hpp @brief Dialog widget 7 | 8 | #ifndef BOOST_UI_DIALOG_HPP 9 | #define BOOST_UI_DIALOG_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Top level widget that hosts other widgets 23 | /// @details 24 | /// Usage example: 25 | /// @snippet cpp11/snippet.cpp dialog 26 | /// @see Dialog (Wikipedia) 27 | /// @ingroup tlw 28 | 29 | class BOOST_UI_DECL dialog : public window 30 | { 31 | public: 32 | dialog() {} 33 | 34 | ///@{ Creates dialog with the title 35 | explicit dialog(const uistring& title) 36 | { create(title); } 37 | dialog& create(const uistring& title); 38 | ///@} 39 | 40 | private: 41 | class detail_impl; 42 | }; 43 | 44 | } // namespace ui 45 | } // namespace boost 46 | 47 | #endif // BOOST_UI_DIALOG_HPP 48 | -------------------------------------------------------------------------------- /include/boost/ui/event_loop.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file event_loop.hpp @brief Event loop class 7 | 8 | #ifndef BOOST_UI_EVENT_LOOP_HPP 9 | #define BOOST_UI_EVENT_LOOP_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Event loop class 23 | /// @see Event loop (Wikipedia) 24 | /// @ingroup event 25 | 26 | class BOOST_UI_DECL event_loop : private boost::noncopyable 27 | { 28 | public: 29 | event_loop() : m_loop(NULL) {} 30 | 31 | /// Returns true only if event loop is running 32 | bool is_running() const; 33 | 34 | /// Start the event loop 35 | void run(); 36 | 37 | /// Exit from the event loop 38 | void exit(); 39 | 40 | private: 41 | class native_impl; 42 | native_impl* m_loop; 43 | }; 44 | 45 | } // namespace ui 46 | } // namespace boost 47 | 48 | #endif // BOOST_UI_EVENT_LOOP_HPP 49 | -------------------------------------------------------------------------------- /include/boost/ui/hyperlink.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file hyperlink.hpp @brief Hyperlink widget 7 | 8 | #ifndef BOOST_UI_HYPERLINK_HPP 9 | #define BOOST_UI_HYPERLINK_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Widget that displays static text which links to an URL 23 | /// @see Hyperlink (Wikipedia) 24 | /// @ingroup command 25 | 26 | class BOOST_UI_DECL hyperlink : public widget 27 | { 28 | public: 29 | hyperlink() {} 30 | 31 | ///@{ Creates hyperlink widget with URL and text 32 | explicit hyperlink(widget& parent, const uistring& url, const uistring& text) 33 | { create(parent, url, text); } 34 | hyperlink& create(widget& parent, const uistring& url, const uistring& text); 35 | ///@} 36 | 37 | private: 38 | class detail_impl; 39 | }; 40 | 41 | } // namespace ui 42 | } // namespace boost 43 | 44 | #endif // BOOST_UI_HYPERLINK_HPP 45 | -------------------------------------------------------------------------------- /include/boost/ui/group_box.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file group_box.hpp @brief Group box widget 7 | 8 | #ifndef BOOST_UI_GROUP_BOX_HPP 9 | #define BOOST_UI_GROUP_BOX_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Widget that groups other widgets using a frame and a title 23 | /// @see Frame (Wikipedia) 24 | /// @ingroup container 25 | 26 | class BOOST_UI_DECL group_box : public widget 27 | { 28 | public: 29 | group_box() {} 30 | 31 | ///@{ Creates group box widget 32 | explicit group_box(widget& parent, const uistring& title = uistring()) 33 | { create(parent, title); } 34 | group_box& create(widget& parent, const uistring& title = uistring()); 35 | ///@} 36 | 37 | private: 38 | class detail_impl; 39 | detail_impl* get_impl(); 40 | const detail_impl* get_impl() const; 41 | }; 42 | 43 | } // namespace ui 44 | } // namespace boost 45 | 46 | #endif // BOOST_UI_GROUP_BOX_HPP 47 | -------------------------------------------------------------------------------- /example/cpp11/hello.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // "Hello, World" example 7 | // This example creates dialog with one button. When user press button 8 | // informational dialog is shown. 9 | 10 | // Include all Boost.UI headers 11 | #include 12 | 13 | namespace ui = boost::ui; 14 | 15 | int ui_main() 16 | { 17 | // Create dialog window with title 18 | ui::dialog dlg("Hello, Boost.UI!"); 19 | 20 | // Put button with title on this dialog window 21 | ui::button(dlg, "Say &hello") 22 | // Subscribe to button press events to callback function 23 | .on_press([] 24 | { 25 | // Handle button press event 26 | 27 | // Show informational dialog window with text 28 | // and wait while user close it 29 | ui::info_dialog("Hello, C++ World!"); 30 | }); 31 | 32 | // Show dialog window 33 | // and wait while user close it 34 | dlg.show_modal(); 35 | 36 | return 0; 37 | } 38 | 39 | int main(int argc, char* argv[]) 40 | { 41 | // Initialize GUI, call ui_main function, uninitialize GUI, catch exceptions 42 | return ui::entry(&ui_main, argc, argv); 43 | } 44 | -------------------------------------------------------------------------------- /test/native_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace ui = boost::ui; 15 | 16 | void test_label(ui::widget& parent) 17 | { 18 | { 19 | ui::label l; 20 | l.create(parent, "text"); 21 | BOOST_TEST_EQ(ui::native::from_widget(l)->GetWindowStyleFlag(), 0); 22 | ui::native::modify_style_flags(l, wxALIGN_RIGHT); 23 | BOOST_TEST_EQ(ui::native::from_widget(l)->GetWindowStyleFlag(), wxALIGN_RIGHT); 24 | } 25 | { 26 | ui::label l; 27 | ui::native::modify_style_flags(l, wxALIGN_RIGHT); 28 | l.create(parent, "text"); 29 | BOOST_TEST_EQ(ui::native::from_widget(l)->GetWindowStyleFlag(), wxALIGN_RIGHT); 30 | } 31 | } 32 | 33 | int ui_main() 34 | { 35 | ui::dialog dlg("Title"); 36 | 37 | test_label(dlg); 38 | 39 | //dlg.show_modal(); 40 | 41 | return boost::report_errors(); 42 | } 43 | 44 | int cpp_main(int argc, char* argv[]) 45 | { 46 | return ui::entry(&ui_main, argc, argv); 47 | } 48 | -------------------------------------------------------------------------------- /src/hyperlink.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | #if wxUSE_HYPERLINKCTRL 21 | 22 | class hyperlink::detail_impl : public detail::widget_detail 23 | { 24 | public: 25 | explicit detail_impl(widget& parent, 26 | const uistring& url, const uistring& text) 27 | { 28 | set_native_handle(new wxHyperlinkCtrl(native::from_widget(parent), 29 | wxID_ANY, 30 | native::from_uistring(text), native::from_uistring(url))); 31 | } 32 | }; 33 | 34 | #endif 35 | 36 | hyperlink& hyperlink::create(widget& parent, 37 | const uistring& url, const uistring& text) 38 | { 39 | #if wxUSE_HYPERLINKCTRL 40 | detail_set_detail_impl(new detail_impl(parent, url, text)); 41 | #endif 42 | 43 | return *this; 44 | } 45 | 46 | } // namespace ui 47 | } // namespace boost 48 | -------------------------------------------------------------------------------- /include/boost/ui/color_io.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file color_io.hpp @brief Color I/O operations 7 | 8 | #ifndef BOOST_UI_COLOR_IO_HPP 9 | #define BOOST_UI_COLOR_IO_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace boost { 22 | namespace ui { 23 | 24 | ///@{ @brief Writes color into the stream 25 | /// @relatesalso boost::ui::color 26 | 27 | template 28 | std::basic_ostream& 29 | operator<<(std::basic_ostream& os, const boost::ui::color& c) 30 | { 31 | const bool is_transparent = c.alpha255() != 255; 32 | os << 'r' << 'g' << 'b'; 33 | if ( is_transparent ) 34 | os << 'a'; 35 | os << '(' << static_cast(c.red255()); 36 | os << ',' << static_cast(c.green255()); 37 | os << ',' << static_cast(c.blue255()); 38 | if ( is_transparent ) 39 | os << ',' << static_cast(c.alpha255()); 40 | os << ')'; 41 | return os; 42 | } 43 | 44 | } // namespace ui 45 | } // namespace boost 46 | 47 | #endif // BOOST_UI_COLOR_IO_HPP 48 | -------------------------------------------------------------------------------- /src/button.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace boost { 19 | namespace ui { 20 | 21 | #if wxUSE_BUTTON 22 | class button::detail_impl : public detail::widget_detail 23 | { 24 | public: 25 | explicit detail_impl(widget& parent, const uistring& label) 26 | { 27 | set_native_handle(new wxButton(native::from_widget(parent), 28 | wxID_ANY, native::from_uistring(label))); 29 | } 30 | }; 31 | #endif 32 | 33 | button& button::create(widget& parent, const uistring& label) 34 | { 35 | #if wxUSE_BUTTON 36 | detail_set_detail_impl(new detail_impl(parent, label)); 37 | #endif 38 | 39 | return *this; 40 | } 41 | 42 | void button::on_press_raw(const boost::function& handler) 43 | { 44 | #if wxUSE_BUTTON 45 | native::bind_helper(*this, wxEVT_BUTTON, handler); 46 | #endif 47 | } 48 | 49 | } // namespace ui 50 | } // namespace boost 51 | -------------------------------------------------------------------------------- /example/cpp11/demo.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Demonstration of C++11 usage in Boost.UI. 7 | 8 | #include 9 | 10 | namespace ui = boost::ui; 11 | 12 | int ui_main() 13 | { 14 | ui::dialog dlg{"Boost.UI C++11 Demo"}; 15 | 16 | ui::list_box list_box = ui::list_box(dlg, {"first", "second", "third"} ) 17 | .on_activate_event([&list_box](ui::index_event& e) 18 | { 19 | ui::log::info() << "Item activated" 20 | << e.index() << list_box[e.index()]; 21 | }) 22 | ; 23 | 24 | // Requires at least Visual C++ 14.0 (2015) 25 | #if !defined(_MSC_VER) || (_MSC_VER >= 1900) 26 | list_box.push_back({U'G', U' ', U'\U0001D11E'}); 27 | 28 | list_box.push_back( R"*("(\char)")*"); 29 | list_box.push_back(LR"*("(\wchar_t)")*"); 30 | list_box.push_back(uR"*("(\char16_t)")*"); 31 | list_box.push_back(UR"*("(\char32_t)")*"); 32 | 33 | auto str = list_box.at(0) + " c" + L" w" + u" u" + U" U"; 34 | list_box.push_back(str); 35 | #endif 36 | 37 | ui::log() << 18446744073709551615ull; 38 | 39 | dlg.show_modal(); 40 | 41 | return 0; 42 | } 43 | 44 | int main(int argc, char* argv[]) 45 | { 46 | return ui::entry(&ui_main, argc, argv); 47 | } 48 | -------------------------------------------------------------------------------- /example/cpp17/p1108.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Re-implemented example from P1108R0 C++ Standard proposal web_view 7 | // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1108r0.html 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace ui = boost::ui; 14 | using namespace std::chrono_literals; // c++14 15 | 16 | int ui_main(int argc, char* argv[]) 17 | { 18 | const std::vector args(argv, argv + argc); 19 | 20 | ui::on_timeout(2000ms, [] 21 | { 22 | }); 23 | 24 | std::ostringstream os; 25 | const char uri[] = "https://www.boost.org/"; 26 | 27 | os << "" << uri << "

" << uri << "

"; 28 | for ( auto &a : args ) 29 | os << "" << "\n"; // we need some kind of "to_html" utility function. 30 | os << "
" << a << "
"; 31 | os << "

more

"; 32 | os << "
    "; 33 | os << ""; 34 | 35 | ui::dialog dlg("web_view test app"); 36 | ui::web_widget(dlg) 37 | .html(os.str()); 38 | dlg.show_modal(); 39 | 40 | return 0; 41 | } 42 | 43 | int main(int argc, char* argv[]) 44 | { 45 | return ui::entry(&ui_main, argc, argv); 46 | } 47 | -------------------------------------------------------------------------------- /include/boost/ui/canvas.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file canvas.hpp @brief Canvas widget 7 | 8 | #ifndef BOOST_UI_CANVAS_HPP 9 | #define BOOST_UI_CANVAS_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | #include 19 | 20 | namespace boost { 21 | namespace ui { 22 | 23 | /// @brief Widget for drawing 24 | /// @see boost::ui::painter 25 | /// @see Canvas (Wikipedia) 26 | /// @ingroup info 27 | /// @ingroup graphics 28 | 29 | class BOOST_UI_DECL canvas : public widget 30 | { 31 | public: 32 | canvas() {} 33 | 34 | ///@{ Creates canvas widget. 35 | explicit canvas(widget& parent) 36 | { create(parent); } 37 | canvas& create(widget& parent); 38 | ///@} 39 | 40 | /// @brief Returns painter based on this canvas 41 | /// to work in the retained mode 42 | ui::painter painter(); 43 | 44 | private: 45 | detail::painter_impl* get_impl(); 46 | 47 | #ifndef DOXYGEN 48 | friend class painter; 49 | #endif 50 | }; 51 | 52 | } // namespace ui 53 | } // namespace boost 54 | 55 | #endif // BOOST_UI_CANVAS_HPP 56 | -------------------------------------------------------------------------------- /test/log_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace ui = boost::ui; 13 | 14 | void test_output(ui::log_string& l) 15 | { 16 | l << 12 << .34 << std::size_t(9) << true 17 | << "char*" << "wchar_t*" << 'C' << L'W' 18 | << "" << L"" << ui::uistring() 19 | << std::string("string") << std::wstring(L"wstring") 20 | << ui::uistring("uistring") 21 | ; 22 | } 23 | 24 | int cpp_main(int, char*[]) 25 | { 26 | { 27 | ui::uistring str; 28 | test_output(ui::log_string(str).nospaces().noquotes()); 29 | BOOST_TEST_EQ(str, "120.349truechar*wchar_t*CWstringwstringuistring"); 30 | } 31 | { 32 | ui::uistring str; 33 | test_output(ui::log_string(str).noquotes()); 34 | BOOST_TEST_EQ(str, "12 0.34 9 true char* wchar_t* C W string wstring uistring"); 35 | } 36 | { 37 | ui::uistring str; 38 | ui::log_string l(str); 39 | test_output(l); 40 | BOOST_TEST_EQ(str, "12 0.34 9 true \"char*\" \"wchar_t*\" 'C' 'W' \"\" \"\" \"\" \"string\" \"wstring\" \"uistring\""); 41 | } 42 | 43 | return boost::report_errors(); 44 | } 45 | -------------------------------------------------------------------------------- /example/native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Show native API usage. 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | namespace ui = boost::ui; 18 | 19 | int ui_main() 20 | { 21 | ui::dialog dlg("Boost.UI native API usage example"); 22 | 23 | wxWindow* native_dialog = ui::native::from_widget(dlg); 24 | wxCHECK_MSG(native_dialog, 1, "Invalid native dialog"); 25 | native_dialog->SetTransparent(224); 26 | 27 | std::ostringstream ss; 28 | ss << wxGetLibraryVersionInfo().ToString(); 29 | ss << "\nBuild options: " << WX_BUILD_OPTIONS_SIGNATURE; 30 | wxStaticText* staticText = new wxStaticText(native_dialog, wxID_ANY, ss.str()); 31 | 32 | wxButton* button = new wxButton(native_dialog, wxID_ANY, "C&lose"); 33 | button->Bind(wxEVT_BUTTON, boost::bind(&wxDialog::Close, native_dialog, false)); 34 | 35 | ui::vbox(dlg) 36 | << ui::native_widget(staticText) 37 | .layout().stretch() 38 | << ui::native_widget(button) 39 | .layout().center() 40 | ; 41 | 42 | dlg.show_modal(); 43 | 44 | return 0; 45 | } 46 | 47 | int main(int argc, char* argv[]) 48 | { 49 | return ui::entry(&ui_main, argc, argv); 50 | } 51 | -------------------------------------------------------------------------------- /include/boost/ui/thread.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file thread.hpp @brief Thread support 7 | 8 | #ifndef BOOST_UI_THREAD_HPP 9 | #define BOOST_UI_THREAD_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES 20 | #include // boost::forward() 21 | #endif 22 | 23 | namespace boost { 24 | namespace ui { 25 | 26 | #ifndef DOXYGEN 27 | 28 | namespace detail { 29 | BOOST_UI_DECL void call_async(const boost::function& fn); 30 | } // namespace detail 31 | 32 | #endif 33 | 34 | /// @brief Calls @a f in the idle time in UI thread. This function is thread safe. 35 | /// @see Thread safety (Wikipedia) 36 | /// @ingroup thread 37 | 38 | #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES 39 | template 40 | void call_async(F&& f, Args&&... args) 41 | { 42 | detail::call_async(std::bind(boost::forward(f), boost::forward(args)...)); 43 | } 44 | #else 45 | inline void call_async(const boost::function& fn) 46 | { 47 | detail::call_async(fn); 48 | } 49 | #endif 50 | 51 | 52 | } // namespace ui 53 | } // namespace boost 54 | 55 | #endif // BOOST_UI_THREAD_HPP 56 | -------------------------------------------------------------------------------- /src/dialog.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | #include "res/boost.xpm" 19 | 20 | namespace boost { 21 | namespace ui { 22 | 23 | class dialog::detail_impl : public detail::window_detail 24 | { 25 | public: 26 | explicit detail_impl(const uistring& title) 27 | { 28 | wxDialog* w = new wxDialog(NULL, wxID_ANY, 29 | native::from_uistring(title), 30 | wxDefaultPosition, wxDefaultSize, 31 | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | 32 | wxMAXIMIZE_BOX | wxMINIMIZE_BOX); 33 | w->SetIcon(boost_xpm); 34 | set_native_handle(w); 35 | } 36 | virtual ~detail_impl() 37 | { 38 | delete_native(); 39 | } 40 | void show_modal() 41 | { 42 | wxCHECK_RET(m_native, "Widget should be created"); 43 | m_native->ShowModal(); 44 | } 45 | }; 46 | 47 | dialog& dialog::create(const uistring& title) 48 | { 49 | detail_set_detail_impl(new detail_impl(title)); 50 | 51 | return *this; 52 | } 53 | 54 | } // namespace ui 55 | } // namespace boost 56 | -------------------------------------------------------------------------------- /src/group_box.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | #if wxUSE_STATBOX 21 | 22 | class group_box::detail_impl : public detail::widget_detail 23 | { 24 | public: 25 | explicit detail_impl(widget& parent, const uistring& title) 26 | { 27 | set_native_handle(new wxStaticBox(native::from_widget(parent), 28 | wxID_ANY, native::from_uistring(title))); 29 | } 30 | }; 31 | 32 | #endif 33 | 34 | group_box::detail_impl* group_box::get_impl() 35 | { 36 | #if wxUSE_STATBOX 37 | return get_detail_impl(); 38 | #else 39 | return NULL; 40 | #endif 41 | } 42 | 43 | const group_box::detail_impl* group_box::get_impl() const 44 | { 45 | #if wxUSE_STATBOX 46 | return get_detail_impl(); 47 | #else 48 | return NULL; 49 | #endif 50 | } 51 | 52 | group_box& group_box::create(widget& parent, const uistring& title) 53 | { 54 | #if wxUSE_STATBOX 55 | detail_set_detail_impl(new detail_impl(parent, title)); 56 | #endif 57 | 58 | return *this; 59 | } 60 | 61 | } // namespace ui 62 | } // namespace boost 63 | -------------------------------------------------------------------------------- /include/boost/ui/button.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file button.hpp @brief Button widget 7 | 8 | #ifndef BOOST_UI_BUTTON_HPP 9 | #define BOOST_UI_BUTTON_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Widget with label that generate event when clicked on 23 | /// @details 24 | /// Usage example: 25 | /// @snippet cpp11/snippet.cpp button 26 | /// @see Button (Wikipedia) 27 | /// @ingroup command 28 | 29 | class BOOST_UI_DECL button : public widget 30 | { 31 | public: 32 | button() {} 33 | 34 | ///@{ @brief Creates button with text label with mnemonics 35 | /// @see Mnemonics (Wikipedia) 36 | explicit button(widget& parent, const uistring& label) 37 | { create(parent, label); } 38 | button& create(widget& parent, const uistring& label); 39 | ///@} 40 | 41 | /// Connects button press handler 42 | BOOST_UI_DETAIL_HANDLER(press, button); 43 | 44 | private: 45 | void on_press_raw(const boost::function& handler); 46 | 47 | class detail_impl; 48 | }; 49 | 50 | } // namespace ui 51 | } // namespace boost 52 | 53 | #endif // BOOST_UI_BUTTON_HPP 54 | -------------------------------------------------------------------------------- /example/cpp11/beman.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Beman's challenge: 7 | // "Display Hello C++ World in a window and allow the user to drag that text 8 | // around inside the window with a program that is only slightly more complex 9 | // that the traditional hello world program." 10 | // http://isocpp.org/files/papers/n3791.html 11 | 12 | #include 13 | 14 | namespace ui = boost::ui; 15 | 16 | int ui_main() 17 | { 18 | ui::dialog dlg("Boost.UI Beman's challenge"); 19 | 20 | ui::canvas canvas(dlg); 21 | 22 | ui::point paint_pos(20, 20); 23 | auto repaint = [&] 24 | { 25 | canvas.painter() 26 | .clear_rect(0, 0, canvas.width(), canvas.height()) 27 | .font(canvas.font()) 28 | .fill_text("Hello C++ World", paint_pos) 29 | ; 30 | }; 31 | 32 | ui::point drag_start_pos; 33 | canvas 34 | .on_resize(repaint) 35 | .on_left_mouse_down_event([&](ui::mouse_event& e) 36 | { 37 | drag_start_pos = e.pos(); 38 | }) 39 | .on_mouse_drag_event([&](ui::mouse_event& e) 40 | { 41 | paint_pos += e.pos() - drag_start_pos; 42 | repaint(); 43 | 44 | drag_start_pos = e.pos(); 45 | }) 46 | ; 47 | 48 | dlg.show_modal(); 49 | 50 | return 0; 51 | } 52 | 53 | int main(int argc, char* argv[]) 54 | { 55 | return ui::entry(&ui_main, argc, argv); 56 | } 57 | -------------------------------------------------------------------------------- /include/boost/ui/frame.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file frame.hpp @brief Frame widget 7 | 8 | #ifndef BOOST_UI_FRAME_HPP 9 | #define BOOST_UI_FRAME_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace boost { 22 | namespace ui { 23 | 24 | /// @brief Top level widget that hosts other widgets and supports menu bar 25 | /// @details 26 | /// Usage example: 27 | /// @snippet cpp11/snippet.cpp frame 28 | /// @see Window (Wikipedia) 29 | /// @ingroup tlw 30 | 31 | class BOOST_UI_DECL frame : public window 32 | { 33 | public: 34 | frame() {} 35 | 36 | ///@{ Creates frame with the title 37 | explicit frame(const uistring& title) 38 | { create(title); } 39 | frame& create(const uistring& title); 40 | ///@} 41 | 42 | /// @brief Returns menu bar 43 | /// @details If menu bar wasn't created, creates menu bar. 44 | ui::menu_bar menu_bar(); 45 | 46 | /// @brief Returns status bar 47 | /// @details If status bar wasn't created, creates status bar. 48 | ui::status_bar status_bar(); 49 | 50 | private: 51 | class detail_impl; 52 | detail_impl* get_impl(); 53 | }; 54 | 55 | } // namespace ui 56 | } // namespace boost 57 | 58 | #endif // BOOST_UI_FRAME_HPP 59 | -------------------------------------------------------------------------------- /include/boost/ui/image_widget.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file image_widget.hpp @brief Image widget 7 | 8 | #ifndef BOOST_UI_IMAGE_WIDGET_HPP 9 | #define BOOST_UI_IMAGE_WIDGET_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | #include 19 | 20 | namespace boost { 21 | namespace ui { 22 | 23 | /// @brief Widget that displays image 24 | /// @see boost::ui::image 25 | /// @ingroup info 26 | 27 | class BOOST_UI_DECL image_widget : public widget 28 | { 29 | public: 30 | image_widget() { init(); } 31 | 32 | ///@{ Creates image_widget without image 33 | explicit image_widget(widget& parent) 34 | { init(); create(parent); } 35 | image_widget& create(widget& parent); 36 | ///@} 37 | 38 | ///@{ Creates image_widget with image 39 | explicit image_widget(widget& parent, const ui::image& img) 40 | { init(); create(parent, img); } 41 | image_widget& create(widget& parent, const ui::image& img); 42 | ///@} 43 | 44 | /// Sets image 45 | image_widget& image(const image& img); 46 | 47 | /// Clears image 48 | void clear(); 49 | 50 | private: 51 | void init() {} 52 | 53 | class detail_impl; 54 | detail_impl* get_impl(); 55 | const detail_impl* get_impl() const; 56 | }; 57 | 58 | } // namespace ui 59 | } // namespace boost 60 | 61 | #endif // BOOST_UI_IMAGE_WIDGET_HPP 62 | -------------------------------------------------------------------------------- /include/boost/ui/web_widget.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file web_widget.hpp @brief Web widget 7 | 8 | #ifndef BOOST_UI_WEB_WIDGET_HPP 9 | #define BOOST_UI_WEB_WIDGET_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Widget that renders HTML 23 | /// @see Web browser engine (Wikipedia) 24 | /// @see iframe (W3C) 25 | /// @ingroup info 26 | 27 | class BOOST_UI_DECL web_widget : public widget 28 | { 29 | public: 30 | web_widget() {} 31 | 32 | ///@{ Creates web_widget widget 33 | explicit web_widget(widget& parent) 34 | { create(parent); } 35 | web_widget& create(widget& parent); 36 | ///@} 37 | 38 | /// @brief Sets HTML content 39 | /// @see HTML (Wikipedia) 40 | web_widget& html(const uistring& html); 41 | 42 | /// @brief Loads content from the URL 43 | /// @see Uniform resource locator (Wikipedia) 44 | web_widget& load(const uistring& url); 45 | 46 | private: 47 | class detail_impl; 48 | detail_impl* get_impl(); 49 | }; 50 | 51 | } // namespace ui 52 | } // namespace boost 53 | 54 | #endif // BOOST_UI_WEB_WIDGET_HPP 55 | -------------------------------------------------------------------------------- /include/boost/ui/label.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file label.hpp @brief Label widget 7 | 8 | #ifndef BOOST_UI_LABEL_HPP 9 | #define BOOST_UI_LABEL_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Widget that displays static text 23 | /// @see Label (Wikipedia) 24 | /// @ingroup info 25 | 26 | class BOOST_UI_DECL label : public widget 27 | { 28 | public: 29 | label() { init(); } 30 | 31 | ///@{ Creates label widget with text 32 | explicit label(widget& parent, const uistring& txt = uistring()) 33 | { init(); create(parent, txt); } 34 | explicit label(const uistring& txt) 35 | { init(); create(txt); } 36 | label& create(widget& parent, const uistring& txt = uistring()); 37 | label& create(const uistring& txt = uistring()) 38 | { text(txt); return *this; } 39 | ///@} 40 | 41 | /// Clears text 42 | void clear() { text(uistring()); } 43 | 44 | /// Sets text 45 | label& text(const uistring& txt); 46 | 47 | /// Returns text 48 | uistring text() const; 49 | 50 | private: 51 | void init(); 52 | 53 | class detail_impl; 54 | detail_impl* get_impl(); 55 | const detail_impl* get_impl() const; 56 | }; 57 | 58 | } // namespace ui 59 | } // namespace boost 60 | 61 | #endif // BOOST_UI_LABEL_HPP 62 | -------------------------------------------------------------------------------- /include/boost/ui/coord_io.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file coord_io.hpp @brief Coordinates I/O 7 | 8 | #ifndef BOOST_UI_COORD_IO_HPP 9 | #define BOOST_UI_COORD_IO_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | #include 19 | 20 | namespace boost { 21 | namespace ui { 22 | 23 | /// @brief Writes basic_size into basic_size stream. 24 | /// @relatesalso boost::ui::basic_size 25 | template 26 | std::basic_ostream& 27 | operator<<(std::basic_ostream& os, const basic_size& p) 28 | { 29 | return os << '(' << p.width() << ',' << p.height() << ')'; 30 | } 31 | 32 | /// @brief Writes basic_point into the stream. 33 | /// @relatesalso boost::ui::basic_point 34 | template 35 | std::basic_ostream& 36 | operator<<(std::basic_ostream& os, const basic_point& p) 37 | { 38 | return os << '(' << p.x() << ',' << p.y() << ')'; 39 | } 40 | 41 | /// @brief Writes basic_rect into the stream. 42 | /// @relatesalso boost::ui::basic_rect 43 | template 44 | std::basic_ostream& 45 | operator<<(std::basic_ostream& os, const basic_rect& r) 46 | { 47 | return os << '(' << r.x() << ',' << r.y() << ',' << r.width() << ',' << r.height() << ')'; 48 | } 49 | 50 | } // namespace ui 51 | } // namespace boost 52 | 53 | #endif // BOOST_UI_COORD_IO_HPP 54 | -------------------------------------------------------------------------------- /include/boost/ui/native/widget.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_WIDGET_HPP 7 | #define BOOST_UI_NATIVE_WIDGET_HPP 8 | 9 | #include 10 | 11 | class wxWindow; 12 | 13 | #include 14 | #include // TODO: Remove 15 | 16 | namespace boost { 17 | namespace ui { 18 | namespace native { 19 | 20 | /// Modifies wxWindow style flags in constructor or using wxWindow::SetWindowStyleFlag() function 21 | BOOST_UI_DECL void modify_style_flags(ui::widget& w, long add, long remove = 0); 22 | 23 | inline wxWindow* from_widget(ui::widget& w) 24 | { 25 | return static_cast(w.native_handle()); 26 | } 27 | 28 | inline const wxWindow* from_widget(const ui::widget& w) 29 | { 30 | return static_cast(w.native_handle()); 31 | } 32 | 33 | template 34 | T* impl(ui::widget& w) 35 | { 36 | return dynamic_cast(from_widget(w)); 37 | } 38 | 39 | template 40 | const T* impl(const ui::widget& w) 41 | { 42 | return dynamic_cast(from_widget(w)); 43 | } 44 | 45 | template 46 | T1* impl(ui::widget& w) 47 | { 48 | return static_cast(dynamic_cast(from_widget(w))); 49 | } 50 | 51 | template 52 | const T1* impl(const ui::widget& w) 53 | { 54 | return static_cast(dynamic_cast(from_widget(w))); 55 | } 56 | 57 | } // namespace native 58 | } // namespace ui 59 | } // namespace boost 60 | 61 | #endif // BOOST_UI_NATIVE_WIDGET_HPP 62 | -------------------------------------------------------------------------------- /include/boost/ui/notebook.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file notebook.hpp @brief Notebook widget 7 | 8 | #ifndef BOOST_UI_NOTEBOOK_HPP 9 | #define BOOST_UI_NOTEBOOK_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Widget that is an array of tabbed widgets 23 | /// @see Tab (Wikipedia) 24 | /// @ingroup container 25 | 26 | class BOOST_UI_DECL notebook : public widget 27 | { 28 | public: 29 | /// Unsigned integral type 30 | typedef index_type size_type; 31 | 32 | notebook() {} 33 | 34 | ///@{ Creates notebook widget 35 | explicit notebook(widget& parent) 36 | { create(parent); } 37 | notebook& create(widget& parent); 38 | ///@} 39 | 40 | /// Appends page with associated label 41 | void append_page(widget& page, const uistring& label); 42 | 43 | /// Shows page with @a index 44 | void current_page(size_type index); 45 | 46 | /// Returns index of the current page. If notebook has no pages then returns @ref npos 47 | size_type current_page_index() const; 48 | 49 | /// Invalid page index 50 | static const size_type npos = nindex; 51 | 52 | private: 53 | class detail_impl; 54 | detail_impl* get_impl(); 55 | const detail_impl* get_impl() const; 56 | }; 57 | 58 | } // namespace ui 59 | } // namespace boost 60 | 61 | #endif // BOOST_UI_NOTEBOOK_HPP 62 | -------------------------------------------------------------------------------- /include/boost/ui/line.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file line.hpp @brief line widget 7 | 8 | #ifndef BOOST_UI_LINE_HPP 9 | #define BOOST_UI_LINE_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Abstract widget that displays horizontal or vertical line 23 | /// @ingroup info 24 | 25 | class BOOST_UI_DECL line_widget : public widget 26 | { 27 | protected: 28 | line_widget() {} 29 | 30 | #ifndef DOXYGEN 31 | void detail_create(widget& parent, bool horizontal); 32 | #endif 33 | 34 | private: 35 | class detail_impl; 36 | }; 37 | 38 | /// @brief Horizontal line widget 39 | /// @ingroup info 40 | 41 | class BOOST_UI_DECL hline : public line_widget 42 | { 43 | public: 44 | hline() {} 45 | 46 | ///@{ Creates horizontal line widget 47 | explicit hline(widget& parent) 48 | { create(parent); } 49 | hline& create(widget& parent) 50 | { detail_create(parent, true); return *this; } 51 | ///@} 52 | 53 | }; 54 | 55 | /// @brief Vertical line widget 56 | /// @ingroup info 57 | 58 | class BOOST_UI_DECL vline : public line_widget 59 | { 60 | public: 61 | vline() {} 62 | 63 | ///@{ Creates vertical line widget 64 | explicit vline(widget& parent) 65 | { create(parent); } 66 | vline& create(widget& parent) 67 | { detail_create(parent, false); return *this; } 68 | ///@} 69 | }; 70 | 71 | } // namespace ui 72 | } // namespace boost 73 | 74 | #endif // BOOST_UI_LINE_HPP 75 | -------------------------------------------------------------------------------- /include/boost/ui/status_bar.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file status_bar.hpp @brief Status bar class 7 | 8 | #ifndef BOOST_UI_STATUS_BAR_HPP 9 | #define BOOST_UI_STATUS_BAR_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Status bar class 23 | /// @details Default constructor is a private member, so use @ref boost::ui::frame::status_bar() to create this class instance 24 | /// @see Status bar (Wikipedia) 25 | /// @ingroup info 26 | 27 | class BOOST_UI_DECL status_bar 28 | { 29 | status_bar(); 30 | void create(widget& parent); 31 | 32 | public: 33 | /// Copy constructor 34 | status_bar(const status_bar& other); 35 | ~status_bar(); 36 | 37 | /// Sets text into the status bar 38 | status_bar& text(const uistring& text); 39 | 40 | /// Returns text from the status bar 41 | uistring text() const; 42 | 43 | /// Implementation-defined status bar type 44 | typedef void* native_handle_type; 45 | 46 | ///@{ Returns the implementation-defined underlying status bar handle 47 | native_handle_type native_handle() { return m_impl; } 48 | const native_handle_type native_handle() const { return m_impl; } 49 | ///@} 50 | 51 | private: 52 | class native_impl; 53 | native_impl* m_impl; 54 | 55 | #ifndef DOXYGEN 56 | friend class frame; 57 | #endif 58 | }; 59 | 60 | } // namespace ui 61 | } // namespace boost 62 | 63 | #endif // BOOST_UI_STATUS_BAR_HPP 64 | -------------------------------------------------------------------------------- /include/boost/ui/detail/shared_count.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_DETAIL_SHARED_COUNT_HPP 7 | #define BOOST_UI_DETAIL_SHARED_COUNT_HPP 8 | 9 | namespace boost { 10 | namespace ui { 11 | namespace detail { 12 | 13 | class BOOST_UI_DECL shared_count 14 | { 15 | class data_type 16 | { 17 | public: 18 | data_type() : m_use_count(1), m_attached(true) {} 19 | bool may_delete() const { return m_attached && m_use_count == 1; } 20 | 21 | long m_use_count; 22 | bool m_attached; 23 | }; 24 | 25 | public: 26 | shared_count() { m_data = new data_type; } 27 | explicit shared_count(const shared_count& other) 28 | { 29 | m_data = other.m_data; 30 | add_ref(); 31 | } 32 | shared_count& operator=(const shared_count& other) 33 | { 34 | if ( this != &other ) 35 | { 36 | dec_ref(); 37 | 38 | m_data = other.m_data; 39 | add_ref(); 40 | } 41 | return *this; 42 | } 43 | ~shared_count() { dec_ref(); } 44 | 45 | long use_count() const { return m_data->m_use_count; } 46 | 47 | void detach() { m_data->m_attached = false; } 48 | bool may_delete() const { return m_data->may_delete(); } 49 | 50 | private: 51 | void add_ref() 52 | { 53 | ++m_data->m_use_count; 54 | } 55 | void dec_ref() 56 | { 57 | if ( --m_data->m_use_count == 0 ) 58 | delete m_data; 59 | } 60 | 61 | data_type* m_data; 62 | }; 63 | 64 | } // namespace detail 65 | } // namespace ui 66 | } // namespace boost 67 | 68 | #endif // BOOST_UI_DETAIL_SHARED_COUNT_HPP 69 | -------------------------------------------------------------------------------- /example/cpp11/minimal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Re-implemented wxWidgets minimal sample: 7 | // https://github.com/wxWidgets/wxWidgets/blob/master/samples/minimal/minimal.cpp 8 | 9 | #include 10 | 11 | namespace ui = boost::ui; 12 | 13 | class my_frame : public ui::frame 14 | { 15 | public: 16 | my_frame(const ui::uistring& title); 17 | }; 18 | 19 | my_frame::my_frame(const ui::uistring& title) 20 | : ui::frame(title) 21 | { 22 | menu_bar() 23 | << ( ui::menu("&File") 24 | << ui::menu::item("E&xit\tAlt-X") 25 | .on_press(&my_frame::close, this) 26 | ) 27 | << ( ui::menu("&Help") 28 | << ui::menu::item("&About\tF1") 29 | .on_press([] 30 | { 31 | ui::uiostringstream ss; 32 | ss << "Welcome to Boost " << BOOST_VERSION / 100000 33 | << '.' << BOOST_VERSION / 100 % 1000 34 | << '.' << BOOST_VERSION % 100 35 | << "!\n" 36 | << "\n" 37 | << "This is the minimal Boost.UI sample\n" 38 | << "running under " << BOOST_PLATFORM << "." 39 | ; 40 | ui::info_dialog(ss.str(), "About Boost.UI minimal sample"); 41 | }) 42 | ) 43 | ; 44 | 45 | status_bar().text("Welcome to Boost.UI!"); 46 | } 47 | 48 | int ui_main() 49 | { 50 | my_frame frame("Minimal Boost.UI App"); 51 | 52 | frame.show_modal(); 53 | 54 | return 0; 55 | } 56 | 57 | int main(int argc, char* argv[]) 58 | { 59 | return ui::entry(&ui_main, argc, argv); 60 | } 61 | -------------------------------------------------------------------------------- /src/status_bar.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | #if wxUSE_STATUSBAR 21 | 22 | class status_bar::native_impl : public wxStatusBar, private detail::memcheck 23 | { 24 | public: 25 | native_impl(widget& parent) : wxStatusBar(native::from_widget(parent)) 26 | { 27 | SetFieldsCount(1); 28 | } 29 | }; 30 | 31 | #endif // wxUSE_STATUSBAR 32 | 33 | status_bar::status_bar() : m_impl(NULL) 34 | { 35 | } 36 | 37 | status_bar::status_bar(const status_bar& other) 38 | { 39 | m_impl = other.m_impl; 40 | } 41 | 42 | void status_bar::create(widget& parent) 43 | { 44 | #if wxUSE_STATUSBAR 45 | m_impl = new native_impl(parent); 46 | #else 47 | m_impl = NULL; 48 | #endif 49 | } 50 | 51 | status_bar::~status_bar() 52 | { 53 | // It should be deleted by frame 54 | //delete m_impl; 55 | } 56 | 57 | status_bar& status_bar::text(const uistring& text) 58 | { 59 | wxCHECK_MSG(m_impl, *this, "Widget should be created"); 60 | #if wxUSE_STATUSBAR 61 | m_impl->SetStatusText(native::from_uistring(text)); 62 | #endif 63 | return *this; 64 | } 65 | 66 | uistring status_bar::text() const 67 | { 68 | wxCHECK_MSG(m_impl, uistring(), "Widget should be created"); 69 | #if wxUSE_STATUSBAR 70 | return native::to_uistring(m_impl->GetStatusText()); 71 | #else 72 | return uistring(); 73 | #endif 74 | } 75 | 76 | } // namespace ui 77 | } // namespace boost 78 | -------------------------------------------------------------------------------- /test/image_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace ui = boost::ui; 13 | 14 | int ui_main(int argc, char* argv[]) 15 | { 16 | { 17 | ui::image img; 18 | BOOST_TEST(!img.valid()); 19 | BOOST_TEST(img.native_handle()); 20 | BOOST_TEST_THROWS(img.width(), std::runtime_error); 21 | BOOST_TEST_THROWS(img.height(), std::runtime_error); 22 | 23 | if ( argc < 2 ) 24 | return 1; 25 | 26 | std::ifstream fs(argv[1]); 27 | BOOST_TEST(fs); 28 | 29 | img.load(fs); 30 | BOOST_TEST(img.valid()); 31 | BOOST_TEST(img.native_handle()); 32 | BOOST_TEST_EQ(img.width(), 16); 33 | BOOST_TEST_EQ(img.height(), 16); 34 | 35 | ui::image img2 = img; 36 | BOOST_TEST(img2.valid()); 37 | BOOST_TEST(img2.native_handle()); 38 | 39 | img2 = ui::image(); 40 | BOOST_TEST(!img2.valid()); 41 | BOOST_TEST(img2.native_handle()); 42 | 43 | std::istringstream ss; 44 | BOOST_TEST_THROWS(img.load(fs), std::runtime_error); 45 | BOOST_TEST(!img.valid()); 46 | BOOST_TEST(img.native_handle()); 47 | } 48 | 49 | { 50 | const ui::image img = ui::image::xdg("folder", 32, 32); 51 | BOOST_TEST(img.valid()); 52 | BOOST_TEST(img.native_handle()); 53 | BOOST_TEST_EQ(img.width(), 32); 54 | BOOST_TEST_EQ(img.height(), 32); 55 | } 56 | 57 | return boost::report_errors(); 58 | } 59 | 60 | int cpp_main(int argc, char* argv[]) 61 | { 62 | //return ui_main(argc, argv); 63 | return ui::entry(&ui_main, argc, argv); 64 | } 65 | -------------------------------------------------------------------------------- /include/boost/ui/detail/event.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES 7 | #include 8 | #else 9 | #include 10 | #endif 11 | 12 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 13 | 14 | #define BOOST_UI_DETAIL_HANDLER(handler, cls) \ 15 | template \ 16 | cls& on_##handler(F&& f, Args&&... args) \ 17 | { on_##handler##_raw(std::bind(boost::forward(f), boost::forward(args)...)); return *this; } \ 18 | 19 | #define BOOST_UI_DETAIL_HANDLER_EVENT(handler, cls, event) \ 20 | template \ 21 | cls& on_##handler(F&& f, Args&&... args) \ 22 | { on_##handler##_raw(std::bind(boost::forward(f), boost::forward(args)..., std::placeholders::_1)); return *this; } \ 23 | 24 | #else // defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 25 | 26 | #define BOOST_UI_DETAIL_HANDLER(handler, cls) \ 27 | cls& on_##handler(const boost::function& handler) \ 28 | { on_##handler##_raw(handler); return *this; } \ 29 | template \ 30 | cls& on_##handler(F f, Arg1 a1) \ 31 | { on_##handler##_raw(boost::bind(f, a1)); return *this; } \ 32 | template \ 33 | cls& on_##handler(F f, Arg1 a1, Arg2 a2) \ 34 | { on_##handler##_raw(boost::bind(f, a1, a2)); return *this; } \ 35 | 36 | #define BOOST_UI_DETAIL_HANDLER_EVENT(handler, cls, event) \ 37 | cls& on_##handler(const boost::function& handler) \ 38 | { on_##handler##_raw(handler); return *this; } \ 39 | template \ 40 | cls& on_##handler(F f, Arg1 a1) \ 41 | { on_##handler##_raw(boost::bind(f, a1, _1)); return *this; } \ 42 | template \ 43 | cls& on_##handler(F f, Arg1 a1, Arg2 a2) \ 44 | { on_##handler##_raw(boost::bind(f, a1, a2, _1)); return *this; } \ 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/web_widget.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace boost { 17 | namespace ui { 18 | 19 | #if wxUSE_WEBVIEW 20 | 21 | class web_widget::detail_impl : public detail::widget_detail 22 | { 23 | public: 24 | explicit detail_impl(widget& parent) 25 | { 26 | set_native_handle(wxWebView::New( native::from_widget(parent), wxID_ANY )); 27 | } 28 | void set_html(const uistring& html) 29 | { 30 | wxCHECK_RET(m_native, "Widget should be created"); 31 | m_native->SetPage(native::from_uistring(html), wxString()); 32 | } 33 | void load(const uistring& url) 34 | { 35 | wxCHECK_RET(m_native, "Widget should be created"); 36 | m_native->LoadURL(native::from_uistring(url)); 37 | } 38 | }; 39 | 40 | #endif 41 | 42 | web_widget::detail_impl* web_widget::get_impl() 43 | { 44 | #if wxUSE_WEBVIEW 45 | return get_detail_impl(); 46 | #else 47 | return NULL; 48 | #endif 49 | } 50 | 51 | web_widget& web_widget::create(widget& parent) 52 | { 53 | #if wxUSE_WEBVIEW 54 | detail_set_detail_impl(new detail_impl(parent)); 55 | #endif 56 | 57 | return *this; 58 | } 59 | 60 | web_widget& web_widget::html(const uistring& html) 61 | { 62 | #if wxUSE_WEBVIEW 63 | detail_impl* impl = get_impl(); 64 | wxCHECK_MSG(impl, *this, "Widget should be created"); 65 | 66 | impl->set_html(html); 67 | #endif 68 | 69 | return *this; 70 | } 71 | 72 | web_widget& web_widget::load(const uistring& url) 73 | { 74 | #if wxUSE_WEBVIEW 75 | detail_impl* impl = get_impl(); 76 | wxCHECK_MSG(impl, *this, "Widget should be created"); 77 | 78 | impl->load(url); 79 | #endif 80 | 81 | return *this; 82 | } 83 | 84 | } // namespace ui 85 | } // namespace boost 86 | -------------------------------------------------------------------------------- /example/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost UI Library Build Jamfile 2 | 3 | # Copyright (c) 2017 Kolya Kosenko 4 | 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # See www.boost.org/LICENSE_1_0.txt 7 | 8 | project 9 | : requirements 10 | /boost/ui//boost_ui 11 | 12 | # msvc: /subsystem:windows requires WinMain 13 | windows:gui 14 | ; 15 | 16 | # WinMain implementation 17 | obj winmain : ../include/boost/ui/native/winmain.cpp ; 18 | 19 | obj example_rc : res/example.rc ; 20 | 21 | exe hello : hello.cpp example_rc winmain ; 22 | exe demo : demo.cpp example_rc winmain ; 23 | exe native : native.cpp example_rc winmain ; 24 | exe spirit : spirit.cpp example_rc winmain ; 25 | 26 | exe asio_chat_client : asio_chat_client.cpp example_rc winmain 27 | /boost/system//boost_system 28 | /boost/thread//boost_thread 29 | ; 30 | 31 | exe chrono : chrono.cpp example_rc winmain 32 | /boost/chrono//boost_chrono ; 33 | 34 | exe date_time : date_time.cpp example_rc winmain 35 | /boost/date_time//boost_date_time ; 36 | 37 | exe font : font.cpp example_rc winmain ; 38 | 39 | exe filesystem : filesystem.cpp example_rc winmain 40 | /boost/filesystem//boost_filesystem 41 | #: gcc,linux:"-lstdc++fs" 42 | ; 43 | 44 | exe interprocess : interprocess.cpp example_rc winmain 45 | /boost/date_time//boost_date_time 46 | /boost/chrono//boost_chrono 47 | : linux:"-lrt" ; 48 | 49 | exe lexical_cast : lexical_cast.cpp example_rc winmain ; 50 | 51 | exe locale : locale.cpp example_rc winmain 52 | /boost/locale//boost_locale ; 53 | 54 | exe random : random.cpp example_rc winmain 55 | /boost/random//boost_random ; 56 | 57 | exe regex : regex.cpp example_rc winmain 58 | /boost/regex//boost_regex ; 59 | 60 | exe sort : sort.cpp example_rc winmain 61 | /boost/chrono//boost_chrono ; 62 | 63 | exe thread : thread.cpp example_rc winmain 64 | /boost/thread//boost_thread ; 65 | 66 | exe timer : timer.cpp example_rc winmain 67 | /boost/chrono//boost_chrono 68 | /boost/timer//boost_timer ; 69 | 70 | exe tokenizer : tokenizer.cpp example_rc winmain ; 71 | -------------------------------------------------------------------------------- /include/boost/ui/native/impl/canvas.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_IMPL_CANVAS_HPP 7 | #define BOOST_UI_NATIVE_IMPL_CANVAS_HPP 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #if wxUSE_GRAPHICS_CONTEXT 21 | #define BOOST_UI_USE_GRAPHICS_CONTEXT 22 | #endif 23 | 24 | #ifdef BOOST_UI_USE_GRAPHICS_CONTEXT 25 | #include 26 | #endif 27 | 28 | #include 29 | 30 | namespace boost { 31 | namespace ui { 32 | namespace detail { 33 | 34 | class painter_impl : public detail::widget_detail 35 | { 36 | public: 37 | explicit painter_impl(widget& parent); 38 | virtual ~painter_impl(); 39 | 40 | void prepare(); 41 | void save(); 42 | void restore(); 43 | void update_brush(); 44 | void begin_path(); 45 | 46 | #ifdef BOOST_UI_USE_GRAPHICS_CONTEXT 47 | wxGraphicsContext* get_context(); 48 | #endif 49 | wxMemoryDC& GetMemoryDCRef() { return m_memdc; } 50 | 51 | void update_pen(); 52 | void update_fill_font(); 53 | 54 | #ifdef BOOST_UI_USE_GRAPHICS_CONTEXT 55 | wxGraphicsPath m_path; 56 | #else 57 | typedef std::vector path_type; 58 | path_type m_path; 59 | wxPoint m_start_point; 60 | #endif 61 | 62 | struct state 63 | { 64 | color m_fill; 65 | color m_stroke; 66 | int m_line_width; 67 | wxPenCap m_cap; 68 | wxPenJoin m_join; 69 | std::vector m_dashes; 70 | wxFont m_font; 71 | }; 72 | 73 | state m_state; 74 | 75 | private: 76 | void init_dc(); 77 | void prepare_dc(); 78 | void flush(); 79 | 80 | void on_paint(wxPaintEvent& e); 81 | 82 | std::stack m_states; 83 | 84 | #ifdef BOOST_UI_USE_GRAPHICS_CONTEXT 85 | wxGraphicsContext* m_gc; 86 | #endif 87 | wxBitmap m_bitmap; 88 | wxMemoryDC m_memdc; 89 | }; 90 | 91 | } // namespace detail 92 | } // namespace ui 93 | } // namespace boost 94 | 95 | #endif // BOOST_UI_NATIVE_IMPL_CANVAS_HPP 96 | -------------------------------------------------------------------------------- /example/cpp11/beman.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | Beman's challenge 13 | 14 | 74 | 75 | 77 | 78 | 79 | Your browser does not support the HTML5 canvas tag. 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /example/cpp11/bootstrap.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Text processor 7 | // This example creates dialog with input and output fields, and one button 8 | // between them. When user press button, reversed input field text copied into output field. 9 | // Input field is cleared. 10 | 11 | #include 12 | #include 13 | 14 | namespace ui = boost::ui; 15 | 16 | class bootstrap_dialog : public ui::dialog 17 | { 18 | typedef bootstrap_dialog this_type; 19 | 20 | public: 21 | bootstrap_dialog(); 22 | 23 | private: 24 | void process(); 25 | 26 | ui::text_box m_input_widget; 27 | ui::label m_output_widget; 28 | }; 29 | 30 | bootstrap_dialog::bootstrap_dialog() 31 | : ui::dialog("Bootstrap example") 32 | { 33 | // Create vertical box layout inside dialog window 34 | // and put children widgets inside it 35 | ui::vbox(*this) 36 | << ui::label(*this, "Input:") 37 | << m_input_widget.create(*this, "Boost.UI default input data 0123456789") 38 | .tooltip("Input string") 39 | .layout().justify().stretch() 40 | 41 | << ui::button(*this, "&Process") 42 | .on_press(&this_type::process, this) 43 | .tooltip("Process input data") 44 | 45 | << ui::label(*this, "Output:") 46 | << m_output_widget.create(*this) 47 | .tooltip("Output") 48 | .layout().justify().stretch() 49 | ; 50 | 51 | // Change dialog window size 52 | resize(400, 300); 53 | } 54 | 55 | void bootstrap_dialog::process() 56 | { 57 | // Read string from input widget 58 | std::wstring data = m_input_widget.text().wstring(); 59 | 60 | // TODO: Add your process code here 61 | std::reverse(data.begin(), data.end()); 62 | 63 | std::wostringstream ss; 64 | ss << data; 65 | 66 | // Write string to output widget 67 | m_output_widget.text(ss.str()); 68 | 69 | // Clear input widget text 70 | m_input_widget.clear(); 71 | } 72 | 73 | int ui_main() 74 | { 75 | bootstrap_dialog().show_modal(); 76 | 77 | return 0; 78 | } 79 | 80 | int main(int argc, char* argv[]) 81 | { 82 | return ui::entry(&ui_main, argc, argv); 83 | } 84 | -------------------------------------------------------------------------------- /test/stream_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace ui = boost::ui; 12 | 13 | template 14 | void test_stream_api() 15 | { 16 | { 17 | Stream ss; 18 | BOOST_TEST(ss.str() == ""); 19 | 20 | ss << 'A' << "aA" << std::string("1") << 3 << 1.2 << true << false << std::endl; 21 | BOOST_TEST(ss.str() == "AaA131.210\n"); 22 | } 23 | { 24 | Stream ss("x1"); 25 | BOOST_TEST(ss.str() == "x1"); 26 | 27 | ss.str("y2"); 28 | BOOST_TEST(ss.str() == "y2"); 29 | } 30 | } 31 | 32 | template 33 | void test_wstream_api() 34 | { 35 | { 36 | Stream ss; 37 | ss << L'B' << L"bB" << std::wstring(L"2"); 38 | BOOST_TEST(ss.str() == L"BbB2"); 39 | } 40 | } 41 | 42 | int cpp_main(int, char*[]) 43 | { 44 | test_stream_api(); 45 | test_stream_api(); 46 | 47 | test_wstream_api(); 48 | test_wstream_api(); 49 | 50 | { 51 | #ifndef BOOST_NO_CXX11_CHAR16_T 52 | ui::uiostringstream ss; 53 | ss << u'C' << u"cC" << std::u16string(u"3"); 54 | BOOST_TEST(ss.str() == "CcC3"); 55 | #endif 56 | } 57 | { 58 | #ifndef BOOST_NO_CXX11_CHAR32_T 59 | ui::uiostringstream ss; 60 | ss << U'D' << U"dD" << std::u32string(U"4"); 61 | BOOST_TEST(ss.str() == "DdD4"); 62 | #endif 63 | } 64 | { 65 | ui::uiostringstream ss; 66 | 67 | void* ptr = reinterpret_cast(0x42); 68 | ss << ptr; 69 | BOOST_TEST_NE(ss.str().wstring().find(L"42"), -1); 70 | } 71 | { 72 | ui::uiostringstream ss1("1"); 73 | ui::uiostringstream ss2("2"); 74 | BOOST_TEST(ss1.str() == "1"); 75 | BOOST_TEST(ss2.str() == "2"); 76 | 77 | ss1.swap(ss2); 78 | BOOST_TEST(ss1.str() == "2"); 79 | BOOST_TEST(ss2.str() == "1"); 80 | 81 | std::swap(ss1, ss2); 82 | BOOST_TEST(ss1.str() == "1"); 83 | BOOST_TEST(ss2.str() == "2"); 84 | } 85 | 86 | return boost::report_errors(); 87 | } 88 | -------------------------------------------------------------------------------- /include/boost/ui/window.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file window.hpp @brief Window class 7 | 8 | #ifndef BOOST_UI_WINDOW_HPP 9 | #define BOOST_UI_WINDOW_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Close event class 23 | /// @ingroup event 24 | 25 | class close_event : public event 26 | { 27 | public: 28 | close_event() : m_veto(false) {} 29 | ~close_event(); 30 | 31 | /// Don't close application 32 | void veto() { m_veto = true; } 33 | 34 | private: 35 | bool m_veto; 36 | boost::function m_veto_fn; 37 | boost::function m_skip_fn; 38 | 39 | #ifndef DOXYGEN 40 | template 41 | friend class native::event_functor_event; 42 | #endif 43 | }; 44 | 45 | /// @brief Abstract top level widget that hosts other widgets 46 | /// @details 47 | /// Usage examples: 48 | /// @snippet cpp11/snippet.cpp dialog 49 | /// @snippet cpp11/snippet.cpp frame 50 | /// @see Window (Wikipedia) 51 | /// @ingroup tlw 52 | 53 | class BOOST_UI_DECL window : public widget 54 | { 55 | public: 56 | /// @brief Sets title 57 | /// @see Title bar (Wikipedia) 58 | window& title(const uistring& title); 59 | 60 | /// Returns title 61 | uistring title() const; 62 | 63 | /// @brief Shows an application-modal dialog 64 | /// @see Modal window (Wikipedia) 65 | void show_modal(); 66 | 67 | /// Initiates window close. Returns false if operation was vetoed 68 | bool close(); 69 | 70 | ///@{ Connects window close handler 71 | BOOST_UI_DETAIL_HANDLER(close, window); 72 | BOOST_UI_DETAIL_HANDLER_EVENT(close_event, window, close_event); 73 | ///@} 74 | 75 | private: 76 | void on_close_raw(const boost::function& handler); 77 | void on_close_event_raw(const boost::function& handler); 78 | }; 79 | } // namespace ui 80 | } // namespace boost 81 | 82 | #endif // BOOST_UI_WINDOW_HPP 83 | -------------------------------------------------------------------------------- /include/boost/ui/image.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file image.hpp @brief Image class 7 | 8 | #ifndef BOOST_UI_IMAGE_HPP 9 | #define BOOST_UI_IMAGE_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace boost { 22 | namespace ui { 23 | 24 | /// @brief Image class 25 | /// @see Digital image (Wikipedia) 26 | /// @ingroup graphics 27 | 28 | class BOOST_UI_DECL image 29 | { 30 | class impl; 31 | 32 | public: 33 | image(); 34 | #ifndef DOXYGEN 35 | image(const image& other); 36 | image& operator=(const image& other); 37 | #endif 38 | ~image(); 39 | 40 | /// @brief Loads image from the stream 41 | /// @throw std::runtime_error On image load failure 42 | /// @see Image file formats (Wikipedia) 43 | image& load(std::istream& s); 44 | 45 | /// @brief Returns standard freedesktop.org (XDG) icon by name 46 | /// @see 47 | /// freedesktop.org Icon Naming Specification 48 | static image xdg(const char* name, coord_type width, coord_type height); 49 | 50 | /// @brief Returns image width 51 | /// @throw std::runtime_error On invalid image 52 | coord_type width() const; 53 | 54 | /// @brief Returns image height 55 | /// @throw std::runtime_error On invalid image 56 | coord_type height() const; 57 | 58 | /// @brief Returns image size 59 | /// @throw std::runtime_error On invalid image 60 | size dimensions() const 61 | { return size(width(), height()); } 62 | 63 | /// Returns true only if image is valid 64 | bool valid() const BOOST_NOEXCEPT; 65 | 66 | /// Implementation-defined image type 67 | typedef void* native_handle_type; 68 | 69 | ///@{ Returns the implementation-defined underlying image handle 70 | native_handle_type native_handle() { return m_impl; } 71 | const native_handle_type native_handle() const { return m_impl; } 72 | ///@} 73 | 74 | private: 75 | impl* m_impl; 76 | }; 77 | 78 | } // namespace ui 79 | } // namespace boost 80 | 81 | #endif // BOOST_UI_IMAGE_HPP 82 | -------------------------------------------------------------------------------- /example/random.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Draw normal distribution graph using C++11 or Boost.Random. 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #if !defined(BOOST_NO_CXX11_HDR_RANDOM) 14 | #include 15 | namespace random_ns = std; 16 | #else 17 | #include 18 | #include 19 | namespace random_ns = boost::random; 20 | #endif 21 | 22 | namespace ui = boost::ui; 23 | 24 | class random_dialog : public ui::dialog 25 | { 26 | typedef random_dialog this_type; 27 | 28 | public: 29 | random_dialog(); 30 | 31 | private: 32 | void draw(); 33 | 34 | ui::canvas m_canvas; 35 | }; 36 | 37 | random_dialog::random_dialog() : ui::dialog( 38 | #if !defined(BOOST_NO_CXX11_HDR_RANDOM) 39 | "C++11 " 40 | #else 41 | "Boost." 42 | #endif 43 | "Random + Boost.UI example") 44 | { 45 | m_canvas.create(*this) 46 | .tooltip("Normal distribution") 47 | .on_resize(&this_type::draw, this) 48 | .on_left_mouse_up(&this_type::draw, this) 49 | ; 50 | } 51 | 52 | void random_dialog::draw() 53 | { 54 | random_ns::random_device rd; 55 | random_ns::mt19937 generator(rd()); 56 | 57 | random_ns::normal_distribution<> distribution(0, 10); 58 | 59 | typedef std::map histogram_type; 60 | histogram_type histogram; 61 | static const int repeats = 1000; 62 | for ( int n = 0; n < repeats; ++n ) 63 | { 64 | ++histogram[boost::math::iround( distribution(generator) )]; 65 | } 66 | 67 | ui::painter painter = m_canvas.painter(); 68 | painter.clear_rect(0, 0, m_canvas.width(), m_canvas.height()); 69 | painter.translate(m_canvas.width() / 2, m_canvas.height()).scale(4, -4); 70 | for ( histogram_type::const_iterator iter = histogram.begin(); 71 | iter != histogram.end(); ++iter ) 72 | { 73 | const double x = iter->first; 74 | const double y = 1000.0 * iter->second / repeats; 75 | 76 | if ( iter == histogram.begin() ) 77 | painter.move_to(x, y); 78 | else 79 | painter.line_to(x, y); 80 | } 81 | painter.stroke_color(ui::color::blue).stroke(); 82 | } 83 | 84 | int ui_main() 85 | { 86 | random_dialog().show_modal(); 87 | 88 | return 0; 89 | } 90 | 91 | int main(int argc, char* argv[]) 92 | { 93 | return ui::entry(&ui_main, argc, argv); 94 | } 95 | -------------------------------------------------------------------------------- /doc/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost UI Library Build Jamfile 2 | 3 | # Copyright (c) 2017 Kolya Kosenko 4 | 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # See www.boost.org/LICENSE_1_0.txt 7 | 8 | project boost/ui/doc ; 9 | using doxygen ; 10 | using quickbook ; 11 | using boostbook ; 12 | 13 | doxygen 14 | # target 15 | ui_reference 16 | : 17 | # sources 18 | [ glob ../../../libs/ui/include/boost/ui/*.hpp ] 19 | [ glob ../../../libs/ui/include/boost/ui.hpp ] 20 | : 21 | # requirements 22 | GENERATE_HTML=YES 23 | PROJECT_NAME="Boost.UI" 24 | PROJECT_BRIEF="User Interface Boost library" 25 | HTML_COLORSTYLE_HUE=206 26 | HTML_COLORSTYLE_SAT=100 27 | HTML_COLORSTYLE_GAMMA=80 28 | HAVE_DOT=yes 29 | DOT_IMAGE_FORMAT=svg 30 | COLLABORATION_GRAPH=no 31 | GRAPHICAL_HIERARCHY=no 32 | DISTRIBUTE_GROUP_DOC=YES 33 | MACRO_EXPANSION=YES 34 | SHOW_INCLUDE_FILES=NO 35 | STRIP_FROM_PATH=$(BOOST_ROOT)/libs/ui/include 36 | EXAMPLE_PATH=$(BOOST_ROOT)/libs/ui/example 37 | IMAGE_PATH=$(BOOST_ROOT)/libs/ui/doc/doxygen/images 38 | HTML_FOOTER=$(BOOST_ROOT)/libs/ui/doc/doxygen/footer.html 39 | PREDEFINED="DOXYGEN BOOST_UI_DECL BOOST_NOEXCEPT=noexcept \\ 40 | \"BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType)=enum class EnumType\" \\ 41 | BOOST_SCOPED_ENUM_DECLARE_END(EnumType)=; \\ 42 | \"BOOST_UI_DETAIL_HANDLER(handler, cls)=template cls& on_##handler(F&& f, Args&&... args)\" \\ 43 | \"BOOST_UI_DETAIL_HANDLER_EVENT(handler, cls, event)=template cls& on_##handler(F&& f, Args&&... args)\" \\ 44 | " 45 | ; 46 | 47 | xml ui : ui.qbk : ui_reference ; 48 | 49 | boostbook standalone 50 | : 51 | ui 52 | : 53 | #boost.root=../../../.. 54 | "boost.root=https://kosenko.github.io/boost.org" 55 | #"boost.root=https://www.boost.org/doc/libs/1_65_1" 56 | ; 57 | 58 | ############################################################################### 59 | 60 | alias boostdoc : standalone ; 61 | explicit boostdoc ; 62 | 63 | alias boostrelease ; 64 | explicit boostrelease ; 65 | -------------------------------------------------------------------------------- /test/color_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace ui = boost::ui; 16 | 17 | template 18 | void test_stream() 19 | { 20 | { 21 | std::basic_ostringstream oss_actual; 22 | oss_actual << ui::color::yellow_green; 23 | 24 | std::basic_ostringstream oss_expected; 25 | oss_expected << 'r' << 'g' << 'b' << '(' 26 | << '1' << '5' << '4' << ',' 27 | << '2' << '0' << '5' << ',' 28 | << '5' << '0' << ')'; 29 | BOOST_TEST(oss_actual.str() == oss_expected.str()); 30 | } 31 | { 32 | std::basic_ostringstream oss_actual; 33 | oss_actual << ui::color::rgba255(1, 2, 3, 4); 34 | 35 | std::basic_ostringstream oss_expected; 36 | oss_expected << 'r' << 'g' << 'b' << 'a' << '(' 37 | << '1' << ',' << '2' << ',' << '3' << ',' << '4' << ')'; 38 | BOOST_TEST(oss_actual.str() == oss_expected.str()); 39 | } 40 | } 41 | 42 | int cpp_main(int argc, char* argv[]) 43 | { 44 | BOOST_TEST_EQ(ui::color::rgba255(0, 0, 0, 0), ui::color()); 45 | BOOST_TEST_EQ(ui::color::rgba255(0, 0, 0, 255), ui::color::black); 46 | BOOST_TEST_EQ(ui::color::rgb255(0xff, 0, 0), ui::color::red); 47 | BOOST_TEST_NE(ui::color::blue, ui::color::red); 48 | 49 | BOOST_TEST_EQ(ui::color::rgba1(1, 0.25, 0.5, 0.75), 50 | ui::color::rgba255(255, 64, 128, 191)); 51 | 52 | BOOST_TEST_EQ(ui::color::olive.red1(), 128. / 255); 53 | BOOST_TEST_EQ(ui::color::olive.green1(), 128. / 255); 54 | BOOST_TEST_EQ(ui::color::olive.blue1(), 0); 55 | BOOST_TEST_EQ(ui::color::olive.alpha1(), 1); 56 | 57 | BOOST_TEST_EQ(ui::color::navy.red1(), 0); 58 | BOOST_TEST_EQ(ui::color::navy.green1(), 0); 59 | BOOST_TEST_EQ(ui::color::navy.blue1(), 128. / 255); 60 | BOOST_TEST_EQ(ui::color::navy.alpha1(), 1); 61 | 62 | BOOST_TEST_THROWS(ui::color::rgb1(2, 0, 0), std::out_of_range); 63 | BOOST_TEST_THROWS(ui::color::rgb1(0, -0.5, 0), std::out_of_range); 64 | 65 | test_stream(); 66 | test_stream(); 67 | #ifndef BOOST_NO_CXX11_CHAR16_T 68 | //test_stream(); 69 | #endif 70 | #ifndef BOOST_NO_CXX11_CHAR32_T 71 | //test_stream(); 72 | #endif 73 | 74 | return boost::report_errors(); 75 | } 76 | -------------------------------------------------------------------------------- /src/window.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | 18 | namespace boost { 19 | namespace ui { 20 | 21 | namespace native { 22 | 23 | template <> 24 | void event_functor_event::init(close_event& uievent, wxCloseEvent& wxevent) 25 | { 26 | uievent.m_veto_fn = boost::bind(&wxCloseEvent::Veto, boost::ref(wxevent), boost::placeholders::_1); 27 | uievent.m_skip_fn = boost::bind(&wxCloseEvent::Skip, boost::ref(wxevent), boost::placeholders::_1); 28 | } 29 | 30 | } // namespace native 31 | 32 | close_event::~close_event() 33 | { 34 | if ( m_veto ) 35 | { 36 | m_veto_fn(true); 37 | m_skip_fn(false); 38 | } 39 | } 40 | 41 | namespace { 42 | 43 | wxTopLevelWindow* get_impl(widget& w) 44 | { return static_cast(w.native_handle()); } 45 | 46 | const wxTopLevelWindow* get_impl(const widget& w) 47 | { return static_cast(w.native_handle()); } 48 | 49 | } // namespace unnamed 50 | 51 | window& window::title(const uistring& title) 52 | { 53 | wxTopLevelWindow* impl = get_impl(*this); 54 | wxCHECK_MSG(impl, *this, "Widget should be created"); 55 | 56 | impl->SetTitle(native::from_uistring(title)); 57 | 58 | return *this; 59 | } 60 | 61 | uistring window::title() const 62 | { 63 | const wxTopLevelWindow* impl = get_impl(*this); 64 | wxCHECK_MSG(impl, uistring(), "Widget should be created"); 65 | 66 | return native::to_uistring(impl->GetTitle()); 67 | } 68 | 69 | void window::show_modal() 70 | { 71 | detail::window_detail_base* impl = 72 | get_detail_impl(); 73 | wxCHECK_RET(impl, "Widget should be created"); 74 | 75 | impl->show_modal(); 76 | } 77 | 78 | bool window::close() 79 | { 80 | wxTopLevelWindow* impl = get_impl(*this); 81 | wxCHECK_MSG(impl, true, "Widget should be created"); 82 | 83 | return impl->Close(); 84 | } 85 | 86 | void window::on_close_raw(const boost::function& handler) 87 | { 88 | native::bind_helper(*this, wxEVT_CLOSE_WINDOW, handler); 89 | } 90 | 91 | void window::on_close_event_raw(const boost::function& handler) 92 | { 93 | native::bind_event_helper(*this, wxEVT_CLOSE_WINDOW, handler); 94 | } 95 | 96 | } // namespace ui 97 | } // namespace boost 98 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Travis CI build script 2 | 3 | # Copyright (c) 2017 Kolya Kosenko 4 | 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # See www.boost.org/LICENSE_1_0.txt 7 | 8 | language: cpp 9 | dist: xenial 10 | 11 | matrix: 12 | include: 13 | - env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++17 14 | compiler: g++ 15 | - env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++17 16 | compiler: clang++ 17 | - env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++11 SKIP_CPP17=1 18 | compiler: g++ 19 | - env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11 SKIP_CPP17=1 20 | compiler: clang++ 21 | - env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++03 SKIP_CPP17=1 SKIP_CPP11=1 SKIP_CPP03=1 22 | compiler: g++ 23 | #- env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03 SKIP_CPP17=1 SKIP_CPP11=1 24 | # compiler: clang++ 25 | # dist: trusty 26 | 27 | addons: 28 | apt: 29 | packages: 30 | - libgtk2.0-dev 31 | - libwebkitgtk-dev 32 | - realpath 33 | 34 | before_install: 35 | - sudo apt-get update -yq 36 | - sudo sh -c "echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections" 37 | - sudo apt-get install msttcorefonts -qq 38 | 39 | install: 40 | - cd .. 41 | - git clone -b boost-1.77.0 --depth 1 https://github.com/boostorg/boost.git boost-root 42 | - cd boost-root 43 | - git submodule update --init --checkout --depth 1 44 | - git submodule update --init tools/build 45 | - git submodule update --init libs/config 46 | - git submodule update --init tools/boostdep 47 | - ln -s $TRAVIS_BUILD_DIR libs/ui 48 | - python tools/boostdep/depinst/depinst.py ui 49 | - ./bootstrap.sh 50 | - ./b2 headers 51 | 52 | script: 53 | - set -e 54 | - |- 55 | echo "using $TOOLSET : : $COMPILER : -std=$CXXSTD ;" > ~/user-config.jam 56 | - wget https://github.com/wxWidgets/wxWidgets/releases/download/v3.0.5/wxWidgets-3.0.5.tar.bz2 57 | - tar -xf wxWidgets-3.0.5.tar.bz2 58 | - mkdir build-wx 59 | - pushd build-wx 60 | - ../wxWidgets-3.0.5/configure --disable-optimise --enable-debug=max 61 | - make 62 | - export WX_CONFIG=`realpath .`/wx-config 63 | - popd 64 | - ./b2 libs/ui/build toolset=$TOOLSET 65 | - xvfb-run ./b2 libs/ui/test toolset=$TOOLSET 66 | - (test "$SKIP_CPP03" && echo "SKIPPED") || ./b2 libs/ui/example toolset=$TOOLSET 67 | - (test "$SKIP_CPP11" && echo "SKIPPED") || ./b2 libs/ui/example/cpp11 toolset=$TOOLSET 68 | - (test "$SKIP_CPP17" && echo "SKIPPED") || ./b2 libs/ui/example/cpp17 toolset=$TOOLSET 69 | -------------------------------------------------------------------------------- /include/boost/ui/config.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file config.hpp @brief Configuration options 7 | 8 | #ifndef BOOST_UI_CONFIG_HPP 9 | #define BOOST_UI_CONFIG_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | //------------------------------------------------------------------------------ 18 | 19 | #ifndef DOXYGEN 20 | 21 | #if (__cplusplus < 201103L || \ 22 | defined(_MSC_VER) && _MSC_VER < 1600) /* Visual C++ 10 (2010)*/ \ 23 | && ( (!defined __GLIBCXX__) || (__GLIBCXX__ > 20070719) ) 24 | 25 | #define BOOST_UI_NO_STD_HASH 26 | 27 | #endif 28 | 29 | //------------------------------------------------------------------------------ 30 | // normalize macros 31 | 32 | #if defined(BOOST_UI_DYN_LINK) && defined(BOOST_UI_STATIC_LINK) 33 | # error Must not define both BOOST_UI_DYN_LINK and BOOST_UI_STATIC_LINK 34 | #endif 35 | 36 | //------------------------------------------------------------------------------ 37 | // dynamic linking 38 | 39 | #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_UI_DYN_LINK) 40 | # if defined(BOOST_UI_SOURCE) 41 | # define BOOST_UI_DECL BOOST_SYMBOL_EXPORT 42 | # else 43 | # define BOOST_UI_DECL BOOST_SYMBOL_IMPORT 44 | # endif 45 | #else 46 | # define BOOST_UI_DECL 47 | #endif 48 | 49 | //------------------------------------------------------------------------------ 50 | // auto-linking 51 | 52 | #if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_UI_NO_LIB) \ 53 | && !defined(BOOST_UI_SOURCE) 54 | 55 | #ifndef BOOST_LIB_NAME 56 | #define BOOST_LIB_NAME boost_ui 57 | #endif 58 | 59 | #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_UI_DYN_LINK) 60 | #define BOOST_DYN_LINK 61 | #endif 62 | 63 | #include 64 | 65 | #if defined(_MSC_VER) && !defined(BOOST_UI_WXWIDGETS_NO_LIB) 66 | #include // In %WXWIN%\include\ folder 67 | #ifdef BOOST_LIB_DIAGNOSTIC 68 | #pragma message("Linking to wxWidgets") 69 | #endif 70 | #endif 71 | 72 | #endif // auto-linking 73 | 74 | #endif // !DOXYGEN 75 | 76 | //------------------------------------------------------------------------------ 77 | // Doxygen 78 | 79 | #ifdef DOXYGEN 80 | 81 | /// @brief Enables Boost.Chrono library 82 | /// @ingroup helper 83 | #define BOOST_UI_USE_CHRONO 84 | 85 | /// @brief Enables Boost.Date_Time library 86 | /// @ingroup helper 87 | #define BOOST_UI_USE_DATE_TIME 88 | 89 | /// @brief Enables Boost.Filesystem library 90 | /// @ingroup helper 91 | #define BOOST_UI_USE_FILESYSTEM 92 | 93 | #endif // DOXYGEN 94 | 95 | #endif // BOOST_UI_CONFIG_HPP 96 | -------------------------------------------------------------------------------- /src/image_widget.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace boost { 16 | namespace ui { 17 | 18 | #if wxUSE_STATBMP 19 | class image_widget::detail_impl : public detail::widget_detail 20 | { 21 | public: 22 | explicit detail_impl(widget& parent) 23 | { 24 | set_native_handle(new wxStaticBitmap(native::from_widget(parent), 25 | wxID_ANY, wxBitmap())); 26 | } 27 | explicit detail_impl(widget& parent, const ui::image& img) 28 | { 29 | const wxBitmap bitmap = img.valid() 30 | ? *static_cast(img.native_handle()) 31 | : wxBitmap(); 32 | set_native_handle(new wxStaticBitmap(native::from_widget(parent), 33 | wxID_ANY, bitmap)); 34 | } 35 | void image(const ui::image& img) 36 | { 37 | wxCHECK_RET(m_native, "Widget should be created"); 38 | wxCHECK_RET(img.valid(), "Invalid image"); 39 | m_native->SetBitmap(*static_cast( img.native_handle() )); 40 | } 41 | void clear() 42 | { 43 | wxCHECK_RET(m_native, "Widget should be created"); 44 | m_native->SetBitmap(wxBitmap()); 45 | } 46 | }; 47 | #endif 48 | 49 | image_widget::detail_impl* image_widget::get_impl() 50 | { 51 | #if wxUSE_STATBMP 52 | return get_detail_impl(); 53 | #else 54 | return NULL; 55 | #endif 56 | } 57 | 58 | const image_widget::detail_impl* image_widget::get_impl() const 59 | { 60 | #if wxUSE_STATBMP 61 | return get_detail_impl(); 62 | #else 63 | return NULL; 64 | #endif 65 | } 66 | 67 | image_widget& image_widget::create(widget& parent) 68 | { 69 | #if wxUSE_STATBMP 70 | detail_set_detail_impl(new detail_impl(parent)); 71 | #endif 72 | 73 | return *this; 74 | } 75 | 76 | image_widget& image_widget::create(widget& parent, const ui::image& img) 77 | { 78 | #if wxUSE_STATBMP 79 | detail_set_detail_impl(new detail_impl(parent, img)); 80 | #endif 81 | 82 | return *this; 83 | } 84 | 85 | image_widget& image_widget::image(const ui::image& img) 86 | { 87 | #if wxUSE_STATBMP 88 | detail_impl* impl = get_impl(); 89 | wxCHECK_MSG(impl, *this, "Widget should be created"); 90 | 91 | impl->image(img); 92 | #endif 93 | 94 | return *this; 95 | } 96 | 97 | void image_widget::clear() 98 | { 99 | #if wxUSE_STATBMP 100 | detail_impl* impl = get_impl(); 101 | wxCHECK_RET(impl, "Widget should be created"); 102 | 103 | impl->clear(); 104 | #endif 105 | 106 | } 107 | 108 | } // namespace ui 109 | } // namespace boost 110 | -------------------------------------------------------------------------------- /example/timer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Runs function with boost::ui::on_timeout() function with 1 second delay and 7 | // checks timeout error using Boost.Timer. 8 | 9 | #include 10 | 11 | #if !defined(BOOST_NO_CXX11_HDR_CHRONO) 12 | #include 13 | namespace chrono_ns = std::chrono; 14 | #else 15 | #define BOOST_UI_USE_CHRONO 16 | #include 17 | namespace chrono_ns = boost::chrono; 18 | #endif 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | namespace ui = boost::ui; 29 | 30 | class timer_dialog : public ui::dialog 31 | { 32 | typedef timer_dialog this_type; 33 | 34 | public: 35 | timer_dialog(); 36 | 37 | private: 38 | void on_start(); 39 | void on_clear(); 40 | void on_timeout(); 41 | 42 | ui::list_box m_results_list_box; 43 | std::queue m_timers; 44 | }; 45 | 46 | timer_dialog::timer_dialog() : ui::dialog("Boost.Timer + Boost.UI example") 47 | { 48 | ui::vbox(*this) 49 | << ( ui::hbox() 50 | << ui::button(*this, "&Start") 51 | .on_press(&this_type::on_start, this) 52 | .tooltip("Start timer with one second delay and show results") 53 | << ui::button(*this, "&Clear results") 54 | .on_press(&this_type::on_clear, this) 55 | .tooltip("Clear log") 56 | ) 57 | << ui::label(*this, "Timer precision results of 1 second delay:") 58 | << m_results_list_box.create(*this) 59 | .tooltip("Timeout precision") 60 | .layout().stretch().justify() 61 | ; 62 | 63 | resize(1000, 500); 64 | } 65 | 66 | void timer_dialog::on_start() 67 | { 68 | m_timers.push(boost::timer::cpu_timer()); 69 | ui::on_timeout(chrono_ns::milliseconds(1000), &this_type::on_timeout, this); 70 | m_timers.back().start(); 71 | } 72 | 73 | void timer_dialog::on_clear() 74 | { 75 | m_results_list_box.clear(); 76 | } 77 | 78 | void timer_dialog::on_timeout() 79 | { 80 | const boost::timer::cpu_times times = m_timers.front().elapsed(); 81 | m_timers.pop(); 82 | 83 | std::ostringstream ss; 84 | ss << times.wall - 1e9 << "ns (" 85 | << (times.wall - 1e9) / 1.e9 * 100 << "%) "; 86 | 87 | const std::string format = boost::timer::format(times, 9); 88 | ss << " (" << format.substr(0, format.find_first_of('\n')) << ")"; 89 | 90 | m_results_list_box.push_back(ss.str()); 91 | } 92 | 93 | int ui_main() 94 | { 95 | timer_dialog().show_modal(); 96 | 97 | return 0; 98 | } 99 | 100 | int main(int argc, char* argv[]) 101 | { 102 | return ui::entry(&ui_main, argc, argv); 103 | } 104 | -------------------------------------------------------------------------------- /src/event.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace boost { 16 | namespace ui { 17 | 18 | mouse_event::mouse_event() : m_x(-1), m_y(-1), 19 | m_left(false), m_right(false), m_middle(false) 20 | { 21 | } 22 | 23 | namespace native { 24 | 25 | template <> 26 | void event_functor_event::init(event& uievent, wxCommandEvent& wxevent) 27 | { 28 | } 29 | 30 | template <> 31 | void event_functor_event::init(index_event& uievent, wxCommandEvent& wxevent) 32 | { 33 | uievent.m_index = wxevent.GetInt(); 34 | } 35 | 36 | template <> 37 | void event_functor_event::init(key_event& uievent, wxKeyEvent& wxevent) 38 | { 39 | uievent.m_code = wxevent.GetKeyCode(); 40 | 41 | #if wxUSE_UNICODE 42 | uievent.m_char = wxevent.GetUnicodeKey(); 43 | #endif 44 | 45 | uievent.m_ctrl = wxevent.ControlDown(); 46 | uievent.m_shift = wxevent.ShiftDown(); 47 | uievent.m_alt = wxevent.AltDown(); 48 | uievent.m_meta = wxevent.MetaDown(); 49 | } 50 | 51 | template <> 52 | void event_functor_event::init(mouse_event& uievent, wxMouseEvent& wxevent) 53 | { 54 | uievent.m_x = wxevent.GetX(); 55 | uievent.m_y = wxevent.GetY(); 56 | uievent.m_left = wxevent.LeftIsDown() || wxevent.LeftUp(); 57 | uievent.m_right = wxevent.RightIsDown() || wxevent.RightUp(); 58 | uievent.m_middle = wxevent.MiddleIsDown() || wxevent.MiddleUp(); 59 | } 60 | 61 | template <> 62 | void event_functor_event::init(wheel_event& uievent, wxMouseEvent& wxevent) 63 | { 64 | uievent.m_x = wxevent.GetX(); 65 | uievent.m_y = wxevent.GetY(); 66 | uievent.m_left = wxevent.LeftIsDown() || wxevent.LeftUp(); 67 | uievent.m_right = wxevent.RightIsDown() || wxevent.RightUp(); 68 | uievent.m_middle = wxevent.MiddleIsDown() || wxevent.MiddleUp(); 69 | 70 | uievent.m_horizontal = wxevent.GetWheelAxis() == wxMOUSE_WHEEL_HORIZONTAL; 71 | uievent.m_delta = wxevent.GetWheelRotation(); 72 | if ( uievent.m_horizontal ) 73 | uievent.m_delta = -uievent.m_delta; 74 | } 75 | 76 | template <> 77 | void event_functor_event::init(mouse_event& uievent, wxContextMenuEvent& wxevent) 78 | { 79 | wxPoint pos = wxevent.GetPosition(); 80 | 81 | wxWindow* window = dynamic_cast(wxevent.GetEventObject()); 82 | wxCHECK_RET(window, "Context menu event has no associated widget"); 83 | pos = window->ScreenToClient(pos); 84 | 85 | uievent.m_x = pos.x; 86 | uievent.m_y = pos.y; 87 | } 88 | 89 | } // namespace native 90 | } // namespace ui 91 | } // namespace boost 92 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # AppVeyor build script 2 | 3 | # Copyright (c) 2017 Kolya Kosenko 4 | 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # See www.boost.org/LICENSE_1_0.txt 7 | 8 | version: 1.0.{build}-{branch} 9 | 10 | shallow_clone: true 11 | 12 | environment: 13 | matrix: 14 | # Visual Studio 2008, _CPPLIB_VER: 505 15 | - VS: 9.0 16 | SKIP_CPP03: 1 17 | SKIP_CPP11: 1 18 | SKIP_CPP17: 1 19 | 20 | # Visual Studio 2017 21 | #- VS: 14.1 22 | # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 23 | 24 | # Visual Studio 2015, _CPPLIB_VER: 650 25 | - VS: 14.0 26 | NMAKE_ARGS: TARGET_CPU=X64 27 | ARCH: amd64 28 | B2_ARGS: address-model=64 29 | SKIP_CPP17: 1 30 | 31 | # Visual Studio 2013, _CPPLIB_VER: 610 32 | - VS: 12.0 33 | NMAKE_ARGS: TARGET_CPU=X64 34 | ARCH: amd64 35 | B2_ARGS: address-model=64 36 | SKIP_CPP03: 1 37 | SKIP_CPP11: 1 38 | SKIP_CPP17: 1 39 | 40 | # Visual Studio 2012, _CPPLIB_VER: 540 41 | - VS: 11.0 42 | NMAKE_ARGS: BUILD=release 43 | B2_ARGS: variant=release 44 | SKIP_CPP03: 1 45 | SKIP_CPP11: 1 46 | SKIP_CPP17: 1 47 | 48 | # Visual Studio 2010, _CPPLIB_VER: 520 49 | - VS: 10.0 50 | SKIP_CPP03: 1 51 | SKIP_CPP11: 1 52 | SKIP_CPP17: 1 53 | 54 | install: 55 | - cmd: | 56 | cd .. 57 | git clone -b boost-1.77.0 --depth 1 https://github.com/boostorg/boost.git boost-root 58 | cd boost-root 59 | git submodule update --init --checkout --depth 1 60 | git submodule update --init tools/build 61 | git submodule update --init libs/config 62 | git submodule update --init tools/boostdep 63 | xcopy /s /e /q /i %APPVEYOR_BUILD_FOLDER% libs\ui\ 64 | python tools/boostdep/depinst/depinst.py ui 65 | cmd /c bootstrap 66 | b2 headers 67 | 68 | build: off 69 | 70 | test_script: 71 | - cmd: | 72 | cd .. 73 | appveyor DownloadFile https://github.com/wxWidgets/wxWidgets/releases/download/v3.0.5/wxWidgets-3.0.5.zip 74 | 7z x wxWidgets-3.0.5.zip -y -owxWidgets 75 | set WXWIN=%APPVEYOR_BUILD_FOLDER%\..\wxWidgets 76 | cd %WXWIN% 77 | cd build\msw 78 | call "C:\Program Files (x86)\Microsoft Visual Studio %VS%\VC\vcvarsall.bat" %ARCH% 79 | nmake -f makefile.vc %NMAKE_ARGS% 80 | cd %APPVEYOR_BUILD_FOLDER%\..\boost-root\ 81 | 82 | b2 libs/ui/build link=static toolset=msvc-%VS% %B2_ARGS% 83 | b2 libs/ui/test link=static toolset=msvc-%VS% %B2_ARGS% 84 | IF NOT DEFINED SKIP_CPP03 (b2 libs/ui/example link=static toolset=msvc-%VS% %B2_ARGS%) ELSE (ECHO SKIPPED) 85 | IF NOT DEFINED SKIP_CPP11 (b2 libs/ui/example/cpp11 link=static toolset=msvc-%VS% %B2_ARGS%) ELSE (ECHO SKIPPED) 86 | IF NOT DEFINED SKIP_CPP17 (b2 libs/ui/example/cpp17 link=static toolset=msvc-%VS% %B2_ARGS%) ELSE (ECHO SKIPPED) 87 | -------------------------------------------------------------------------------- /test/cache_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace ui = boost::ui; 12 | 13 | void test_label(ui::window& parent) 14 | { 15 | ui::label l1; 16 | BOOST_TEST(!l1.native_valid()); 17 | BOOST_TEST_EQ(l1.text(), ""); 18 | BOOST_TEST_EQ(l1.pos(), ui::point()); 19 | BOOST_TEST_EQ(l1.dimensions(), ui::size()); 20 | BOOST_TEST(l1.is_enabled()); 21 | BOOST_TEST(l1.is_shown()); // TODO: false 22 | 23 | //boost::function f1; 24 | //l1.on_mouse_move(f1); 25 | 26 | l1 .create("test label") 27 | .move(5, 5) 28 | .resize(200, 100) 29 | .disable() 30 | .hide() 31 | ; 32 | BOOST_TEST(!l1.native_valid()); 33 | BOOST_TEST_EQ(l1.text(), "test label"); 34 | BOOST_TEST_EQ(l1.pos(), ui::point(5, 5)); 35 | BOOST_TEST_EQ(l1.dimensions(), ui::size(200, 100)); 36 | BOOST_TEST(!l1.is_enabled()); 37 | BOOST_TEST(!l1.is_shown()); 38 | 39 | const ui::label l2 = l1; 40 | BOOST_TEST(!l1.native_valid()); 41 | BOOST_TEST(!l2.native_valid()); 42 | 43 | parent << l1; 44 | BOOST_TEST(l1.native_valid()); 45 | BOOST_TEST(l2.native_valid()); 46 | BOOST_TEST_EQ(l1.text(), "test label"); 47 | BOOST_TEST_EQ(l2.text(), "test label"); 48 | BOOST_TEST_EQ(l1.pos(), ui::point(5, 5)); 49 | BOOST_TEST_EQ(l2.pos(), ui::point(5, 5)); 50 | BOOST_TEST_EQ(l1.dimensions(), ui::size(200, 100)); 51 | BOOST_TEST_EQ(l2.dimensions(), ui::size(200, 100)); 52 | BOOST_TEST(!l1.is_enabled()); 53 | BOOST_TEST(!l2.is_enabled()); 54 | BOOST_TEST(!l1.is_shown()); 55 | BOOST_TEST(!l2.is_shown()); 56 | 57 | parent.show(); 58 | BOOST_TEST(!l1.is_shown()); 59 | BOOST_TEST(!l2.is_shown()); 60 | 61 | l1 .text("new") 62 | .move(10, 15) 63 | .resize(300, 150) 64 | .enable() 65 | .show() 66 | ; 67 | BOOST_TEST(l1.native_valid()); 68 | BOOST_TEST(l2.native_valid()); 69 | BOOST_TEST_EQ(l1.text(), "new"); 70 | BOOST_TEST_EQ(l2.text(), "new"); 71 | BOOST_TEST_EQ(l1.pos(), ui::point(10, 15)); 72 | BOOST_TEST_EQ(l2.pos(), ui::point(10, 15)); 73 | BOOST_TEST_EQ(l1.dimensions(), ui::size(300, 150)); 74 | BOOST_TEST_EQ(l2.dimensions(), ui::size(300, 150)); 75 | BOOST_TEST(l1.is_enabled()); 76 | BOOST_TEST(l2.is_enabled()); 77 | BOOST_TEST(l1.is_shown()); 78 | BOOST_TEST(l2.is_shown()); 79 | 80 | boost::function f2; 81 | l1.on_mouse_drag(f2); 82 | } 83 | 84 | int ui_main() 85 | { 86 | ui::frame frm("Cache test dialog"); 87 | 88 | test_label(frm); 89 | 90 | //frm.show_modal(); 91 | 92 | return boost::report_errors(); 93 | } 94 | 95 | int cpp_main(int argc, char* argv[]) 96 | { 97 | return ui::entry(&ui_main, argc, argv); 98 | } 99 | -------------------------------------------------------------------------------- /test/font_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace ui = boost::ui; 13 | 14 | int ui_main() 15 | { 16 | BOOST_TEST(!ui::font().valid()); 17 | BOOST_TEST(ui::font().native_handle()); 18 | BOOST_TEST_THROWS(ui::font().name(), std::runtime_error); 19 | BOOST_TEST_THROWS(ui::font().size_pt(), std::runtime_error); 20 | BOOST_TEST_THROWS(ui::font().get_family(), std::runtime_error); 21 | BOOST_TEST_THROWS(ui::font().get_slant(), std::runtime_error); 22 | BOOST_TEST_THROWS(ui::font().get_weight(), std::runtime_error); 23 | 24 | BOOST_TEST(ui::font::caption().valid()); 25 | BOOST_TEST(ui::font::caption().native_handle()); 26 | 27 | const std::wstring font_name = ui::font::caption().name().wstring(); 28 | BOOST_TEST_THROWS(ui::font(-1, font_name), std::out_of_range); 29 | BOOST_TEST_THROWS(ui::font(-1, ui::font::family::serif), std::out_of_range); 30 | 31 | BOOST_TEST_THROWS(ui::font(12, "My invalid font name"), std::out_of_range); 32 | 33 | { 34 | const ui::font f(12, font_name); 35 | BOOST_TEST(f.valid()); 36 | BOOST_TEST(f.native_handle()); 37 | BOOST_TEST_EQ(f.size_pt(), 12); 38 | BOOST_TEST(f.name().wstring() == font_name); 39 | BOOST_TEST(f.get_family() != ui::font::family::monospace); 40 | BOOST_TEST(f.get_slant() == ui::font::slant::normal); 41 | BOOST_TEST(f.get_weight() == ui::font::weight::normal); 42 | } 43 | 44 | { 45 | const ui::font f(16, ui::font::family::sans_serif, 46 | ui::font::slant::italic, ui::font::weight::bold); 47 | BOOST_TEST(f.valid()); 48 | BOOST_TEST(f.native_handle()); 49 | BOOST_TEST_EQ(f.size_pt(), 16); 50 | BOOST_TEST(f.get_family() == ui::font::family::sans_serif); 51 | BOOST_TEST(f.get_slant() == ui::font::slant::italic); 52 | BOOST_TEST(f.get_weight() == ui::font::weight::bold); 53 | } 54 | 55 | { 56 | ui::font f = ui::font::caption(); 57 | BOOST_TEST_EQ(f.size_pt(14).size_pt(), 14); 58 | BOOST_TEST(f.name(font_name).name().wstring() == font_name); 59 | BOOST_TEST(f.set_slant(ui::font::slant::italic).get_slant() 60 | == ui::font::slant::italic); 61 | BOOST_TEST(f.set_weight(ui::font::weight::bold).get_weight() 62 | == ui::font::weight::bold); 63 | 64 | BOOST_TEST_THROWS(f.size_pt(-1), std::out_of_range); 65 | BOOST_TEST_THROWS(f.size_pt(0), std::out_of_range); 66 | BOOST_TEST_THROWS(f.name("Invalid name XXX"), std::out_of_range); 67 | } 68 | 69 | return boost::report_errors(); 70 | } 71 | 72 | int cpp_main(int argc, char* argv[]) 73 | { 74 | return ui::entry(&ui_main, argc, argv); 75 | } 76 | -------------------------------------------------------------------------------- /src/label.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | #if wxUSE_STATTEXT 21 | 22 | class label::detail_impl : public detail::widget_detail 23 | { 24 | public: 25 | void create(widget& parent, const uistring& txt) 26 | { 27 | m_txt = txt; 28 | set_native_handle(new wxStaticText(native::from_widget(parent), 29 | wxID_ANY, native::from_uistring(txt), 30 | wxDefaultPosition, wxDefaultSize, 31 | style_flags(0) )); 32 | } 33 | void text(const uistring& txt) 34 | { 35 | if ( m_native ) 36 | m_native->SetLabel(native::from_uistring(txt)); 37 | else 38 | m_txt = txt; 39 | } 40 | uistring text() const 41 | { 42 | if ( m_native ) 43 | return native::to_uistring(m_native->GetLabel()); 44 | else 45 | return m_txt; 46 | } 47 | 48 | protected: 49 | virtual void do_create_native(widget& parent) 50 | { 51 | create(parent, m_txt); 52 | create_base(); 53 | } 54 | 55 | private: 56 | uistring m_txt; // TODO: Move to cache 57 | }; 58 | 59 | #endif 60 | 61 | label::detail_impl* label::get_impl() 62 | { 63 | #if wxUSE_STATTEXT 64 | return get_detail_impl(); 65 | #else 66 | return NULL; 67 | #endif 68 | } 69 | 70 | const label::detail_impl* label::get_impl() const 71 | { 72 | #if wxUSE_STATTEXT 73 | return get_detail_impl(); 74 | #else 75 | return NULL; 76 | #endif 77 | } 78 | 79 | void label::init() 80 | { 81 | #if wxUSE_STATTEXT 82 | detail_set_detail_impl(new detail_impl); 83 | #endif 84 | } 85 | 86 | label& label::create(widget& parent, const uistring& txt) 87 | { 88 | #if wxUSE_STATTEXT 89 | detail_impl* impl = get_impl(); 90 | wxCHECK_MSG(impl, *this, "Failed to create widget"); 91 | 92 | impl->create(parent, txt); 93 | #endif 94 | 95 | return *this; 96 | } 97 | 98 | label& label::text(const uistring& txt) 99 | { 100 | #if wxUSE_STATTEXT 101 | detail_impl* impl = get_impl(); 102 | wxCHECK_MSG(impl, *this, "Widget should be created"); 103 | 104 | impl->text(txt); 105 | #endif 106 | 107 | return *this; 108 | } 109 | 110 | uistring label::text() const 111 | { 112 | #if wxUSE_STATTEXT 113 | const detail_impl* impl = get_impl(); 114 | wxCHECK_MSG(impl, uistring(), "Widget should be created"); 115 | 116 | return impl->text(); 117 | #else 118 | return uistring(); 119 | #endif 120 | } 121 | 122 | } // namespace ui 123 | } // namespace boost 124 | -------------------------------------------------------------------------------- /src/notebook.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | #if wxUSE_NOTEBOOK 21 | 22 | class notebook::detail_impl : public detail::widget_detail 23 | { 24 | public: 25 | explicit detail_impl(widget& parent) 26 | { 27 | set_native_handle(new wxNotebook(native::from_widget(parent), 28 | wxID_ANY)); 29 | } 30 | void append_page(widget& page, const uistring& label) 31 | { 32 | wxWindow* page_window = native::from_widget(page); 33 | wxCHECK_RET(page_window, "Page widget should be created"); 34 | 35 | wxCHECK_RET(m_native, "Widget should be created"); 36 | m_native->AddPage(page_window, native::from_uistring(label)); 37 | } 38 | void set_current_page(size_type index) 39 | { 40 | wxCHECK_RET(m_native, "Widget should be created"); 41 | m_native->ChangeSelection(index); 42 | } 43 | size_type current_page_index() const 44 | { 45 | wxCHECK_MSG(m_native, npos, "Widget should be created"); 46 | return m_native->GetSelection(); 47 | } 48 | }; 49 | 50 | #endif 51 | 52 | notebook::detail_impl* notebook::get_impl() 53 | { 54 | #if wxUSE_NOTEBOOK 55 | return get_detail_impl(); 56 | #else 57 | return NULL; 58 | #endif 59 | } 60 | 61 | const notebook::detail_impl* notebook::get_impl() const 62 | { 63 | #if wxUSE_NOTEBOOK 64 | return get_detail_impl(); 65 | #else 66 | return NULL; 67 | #endif 68 | } 69 | 70 | notebook& notebook::create(widget& parent) 71 | { 72 | #if wxUSE_NOTEBOOK 73 | detail_set_detail_impl(new detail_impl(parent)); 74 | #endif 75 | 76 | return *this; 77 | } 78 | 79 | void notebook::append_page(widget& page, const uistring& label) 80 | { 81 | #if wxUSE_NOTEBOOK 82 | detail_impl* impl = get_impl(); 83 | wxCHECK_RET(impl, "Widget should be created"); 84 | 85 | impl->append_page(page, label); 86 | #endif 87 | } 88 | 89 | void notebook::current_page(size_type index) 90 | { 91 | #if wxUSE_NOTEBOOK 92 | detail_impl* impl = get_impl(); 93 | wxCHECK_RET(impl, "Widget should be created"); 94 | 95 | impl->set_current_page(index); 96 | #endif 97 | } 98 | 99 | notebook::size_type notebook::current_page_index() const 100 | { 101 | #if wxUSE_NOTEBOOK 102 | const detail_impl* impl = get_impl(); 103 | wxCHECK_MSG(impl, npos, "Widget should be created"); 104 | 105 | return impl->current_page_index(); 106 | #else 107 | return npos; 108 | #endif 109 | } 110 | 111 | } // namespace ui 112 | } // namespace boost 113 | -------------------------------------------------------------------------------- /include/boost/ui/choice.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file choice.hpp @brief Choice widget 7 | 8 | #ifndef BOOST_UI_CHOICE_HPP 9 | #define BOOST_UI_CHOICE_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Widget to select string from popup list of strings 23 | /// @details 24 | /// Usage example: 25 | /// @snippet cpp11/snippet.cpp choice 26 | /// @see Drop-down list (Wikipedia) 27 | /// @ingroup strings 28 | 29 | class BOOST_UI_DECL choice : public strings_box 30 | { 31 | public: 32 | choice() {} 33 | 34 | ///@{ Creates empty choice widget 35 | explicit choice(widget& parent) 36 | { create(parent); } 37 | choice& create(widget& parent); 38 | ///@} 39 | 40 | ///@{ Creates choice widget with options 41 | explicit choice(widget& parent, const std::vector& options) 42 | { create(parent, options); } 43 | 44 | choice& create(widget& parent, const std::vector& options); 45 | 46 | template 47 | explicit choice(widget& parent, Iterator first, Iterator last) 48 | { create(parent, first, last); } 49 | 50 | template 51 | choice& create(widget& parent, Iterator first, Iterator last) 52 | { return create(parent, std::vector(first, last)); } 53 | 54 | template 55 | explicit choice(widget& parent, const Range& r) 56 | { create(parent, r); } 57 | 58 | template 59 | choice& create(widget& parent, const Range& r) 60 | { return create(parent, detail::range_to_vector_uistring(r)); } 61 | 62 | #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST 63 | template 64 | explicit choice(widget& parent, std::initializer_list list) 65 | { create(parent, list); } 66 | 67 | template 68 | choice& create(widget& parent, std::initializer_list list) 69 | { return create(parent, detail::initializer_list_to_vector_uistring(list)); } 70 | #endif 71 | ///@} 72 | 73 | /// Returns text that is associated this widget 74 | uistring text() const; 75 | 76 | /// Returns index of the selected text item. If widget has no items then returns @ref npos 77 | index_type current_selection_index() const; 78 | 79 | ///@{ Connects item selection handler 80 | BOOST_UI_DETAIL_HANDLER(select, choice); 81 | BOOST_UI_DETAIL_HANDLER_EVENT(select_event, choice, index_event); 82 | ///@} 83 | 84 | private: 85 | void on_select_raw(const boost::function& handler); 86 | void on_select_event_raw(const boost::function& handler); 87 | 88 | class detail_impl; 89 | detail_impl* get_impl(); 90 | const detail_impl* get_impl() const; 91 | }; 92 | 93 | } // namespace ui 94 | } // namespace boost 95 | 96 | #endif // BOOST_UI_CHOICE_HPP 97 | -------------------------------------------------------------------------------- /include/boost/ui/progress_bar.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file progress_bar.hpp @brief Progress bar widget 7 | 8 | #ifndef BOOST_UI_PROGRESS_BAR_HPP 9 | #define BOOST_UI_PROGRESS_BAR_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Progress bar widget base class 23 | /// @see Progress bar (Wikipedia) 24 | /// @ingroup info 25 | 26 | class BOOST_UI_DECL progress_bar : public widget 27 | { 28 | public: 29 | /// Progress bar value type 30 | typedef int value_type; 31 | 32 | /// @brief Sets value position 33 | /// @throw std::out_of_range If @a value is out of range 34 | progress_bar& value(value_type value); 35 | 36 | /// Returns value position 37 | value_type value() const; 38 | 39 | /// Returns maximum value position 40 | value_type max() const; 41 | 42 | protected: 43 | progress_bar() {} 44 | 45 | #ifndef DOXYGEN 46 | void detail_create(widget& parent, bool horizontal, value_type initial, 47 | value_type max); 48 | #endif 49 | 50 | private: 51 | void check_range(value_type value) const 52 | { check_range(value, max()); } 53 | static void check_range(value_type value, value_type max); 54 | 55 | class detail_impl; 56 | detail_impl* get_impl(); 57 | const detail_impl* get_impl() const; 58 | }; 59 | 60 | /// @brief Horizontal progress bar widget 61 | /// @ingroup info 62 | 63 | class BOOST_UI_DECL hprogress_bar : public progress_bar 64 | { 65 | public: 66 | hprogress_bar() {} 67 | 68 | ///@{ @brief Creates horizontal progress bar 69 | /// @throw std::out_of_range 70 | explicit hprogress_bar(widget& parent, value_type initial = 0, 71 | value_type max = 100) 72 | { create(parent, initial, max); } 73 | hprogress_bar& create(widget& parent, value_type initial = 0, 74 | value_type max = 100) 75 | { detail_create(parent, true, initial, max); return *this; } 76 | ///@} 77 | }; 78 | 79 | /// @brief Vertical progress bar widget 80 | /// @ingroup info 81 | 82 | class BOOST_UI_DECL vprogress_bar : public progress_bar 83 | { 84 | public: 85 | vprogress_bar() {} 86 | 87 | ///@{ @brief Creates vertical progress bar 88 | /// @throw std::out_of_range 89 | explicit vprogress_bar(widget& parent, value_type initial = 0, 90 | value_type max = 100) 91 | { create(parent, initial, max); } 92 | vprogress_bar& create(widget& parent, value_type initial = 0, 93 | value_type max = 100) 94 | { detail_create(parent, false, initial, max); return *this; } 95 | ///@} 96 | }; 97 | 98 | } // namespace ui 99 | } // namespace boost 100 | 101 | #endif // BOOST_UI_PROGRESS_BAR_HPP 102 | -------------------------------------------------------------------------------- /src/strings_box.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | #if wxUSE_CONTROLS 23 | 24 | class strings_box::native_impl : public wxControlWithItems, private detail::memcheck 25 | { 26 | }; 27 | 28 | #endif 29 | 30 | strings_box::native_impl* strings_box::get_native() 31 | { 32 | #if wxUSE_CONTROLS 33 | return native::impl(*this); 34 | #else 35 | return NULL; 36 | #endif 37 | } 38 | 39 | const strings_box::native_impl* strings_box::get_native() const 40 | { 41 | #if wxUSE_CONTROLS 42 | return native::impl(*this); 43 | #else 44 | return NULL; 45 | #endif 46 | } 47 | 48 | uistring strings_box::at(size_type pos) const 49 | { 50 | check_range(pos); 51 | return operator[](pos); 52 | } 53 | 54 | uistring strings_box::operator[](size_type pos) const 55 | { 56 | #if wxUSE_CONTROLS 57 | const native_impl* impl = get_native(); 58 | wxCHECK_MSG(impl, uistring(), "Widget should be created"); 59 | 60 | return native::to_uistring(impl->GetString(pos)); 61 | #else 62 | return uistring(); 63 | #endif 64 | } 65 | 66 | strings_box::size_type strings_box::size() const 67 | { 68 | #if wxUSE_CONTROLS 69 | const native_impl* impl = get_native(); 70 | wxCHECK_MSG(impl, 0, "Widget should be created"); 71 | 72 | return impl->GetCount(); 73 | #else 74 | return 0; 75 | #endif 76 | } 77 | 78 | void strings_box::clear() 79 | { 80 | #if wxUSE_CONTROLS 81 | native_impl* impl = get_native(); 82 | wxCHECK_RET(impl, "Widget should be created"); 83 | 84 | impl->Clear(); 85 | #endif 86 | } 87 | 88 | strings_box& strings_box::append(const std::vector& options) 89 | { 90 | #if wxUSE_CONTROLS 91 | native_impl* impl = get_native(); 92 | wxCHECK_MSG(impl, *this, "Widget should be created"); 93 | 94 | impl->Set(native::from_vector_uistring(options)); 95 | #endif 96 | 97 | return *this; 98 | } 99 | 100 | void strings_box::push_back(const uistring& value) 101 | { 102 | #if wxUSE_CONTROLS 103 | native_impl* impl = get_native(); 104 | wxCHECK_RET(impl, "Widget should be created"); 105 | 106 | impl->Append(native::from_uistring(value)); 107 | #endif 108 | } 109 | 110 | strings_box& strings_box::select(size_type pos) 111 | { 112 | #if wxUSE_CONTROLS 113 | native_impl* impl = get_native(); 114 | wxCHECK_MSG(impl, *this, "Widget should be created"); 115 | 116 | impl->Select(pos); 117 | #endif 118 | 119 | return *this; 120 | } 121 | 122 | void strings_box::check_range(size_type pos) const 123 | { 124 | if ( pos < 0 || pos >= size() ) 125 | BOOST_THROW_EXCEPTION(std::out_of_range("ui::strings_box::check_range(): invalid index")); 126 | } 127 | 128 | } // namespace ui 129 | } // namespace boost 130 | -------------------------------------------------------------------------------- /include/boost/ui/detail/widget.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_DETAIL_WIDGET_HPP 7 | #define BOOST_UI_DETAIL_WIDGET_HPP 8 | 9 | #include 10 | 11 | namespace boost { 12 | namespace ui { 13 | namespace detail { 14 | 15 | /// Holds state of boost::ui::widget derived object while wxWindow isn't created yet 16 | class widget_detail_base 17 | { 18 | public: 19 | widget_detail_base() : m_x(0), m_y(0), m_width(0), m_height(0), 20 | m_enabled(true), 21 | m_shown(true), m_shown_modified(false), // TODO: Support wxTLWs 22 | m_window_style_flags_add(0), 23 | m_window_style_flags_remove(0) 24 | {} 25 | virtual ~widget_detail_base() {} 26 | 27 | void create_native(widget& parent) { do_create_native(parent); } 28 | 29 | void move(coord_type x, coord_type y); 30 | void resize(coord_type width, coord_type height); 31 | coord_type x() const; 32 | coord_type y() const; 33 | coord_type width() const; 34 | coord_type height() const; 35 | void enable(bool do_enable); 36 | bool is_enabled() const; 37 | void show(bool do_show); 38 | bool is_shown() const; 39 | void modify_style_flags(long add, long remove = 0); 40 | long style_flags(long default_flags = 0); 41 | 42 | typedef void* native_handle_type; 43 | virtual native_handle_type native_handle() = 0; 44 | virtual const native_handle_type native_handle() const = 0; 45 | virtual void set_native_handle(native_handle_type n) = 0; 46 | 47 | protected: 48 | void create_base(); 49 | virtual void do_create_native(widget& parent) {} // = 0 50 | 51 | private: 52 | // TODO: Move to cache 53 | coord_type m_x, m_y, m_width, m_height; 54 | bool m_enabled, m_shown, m_shown_modified; 55 | long m_window_style_flags_add; 56 | long m_window_style_flags_remove; 57 | }; 58 | 59 | class window_detail_base : public widget_detail_base 60 | { 61 | public: 62 | virtual void show_modal() = 0; 63 | }; 64 | 65 | template 66 | class widget_detail_base_type : public TBase 67 | { 68 | public: 69 | widget_detail_base_type() : m_native(NULL) {} 70 | 71 | virtual typename TBase::native_handle_type native_handle() { return m_native; } 72 | virtual const typename TBase::native_handle_type native_handle() const { return m_native; } 73 | virtual void set_native_handle(typename TBase::native_handle_type n) 74 | { 75 | //assert(!m_native); 76 | //assert(n); 77 | 78 | m_native = static_cast(n); 79 | } 80 | 81 | void delete_native() 82 | { 83 | delete m_native; 84 | m_native = NULL; 85 | } 86 | 87 | protected: 88 | TNative* m_native; 89 | }; 90 | 91 | template 92 | class widget_detail : public widget_detail_base_type 93 | { 94 | }; 95 | 96 | template 97 | class window_detail : public widget_detail_base_type 98 | { 99 | }; 100 | 101 | } // namespace detail 102 | } // namespace ui 103 | } // namespace boost 104 | 105 | #endif // BOOST_UI_DETAIL_WIDGET_HPP 106 | -------------------------------------------------------------------------------- /include/boost/ui/native/event.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #ifndef BOOST_UI_NATIVE_EVENT_HPP 7 | #define BOOST_UI_NATIVE_EVENT_HPP 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace boost { 15 | namespace ui { 16 | namespace native { 17 | 18 | template 19 | class empty_filter 20 | { 21 | public: 22 | bool operator()(NativeEvent& wxevent) { return true; } 23 | }; 24 | 25 | template 26 | class event_functor 27 | { 28 | public: 29 | event_functor(const boost::function& handler, 30 | const boost::function& filter) 31 | : m_handler(handler), m_filter(filter) 32 | {} 33 | 34 | void operator()(NativeEvent& wxevent) 35 | { 36 | wxevent.Skip(); 37 | 38 | if ( !m_filter(wxevent) ) 39 | return; 40 | 41 | m_handler(); 42 | } 43 | 44 | private: 45 | const boost::function m_handler; 46 | const boost::function m_filter; 47 | }; 48 | 49 | 50 | template 51 | void bind_helper(widget& w, EventTag eventType, 52 | const boost::function& handler, 53 | const boost::function& filter 54 | = empty_filter()) 55 | { 56 | wxWindow* impl = from_widget(w); 57 | wxCHECK_RET(impl, "Widget should be created"); 58 | 59 | impl->Bind(eventType, event_functor< 60 | typename EventTag::EventClass>(handler, filter)); 61 | } 62 | 63 | template 64 | class event_functor_event 65 | { 66 | public: 67 | event_functor_event(const boost::function& handler, 68 | const boost::function& filter) 69 | : m_handler(handler), m_filter(filter) 70 | {} 71 | 72 | void operator()(NativeEvent& wxevent) 73 | { 74 | wxevent.Skip(); 75 | 76 | if ( !m_filter(wxevent) ) 77 | return; 78 | 79 | UIEvent uievent; 80 | init(uievent, wxevent); 81 | m_handler(uievent); 82 | } 83 | 84 | private: 85 | void init(UIEvent& uievent, NativeEvent& wxevent); 86 | 87 | const boost::function m_handler; 88 | const boost::function m_filter; 89 | }; 90 | 91 | template 92 | void bind_event_helper(widget& w, EventTag eventType, 93 | const boost::function& handler, 94 | const boost::function& filter 95 | = empty_filter()) 96 | { 97 | wxWindow* impl = from_widget(w); 98 | wxCHECK_RET(impl, "Widget should be created"); 99 | 100 | impl->Bind(eventType, event_functor_event< 101 | typename EventTag::EventClass, UIEvent>(handler, filter)); 102 | } 103 | 104 | } // namespace native 105 | } // namespace ui 106 | } // namespace boost 107 | 108 | #endif // BOOST_UI_NATIVE_EVENT_HPP 109 | -------------------------------------------------------------------------------- /src/choice.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace boost { 19 | namespace ui { 20 | 21 | #if wxUSE_CHOICE 22 | 23 | class choice::detail_impl : public detail::widget_detail 24 | { 25 | public: 26 | explicit detail_impl(widget& parent) 27 | { 28 | set_native_handle(new wxChoice(native::from_widget(parent), wxID_ANY)); 29 | } 30 | 31 | explicit detail_impl(widget& parent, const std::vector& options) 32 | { 33 | set_native_handle(new wxChoice(native::from_widget(parent), 34 | wxID_ANY, wxDefaultPosition, wxDefaultSize, 35 | native::from_vector_uistring(options))); 36 | } 37 | uistring text() const 38 | { 39 | wxCHECK_MSG(m_native, uistring(), "Widget should be created"); 40 | return native::to_uistring(m_native->GetStringSelection()); 41 | } 42 | index_type current_selection_index() const 43 | { 44 | wxCHECK_MSG(m_native, -1, "Widget should be created"); 45 | return m_native->GetCurrentSelection(); 46 | } 47 | }; 48 | 49 | #endif 50 | 51 | choice::detail_impl* choice::get_impl() 52 | { 53 | #if wxUSE_CHOICE 54 | return get_detail_impl(); 55 | #else 56 | return NULL; 57 | #endif 58 | } 59 | 60 | const choice::detail_impl* choice::get_impl() const 61 | { 62 | #if wxUSE_CHOICE 63 | return get_detail_impl(); 64 | #else 65 | return NULL; 66 | #endif 67 | } 68 | 69 | choice& choice::create(widget& parent) 70 | { 71 | #if wxUSE_CHOICE 72 | detail_set_detail_impl(new detail_impl(parent)); 73 | #endif 74 | 75 | return *this; 76 | } 77 | 78 | choice& choice::create(widget& parent, const std::vector& options) 79 | { 80 | #if wxUSE_CHOICE 81 | detail_set_detail_impl(new detail_impl(parent, options)); 82 | #endif 83 | 84 | return *this; 85 | } 86 | 87 | uistring choice::text() const 88 | { 89 | #if wxUSE_CHOICE 90 | const detail_impl* impl = get_impl(); 91 | wxCHECK_MSG(impl, uistring(), "Widget should be created"); 92 | 93 | return impl->text(); 94 | #else 95 | return uistring(); 96 | #endif 97 | } 98 | 99 | index_type choice::current_selection_index() const 100 | { 101 | #if wxUSE_CHOICE 102 | const detail_impl* impl = get_impl(); 103 | wxCHECK_MSG(impl, npos, "Widget should be created"); 104 | 105 | return impl->current_selection_index(); 106 | #else 107 | return npos; 108 | #endif 109 | } 110 | 111 | void choice::on_select_raw(const boost::function& handler) 112 | { 113 | #if wxUSE_CHOICE 114 | native::bind_helper(*this, wxEVT_CHOICE, handler); 115 | #endif 116 | } 117 | 118 | void choice::on_select_event_raw(const boost::function& handler) 119 | { 120 | #if wxUSE_CHOICE 121 | native::bind_event_helper(*this, wxEVT_CHOICE, handler); 122 | #endif 123 | } 124 | 125 | } // namespace ui 126 | } // namespace boost 127 | -------------------------------------------------------------------------------- /example/thread.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Fill text box using multiple worker threads. 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "to_string.hpp" 14 | 15 | #if !defined(BOOST_NO_CXX11_HDR_THREAD) 16 | #include 17 | namespace thread_ns = std; 18 | #else 19 | #include 20 | namespace thread_ns = boost; 21 | #endif 22 | 23 | namespace ui = boost::ui; 24 | 25 | class thread_dialog : public ui::dialog 26 | { 27 | typedef thread_dialog this_type; 28 | 29 | public: 30 | thread_dialog(); 31 | 32 | private: 33 | void on_start(); 34 | void thread_entry(int thread_number, int repeats); 35 | void write(std::wstring str); 36 | 37 | ui::text_box m_output_widget; 38 | ui::string_box m_threads_count_widget; 39 | ui::string_box m_repeats_widget; 40 | }; 41 | 42 | thread_dialog::thread_dialog() : ui::dialog( 43 | #if !defined(BOOST_NO_CXX11_HDR_THREAD) 44 | "C++11 " 45 | #else 46 | "Boost." 47 | #endif 48 | "Thread + Boost.UI Example") 49 | { 50 | ui::hbox(*this) 51 | << m_output_widget.create(*this) 52 | .tooltip("Output") 53 | .layout().justify().stretch() 54 | << ( ui::vbox().layout().justify() 55 | << ui::label(*this, "Threads count:") 56 | .layout().margin(1, 1, 0, 1) 57 | << m_threads_count_widget.create(*this, to_string( 58 | 100 * thread_ns::thread::hardware_concurrency() )) 59 | .layout().justify() 60 | << ui::label(*this, "Repeats:") 61 | .layout().margin(1, 1, 0, 1) 62 | << m_repeats_widget.create(*this, "10") 63 | .layout().justify() 64 | << ui::button(*this, "&Start threads") 65 | .on_press(&this_type::on_start, this) 66 | .layout().justify() 67 | ) 68 | ; 69 | 70 | resize(600, 400); 71 | } 72 | 73 | void thread_dialog::on_start() 74 | { 75 | const int threads_count = boost::lexical_cast(m_threads_count_widget.text()); 76 | const int repeats = boost::lexical_cast(m_repeats_widget.text()); 77 | 78 | m_output_widget.clear(); 79 | 80 | for ( int i = 0; i < threads_count; i++ ) 81 | { 82 | // Single thread 83 | //thread_entry(i, repeats); 84 | 85 | thread_ns::thread t(&this_type::thread_entry, this, i, repeats); 86 | t.detach(); 87 | } 88 | } 89 | 90 | void thread_dialog::thread_entry(int thread_number, int repeats) 91 | { 92 | for ( int r = 0; r < repeats; r++ ) 93 | { 94 | std::wostringstream ss; 95 | ss << thread_number << L"-" << r << " "; 96 | 97 | // Not thread safe 98 | //write(ss.str()); 99 | 100 | // Thread safe 101 | ui::call_async( boost::bind(&this_type::write, this, ss.str()) ); 102 | } 103 | } 104 | 105 | void thread_dialog::write(std::wstring str) 106 | { 107 | m_output_widget.text(m_output_widget.text() + str); 108 | } 109 | 110 | int ui_main() 111 | { 112 | thread_dialog().show_modal(); 113 | 114 | return 0; 115 | } 116 | 117 | int main(int argc, char* argv[]) 118 | { 119 | return ui::entry(&ui_main, argc, argv); 120 | } 121 | -------------------------------------------------------------------------------- /src/progress_bar.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | 18 | namespace boost { 19 | namespace ui { 20 | 21 | #if wxUSE_GAUGE 22 | 23 | class progress_bar::detail_impl : public detail::widget_detail 24 | { 25 | public: 26 | explicit detail_impl(widget& parent, bool horizontal, value_type initial, 27 | value_type max) 28 | { 29 | wxGauge* w = new wxGauge(native::from_widget(parent), 30 | wxID_ANY, max, wxDefaultPosition, wxDefaultSize, 31 | horizontal ? wxGA_HORIZONTAL : wxGA_VERTICAL); 32 | w->SetValue(initial); 33 | set_native_handle(w); 34 | } 35 | void value(value_type value) 36 | { 37 | wxCHECK_RET(m_native, "Widget should be created"); 38 | m_native->SetValue(value); 39 | } 40 | value_type value() const 41 | { 42 | wxCHECK_MSG(m_native, -1, "Widget should be created"); 43 | return m_native->GetValue(); 44 | } 45 | value_type max() const 46 | { 47 | wxCHECK_MSG(m_native, -1, "Widget should be created"); 48 | return m_native->GetRange(); 49 | } 50 | }; 51 | 52 | #endif 53 | 54 | progress_bar::detail_impl* progress_bar::get_impl() 55 | { 56 | #if wxUSE_GAUGE 57 | return get_detail_impl(); 58 | #else 59 | return NULL; 60 | #endif 61 | } 62 | 63 | const progress_bar::detail_impl* progress_bar::get_impl() const 64 | { 65 | #if wxUSE_GAUGE 66 | return get_detail_impl(); 67 | #else 68 | return NULL; 69 | #endif 70 | } 71 | 72 | void progress_bar::detail_create(widget& parent, bool horizontal, value_type initial, 73 | value_type max) 74 | 75 | { 76 | check_range(initial, max); 77 | 78 | #if wxUSE_GAUGE 79 | detail_set_detail_impl(new detail_impl(parent, horizontal, initial, max)); 80 | #endif 81 | } 82 | 83 | progress_bar& progress_bar::value(value_type value) 84 | { 85 | check_range(value); 86 | 87 | #if wxUSE_GAUGE 88 | detail_impl* impl = get_impl(); 89 | wxCHECK_MSG(impl, *this, "Widget should be created"); 90 | 91 | impl->value(value); 92 | #endif 93 | 94 | return *this; 95 | } 96 | 97 | progress_bar::value_type progress_bar::value() const 98 | { 99 | #if wxUSE_GAUGE 100 | const detail_impl* impl = get_impl(); 101 | wxCHECK_MSG(impl, -1, "Widget should be created"); 102 | 103 | return impl->value(); 104 | #else 105 | return -1; 106 | #endif 107 | } 108 | 109 | progress_bar::value_type progress_bar::max() const 110 | { 111 | #if wxUSE_GAUGE 112 | const detail_impl* impl = get_impl(); 113 | wxCHECK_MSG(impl, -1, "Widget should be created"); 114 | 115 | return impl->max(); 116 | #else 117 | return -1; 118 | #endif 119 | } 120 | 121 | void progress_bar::check_range(value_type value, value_type max) 122 | { 123 | if ( value < 0 || value > max ) 124 | BOOST_THROW_EXCEPTION(std::out_of_range("ui::progress_bar::check_range(): invalid value")); 125 | } 126 | 127 | } // namespace ui 128 | } // namespace boost 129 | -------------------------------------------------------------------------------- /src/combo_box.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace boost { 19 | namespace ui { 20 | 21 | #if wxUSE_COMBOBOX 22 | 23 | class combo_box::detail_impl : public detail::widget_detail 24 | { 25 | public: 26 | explicit detail_impl(widget& parent) 27 | { 28 | set_native_handle(new wxComboBox(native::from_widget(parent), wxID_ANY)); 29 | } 30 | explicit detail_impl(widget& parent, const uistring& txt, 31 | const std::vector& options) 32 | { 33 | set_native_handle(new wxComboBox(native::from_widget(parent), wxID_ANY, 34 | native::from_uistring(txt), 35 | wxDefaultPosition, wxDefaultSize, 36 | native::from_vector_uistring(options))); 37 | } 38 | void text(const uistring& txt) 39 | { 40 | wxCHECK_RET(m_native, "Widget should be created"); 41 | m_native->ChangeValue(native::from_uistring(txt)); 42 | } 43 | uistring text() const 44 | { 45 | wxCHECK_MSG(m_native, uistring(), "Widget should be created"); 46 | return native::to_uistring(m_native->GetValue()); 47 | } 48 | }; 49 | 50 | #endif 51 | 52 | combo_box::detail_impl* combo_box::get_impl() 53 | { 54 | #if wxUSE_COMBOBOX 55 | return get_detail_impl(); 56 | #else 57 | return NULL; 58 | #endif 59 | } 60 | 61 | const combo_box::detail_impl* combo_box::get_impl() const 62 | { 63 | #if wxUSE_COMBOBOX 64 | return get_detail_impl(); 65 | #else 66 | return NULL; 67 | #endif 68 | } 69 | 70 | combo_box& combo_box::create(widget& parent) 71 | { 72 | #if wxUSE_COMBOBOX 73 | detail_set_detail_impl(new detail_impl(parent)); 74 | #endif 75 | 76 | return *this; 77 | } 78 | 79 | combo_box& combo_box::create(widget& parent, const uistring& txt, 80 | const std::vector& options) 81 | { 82 | #if wxUSE_COMBOBOX 83 | detail_set_detail_impl(new detail_impl(parent, txt, options)); 84 | #endif 85 | 86 | return *this; 87 | } 88 | 89 | combo_box& combo_box::text(const uistring& txt) 90 | { 91 | #if wxUSE_COMBOBOX 92 | detail_impl* impl = get_impl(); 93 | wxCHECK_MSG(impl, *this, "Widget should be created"); 94 | 95 | impl->text(txt); 96 | #endif 97 | 98 | return *this; 99 | } 100 | 101 | uistring combo_box::text() const 102 | { 103 | #if wxUSE_COMBOBOX 104 | const detail_impl* impl = get_impl(); 105 | wxCHECK_MSG(impl, uistring(), "Widget should be created"); 106 | 107 | return impl->text(); 108 | #else 109 | return uistring(); 110 | #endif 111 | } 112 | 113 | void combo_box::on_select_raw(const boost::function& handler) 114 | { 115 | #if wxUSE_COMBOBOX 116 | native::bind_helper(*this, wxEVT_COMBOBOX, handler); 117 | #endif 118 | } 119 | 120 | void combo_box::on_select_event_raw(const boost::function& handler) 121 | { 122 | #if wxUSE_COMBOBOX 123 | native::bind_event_helper(*this, wxEVT_COMBOBOX, handler); 124 | #endif 125 | } 126 | 127 | } // namespace ui 128 | } // namespace boost 129 | -------------------------------------------------------------------------------- /example/cpp11/io2d.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Re-implemented examples from P0267R6 C++ Standard proposal 7 | // "A Proposal to Add 2D Graphics Rendering and Display to C++" 8 | // (io2d library) 9 | // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0267r6.pdf 10 | 11 | #include 12 | #include 13 | 14 | namespace ui = boost::ui; 15 | 16 | int ui_main() 17 | { 18 | ui::dialog dlg("io2d examples implementation"); 19 | dlg.resize(700, 500); 20 | 21 | ui::canvas canvas(dlg); 22 | canvas.on_resize([&] 23 | { 24 | ui::painter painter = canvas.painter(); 25 | painter.translate(0.5, 0.5); 26 | 27 | painter.fill_rect(0, 0, 600, 400); 28 | painter.stroke_color(ui::color::white) 29 | .fill_color( ui::color::white); 30 | 31 | // Example 1 32 | { 33 | painter.begin_path() 34 | .move_to(80, 20).line_to(220, 20).line_to(280, 180).line_to(20, 180) 35 | .close_path().stroke(); 36 | } 37 | 38 | painter.translate(300, 0); 39 | 40 | // Example 2 41 | { 42 | ui::painter::state_saver state(painter); 43 | 44 | painter.line_width(10).begin_path() 45 | .move_to(20, 20).line_to(120, 20).line_to(120, 160).line_to(20, 160).line_to(20, 20) 46 | .stroke(); 47 | painter.translate(160, 0) 48 | .move_to(20, 20).line_to(120, 20).line_to(120, 160).line_to(20, 160).line_to(20, 20) 49 | .close_path().stroke(); 50 | } 51 | 52 | painter.translate(-300, 200); 53 | 54 | // Example 3 55 | { 56 | painter.begin_path() 57 | .move_to(20, 20).quadratic_curve_to(80, 140, 140, 20) 58 | .move_to(160, 20).quadratic_curve_to(220, 140, 280, 20).close_path() 59 | .stroke(); 60 | painter.begin_path() 61 | .move_to( 20, 150).bezier_curve_to( 60, 30, 100, 270, 140, 150) 62 | .move_to(160, 150).bezier_curve_to(220, 30, 260, 270, 300, 150).close_path() 63 | .stroke(); 64 | } 65 | 66 | painter.translate(300, 0); 67 | 68 | // Example 4 69 | { 70 | { 71 | ui::painter::state_saver state(painter); 72 | 73 | static const double pi = boost::math::constants::pi(); 74 | 75 | painter.line_width(10).translate(85, 100).scale(.9, 1.1).begin_path() 76 | .arc(0, 0, 50, pi / 4, pi * 7 / 4) 77 | .stroke(); 78 | } 79 | 80 | auto drawPlus = [&painter]() 81 | { 82 | painter.begin_path() 83 | .move_to(130, 105).line_to(130, 95).line_to(155, 95) 84 | .line_to(155, 70).line_to(165, 70).line_to(165, 95) 85 | .line_to(190, 95).line_to(190, 105).line_to(165, 105) 86 | .line_to(165, 130).line_to(155, 130).line_to(155, 105) 87 | .fill(); 88 | }; 89 | 90 | drawPlus(); 91 | 92 | painter.translate(80, 0); 93 | drawPlus(); 94 | } 95 | }); 96 | 97 | dlg.show_modal(); 98 | 99 | return 0; 100 | } 101 | 102 | int main(int argc, char* argv[]) 103 | { 104 | return ui::entry(&ui_main, argc, argv); 105 | } 106 | -------------------------------------------------------------------------------- /example/lexical_cast.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Show boost::lexical_cast<> work using user provided data. 7 | 8 | #include 9 | #include // boost::split() 10 | #include // boost::is_any_of() 11 | 12 | #include 13 | 14 | namespace ui = boost::ui; 15 | 16 | class lc_dialog : public ui::dialog 17 | { 18 | typedef lc_dialog this_type; 19 | 20 | public: 21 | lc_dialog(); 22 | 23 | private: 24 | void convert(); 25 | 26 | ui::text_box m_input_widget; 27 | ui::label m_output_widget; 28 | ui::choice m_type_choice; 29 | }; 30 | 31 | lc_dialog::lc_dialog() : ui::dialog("Boost.Lexical_Cast + Boost.UI example") 32 | { 33 | static const char* types[] = { "short", "unsigned short", "int", "float", 34 | "bool", "wchar_t", "std::wstring" }; 35 | 36 | ui::vbox(*this) 37 | << ( ui::hbox() 38 | << ui::label(*this, "Convert to: ") 39 | .layout().stretch() 40 | << m_type_choice.create(*this, types) 41 | .on_select(&this_type::convert, this) 42 | .select(0) 43 | .layout().stretch() 44 | ).layout().justify() 45 | << ( ui::hbox() 46 | << m_input_widget.create(*this, "0\n1\n123\n-4\n5.6\n5,6\n1000000\n1e6\ninf\nx\ntext") 47 | .on_edit(&this_type::convert, this) 48 | .tooltip("Input") 49 | .layout().justify().stretch() 50 | << m_output_widget.create(*this) 51 | .tooltip("Output") 52 | .layout().justify().stretch() 53 | ).layout().justify().stretch() 54 | ; 55 | 56 | convert(); 57 | } 58 | 59 | template 60 | static std::wstring convert_to(const std::vector& input_strings) 61 | { 62 | std::wostringstream ss; 63 | 64 | for ( std::vector::const_iterator iter = input_strings.begin(); 65 | iter != input_strings.end(); ++iter ) 66 | { 67 | try 68 | { 69 | ss << boost::lexical_cast(*iter); 70 | } 71 | catch (const boost::bad_lexical_cast&) 72 | { 73 | ss << L"(Bad lexical cast)"; 74 | } 75 | ss << std::endl; 76 | } 77 | 78 | return ss.str(); 79 | } 80 | 81 | void lc_dialog::convert() 82 | { 83 | const std::wstring input = m_input_widget.text().wstring(); 84 | 85 | std::vector input_strings; 86 | boost::split(input_strings, input, boost::is_any_of(L"\n")); 87 | 88 | std::wstring output; 89 | switch ( m_type_choice.current_selection_index() ) 90 | { 91 | case 0: output = convert_to(input_strings); break; 92 | case 1: output = convert_to(input_strings); break; 93 | case 2: output = convert_to(input_strings); break; 94 | case 3: output = convert_to(input_strings); break; 95 | case 4: output = convert_to(input_strings); break; 96 | case 5: output = convert_to(input_strings); break; 97 | case 6: output = convert_to(input_strings); break; 98 | } 99 | m_output_widget.text(output); 100 | } 101 | 102 | int ui_main() 103 | { 104 | lc_dialog().show_modal(); 105 | 106 | return 0; 107 | } 108 | 109 | int main(int argc, char* argv[]) 110 | { 111 | return ui::entry(&ui_main, argc, argv); 112 | } 113 | -------------------------------------------------------------------------------- /example/spirit.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Parse user data using Boost.Spirit. 7 | // Not finished yet. 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace ui = boost::ui; 18 | 19 | template 20 | struct calculator : boost::spirit::qi::grammar 22 | { 23 | calculator() : calculator::base_type(expression) 24 | { 25 | using boost::spirit::qi::char_; 26 | 27 | expression = 28 | term 29 | >> *( (char_('+') >> term) 30 | | (char_('-') >> term) 31 | ) 32 | ; 33 | 34 | term = 35 | factor 36 | >> *( (char_('*') >> factor) 37 | | (char_('/') >> factor) 38 | ) 39 | ; 40 | 41 | factor = 42 | boost::spirit::qi::double_ 43 | | '(' >> expression >> ')' 44 | | (char_('-') >> factor) 45 | | (char_('+') >> factor) 46 | ; 47 | 48 | BOOST_SPIRIT_DEBUG_NODE(expression); 49 | BOOST_SPIRIT_DEBUG_NODE(term); 50 | BOOST_SPIRIT_DEBUG_NODE(factor); 51 | } 52 | 53 | boost::spirit::qi::rule expression; 54 | boost::spirit::qi::rule term; 55 | boost::spirit::qi::rule factor; 56 | }; 57 | 58 | template 59 | void phrase_parse(Iterator first, Iterator last) 60 | { 61 | calculator calc; 62 | boost::spirit::utree ut; 63 | Iterator begin = first; 64 | const bool result = boost::spirit::qi::phrase_parse( 65 | first, last, calc, boost::spirit::ascii::space, ut); 66 | 67 | if ( !result || first != last ) 68 | { 69 | std::ostringstream ss; 70 | ss << "Parser error at position " << (first - begin) 71 | << ", text: \"" 72 | << std::basic_string< typename std::iterator_traits::value_type >(first, last) 73 | << "\""; 74 | BOOST_THROW_EXCEPTION( std::runtime_error(ss.str()) ); 75 | } 76 | 77 | ui::log() << "Parsed: " << ut; 78 | } 79 | 80 | class spirit_dialog : public ui::dialog 81 | { 82 | typedef spirit_dialog this_type; 83 | 84 | public: 85 | spirit_dialog(); 86 | 87 | private: 88 | void on_parse(); 89 | 90 | ui::string_box m_input_widget; 91 | }; 92 | 93 | spirit_dialog::spirit_dialog() : ui::dialog("Boost.Spirit + Boost.UI example") 94 | { 95 | ui::hbox(*this) 96 | << m_input_widget.create(*this, "(11.1 + 2 * 3 - 1) / 2") 97 | .layout().stretch() 98 | << ui::button(*this, "&Parse") 99 | .on_press(&this_type::on_parse, this) 100 | ; 101 | } 102 | 103 | void spirit_dialog::on_parse() 104 | { 105 | const std::string input = m_input_widget.text().string(); 106 | phrase_parse(input.begin(), input.end()); 107 | } 108 | 109 | int ui_main() 110 | { 111 | spirit_dialog().show_modal(); 112 | 113 | return 0; 114 | } 115 | 116 | int main(int argc, char* argv[]) 117 | { 118 | return ui::entry(&ui_main, argc, argv); 119 | } 120 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Boost.UI 2 | ======== 3 | 4 | Boost.UI is a C++ User Interface (GUI) Boost library that 5 | * is cross-platform 6 | * uses native system-provided widgets 7 | * has STL-like and Boost-like API 8 | * compatible with other Boost libraries 9 | * supports modern C++11/14/17 features 10 | 11 | [![Licence](https://img.shields.io/badge/license-boost-4480cc.svg)](http://www.boost.org/LICENSE_1_0.txt) 12 | [![Travis](https://img.shields.io/travis/kosenko/ui/master.svg?label=Linux)](https://travis-ci.org/kosenko/ui) 13 | [![AppVeyor](https://img.shields.io/appveyor/ci/kosenko/ui/master.svg?label=Windows)](https://ci.appveyor.com/project/kosenko/ui/branch/master) 14 | 15 | ### Documentation 16 | 17 | Latest development documentation is available [online](https://kosenko.github.io/boost.ui/). 18 | 19 | ### Contents 20 | 21 | * **build** - Build scripts and instructions 22 | * **doc** - Documentation generator scripts 23 | * **example** - Examples 24 | * example/hello.cpp - **"Hello, world!"** application 25 | * example/asio_chat_client.cpp - **Boost.ASIO** chat client example 26 | * example/chrono.cpp - **Boost.Chrono** and **std::chrono** usage example 27 | * example/date_time.cpp - **Boost.Date_Time** usage example 28 | * example/font.cpp - Font usage example 29 | * example/filesystem.cpp - **Boost.Filesystem** and **std::filesystem** file manager 30 | * example/interprocess.cpp - **Boost.Interprocess** usage example 31 | * example/lexical_cast.cpp - **Boost.Lexical_Cast** usage example 32 | * example/locale.cpp - **Boost.Locale** usage example 33 | * example/random.cpp - **Boost.Random** and **std::random** usage example 34 | * example/regex.cpp - **Boost.Regex** and **std::regex** usage example 35 | * example/sort.cpp - Visualization of **sorting algorithms** 36 | * example/thread.cpp - **Boost.Thread** and **std::thread** usage example 37 | * example/timer.cpp - **Boost.Timer** usage example 38 | * example/tokenizer.cpp - **Boost.Tokenizer** usage example 39 | * **example/cpp11** - C++11 Examples 40 | * example/cpp11/hello.cpp - C++11 **"Hello, world!"** application 41 | * example/cpp11/beman.cpp - [Beman's challenge](https://isocpp.org/files/papers/n3791.html) 42 | * example/cpp11/stacktrace.cpp - **Boost.Stacktrace** usage example 43 | * example/cpp11/stroustrup.cpp - Re-implemented GUI examples 44 | from ["Programming -- Principles and Practice Using C++"](http://www.stroustrup.com/programming.html) 45 | by Bjarne Stroustrup 46 | * example/cpp11/io2d.cpp - Re-implemented examples from 47 | [P0267 proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0267r6.pdf) (io2d library) 48 | * example/cpp11/snippet.cpp - Documentation snippets 49 | * example/cpp11/datarep.cpp - Data representation example 50 | * **example/cpp17** - C++17 Examples 51 | * example/cpp17/geometry.cpp - **Boost.Geometry** usage example 52 | * **include** - Interface headers with documentation 53 | * **src** - Source code 54 | * **test** - Unit tests 55 | 56 | ### Build instructions and dependencies 57 | 58 | See [build instructions](build/README.md). 59 | 60 | Tested compilers: GCC 5.4.0, Clang 3.8.0, Visual C++ 9.0 (2008), 14.0 (2015), Travis CI and AppVeyor compilers. 61 | 62 | Boost.UI depends on Boost.Config, Boost.Core, Boost.Function, Boost.Bind, Boost.Move, Boost.Optional, Boost.Tribool, Boost.Range and wxWidgets libraries. 63 | Also optionally Boost.Chrono and Boost.Date_Time could be used. 64 | Note that corresponding classes from C++11 Standard also could be used with Boost.UI if available. 65 | 66 | Boost.UI is a binary library (not header-only) and must be built separately. 67 | 68 | ### License 69 | 70 | Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt). 71 | -------------------------------------------------------------------------------- /src/frame.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "res/boost.xpm" 22 | 23 | namespace boost { 24 | namespace ui { 25 | 26 | class frame::detail_impl : public detail::window_detail 27 | { 28 | public: 29 | explicit detail_impl(const uistring& title) 30 | { 31 | wxFrame* w = new wxFrame(NULL, wxID_ANY, native::from_uistring(title), 32 | wxDefaultPosition, wxDefaultSize, 33 | wxDEFAULT_FRAME_STYLE 34 | ); 35 | w->SetIcon(boost_xpm); 36 | set_native_handle(w); 37 | 38 | w->Bind(wxEVT_CLOSE_WINDOW, &detail_impl::on_close, this); 39 | } 40 | virtual ~detail_impl() 41 | { 42 | delete_native(); 43 | } 44 | void show_modal() 45 | { 46 | wxCHECK_RET(m_native, "Widget should be created"); 47 | m_native->Show(); 48 | 49 | m_modal_loop.run(); 50 | } 51 | #if wxUSE_MENUS 52 | void set_menu_bar(wxMenuBar* wxmb) 53 | { 54 | wxCHECK_RET(m_native, "Widget should be created"); 55 | m_native->SetMenuBar(wxmb); 56 | } 57 | #endif 58 | #if wxUSE_STATUSBAR 59 | void set_status_bar(wxStatusBar* wxsb) 60 | { 61 | wxCHECK_RET(m_native, "Widget should be created"); 62 | m_native->SetStatusBar(wxsb); 63 | } 64 | #endif 65 | 66 | private: 67 | void on_close(wxCloseEvent& e) 68 | { 69 | e.Skip(); 70 | 71 | m_modal_loop.exit(); 72 | } 73 | 74 | event_loop m_modal_loop; 75 | }; 76 | 77 | frame::detail_impl* frame::get_impl() 78 | { 79 | return get_detail_impl(); 80 | } 81 | 82 | 83 | frame& frame::create(const uistring& title) 84 | { 85 | detail_set_detail_impl(new detail_impl(title)); 86 | 87 | return *this; 88 | } 89 | 90 | ui::menu_bar frame::menu_bar() 91 | { 92 | ui::menu_bar mb; 93 | mb.create(); 94 | 95 | menu_bar::native_handle_type void_mb = mb.native_handle(); 96 | wxCHECK_MSG(void_mb, ui::menu_bar(), "Invalid menu bar handle"); 97 | 98 | #if wxUSE_MENUS 99 | wxObject* object_mb = static_cast(void_mb); 100 | wxMenuBar* wxmb = dynamic_cast(object_mb); 101 | wxCHECK_MSG(wxmb, ui::menu_bar(), "Invalid menu bar type"); 102 | 103 | detail_impl* impl = get_impl(); 104 | wxCHECK_MSG(impl, mb, "Widget should be created"); 105 | 106 | impl->set_menu_bar(wxmb); 107 | #endif 108 | 109 | return mb; 110 | } 111 | 112 | ui::status_bar frame::status_bar() 113 | { 114 | ui::status_bar sb; 115 | sb.create(*this); 116 | 117 | status_bar::native_handle_type void_sb = sb.native_handle(); 118 | wxCHECK_MSG(void_sb, ui::status_bar(), "Invalid status bar handle"); 119 | 120 | #if wxUSE_STATUSBAR 121 | wxObject* object_sb = static_cast(void_sb); 122 | wxStatusBar* wxsb = dynamic_cast(object_sb); 123 | wxCHECK_MSG(wxsb, ui::status_bar(), "Invalid status bar type"); 124 | 125 | detail_impl* impl = get_impl(); 126 | wxCHECK_MSG(impl, sb, "Widget should be created"); 127 | 128 | impl->set_status_bar(wxsb); 129 | #endif 130 | 131 | return sb; 132 | } 133 | 134 | } // namespace ui 135 | } // namespace boost 136 | -------------------------------------------------------------------------------- /include/boost/ui/list_box.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file list_box.hpp @brief List box widget 7 | 8 | #ifndef BOOST_UI_LIST_BOX_HPP 9 | #define BOOST_UI_LIST_BOX_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Widget to select one or more strings 23 | /// @details 24 | /// Usage example: 25 | /// @snippet cpp11/snippet.cpp list_box 26 | /// @see List box (Wikipedia) 27 | /// @ingroup strings 28 | 29 | class BOOST_UI_DECL list_box : public strings_box 30 | { 31 | public: 32 | list_box() {} 33 | 34 | ///@{ Creates empty list_box widget 35 | explicit list_box(widget& parent) 36 | { create(parent); } 37 | list_box& create(widget& parent); 38 | ///@} 39 | 40 | ///@{ Creates list_box widget with options 41 | explicit list_box(widget& parent, const std::vector& options) 42 | { create(parent, options); } 43 | 44 | list_box& create(widget& parent, const std::vector& options); 45 | 46 | template 47 | explicit list_box(widget& parent, Iterator first, Iterator last) 48 | { create(parent, first, last); } 49 | 50 | template 51 | list_box& create(widget& parent, Iterator first, Iterator last) 52 | { return create(parent, std::vector(first, last)); } 53 | 54 | template 55 | explicit list_box(widget& parent, const Range& r) 56 | { create(parent, r); } 57 | 58 | template 59 | list_box& create(widget& parent, const Range& r) 60 | { return create(parent, detail::range_to_vector_uistring(r)); } 61 | 62 | #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST 63 | template 64 | explicit list_box(widget& parent, std::initializer_list list) 65 | { create(parent, list); } 66 | 67 | template 68 | list_box& create(widget& parent, std::initializer_list list) 69 | { return create(parent, detail::initializer_list_to_vector_uistring(list)); } 70 | #endif 71 | ///@} 72 | 73 | /// Returns true if list_box has selected options, false otherwise. 74 | bool has_selection() const 75 | { return selected_index() != npos; } 76 | 77 | /// Returns index of the selected option. If list_box has no selected options then returns @ref npos. 78 | size_type selected_index() const; 79 | 80 | /// Returns selected option string 81 | uistring selected_string() const; 82 | 83 | ///@{ Connects item selection handler 84 | BOOST_UI_DETAIL_HANDLER(select, list_box); 85 | BOOST_UI_DETAIL_HANDLER_EVENT(select_event, list_box, index_event); 86 | ///@} 87 | 88 | ///@{ Connects item activation handler 89 | BOOST_UI_DETAIL_HANDLER(activate, list_box); 90 | BOOST_UI_DETAIL_HANDLER_EVENT(activate_event, list_box, index_event); 91 | ///@} 92 | 93 | private: 94 | void on_select_raw(const boost::function& handler); 95 | void on_select_event_raw(const boost::function& handler); 96 | 97 | void on_activate_raw(const boost::function& handler); 98 | void on_activate_event_raw(const boost::function& handler); 99 | 100 | class detail_impl; 101 | detail_impl* get_impl(); 102 | const detail_impl* get_impl() const; 103 | }; 104 | 105 | } // namespace ui 106 | } // namespace boost 107 | 108 | #endif // BOOST_UI_LIST_BOX_HPP 109 | -------------------------------------------------------------------------------- /include/boost/ui/slider.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file slider.hpp @brief Slider widget 7 | 8 | #ifndef BOOST_UI_SLIDER_HPP 9 | #define BOOST_UI_SLIDER_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Slider widget base class 23 | /// @see Slider (Wikipedia) 24 | /// @ingroup io 25 | 26 | class BOOST_UI_DECL slider : public widget 27 | { 28 | public: 29 | /// Slider value type 30 | typedef int value_type; 31 | 32 | /// Retruns position value 33 | value_type value() const; 34 | 35 | /// Retruns minimum position value 36 | value_type min() const; 37 | 38 | /// Retruns maximum position value 39 | value_type max() const; 40 | 41 | /// Connects slide handler 42 | BOOST_UI_DETAIL_HANDLER(slide, slider); 43 | 44 | /// Connects slide end handler 45 | BOOST_UI_DETAIL_HANDLER(slide_end, slider); 46 | 47 | protected: 48 | slider() {} 49 | 50 | #ifndef DOXYGEN 51 | void detail_create(widget& parent, bool horizontal, value_type initial, 52 | value_type min, value_type max); 53 | #endif 54 | 55 | private: 56 | void check_range(value_type value) const 57 | { check_range(value, min(), max()); } 58 | static void check_range(value_type value, value_type min, value_type max); 59 | 60 | void on_slide_raw(const boost::function& handler); 61 | void on_slide_end_raw(const boost::function& handler); 62 | 63 | class detail_impl; 64 | detail_impl* get_impl(); 65 | const detail_impl* get_impl() const; 66 | }; 67 | 68 | /// @brief Horizontal slider widget 69 | /// @ingroup io 70 | 71 | class BOOST_UI_DECL hslider : public slider 72 | { 73 | public: 74 | hslider() {} 75 | 76 | ///@{ @brief Creates horizontal slider 77 | /// @throw std::out_of_range 78 | explicit hslider(widget& parent, value_type initial, 79 | value_type min, value_type max) 80 | { create(parent, initial, min, max); } 81 | explicit hslider(widget& parent, value_type initial = 0) 82 | { create(parent, initial); } 83 | hslider& create(widget& parent, value_type initial, 84 | value_type min, value_type max) 85 | { detail_create(parent, true, initial, min, max); return *this; } 86 | hslider& create(widget& parent, value_type initial = 0) 87 | { return create(parent, initial, 0, 100); } 88 | ///@} 89 | }; 90 | 91 | /// @brief Vertical slider widget 92 | /// @ingroup io 93 | 94 | class BOOST_UI_DECL vslider : public slider 95 | { 96 | public: 97 | vslider() {} 98 | 99 | ///@{ @brief Creates vertical slider 100 | /// @throw std::out_of_range 101 | explicit vslider(widget& parent, value_type initial, 102 | value_type min, value_type max) 103 | { create(parent, initial, min, max); } 104 | explicit vslider(widget& parent, value_type initial = 0) 105 | { create(parent, initial); } 106 | vslider& create(widget& parent, value_type initial, 107 | value_type min, value_type max) 108 | { detail_create(parent, false, initial, min, max); return *this; } 109 | vslider& create(widget& parent, value_type initial = 0) 110 | { return create(parent, initial, 0, 100); } 111 | ///@} 112 | }; 113 | 114 | } // namespace ui 115 | } // namespace boost 116 | 117 | #endif // BOOST_UI_SLIDER_HPP 118 | -------------------------------------------------------------------------------- /src/slider.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | #if wxUSE_SLIDER 21 | 22 | class slider::detail_impl : public detail::widget_detail 23 | { 24 | public: 25 | explicit detail_impl(widget& parent, bool horizontal, value_type initial, 26 | value_type min, value_type max) 27 | { 28 | set_native_handle(new wxSlider(native::from_widget(parent), 29 | wxID_ANY, initial, min, max, 30 | wxDefaultPosition, wxDefaultSize, 31 | horizontal ? wxSL_HORIZONTAL : wxSL_VERTICAL)); 32 | } 33 | value_type value() const 34 | { 35 | wxCHECK_MSG(m_native, -1, "Widget should be created"); 36 | return m_native->GetValue(); 37 | } 38 | value_type min() const 39 | { 40 | wxCHECK_MSG(m_native, -1, "Widget should be created"); 41 | return m_native->GetMin(); 42 | } 43 | value_type max() const 44 | { 45 | wxCHECK_MSG(m_native, -1, "Widget should be created"); 46 | return m_native->GetMax(); 47 | } 48 | }; 49 | 50 | #endif 51 | 52 | slider::detail_impl* slider::get_impl() 53 | { 54 | #if wxUSE_SLIDER 55 | return get_detail_impl(); 56 | #else 57 | return NULL; 58 | #endif 59 | } 60 | 61 | const slider::detail_impl* slider::get_impl() const 62 | { 63 | #if wxUSE_SLIDER 64 | return get_detail_impl(); 65 | #else 66 | return NULL; 67 | #endif 68 | } 69 | 70 | void slider::detail_create(widget& parent, bool horizontal, value_type initial, 71 | value_type min, value_type max) 72 | 73 | { 74 | check_range(initial, min, max); 75 | 76 | #if wxUSE_SLIDER 77 | detail_set_detail_impl(new detail_impl(parent, horizontal, initial, min, max)); 78 | #endif 79 | } 80 | 81 | slider::value_type slider::value() const 82 | { 83 | #if wxUSE_SLIDER 84 | const detail_impl* impl = get_impl(); 85 | wxCHECK_MSG(impl, -1, "Widget should be created"); 86 | 87 | return impl->value(); 88 | #else 89 | return -1; 90 | #endif 91 | } 92 | 93 | slider::value_type slider::min() const 94 | { 95 | #if wxUSE_SLIDER 96 | const detail_impl* impl = get_impl(); 97 | wxCHECK_MSG(impl, -1, "Widget should be created"); 98 | 99 | return impl->min(); 100 | #else 101 | return -1; 102 | #endif 103 | } 104 | 105 | slider::value_type slider::max() const 106 | { 107 | #if wxUSE_SLIDER 108 | const detail_impl* impl = get_impl(); 109 | wxCHECK_MSG(impl, -1, "Widget should be created"); 110 | 111 | return impl->max(); 112 | #else 113 | return -1; 114 | #endif 115 | } 116 | 117 | void slider::check_range(value_type value, value_type min, value_type max) 118 | { 119 | if ( value < min || value > max ) 120 | BOOST_THROW_EXCEPTION(std::out_of_range("ui::slider::check_range(): invalid value")); 121 | } 122 | 123 | void slider::on_slide_raw(const boost::function& handler) 124 | { 125 | #if wxUSE_SLIDER 126 | native::bind_helper(*this, wxEVT_SLIDER, handler); 127 | #endif 128 | } 129 | 130 | void slider::on_slide_end_raw(const boost::function& handler) 131 | { 132 | #if wxUSE_SLIDER 133 | native::bind_helper(*this, wxEVT_SCROLL_THUMBRELEASE, handler); 134 | #endif 135 | } 136 | 137 | } // namespace ui 138 | } // namespace boost 139 | -------------------------------------------------------------------------------- /src/list_box.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | #define BOOST_UI_SOURCE 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace boost { 19 | namespace ui { 20 | 21 | #if wxUSE_LISTBOX 22 | 23 | class list_box::detail_impl : public detail::widget_detail 24 | { 25 | public: 26 | explicit detail_impl(widget& parent) 27 | { 28 | set_native_handle(new wxListBox(native::from_widget(parent), wxID_ANY)); 29 | } 30 | 31 | explicit detail_impl(widget& parent, const std::vector& options) 32 | { 33 | 34 | set_native_handle(new wxListBox(native::from_widget(parent), 35 | wxID_ANY, wxDefaultPosition, wxDefaultSize, 36 | native::from_vector_uistring(options))); 37 | } 38 | size_type selected_index() const 39 | { 40 | wxCHECK_MSG(m_native, npos, "Widget should be created"); 41 | return m_native->GetSelection(); 42 | } 43 | uistring selected_string() const 44 | { 45 | wxCHECK_MSG(m_native, uistring(), "Widget should be created"); 46 | return native::to_uistring(m_native->GetStringSelection()); 47 | } 48 | }; 49 | 50 | #endif 51 | 52 | list_box::detail_impl* list_box::get_impl() 53 | { 54 | #if wxUSE_LISTBOX 55 | return get_detail_impl(); 56 | #else 57 | return NULL; 58 | #endif 59 | } 60 | 61 | const list_box::detail_impl* list_box::get_impl() const 62 | { 63 | #if wxUSE_LISTBOX 64 | return get_detail_impl(); 65 | #else 66 | return NULL; 67 | #endif 68 | } 69 | 70 | list_box& list_box::create(widget& parent) 71 | { 72 | #if wxUSE_LISTBOX 73 | detail_set_detail_impl(new detail_impl(parent)); 74 | #endif 75 | 76 | return *this; 77 | } 78 | 79 | list_box& list_box::create(widget& parent, const std::vector& options) 80 | { 81 | #if wxUSE_LISTBOX 82 | detail_set_detail_impl(new detail_impl(parent, options)); 83 | #endif 84 | 85 | return *this; 86 | } 87 | 88 | list_box::size_type list_box::selected_index() const 89 | { 90 | #if wxUSE_LISTBOX 91 | const detail_impl* impl = get_impl(); 92 | wxCHECK_MSG(impl, npos, "Widget should be created"); 93 | 94 | return impl->selected_index(); 95 | #else 96 | return npos; 97 | #endif 98 | } 99 | 100 | uistring list_box::selected_string() const 101 | { 102 | #if wxUSE_LISTBOX 103 | const detail_impl* impl = get_impl(); 104 | wxCHECK_MSG(impl, uistring(), "Widget should be created"); 105 | wxASSERT_MSG(has_selection(), "Nothing was selected"); 106 | 107 | return impl->selected_string(); 108 | #else 109 | return uistring(); 110 | #endif 111 | } 112 | 113 | void list_box::on_select_raw(const boost::function& handler) 114 | { 115 | #if wxUSE_LISTBOX 116 | native::bind_helper(*this, wxEVT_LISTBOX, handler); 117 | #endif 118 | } 119 | 120 | void list_box::on_select_event_raw(const boost::function& handler) 121 | { 122 | #if wxUSE_LISTBOX 123 | native::bind_event_helper(*this, wxEVT_LISTBOX, handler); 124 | #endif 125 | } 126 | 127 | void list_box::on_activate_raw(const boost::function& handler) 128 | { 129 | #if wxUSE_LISTBOX 130 | native::bind_helper(*this, wxEVT_LISTBOX_DCLICK, handler); 131 | #endif 132 | } 133 | 134 | void list_box::on_activate_event_raw(const boost::function& handler) 135 | { 136 | #if wxUSE_LISTBOX 137 | native::bind_event_helper(*this, wxEVT_LISTBOX_DCLICK, handler); 138 | #endif 139 | } 140 | 141 | } // namespace ui 142 | } // namespace boost 143 | -------------------------------------------------------------------------------- /include/boost/ui/check_box.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file check_box.hpp @brief Check box widget 7 | 8 | #ifndef BOOST_UI_CHECK_BOX_HPP 9 | #define BOOST_UI_CHECK_BOX_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace boost { 23 | namespace ui { 24 | 25 | /// @brief Check box base class 26 | /// @ingroup io 27 | 28 | class BOOST_UI_DECL check_box_base : public widget 29 | { 30 | public: 31 | ///@{ Sets check box state 32 | check_box_base& check(nullopt_t) { indeterminate(); return *this; } 33 | check_box_base& check(bool checked = true); 34 | check_box_base& uncheck() { return check(false); } 35 | check_box_base& indeterminate(); 36 | check_box_base& tribool(boost::tribool value) 37 | { 38 | if ( value ) check(); 39 | else if ( !value ) uncheck(); 40 | else indeterminate(); 41 | return *this; 42 | } 43 | check_box_base& optional(boost::optional value) 44 | { 45 | if ( !value ) indeterminate(); 46 | else if ( *value ) check(); 47 | else uncheck(); 48 | return *this; 49 | } 50 | ///@} 51 | 52 | ///@{ Returns check box state 53 | bool is_checked() const; 54 | bool is_unchecked() const; 55 | bool is_indeterminate() const; 56 | boost::tribool tribool() const 57 | { 58 | return is_checked() ? boost::tribool(true) 59 | : is_unchecked() ? boost::tribool(false) 60 | : boost::indeterminate; 61 | } 62 | boost::optional optional() const 63 | { 64 | return is_checked() ? boost::optional(true) 65 | : is_unchecked() ? boost::optional(false) 66 | : boost::none; 67 | } 68 | ///@} 69 | 70 | /// Connects check box toggle handler 71 | BOOST_UI_DETAIL_HANDLER(toggle, check_box_base); 72 | 73 | protected: 74 | check_box_base() {} 75 | 76 | #ifndef DOXYGEN 77 | void detail_create(widget& parent, const uistring& text, bool is_tri_state); 78 | #endif 79 | 80 | private: 81 | void on_toggle_raw(const boost::function& handler); 82 | 83 | class detail_impl; 84 | detail_impl* get_impl(); 85 | const detail_impl* get_impl() const; 86 | }; 87 | 88 | /// @brief Labelled widget that that permits the user to make a binary choice 89 | /// @see Checkbox (Wikipedia) 90 | /// @ingroup io 91 | 92 | class BOOST_UI_DECL check_box : public check_box_base 93 | { 94 | public: 95 | check_box() {} 96 | 97 | ///@{ Creates check box widget with text 98 | explicit check_box(widget& parent, const uistring& text) 99 | { create(parent, text); } 100 | check_box& create(widget& parent, const uistring& text) 101 | { detail_create(parent, text, false); return *this; } 102 | ///@} 103 | }; 104 | 105 | /// @brief Labelled widget that that permits the user to make a ternary choice 106 | /// @see Checkbox (Wikipedia) 107 | /// @ingroup io 108 | 109 | class BOOST_UI_DECL tri_state_check_box : public check_box_base 110 | { 111 | public: 112 | tri_state_check_box() {} 113 | 114 | ///@{ Creates tri-state check box widget with text 115 | explicit tri_state_check_box(widget& parent, const uistring& text) 116 | { create(parent, text); } 117 | tri_state_check_box& create(widget& parent, const uistring& text) 118 | { detail_create(parent, text, true); return *this; } 119 | ///@} 120 | }; 121 | 122 | } // namespace ui 123 | } // namespace boost 124 | 125 | #endif // BOOST_UI_CHECK_BOX_HPP 126 | -------------------------------------------------------------------------------- /include/boost/ui/text_box.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file text_box.hpp @brief Text editor widgets 7 | 8 | #ifndef BOOST_UI_TEXT_BOX_HPP 9 | #define BOOST_UI_TEXT_BOX_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | namespace boost { 20 | namespace ui { 21 | 22 | /// @brief Abstract text editor widget 23 | /// @details 24 | /// Usage example: 25 | /// @snippet cpp11/snippet.cpp string_box 26 | /// @ingroup text 27 | 28 | class BOOST_UI_DECL text_box_base : public widget 29 | { 30 | public: 31 | /// Clears the contents 32 | void clear(); 33 | 34 | /// Sets text into the editor 35 | text_box_base& text(const uistring& text); 36 | 37 | /// Returns text from the editor 38 | uistring text() const; 39 | 40 | ///@{ Connects text edit handler 41 | BOOST_UI_DETAIL_HANDLER(edit, text_box_base); 42 | ///@} 43 | 44 | protected: 45 | text_box_base() {} 46 | 47 | #ifndef DOXYGEN 48 | void detail_create(widget& parent, const uistring& text, int style); 49 | text_box_base& detail_placeholder(const uistring& text); 50 | uistring detail_placeholder() const; 51 | #endif 52 | 53 | private: 54 | void on_edit_raw(const boost::function& handler); 55 | 56 | class detail_impl; 57 | detail_impl* get_impl(); 58 | const detail_impl* get_impl() const; 59 | }; 60 | 61 | /// @brief Single-line text editor widget 62 | /// @details 63 | /// Usage example: 64 | /// @snippet cpp11/snippet.cpp string_box 65 | /// @see Text box (Wikipedia) 66 | /// @ingroup text 67 | 68 | class BOOST_UI_DECL string_box : public text_box_base 69 | { 70 | public: 71 | string_box() {} 72 | 73 | ///@{ @brief Creates widget 74 | /// @param parent Parent widget 75 | /// @param text Initial text in the editor 76 | explicit string_box(widget& parent, const uistring& text = uistring()) 77 | { create(parent, text); } 78 | string_box& create(widget& parent, const uistring& text = uistring()); 79 | ///@} 80 | 81 | /// Sets placeholder text into the editor 82 | string_box& placeholder(const uistring& text) { detail_placeholder(text); return *this; } 83 | 84 | /// Returns placeholder text from the editor 85 | uistring placeholder() const { return detail_placeholder(); } 86 | }; 87 | 88 | /// @brief Password editor widget 89 | /// @details 90 | /// Usage example: 91 | /// @snippet cpp11/snippet.cpp string_box 92 | /// @see Text box (Wikipedia) 93 | /// @ingroup text 94 | 95 | class BOOST_UI_DECL password_box : public text_box_base 96 | { 97 | public: 98 | password_box() {} 99 | 100 | ///@{ @brief Creates widget 101 | /// @param parent Parent widget 102 | /// @param text Initial text in the editor 103 | explicit password_box(widget& parent, const uistring& text = uistring()) 104 | { create(parent, text); } 105 | password_box& create(widget& parent, const uistring& text = uistring()); 106 | ///@} 107 | }; 108 | 109 | /// @brief Multi-line text editor widget 110 | /// @details 111 | /// Usage example: 112 | /// @snippet cpp11/snippet.cpp string_box 113 | /// @see Text box (Wikipedia) 114 | /// @ingroup text 115 | 116 | class BOOST_UI_DECL text_box : public text_box_base 117 | { 118 | public: 119 | text_box() {} 120 | 121 | ///@{ @brief Creates widget 122 | /// @param parent Parent widget 123 | /// @param text Initial text in the editor 124 | explicit text_box(widget& parent, const uistring& text = uistring()) 125 | { create(parent, text); } 126 | text_box& create(widget& parent, const uistring& text = uistring()); 127 | ///@} 128 | }; 129 | 130 | } // namespace ui 131 | } // namespace boost 132 | 133 | #endif // BOOST_UI_TEXT_BOX_HPP 134 | -------------------------------------------------------------------------------- /include/boost/ui/font.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file font.hpp @brief Font class 7 | 8 | #ifndef BOOST_UI_FONT_HPP 9 | #define BOOST_UI_FONT_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace boost { 22 | namespace ui { 23 | 24 | /// @brief Font class 25 | /// @see CSS 2 Fonts (W3C) 26 | /// @see CSS Fonts 3 (W3C) 27 | /// @see Font (Wikipedia) 28 | /// @ingroup graphics 29 | 30 | class BOOST_UI_DECL font 31 | { 32 | class impl; 33 | 34 | public: 35 | /// @brief Enumaration of font families 36 | BOOST_SCOPED_ENUM_DECLARE_BEGIN(family) 37 | { 38 | other, ///< Font family not listed here 39 | serif, ///< Serif font family 40 | sans_serif, ///< Sans-serif font family 41 | cursive, ///< Curisive font family 42 | fantasy, ///< Decorative font family 43 | monospace ///< Font family that all glyphs have the same fixed width 44 | } 45 | BOOST_SCOPED_ENUM_DECLARE_END(family) 46 | 47 | /// @brief Enumaration of font slants 48 | BOOST_SCOPED_ENUM_DECLARE_BEGIN(slant) 49 | { 50 | normal, ///< Normal slant 51 | italic, ///< Italic slant 52 | oblique ///< Oblique slant 53 | } 54 | BOOST_SCOPED_ENUM_DECLARE_END(slant) 55 | 56 | /// @brief Enumaration of font weights 57 | BOOST_SCOPED_ENUM_DECLARE_BEGIN(weight) 58 | { 59 | normal, ///< Normal weight 60 | bold ///< Bold weight 61 | } 62 | BOOST_SCOPED_ENUM_DECLARE_END(weight) 63 | 64 | font(); 65 | #ifndef DOXYGEN 66 | font(const font& other); 67 | font& operator=(const font& other); 68 | #endif 69 | ~font(); 70 | 71 | ///@{ @brief Creates font 72 | explicit font(double pt, family f, 73 | slant s = slant::normal, weight w = weight::normal); 74 | explicit font(double pt, const uistring& n, 75 | slant s = slant::normal, weight w = weight::normal); 76 | ///@} 77 | 78 | /// @brief Sets font family 79 | font& set_family(family f); 80 | 81 | /// @brief Returns font family 82 | family get_family() const; 83 | 84 | /// @brief Sets font slant 85 | font& set_slant(slant s); 86 | 87 | /// @brief Returns font slant 88 | slant get_slant() const; 89 | 90 | /// @brief Sets font weight 91 | font& set_weight(weight w); 92 | 93 | /// @brief Returns font weight 94 | weight get_weight() const; 95 | 96 | /// @brief Sets font name 97 | /// @throw std::out_of_range If font name isn't supported 98 | font& name(const uistring& n); 99 | 100 | /// @brief Returns font name 101 | uistring name() const; 102 | 103 | /// @brief Sets font size in points 104 | /// @throw std::out_of_range If font size isn't positive value 105 | font& size_pt(double pt); 106 | 107 | /// @brief Returns font size in points 108 | double size_pt() const; 109 | 110 | /// Returns true only if font is valid 111 | bool valid() const BOOST_NOEXCEPT; 112 | 113 | /// Implementation-defined font type 114 | typedef void* native_handle_type; 115 | 116 | ///@{ Returns the implementation-defined underlying font handle 117 | native_handle_type native_handle() { return m_impl; } 118 | const native_handle_type native_handle() const { return m_impl; } 119 | ///@} 120 | 121 | /// @brief Returns default font used for captioned widgets 122 | static font caption() BOOST_NOEXCEPT; 123 | 124 | private: 125 | impl* m_impl; 126 | 127 | #ifndef DOXYGEN 128 | friend class native_helper; 129 | #endif 130 | }; 131 | 132 | } // namespace ui 133 | } // namespace boost 134 | 135 | #endif // BOOST_UI_FONT_HPP 136 | -------------------------------------------------------------------------------- /include/boost/ui/layout.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | /// @file layout.hpp @brief Layout classes 7 | 8 | #ifndef BOOST_UI_LAYOUT_HPP 9 | #define BOOST_UI_LAYOUT_HPP 10 | 11 | #include 12 | 13 | #ifdef BOOST_HAS_PRAGMA_ONCE 14 | #pragma once 15 | #endif 16 | 17 | namespace boost { 18 | namespace ui { 19 | 20 | class widget; 21 | class box_layout; 22 | 23 | /// @brief Base class for all layouts 24 | /// @ingroup layout 25 | 26 | class BOOST_UI_DECL layout 27 | { 28 | public: 29 | class item; 30 | }; 31 | 32 | /// @brief Layout item with arrangement parameters 33 | /// @ingroup layout 34 | 35 | class BOOST_UI_DECL layout::item 36 | { 37 | class impl; 38 | 39 | public: 40 | item(); 41 | /// Constructs widget item 42 | item(const widget& w); 43 | /// Constructs layout item 44 | item(const box_layout& l); 45 | ~item(); 46 | 47 | #ifndef DOXYGEN 48 | item(const item& other); 49 | item& operator=(const item& other); 50 | #endif 51 | 52 | ///@{ @brief Appends subitem 53 | item& append(const item& item); 54 | item& operator<<(const item& item) 55 | { return append(item); } 56 | ///@} 57 | 58 | /// Resets layout item margin 59 | item& no_margin() 60 | { return margin(0); } 61 | 62 | ///@{ Sets layout item margin in spaces, that are backed-dependent 63 | item& margin(int all) 64 | { return margin(all, all); } 65 | item& margin(int vertical, int horizontal) 66 | { return margin(vertical, horizontal, vertical, horizontal); } 67 | item& margin(int top, int right, int bottom, int left); 68 | ///@} 69 | 70 | ///@{ Sets layout item margin in pixels 71 | item& margin_px(int all) 72 | { return margin_px(all, all); } 73 | item& margin_px(int vertical, int horizontal) 74 | { return margin_px(vertical, horizontal, vertical, horizontal); } 75 | item& margin_px(int top, int right, int bottom, int left); 76 | ///@} 77 | 78 | /// Sets layout item stretch factor 79 | item& stretch(int value = 1); 80 | 81 | ///@{ Sets layout item align 82 | item& left(); 83 | item& right(); 84 | item& top(); 85 | item& bottom(); 86 | item& vcenter(); 87 | item& hcenter(); 88 | item& center(); 89 | item& justify(); 90 | ///@} 91 | 92 | private: 93 | impl* m_impl; 94 | widget* m_widget; 95 | box_layout* m_layout; 96 | #ifndef DOXYGEN 97 | friend class box_layout; 98 | #endif 99 | }; 100 | 101 | /// @brief Abstract vertical or horizontal box layout 102 | /// @ingroup layout 103 | 104 | class BOOST_UI_DECL box_layout : public layout 105 | { 106 | public: 107 | /// Returns @ref layout::item with this widget 108 | item layout() 109 | { return ui::layout::item(*this); } 110 | 111 | ///@{ Appends a layout item to the layout 112 | box_layout& append(const item& item); 113 | box_layout& operator<<(const item& item) 114 | { return append(item); } 115 | ///@} 116 | 117 | protected: 118 | #ifndef DOXYGEN 119 | explicit box_layout(bool horizontal); 120 | explicit box_layout(widget& parent, bool horizontal); 121 | #endif 122 | 123 | private: 124 | class impl; 125 | impl* m_impl; 126 | }; 127 | 128 | /// @brief Horizontal box layout 129 | /// @ingroup layout 130 | 131 | class BOOST_UI_DECL hbox : public box_layout 132 | { 133 | public: 134 | hbox() : box_layout(true) {} 135 | 136 | /// Constructs and sets layout to the widget 137 | explicit hbox(widget& parent) : box_layout(parent, true) {} 138 | }; 139 | 140 | /// @brief Vertical box layout 141 | /// @ingroup layout 142 | 143 | class BOOST_UI_DECL vbox : public box_layout 144 | { 145 | public: 146 | vbox() : box_layout(false) {} 147 | 148 | /// Constructs and sets layout to the widget 149 | explicit vbox(widget& parent) : box_layout(parent, false) {} 150 | }; 151 | 152 | } // namespace ui 153 | } // namespace boost 154 | 155 | #endif // BOOST_UI_LAYOUT_HPP 156 | -------------------------------------------------------------------------------- /example/cpp17/geometry.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Kolya Kosenko 2 | 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | // Draw polygons using Boost.Geometry. 7 | 8 | #define BOOST_UI_USE_GEOMETRY 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace ui = boost::ui; 18 | 19 | template 20 | bool read_wkt_file(const std::string& filename, std::vector& geometries, Box& box) 21 | { 22 | std::ifstream file(filename.c_str()); 23 | if ( !file.is_open() ) 24 | return false; 25 | 26 | while ( !file.eof() ) 27 | { 28 | std::string line; 29 | std::getline(file, line); 30 | if ( !line.empty() ) 31 | { 32 | Geometry geometry; 33 | boost::geometry::read_wkt(line, geometry); 34 | geometries.push_back(geometry); 35 | boost::geometry::expand(box, boost::geometry::return_envelope(geometry)); 36 | } 37 | } 38 | 39 | return true; 40 | } 41 | 42 | class geometry_dialog : public ui::dialog 43 | { 44 | typedef geometry_dialog this_type; 45 | 46 | public: 47 | geometry_dialog(const std::string& filename); 48 | 49 | private: 50 | void draw(); 51 | 52 | ui::canvas m_canvas; 53 | 54 | typedef double value_type; 55 | typedef boost::geometry::model::d2::point_xy point_type; 56 | typedef boost::geometry::model::polygon polygon_type; 57 | typedef boost::geometry::model::multi_polygon country_type; 58 | typedef std::vector countries_type; 59 | 60 | countries_type m_countries; 61 | 62 | typedef boost::geometry::model::box box_type; 63 | box_type m_box; 64 | }; 65 | 66 | geometry_dialog::geometry_dialog(const std::string& filename) 67 | : ui::dialog("Boost.Geometry + Boost.UI example") 68 | { 69 | boost::geometry::assign_inverse(m_box); 70 | if ( !filename.empty() && !read_wkt_file(filename, m_countries, m_box) ) 71 | ui::error_dialog("File not found: " + filename); 72 | 73 | if ( m_countries.empty() ) 74 | { 75 | country_type geometry; 76 | boost::geometry::read_wkt("MULTIPOLYGON(((0 0,0 70,40 20,20 0,0 0)))", geometry); 77 | m_countries.push_back(geometry); 78 | boost::geometry::expand(m_box, boost::geometry::return_envelope(geometry)); 79 | } 80 | 81 | m_canvas.create(*this).on_resize(&this_type::draw, this); 82 | } 83 | 84 | void geometry_dialog::draw() 85 | { 86 | ui::painter painter = m_canvas.painter(); 87 | 88 | boost::geometry::strategy::transform::map_transformer 89 | transformer(m_box, m_canvas.width(), m_canvas.height()); 90 | 91 | for ( countries_type::const_iterator country = m_countries.begin(); 92 | country != m_countries.end(); ++country ) 93 | { 94 | for ( country_type::const_iterator polygon = country->begin(); 95 | polygon != country->end(); ++polygon ) 96 | { 97 | painter.begin_path(); 98 | for ( polygon_type::ring_type::const_iterator point = polygon->outer().begin(); 99 | point != polygon->outer().end(); ++point ) 100 | { 101 | point_type transformed_point = *point; 102 | boost::geometry::transform(*point, transformed_point, transformer); 103 | 104 | if ( point == polygon->outer().begin() ) 105 | painter.move_to(ui::gpoint(transformed_point)); 106 | else 107 | painter.line_to(ui::gpoint(transformed_point)); 108 | } 109 | painter.stroke(); 110 | } 111 | } 112 | } 113 | 114 | int ui_main(int argc, char* argv[]) 115 | { 116 | // filename: boost/libs/geometry/example/data/world.wkt 117 | 118 | geometry_dialog(argc == 2 ? argv[1] : "").show_modal(); 119 | 120 | return 0; 121 | } 122 | 123 | int main(int argc, char* argv[]) 124 | { 125 | return ui::entry(&ui_main, argc, argv); 126 | } 127 | --------------------------------------------------------------------------------