Add the new spinbox widget
This commit is contained in:
parent
0597d895b4
commit
4ff3a6afd5
@ -91,6 +91,7 @@
|
|||||||
<Unit filename="../../source/gui/widgets/scroll.cpp" />
|
<Unit filename="../../source/gui/widgets/scroll.cpp" />
|
||||||
<Unit filename="../../source/gui/widgets/skeletons/text_editor.cpp" />
|
<Unit filename="../../source/gui/widgets/skeletons/text_editor.cpp" />
|
||||||
<Unit filename="../../source/gui/widgets/slider.cpp" />
|
<Unit filename="../../source/gui/widgets/slider.cpp" />
|
||||||
|
<Unit filename="../../source/gui/widgets/spinbox.cpp" />
|
||||||
<Unit filename="../../source/gui/widgets/tabbar.cpp" />
|
<Unit filename="../../source/gui/widgets/tabbar.cpp" />
|
||||||
<Unit filename="../../source/gui/widgets/textbox.cpp" />
|
<Unit filename="../../source/gui/widgets/textbox.cpp" />
|
||||||
<Unit filename="../../source/gui/widgets/toolbar.cpp" />
|
<Unit filename="../../source/gui/widgets/toolbar.cpp" />
|
||||||
|
|||||||
@ -1,11 +1,41 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
<CodeBlocks_layout_file>
|
<CodeBlocks_layout_file>
|
||||||
<ActiveTarget name="Debug" />
|
<ActiveTarget name="Debug" />
|
||||||
|
<File name="..\..\source\gui\programming_interface.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="5022" topLine="159" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
<File name="..\..\source\gui\tooltip.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="4739" topLine="194" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
<File name="..\..\source\gui\widgets\button.cpp" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="7080" topLine="291" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
<File name="..\..\source\paint\graphics.cpp" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="30961" topLine="1020" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
<File name="..\..\source\filesystem\fs_utility.cpp" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="1562" topLine="57" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
<File name="..\..\source\gui\widgets\categorize.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\widgets\categorize.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="6160" topLine="196" />
|
<Cursor1 position="6160" topLine="196" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
|
<File name="..\..\source\paint\image.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="3714" topLine="168" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
<File name="..\..\source\gui\animation.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\animation.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="1164" topLine="43" />
|
<Cursor1 position="1164" topLine="43" />
|
||||||
@ -21,21 +51,26 @@
|
|||||||
<Cursor1 position="16572" topLine="610" />
|
<Cursor1 position="16572" topLine="610" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
<File name="..\..\source\threads\pool.cpp" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="5569" topLine="249" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\gui\widgets\date_chooser.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\widgets\date_chooser.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="457" topLine="3" />
|
<Cursor1 position="457" topLine="3" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
|
<File name="..\..\source\paint\text_renderer.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="5894" topLine="205" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
<File name="..\..\source\gui\widgets\listbox.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\widgets\listbox.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="12428" topLine="532" />
|
<Cursor1 position="12428" topLine="532" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
|
<File name="..\..\source\threads\pool.cpp" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="5569" topLine="249" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
<File name="..\..\source\gui\widgets\menu.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\widgets\menu.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="27717" topLine="1044" />
|
<Cursor1 position="27717" topLine="1044" />
|
||||||
@ -46,29 +81,59 @@
|
|||||||
<Cursor1 position="4901" topLine="171" />
|
<Cursor1 position="4901" topLine="171" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
|
<File name="..\..\source\audio\detail\buffer_preparation.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="1924" topLine="62" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
<File name="..\..\source\gui\detail\window_layout.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\detail\window_layout.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="5198" topLine="161" />
|
<Cursor1 position="5198" topLine="161" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
<File name="..\..\source\gui\widgets\tabbar.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="18615" topLine="760" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\gui\detail\window_manager.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\detail\window_manager.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="30124" topLine="1046" />
|
<Cursor1 position="30124" topLine="1046" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
|
<File name="..\..\source\gui\dragger.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="1316" topLine="59" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
<File name="..\..\source\charset.cpp" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="412" topLine="15" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
<File name="..\..\source\gui\element.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="20890" topLine="542" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
<File name="..\..\source\detail\platform_spec_selector.cpp" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="587" topLine="2" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
<File name="..\..\source\gui\filebox.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="22934" topLine="871" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
<File name="..\..\source\gui\widgets\tabbar.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="18615" topLine="760" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
<File name="..\..\source\gui\widgets\textbox.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\widgets\textbox.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="11188" topLine="459" />
|
<Cursor1 position="11188" topLine="459" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
<File name="..\..\source\gui\dragger.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\msgbox.cpp" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="1316" topLine="59" />
|
<Cursor1 position="48249" topLine="407" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
<File name="..\..\source\gui\widgets\toolbar.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\gui\widgets\toolbar.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
@ -81,74 +146,9 @@
|
|||||||
<Cursor1 position="15535" topLine="539" />
|
<Cursor1 position="15535" topLine="539" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
<File name="..\..\source\detail\platform_spec_selector.cpp" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="587" topLine="2" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\gui\element.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="20890" topLine="542" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\gui\filebox.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="22934" topLine="871" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\charset.cpp" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="412" topLine="15" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\gui\msgbox.cpp" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="48249" topLine="407" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\audio\detail\buffer_preparation.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="1924" topLine="62" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\paint\graphics.cpp" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="30961" topLine="1020" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\gui\programming_interface.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="5022" topLine="159" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\paint\image.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="3714" topLine="168" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\audio\detail\audio_device.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
<File name="..\..\source\audio\detail\audio_device.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
<Cursor>
|
<Cursor>
|
||||||
<Cursor1 position="6256" topLine="215" />
|
<Cursor1 position="6256" topLine="215" />
|
||||||
</Cursor>
|
</Cursor>
|
||||||
</File>
|
</File>
|
||||||
<File name="..\..\source\paint\text_renderer.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="5894" topLine="205" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\gui\tooltip.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="4739" topLine="194" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\gui\widgets\button.cpp" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="7080" topLine="291" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
<File name="..\..\source\filesystem\fs_utility.cpp" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
|
||||||
<Cursor>
|
|
||||||
<Cursor1 position="1562" topLine="57" />
|
|
||||||
</Cursor>
|
|
||||||
</File>
|
|
||||||
</CodeBlocks_layout_file>
|
</CodeBlocks_layout_file>
|
||||||
|
|||||||
@ -139,6 +139,7 @@
|
|||||||
<ClCompile Include="..\..\source\gui\widgets\scroll.cpp" />
|
<ClCompile Include="..\..\source\gui\widgets\scroll.cpp" />
|
||||||
<ClCompile Include="..\..\source\gui\widgets\skeletons\text_editor.cpp" />
|
<ClCompile Include="..\..\source\gui\widgets\skeletons\text_editor.cpp" />
|
||||||
<ClCompile Include="..\..\source\gui\widgets\slider.cpp" />
|
<ClCompile Include="..\..\source\gui\widgets\slider.cpp" />
|
||||||
|
<ClCompile Include="..\..\source\gui\widgets\spinbox.cpp" />
|
||||||
<ClCompile Include="..\..\source\gui\widgets\tabbar.cpp" />
|
<ClCompile Include="..\..\source\gui\widgets\tabbar.cpp" />
|
||||||
<ClCompile Include="..\..\source\gui\widgets\textbox.cpp" />
|
<ClCompile Include="..\..\source\gui\widgets\textbox.cpp" />
|
||||||
<ClCompile Include="..\..\source\gui\widgets\toolbar.cpp" />
|
<ClCompile Include="..\..\source\gui\widgets\toolbar.cpp" />
|
||||||
|
|||||||
@ -297,5 +297,8 @@
|
|||||||
<ClCompile Include="..\..\source\gui\screen.cpp">
|
<ClCompile Include="..\..\source\gui\screen.cpp">
|
||||||
<Filter>Source Files\nana\gui</Filter>
|
<Filter>Source Files\nana\gui</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\source\gui\widgets\spinbox.cpp">
|
||||||
|
<Filter>Source Files\nana\gui\widgets</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -155,7 +155,7 @@ namespace detail
|
|||||||
{
|
{
|
||||||
bool enabled :1;
|
bool enabled :1;
|
||||||
bool dbl_click :1;
|
bool dbl_click :1;
|
||||||
bool capture :1; //if mouse button is down, it always receive mouse move even the mouse is out of its rectangle
|
bool captured :1; //if mouse button is down, it always receive mouse move even the mouse is out of its rectangle
|
||||||
bool modal :1;
|
bool modal :1;
|
||||||
bool take_active:1; //If take_active is false, other.active_window still keeps the focus.
|
bool take_active:1; //If take_active is false, other.active_window still keeps the focus.
|
||||||
bool refreshing :1;
|
bool refreshing :1;
|
||||||
|
|||||||
@ -42,7 +42,7 @@ namespace detail
|
|||||||
|
|
||||||
~bedrock();
|
~bedrock();
|
||||||
void pump_event(window, bool is_modal);
|
void pump_event(window, bool is_modal);
|
||||||
void map_thread_root_buffer(core_window_t* );
|
void map_thread_root_buffer(core_window_t*, bool forced);
|
||||||
static int inc_window(unsigned tid = 0);
|
static int inc_window(unsigned tid = 0);
|
||||||
thread_context* open_thread_context(unsigned tid = 0);
|
thread_context* open_thread_context(unsigned tid = 0);
|
||||||
thread_context* get_thread_context(unsigned tid = 0);
|
thread_context* get_thread_context(unsigned tid = 0);
|
||||||
|
|||||||
@ -110,7 +110,7 @@ namespace nana
|
|||||||
void key_char(const arg_keyboard&);
|
void key_char(const arg_keyboard&);
|
||||||
void key_release(const arg_keyboard&);
|
void key_release(const arg_keyboard&);
|
||||||
void shortkey(const arg_keyboard&);
|
void shortkey(const arg_keyboard&);
|
||||||
void map(window); //Copy the root buffer to screen
|
void map(window, bool forced); //Copy the root buffer to screen
|
||||||
void refresh();
|
void refresh();
|
||||||
drawer_trigger* realizer() const;
|
drawer_trigger* realizer() const;
|
||||||
void attached(widget&, drawer_trigger&);
|
void attached(widget&, drawer_trigger&);
|
||||||
|
|||||||
@ -28,7 +28,7 @@ namespace nana{
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool render(core_window_t * wd)
|
bool render(core_window_t * wd, bool forced)
|
||||||
{
|
{
|
||||||
bool rendered = false;
|
bool rendered = false;
|
||||||
core_window_t * root_wd = wd->root_widget;
|
core_window_t * root_wd = wd->root_widget;
|
||||||
@ -53,7 +53,7 @@ namespace nana{
|
|||||||
rendered = true;
|
rendered = true;
|
||||||
|
|
||||||
//Avoiding duplicated rendering. If the window is declared to lazy refresh, it should be rendered.
|
//Avoiding duplicated rendering. If the window is declared to lazy refresh, it should be rendered.
|
||||||
if (!action.rendered || (action.window->other.upd_state == core_window_t::update_state::refresh))
|
if ((forced && (action.window == wd)) || !action.rendered || (action.window->other.upd_state == core_window_t::update_state::refresh))
|
||||||
{
|
{
|
||||||
rd_set.emplace_back(r, action.window);
|
rd_set.emplace_back(r, action.window);
|
||||||
action.rendered = true;
|
action.rendered = true;
|
||||||
|
|||||||
@ -150,7 +150,7 @@ namespace detail
|
|||||||
core_window_t* root(native_window_type) const;
|
core_window_t* root(native_window_type) const;
|
||||||
|
|
||||||
//Copy the root buffer that wnd specified into DeviceContext
|
//Copy the root buffer that wnd specified into DeviceContext
|
||||||
void map(core_window_t*);
|
void map(core_window_t*, bool forced);
|
||||||
|
|
||||||
bool update(core_window_t*, bool redraw, bool force);
|
bool update(core_window_t*, bool redraw, bool force);
|
||||||
void refresh_tree(core_window_t*);
|
void refresh_tree(core_window_t*);
|
||||||
|
|||||||
@ -106,6 +106,9 @@ namespace nana
|
|||||||
|
|
||||||
void add_arrow(const std::string&, const pat::cloneable<factory_interface<arrow_interface>>&);
|
void add_arrow(const std::string&, const pat::cloneable<factory_interface<arrow_interface>>&);
|
||||||
arrow_interface* const * keeper_arrow(const std::string&);
|
arrow_interface* const * keeper_arrow(const std::string&);
|
||||||
|
|
||||||
|
void add_button(const std::string&, const pat::cloneable<factory_interface<element_interface>>&);
|
||||||
|
element_interface* const* keeper_button(const std::string&);
|
||||||
};
|
};
|
||||||
|
|
||||||
class crook;
|
class crook;
|
||||||
@ -131,6 +134,14 @@ namespace nana
|
|||||||
using factory_t = provider::factory<ArrowElement, arrow_interface>;
|
using factory_t = provider::factory<ArrowElement, arrow_interface>;
|
||||||
provider().add_arrow(name, pat::cloneable<typename factory_t::interface_type>(factory_t()));
|
provider().add_arrow(name, pat::cloneable<typename factory_t::interface_type>(factory_t()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class button;
|
||||||
|
template<typename ButtonElement>
|
||||||
|
void add_button(const std::string& name)
|
||||||
|
{
|
||||||
|
using factory_t = provider::factory<ButtonElement, element_interface>;
|
||||||
|
provider().add_button(name, pat::cloneable<typename factory_t::interface_type>(factory_t()));
|
||||||
|
}
|
||||||
}//end namespace element
|
}//end namespace element
|
||||||
|
|
||||||
template<typename Element> class facade;
|
template<typename Element> class facade;
|
||||||
@ -200,6 +211,20 @@ namespace nana
|
|||||||
::nana::direction dir_{::nana::direction::north};
|
::nana::direction dir_{::nana::direction::north};
|
||||||
};//end class facade<element::arrow>
|
};//end class facade<element::arrow>
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class facade<element::button>
|
||||||
|
: public element::element_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
facade(const char* name = nullptr);
|
||||||
|
void switch_to(const char*);
|
||||||
|
public:
|
||||||
|
//Implement element_interface
|
||||||
|
bool draw(graph_reference, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle&, element_state) override;
|
||||||
|
private:
|
||||||
|
element::element_interface* const * keeper_;
|
||||||
|
};//end class facade<element::button>
|
||||||
|
|
||||||
|
|
||||||
namespace element
|
namespace element
|
||||||
{
|
{
|
||||||
|
|||||||
@ -45,7 +45,7 @@ namespace nana
|
|||||||
void week_name(unsigned index, const nana::string&);
|
void week_name(unsigned index, const nana::string&);
|
||||||
void month_name(unsigned index, const nana::string&);
|
void month_name(unsigned index, const nana::string&);
|
||||||
private:
|
private:
|
||||||
where _m_pos_where(graph_reference, int x, int y);
|
where _m_pos_where(graph_reference, const ::nana::point& pos);
|
||||||
void _m_draw(graph_reference);
|
void _m_draw(graph_reference);
|
||||||
void _m_draw_topbar(graph_reference);
|
void _m_draw_topbar(graph_reference);
|
||||||
void _m_make_drawing_basis(drawing_basis&, graph_reference, const nana::point& refpos);
|
void _m_make_drawing_basis(drawing_basis&, graph_reference, const nana::point& refpos);
|
||||||
|
|||||||
78
include/nana/gui/widgets/spinbox.hpp
Normal file
78
include/nana/gui/widgets/spinbox.hpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* A Spin box widget
|
||||||
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
|
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*
|
||||||
|
* @file: nana/gui/widgets/spanbox.hpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NANA_GUI_WIDGET_SPINBOX_HPP
|
||||||
|
#define NANA_GUI_WIDGET_SPINBOX_HPP
|
||||||
|
#include "widget.hpp"
|
||||||
|
#include "skeletons/text_editor_scheme.hpp"
|
||||||
|
|
||||||
|
namespace nana
|
||||||
|
{
|
||||||
|
namespace drawerbase
|
||||||
|
{
|
||||||
|
namespace spinbox
|
||||||
|
{
|
||||||
|
/// Declaration of internal spinbox implementation
|
||||||
|
class implementation;
|
||||||
|
|
||||||
|
/// Drawer of spinbox
|
||||||
|
class drawer
|
||||||
|
: public ::nana::drawer_trigger
|
||||||
|
{
|
||||||
|
drawer(const drawer&) = delete;
|
||||||
|
drawer(drawer&&) = delete;
|
||||||
|
drawer& operator=(const drawer&) = delete;
|
||||||
|
drawer& operator=(drawer&&) = delete;
|
||||||
|
public:
|
||||||
|
drawer();
|
||||||
|
~drawer();
|
||||||
|
implementation * impl() const;
|
||||||
|
private:
|
||||||
|
//Overrides drawer_trigger
|
||||||
|
void attached(widget_reference, graph_reference) override;
|
||||||
|
void refresh(graph_reference) override;
|
||||||
|
|
||||||
|
void focus(graph_reference, const arg_focus&) override;
|
||||||
|
void mouse_wheel(graph_reference, const arg_wheel&) override;
|
||||||
|
void mouse_down(graph_reference, const arg_mouse&) override;
|
||||||
|
void mouse_move(graph_reference, const arg_mouse&) override;
|
||||||
|
void mouse_up(graph_reference, const arg_mouse& arg) override;
|
||||||
|
void mouse_leave(graph_reference, const arg_mouse&) override;
|
||||||
|
private:
|
||||||
|
implementation * const impl_;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}//end namespace drawerbase
|
||||||
|
|
||||||
|
/// Spinbox Widget
|
||||||
|
class spinbox
|
||||||
|
: public widget_object <category::widget_tag, drawerbase::spinbox::drawer, ::nana::general_events, ::nana::widgets::skeletons::text_editor_scheme>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
spinbox();
|
||||||
|
spinbox(window, bool visible);
|
||||||
|
spinbox(window, const nana::rectangle& = {}, bool visible = true);
|
||||||
|
|
||||||
|
void range(int begin, int last, int step);
|
||||||
|
void range(double begin, double last, double step);
|
||||||
|
void range(std::initializer_list<std::string> steps_utf8);
|
||||||
|
void range(std::initializer_list<std::wstring> steps);
|
||||||
|
|
||||||
|
void qualify(std::wstring prefix, std::wstring suffix);
|
||||||
|
void qualify(const std::string & prefix_utf8, const std::string& suffix_utf8);
|
||||||
|
private:
|
||||||
|
::nana::string _m_caption() const;
|
||||||
|
void _m_caption(::nana::string&&);
|
||||||
|
};
|
||||||
|
}//end namespace nana
|
||||||
|
|
||||||
|
#endif //NANA_GUI_WIDGET_SPINBOX_HPP
|
||||||
@ -327,7 +327,7 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
predef_cursor = cursor::arrow;
|
predef_cursor = cursor::arrow;
|
||||||
flags.capture = false;
|
flags.captured = false;
|
||||||
flags.dbl_click = true;
|
flags.dbl_click = true;
|
||||||
flags.enabled = true;
|
flags.enabled = true;
|
||||||
flags.modal = false;
|
flags.modal = false;
|
||||||
|
|||||||
@ -63,7 +63,7 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
wd_manager.refresh_tree(wd);
|
wd_manager.refresh_tree(wd);
|
||||||
wd_manager.map(wd);
|
wd_manager.map(wd, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -242,7 +242,7 @@ namespace nana
|
|||||||
_m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey);
|
_m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::map(window wd) //Copy the root buffer to screen
|
void drawer::map(window wd, bool forced) //Copy the root buffer to screen
|
||||||
{
|
{
|
||||||
if(wd)
|
if(wd)
|
||||||
{
|
{
|
||||||
@ -264,7 +264,7 @@ namespace nana
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(false == edge_nimbus_renderer_t::instance().render(iwd))
|
if (false == edge_nimbus_renderer_t::instance().render(iwd, forced))
|
||||||
{
|
{
|
||||||
nana::rectangle vr;
|
nana::rectangle vr;
|
||||||
if(bedrock_type::window_manager_t::wndlayout_type::read_visual_rectangle(iwd, vr))
|
if(bedrock_type::window_manager_t::wndlayout_type::read_visual_rectangle(iwd, vr))
|
||||||
|
|||||||
@ -176,9 +176,9 @@ namespace detail
|
|||||||
delete impl_;
|
delete impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bedrock::map_thread_root_buffer(bedrock::core_window_t* wnd)
|
void bedrock::map_thread_root_buffer(core_window_t*, bool forced)
|
||||||
{
|
{
|
||||||
//GUI in X11 is not thread-dependent, so no implementation.
|
//GUI in X11 is thread-independent, so no implementation.
|
||||||
}
|
}
|
||||||
|
|
||||||
//inc_window
|
//inc_window
|
||||||
@ -619,7 +619,8 @@ namespace detail
|
|||||||
msgwnd = brock.wd_manager.find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y);
|
msgwnd = brock.wd_manager.find_window(native_window, xevent.xcrossing.x, xevent.xcrossing.y);
|
||||||
if(msgwnd)
|
if(msgwnd)
|
||||||
{
|
{
|
||||||
msgwnd->flags.action = mouse_action::over;
|
if (mouse_action::pressed != msgwnd->flags.action)
|
||||||
|
msgwnd->flags.action = mouse_action::over;
|
||||||
hovered_wd = msgwnd;
|
hovered_wd = msgwnd;
|
||||||
|
|
||||||
arg_mouse arg;
|
arg_mouse arg;
|
||||||
@ -870,7 +871,8 @@ namespace detail
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
evt_code = event_code::mouse_enter;
|
evt_code = event_code::mouse_enter;
|
||||||
msgwnd->flags.action = mouse_action::over;
|
if (mouse_action::pressed != msgwnd->flags.action)
|
||||||
|
msgwnd->flags.action = mouse_action::over;
|
||||||
}
|
}
|
||||||
arg_mouse arg;
|
arg_mouse arg;
|
||||||
assign_arg(arg, msgwnd, message, xevent);
|
assign_arg(arg, msgwnd, message, xevent);
|
||||||
@ -883,7 +885,10 @@ namespace detail
|
|||||||
{
|
{
|
||||||
arg_mouse arg;
|
arg_mouse arg;
|
||||||
assign_arg(arg, msgwnd, message, xevent);
|
assign_arg(arg, msgwnd, message, xevent);
|
||||||
msgwnd->flags.action = mouse_action::over;
|
|
||||||
|
if (mouse_action::pressed != msgwnd->flags.action)
|
||||||
|
msgwnd->flags.action = mouse_action::over;
|
||||||
|
|
||||||
if (hovered_wd != msgwnd)
|
if (hovered_wd != msgwnd)
|
||||||
{
|
{
|
||||||
hovered_wd = msgwnd;
|
hovered_wd = msgwnd;
|
||||||
|
|||||||
@ -342,9 +342,9 @@ namespace detail
|
|||||||
return bedrock_object;
|
return bedrock_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bedrock::map_thread_root_buffer(core_window_t* wd)
|
void bedrock::map_thread_root_buffer(core_window_t* wd, bool forced)
|
||||||
{
|
{
|
||||||
::PostMessage(reinterpret_cast<HWND>(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast<WPARAM>(wd), 0);
|
::PostMessage(reinterpret_cast<HWND>(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast<WPARAM>(wd), static_cast<LPARAM>(forced ? TRUE : FALSE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void interior_helper_for_menu(MSG& msg, native_window_type menu_window)
|
void interior_helper_for_menu(MSG& msg, native_window_type menu_window)
|
||||||
@ -596,7 +596,7 @@ namespace detail
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case nana::detail::messages::map_thread_root_buffer:
|
case nana::detail::messages::map_thread_root_buffer:
|
||||||
bedrock.wd_manager.map(reinterpret_cast<bedrock::core_window_t*>(wParam));
|
bedrock.wd_manager.map(reinterpret_cast<bedrock::core_window_t*>(wParam), (TRUE == lParam));
|
||||||
::UpdateWindow(wd);
|
::UpdateWindow(wd);
|
||||||
return true;
|
return true;
|
||||||
case nana::detail::messages::remote_thread_move_window:
|
case nana::detail::messages::remote_thread_move_window:
|
||||||
@ -1060,7 +1060,10 @@ namespace detail
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
evt_code = event_code::mouse_enter;
|
evt_code = event_code::mouse_enter;
|
||||||
msgwnd->flags.action = mouse_action::over;
|
if (pressed_wd == msgwnd)
|
||||||
|
msgwnd->flags.action = mouse_action::pressed;
|
||||||
|
else if (mouse_action::pressed != msgwnd->flags.action)
|
||||||
|
msgwnd->flags.action = mouse_action::over;
|
||||||
}
|
}
|
||||||
arg_mouse arg;
|
arg_mouse arg;
|
||||||
assign_arg(arg, msgwnd, message, pmdec);
|
assign_arg(arg, msgwnd, message, pmdec);
|
||||||
@ -1073,9 +1076,14 @@ namespace detail
|
|||||||
{
|
{
|
||||||
arg_mouse arg;
|
arg_mouse arg;
|
||||||
assign_arg(arg, msgwnd, message, pmdec);
|
assign_arg(arg, msgwnd, message, pmdec);
|
||||||
msgwnd->flags.action = mouse_action::over;
|
|
||||||
if (hovered_wd != msgwnd)
|
if (hovered_wd != msgwnd)
|
||||||
{
|
{
|
||||||
|
if (pressed_wd == msgwnd)
|
||||||
|
msgwnd->flags.action = mouse_action::pressed;
|
||||||
|
else if (mouse_action::pressed != msgwnd->flags.action)
|
||||||
|
msgwnd->flags.action = mouse_action::over;
|
||||||
|
|
||||||
hovered_wd = msgwnd;
|
hovered_wd = msgwnd;
|
||||||
arg.evt_code = event_code::mouse_enter;
|
arg.evt_code = event_code::mouse_enter;
|
||||||
brock.emit(event_code::mouse_enter, msgwnd, arg, true, &context);
|
brock.emit(event_code::mouse_enter, msgwnd, arg, true, &context);
|
||||||
@ -1105,21 +1113,34 @@ namespace detail
|
|||||||
auto scrolled_wd = brock.wd_manager.find_window(reinterpret_cast<native_window_type>(pointer_wd), scr_pos.x, scr_pos.y);
|
auto scrolled_wd = brock.wd_manager.find_window(reinterpret_cast<native_window_type>(pointer_wd), scr_pos.x, scr_pos.y);
|
||||||
|
|
||||||
def_window_proc = true;
|
def_window_proc = true;
|
||||||
while (scrolled_wd)
|
auto evt_wd = scrolled_wd;
|
||||||
|
while (evt_wd)
|
||||||
{
|
{
|
||||||
if (scrolled_wd->together.attached_events->mouse_wheel.length() != 0)
|
if (evt_wd->together.attached_events->mouse_wheel.length() != 0)
|
||||||
{
|
{
|
||||||
def_window_proc = false;
|
def_window_proc = false;
|
||||||
nana::point mspos{ scr_pos.x, scr_pos.y };
|
nana::point mspos{ scr_pos.x, scr_pos.y };
|
||||||
brock.wd_manager.calc_window_point(scrolled_wd, mspos);
|
brock.wd_manager.calc_window_point(evt_wd, mspos);
|
||||||
|
|
||||||
arg_wheel arg;
|
arg_wheel arg;
|
||||||
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
|
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
|
||||||
assign_arg(arg, scrolled_wd, pmdec);
|
assign_arg(arg, evt_wd, pmdec);
|
||||||
brock.emit(event_code::mouse_wheel, scrolled_wd, arg, true, &context);
|
brock.emit(event_code::mouse_wheel, evt_wd, arg, true, &context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
scrolled_wd = scrolled_wd->parent;
|
evt_wd = evt_wd->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrolled_wd && (nullptr == evt_wd))
|
||||||
|
{
|
||||||
|
nana::point mspos{ scr_pos.x, scr_pos.y };
|
||||||
|
brock.wd_manager.calc_window_point(scrolled_wd, mspos);
|
||||||
|
|
||||||
|
arg_wheel arg;
|
||||||
|
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
|
||||||
|
assign_arg(arg, scrolled_wd, pmdec);
|
||||||
|
brock.emit_drawer(event_code::mouse_wheel, scrolled_wd, arg, &context);
|
||||||
|
brock.wd_manager.do_lazy_refresh(scrolled_wd, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -671,7 +671,7 @@ namespace detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Copy the root buffer that wnd specified into DeviceContext
|
//Copy the root buffer that wnd specified into DeviceContext
|
||||||
void window_manager::map(core_window_t* wd)
|
void window_manager::map(core_window_t* wd, bool forced)
|
||||||
{
|
{
|
||||||
//Thread-Safe Required!
|
//Thread-Safe Required!
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
@ -682,9 +682,9 @@ namespace detail
|
|||||||
wd->drawer.map(reinterpret_cast<window>(wd));
|
wd->drawer.map(reinterpret_cast<window>(wd));
|
||||||
#elif defined(NANA_WINDOWS)
|
#elif defined(NANA_WINDOWS)
|
||||||
if(nana::system::this_thread_id() == wd->thread_id)
|
if(nana::system::this_thread_id() == wd->thread_id)
|
||||||
wd->drawer.map(reinterpret_cast<window>(wd));
|
wd->drawer.map(reinterpret_cast<window>(wd), forced);
|
||||||
else
|
else
|
||||||
bedrock::instance().map_thread_root_buffer(wd);
|
bedrock::instance().map_thread_root_buffer(wd, forced);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -693,7 +693,7 @@ namespace detail
|
|||||||
//@brief: update is used for displaying the screen-off buffer.
|
//@brief: update is used for displaying the screen-off buffer.
|
||||||
// Because of a good efficiency, if it is called in an event procedure and the event procedure window is the
|
// Because of a good efficiency, if it is called in an event procedure and the event procedure window is the
|
||||||
// same as update's, update would not map the screen-off buffer and just set the window for lazy refresh
|
// same as update's, update would not map the screen-off buffer and just set the window for lazy refresh
|
||||||
bool window_manager::update(core_window_t* wd, bool redraw, bool force)
|
bool window_manager::update(core_window_t* wd, bool redraw, bool forced)
|
||||||
{
|
{
|
||||||
//Thread-Safe Required!
|
//Thread-Safe Required!
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
@ -701,10 +701,10 @@ namespace detail
|
|||||||
|
|
||||||
if (wd->visible && wd->visible_parents())
|
if (wd->visible && wd->visible_parents())
|
||||||
{
|
{
|
||||||
if(force || (false == wd->belong_to_lazy()))
|
if(forced || (false == wd->belong_to_lazy()))
|
||||||
{
|
{
|
||||||
wndlayout_type::paint(wd, redraw, false);
|
wndlayout_type::paint(wd, redraw, false);
|
||||||
this->map(wd);
|
this->map(wd, forced);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -746,13 +746,13 @@ namespace detail
|
|||||||
if ((wd->other.upd_state == core_window_t::update_state::refresh) || force_copy_to_screen)
|
if ((wd->other.upd_state == core_window_t::update_state::refresh) || force_copy_to_screen)
|
||||||
{
|
{
|
||||||
wndlayout_type::paint(wd, false, false);
|
wndlayout_type::paint(wd, false, false);
|
||||||
this->map(wd);
|
this->map(wd, force_copy_to_screen);
|
||||||
}
|
}
|
||||||
else if (effects::edge_nimbus::none != wd->effect.edge_nimbus)
|
else if (effects::edge_nimbus::none != wd->effect.edge_nimbus)
|
||||||
{
|
{
|
||||||
//Update the nimbus effect
|
//Update the nimbus effect
|
||||||
using nimbus_renderer = detail::edge_nimbus_renderer<core_window_t>;
|
using nimbus_renderer = detail::edge_nimbus_renderer<core_window_t>;
|
||||||
nimbus_renderer::instance().render(wd);
|
nimbus_renderer::instance().render(wd, force_copy_to_screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -935,7 +935,7 @@ namespace detail
|
|||||||
|
|
||||||
if (impl_->wd_register.available(wd))
|
if (impl_->wd_register.available(wd))
|
||||||
{
|
{
|
||||||
wd->flags.capture = true;
|
wd->flags.captured = true;
|
||||||
native_interface::capture_window(wd->root, value);
|
native_interface::capture_window(wd->root, value);
|
||||||
auto prev = attr_.capture.window;
|
auto prev = attr_.capture.window;
|
||||||
if(prev && (prev != wd))
|
if(prev && (prev != wd))
|
||||||
@ -953,6 +953,7 @@ namespace detail
|
|||||||
else if(wd == attr_.capture.window)
|
else if(wd == attr_.capture.window)
|
||||||
{
|
{
|
||||||
attr_.capture.window = nullptr;
|
attr_.capture.window = nullptr;
|
||||||
|
wd->flags.captured = false;
|
||||||
if(attr_cap.size())
|
if(attr_cap.size())
|
||||||
{
|
{
|
||||||
std::pair<core_window_t*, bool> last = attr_cap.back();
|
std::pair<core_window_t*, bool> last = attr_cap.back();
|
||||||
@ -964,6 +965,7 @@ namespace detail
|
|||||||
attr_.capture.ignore_children = last.second;
|
attr_.capture.ignore_children = last.second;
|
||||||
native_interface::capture_window(last.first->root, true);
|
native_interface::capture_window(last.first->root, true);
|
||||||
native_interface::calc_window_point(last.first->root, pos);
|
native_interface::calc_window_point(last.first->root, pos);
|
||||||
|
last.first->flags.captured = true;
|
||||||
attr_.capture.inside = _m_effective(last.first, pos);
|
attr_.capture.inside = _m_effective(last.first, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -476,7 +476,57 @@ namespace nana
|
|||||||
graph.set_pixel(x, y + 5);
|
graph.set_pixel(x, y + 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};//end class arrow_double
|
||||||
|
|
||||||
|
class annex_button
|
||||||
|
: public element_interface
|
||||||
|
{
|
||||||
|
bool draw(graph_reference graph, const ::nana::color& arg_bgcolor, const ::nana::color& fgcolor, const rectangle& r, element_state estate) override
|
||||||
|
{
|
||||||
|
auto bgcolor = arg_bgcolor;
|
||||||
|
|
||||||
|
switch (estate)
|
||||||
|
{
|
||||||
|
case element_state::hovered:
|
||||||
|
case element_state::focus_hovered:
|
||||||
|
bgcolor = arg_bgcolor.blend(colors::white, 0.8);
|
||||||
|
break;
|
||||||
|
case element_state::pressed:
|
||||||
|
bgcolor = arg_bgcolor.blend(colors::black, 0.8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto part_px = (r.height - 3) * 5 / 13;
|
||||||
|
graph.rectangle(r, false, bgcolor.blend(colors::black, 0.6));
|
||||||
|
|
||||||
|
::nana::point left_top{ r.x + 1, r.y + 1 }, right_top{r.right() - 2, r.y + 1};
|
||||||
|
::nana::point left_mid{ r.x + 1, r.y + 1 + static_cast<int>(part_px) }, right_mid{ right_top.x, left_mid.y };
|
||||||
|
::nana::point left_bottom{ r.x + 1, r.bottom() - 2 }, right_bottom{ r.right() - 2, r.bottom() - 2 };
|
||||||
|
|
||||||
|
graph.set_color(bgcolor.blend(colors::white, 0.9));
|
||||||
|
graph.line(left_top, left_mid);
|
||||||
|
graph.line(right_top, right_mid);
|
||||||
|
|
||||||
|
graph.set_color(bgcolor.blend(colors::white, 0.5));
|
||||||
|
graph.line(left_top, right_top);
|
||||||
|
|
||||||
|
left_mid.y++;
|
||||||
|
right_mid.y++;
|
||||||
|
graph.set_color(bgcolor.blend(colors::black, 0.8));
|
||||||
|
graph.line(left_mid, left_bottom);
|
||||||
|
graph.line(right_mid, right_bottom);
|
||||||
|
|
||||||
|
::nana::rectangle part_r{ r.x + 2, r.y + 2, r.width - 4, part_px };
|
||||||
|
graph.rectangle(part_r, true, bgcolor.blend(colors::white, 0.8));
|
||||||
|
|
||||||
|
part_r.y += static_cast<int>(part_r.height);
|
||||||
|
part_r.height = (r.height - 3 - part_r.height);
|
||||||
|
graph.rectangle(part_r, true, bgcolor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};//end class annex_button
|
||||||
}//end namespace element
|
}//end namespace element
|
||||||
|
|
||||||
template<typename ElementInterface>
|
template<typename ElementInterface>
|
||||||
@ -558,10 +608,12 @@ namespace nana
|
|||||||
|
|
||||||
element::add_border<element::border_depressed>("");
|
element::add_border<element::border_depressed>("");
|
||||||
|
|
||||||
element::add_arrow<element::arrowhead>("");
|
element::add_arrow<element::arrowhead>(""); //"arrowhead" in default
|
||||||
element::add_arrow<element::arrow_double>("double");
|
element::add_arrow<element::arrow_double>("double");
|
||||||
element::add_arrow<element::arrow_solid_triangle>("solid_triangle");
|
element::add_arrow<element::arrow_solid_triangle>("solid_triangle");
|
||||||
element::add_arrow<element::arrow_hollow_triangle>("hollow_triangle");
|
element::add_arrow<element::arrow_hollow_triangle>("hollow_triangle");
|
||||||
|
|
||||||
|
element::add_button<element::annex_button>(""); //"annex" in default
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -595,6 +647,16 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return _m_get((name.empty() ? "arrowhead" : name), arrow_).keeper();
|
return _m_get((name.empty() ? "arrowhead" : name), arrow_).keeper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void button(const std::string& name, const pat::cloneable<element::provider::factory_interface<element::element_interface>>& factory)
|
||||||
|
{
|
||||||
|
_m_add((name.empty() ? "annex" : name), button_, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
element::element_interface * const * button(const std::string& name) const
|
||||||
|
{
|
||||||
|
return _m_get((name.empty() ? "annex" : name), button_).keeper();
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
using lock_guard = std::lock_guard<std::recursive_mutex>;
|
using lock_guard = std::lock_guard<std::recursive_mutex>;
|
||||||
|
|
||||||
@ -630,6 +692,7 @@ namespace nana
|
|||||||
item<element::crook_interface> crook_;
|
item<element::crook_interface> crook_;
|
||||||
item<element::border_interface> border_;
|
item<element::border_interface> border_;
|
||||||
item<element::arrow_interface> arrow_;
|
item<element::arrow_interface> arrow_;
|
||||||
|
item<element::element_interface> button_;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace element
|
namespace element
|
||||||
@ -664,6 +727,16 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return element_manager::instance().arrow(name);
|
return element_manager::instance().arrow(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void provider::add_button(const std::string& name, const pat::cloneable<factory_interface<element_interface>>& factory)
|
||||||
|
{
|
||||||
|
element_manager::instance().button(name, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
element_interface* const* provider::keeper_button(const std::string& name)
|
||||||
|
{
|
||||||
|
return element_manager::instance().button(name);
|
||||||
|
}
|
||||||
}//end namespace element
|
}//end namespace element
|
||||||
|
|
||||||
//facades
|
//facades
|
||||||
@ -705,7 +778,7 @@ namespace nana
|
|||||||
|
|
||||||
void facade<element::crook>::switch_to(const char* name)
|
void facade<element::crook>::switch_to(const char* name)
|
||||||
{
|
{
|
||||||
keeper_ = element::provider().keeper_crook(name);
|
keeper_ = element::provider().keeper_crook(name ? name : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool facade<element::crook>::draw(graph_reference graph, const ::nana::color& bgcol, const ::nana::color& fgcol, const nana::rectangle& r, element_state es)
|
bool facade<element::crook>::draw(graph_reference graph, const ::nana::color& bgcol, const ::nana::color& fgcol, const nana::rectangle& r, element_state es)
|
||||||
@ -721,7 +794,7 @@ namespace nana
|
|||||||
|
|
||||||
void facade<element::border>::switch_to(const char* name)
|
void facade<element::border>::switch_to(const char* name)
|
||||||
{
|
{
|
||||||
keeper_ = element::provider().keeper_border(name);
|
keeper_ = element::provider().keeper_border(name ? name : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool facade<element::border>::draw(graph_reference graph, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle& r, element_state es)
|
bool facade<element::border>::draw(graph_reference graph, const nana::color& bgcolor, const nana::color& fgcolor, const nana::rectangle& r, element_state es)
|
||||||
@ -754,6 +827,23 @@ namespace nana
|
|||||||
}
|
}
|
||||||
//end class facade<element::arrow>
|
//end class facade<element::arrow>
|
||||||
|
|
||||||
|
//class facade<element::button>::
|
||||||
|
facade<element::button>::facade(const char* name)
|
||||||
|
: keeper_(element::provider().keeper_button(name ? name : ""))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void facade<element::button>::switch_to(const char* name)
|
||||||
|
{
|
||||||
|
keeper_ = element::provider().keeper_button(name ? name : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Implement element_interface
|
||||||
|
bool facade<element::button>::draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate)
|
||||||
|
{
|
||||||
|
return (*keeper_)->draw(graph, bgcolor, fgcolor, r, estate);
|
||||||
|
}
|
||||||
|
//end class facade<element::button>
|
||||||
|
|
||||||
namespace element
|
namespace element
|
||||||
{
|
{
|
||||||
void set_bground(const char* name, const pat::cloneable<element_interface>& obj)
|
void set_bground(const char* name, const pat::cloneable<element_interface>& obj)
|
||||||
|
|||||||
@ -58,16 +58,15 @@ namespace nana
|
|||||||
class drawer_impl
|
class drawer_impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef nana::paint::graphics & graph_reference;
|
using graph_reference = paint::graphics&;
|
||||||
typedef widget & widget_reference;
|
using widget_reference = widget&;
|
||||||
|
|
||||||
enum class where_t{unknown, text, push_button};
|
enum class where_t{unknown, text, push_button};
|
||||||
enum class state_t{none, mouse_over, pressed};
|
|
||||||
|
|
||||||
drawer_impl()
|
drawer_impl()
|
||||||
{
|
{
|
||||||
state_.focused = false;
|
state_.focused = false;
|
||||||
state_.state = state_t::none;
|
state_.button_state = element_state::normal;
|
||||||
state_.pointer_where = where_t::unknown;
|
state_.pointer_where = where_t::unknown;
|
||||||
state_.lister = nullptr;
|
state_.lister = nullptr;
|
||||||
}
|
}
|
||||||
@ -195,13 +194,13 @@ namespace nana
|
|||||||
|
|
||||||
void set_mouse_over(bool mo)
|
void set_mouse_over(bool mo)
|
||||||
{
|
{
|
||||||
state_.state = mo ? state_t::mouse_over : state_t::none;
|
state_.button_state = (mo ? element_state::hovered : element_state::normal);
|
||||||
state_.pointer_where = where_t::unknown;
|
state_.pointer_where = where_t::unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_mouse_press(bool mp)
|
void set_mouse_press(bool mp)
|
||||||
{
|
{
|
||||||
state_.state = (mp ? state_t::pressed : state_t::mouse_over);
|
state_.button_state = (mp ? element_state::pressed : element_state::hovered);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_focused(bool f)
|
void set_focused(bool f)
|
||||||
@ -310,8 +309,8 @@ namespace nana
|
|||||||
{
|
{
|
||||||
auto pos = API::cursor_position();
|
auto pos = API::cursor_position();
|
||||||
API::calc_window_point(widget_->handle(), pos);
|
API::calc_window_point(widget_->handle(), pos);
|
||||||
if(calc_where(*graph_, pos.x, pos.y))
|
if (calc_where(*graph_, pos.x, pos.y))
|
||||||
state_.state = state_t::none;
|
state_.button_state = element_state::normal;
|
||||||
|
|
||||||
editor_->text(items_[index]->item_text);
|
editor_->text(items_[index]->item_text);
|
||||||
_m_draw_push_button(widget_->enabled());
|
_m_draw_push_button(widget_->enabled());
|
||||||
@ -437,7 +436,8 @@ namespace nana
|
|||||||
::nana::rectangle r(graph.size());
|
::nana::rectangle r(graph.size());
|
||||||
auto clr_from = colors::button_face_shadow_start;
|
auto clr_from = colors::button_face_shadow_start;
|
||||||
auto clr_to = colors::button_face_shadow_end;
|
auto clr_to = colors::button_face_shadow_end;
|
||||||
if(state_.state == state_t::pressed)
|
|
||||||
|
if (element_state::pressed == state_.button_state)
|
||||||
{
|
{
|
||||||
r.pare_off(2);
|
r.pare_off(2);
|
||||||
std::swap(clr_from, clr_to);
|
std::swap(clr_from, clr_to);
|
||||||
@ -450,54 +450,30 @@ namespace nana
|
|||||||
|
|
||||||
void _m_draw_push_button(bool enabled)
|
void _m_draw_push_button(bool enabled)
|
||||||
{
|
{
|
||||||
using namespace nana::paint;
|
::nana::rectangle r{graph_->size()};
|
||||||
|
r.x = r.right() - 16;
|
||||||
|
r.y = 1;
|
||||||
|
r.width = 16;
|
||||||
|
r.height -= 2;
|
||||||
|
|
||||||
if (nullptr == graph_) return;
|
auto estate = state_.button_state;
|
||||||
|
if (enabled && !items_.empty())
|
||||||
int left = graph_->width() - 17;
|
|
||||||
int right = left + 16;
|
|
||||||
int top = 1;
|
|
||||||
int bottom = graph_->height() - 2;
|
|
||||||
int mid = top + (bottom - top) * 5 / 18;
|
|
||||||
|
|
||||||
::nana::color topcol, topcol_ln, botcol, botcol_ln;
|
|
||||||
::nana::color arrow_color{ colors::white };
|
|
||||||
if (enabled && items_.size())
|
|
||||||
{
|
{
|
||||||
double percent = 1;
|
if (has_lister() || (element_state::pressed == estate && state_.pointer_where == where_t::push_button))
|
||||||
if (has_lister() || (state_.state == state_t::pressed && state_.pointer_where == where_t::push_button))
|
estate = element_state::pressed;
|
||||||
percent = 0.8;
|
|
||||||
else if (state_.state == state_t::mouse_over)
|
|
||||||
percent = 0.9;
|
|
||||||
|
|
||||||
topcol_ln = color{ 0x3F, 0x47, 0x6C }.blend(arrow_color, percent);
|
|
||||||
botcol_ln = color{ 0x03, 0x31, 0x114 }.blend(arrow_color, percent);
|
|
||||||
topcol = color{ 0x3F, 83, 84 }.blend(arrow_color, percent);
|
|
||||||
botcol = color{ 0x0c, 0x4a, 0x9a }.blend(arrow_color, percent);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
estate = element_state::disabled;
|
||||||
topcol_ln = { 0x7F, 0x7F, 0x7F };
|
|
||||||
botcol_ln = { 0x50, 0x50, 0x50 };
|
|
||||||
topcol = { 0xC3, 0xC3, 0xC3 };
|
|
||||||
botcol = { 0xA0, 0xA0, 0xA0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
graph_->set_color(topcol_ln);
|
facade<element::button> button;
|
||||||
graph_->line({ left, top }, { left, mid });
|
button.draw(*graph_, ::nana::color{ 3, 65, 140 }, colors::white, r, estate);
|
||||||
graph_->line({ right - 1, top }, { right - 1, mid });
|
|
||||||
|
|
||||||
graph_->set_color(botcol_ln);
|
|
||||||
graph_->line({ left, mid + 1 }, { left, bottom });
|
|
||||||
graph_->line({ right - 1, mid + 1 }, { right - 1, bottom });
|
|
||||||
|
|
||||||
|
|
||||||
graph_->rectangle({ left + 1, top, static_cast<unsigned>(right - left - 2), static_cast<unsigned>(mid - top + 1) }, true, topcol);
|
|
||||||
graph_->rectangle({ left + 1, mid + 1, static_cast<unsigned>(right - left - 2), static_cast<unsigned>(bottom - mid) }, true, botcol);
|
|
||||||
|
|
||||||
facade<element::arrow> arrow("solid_triangle");
|
facade<element::arrow> arrow("solid_triangle");
|
||||||
arrow.direction(::nana::direction::south);
|
arrow.direction(::nana::direction::south);
|
||||||
arrow.draw(*graph_, {}, arrow_color, { left, top + (bottom - top) / 2 - 7, 16, 16 }, element_state::normal);
|
|
||||||
|
r.y += (r.height / 2) - 7;
|
||||||
|
r.width = r.height = 16;
|
||||||
|
arrow.draw(*graph_, {}, colors::white, r, element_state::normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _m_draw_image()
|
void _m_draw_image()
|
||||||
@ -558,7 +534,7 @@ namespace nana
|
|||||||
struct state_type
|
struct state_type
|
||||||
{
|
{
|
||||||
bool focused;
|
bool focused;
|
||||||
state_t state;
|
element_state button_state;
|
||||||
where_t pointer_where;
|
where_t pointer_where;
|
||||||
|
|
||||||
nana::float_listbox * lister;
|
nana::float_listbox * lister;
|
||||||
|
|||||||
@ -66,25 +66,24 @@ namespace nana
|
|||||||
this->monthstr_[index] = str;
|
this->monthstr_[index] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger::where trigger::_m_pos_where(graph_reference graph, int x, int y)
|
trigger::where trigger::_m_pos_where(graph_reference graph, const ::nana::point& pos)
|
||||||
{
|
{
|
||||||
int xend = static_cast<int>(graph.width()) - 1;
|
int xend = static_cast<int>(graph.width()) - 1;
|
||||||
int yend = static_cast<int>(graph.height()) - 1;
|
int yend = static_cast<int>(graph.height()) - 1;
|
||||||
if(0 < y && y < static_cast<int>(topbar_height))
|
if(0 < pos.y && pos.y < static_cast<int>(topbar_height))
|
||||||
{
|
{
|
||||||
if(static_cast<int>(border_size) < x && x < xend)
|
if(static_cast<int>(border_size) < pos.x && pos.x < xend)
|
||||||
{
|
{
|
||||||
if(x < border_size + 16)
|
if(pos.x < border_size + 16)
|
||||||
return where::left_button;
|
return where::left_button;
|
||||||
else if(xend - border_size - 16 < x)
|
else if(xend - border_size - 16 < pos.x)
|
||||||
return where::right_button;
|
return where::right_button;
|
||||||
return where::topbar;
|
return where::topbar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(topbar_height < y && y < yend)
|
else if(topbar_height < pos.y && pos.y < yend)
|
||||||
{
|
{
|
||||||
trace_pos_.x = x;
|
trace_pos_ = pos;
|
||||||
trace_pos_.y = y;
|
|
||||||
return where::textarea;
|
return where::textarea;
|
||||||
}
|
}
|
||||||
return where::none;
|
return where::none;
|
||||||
@ -476,7 +475,7 @@ namespace nana
|
|||||||
|
|
||||||
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
|
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
|
||||||
{
|
{
|
||||||
where pos = _m_pos_where(graph, arg.pos.x, arg.pos.y);
|
where pos = _m_pos_where(graph, arg.pos);
|
||||||
if(pos == pos_ && pos_ != where::textarea) return;
|
if(pos == pos_ && pos_ != where::textarea) return;
|
||||||
pos_ = pos;
|
pos_ = pos;
|
||||||
_m_draw(graph);
|
_m_draw(graph);
|
||||||
@ -494,7 +493,7 @@ namespace nana
|
|||||||
void trigger::mouse_up(graph_reference graph, const arg_mouse& arg)
|
void trigger::mouse_up(graph_reference graph, const arg_mouse& arg)
|
||||||
{
|
{
|
||||||
bool redraw = true;
|
bool redraw = true;
|
||||||
where pos = _m_pos_where(graph, arg.pos.x, arg.pos.y);
|
where pos = _m_pos_where(graph, arg.pos);
|
||||||
transform_action tfid = transform_action::none;
|
transform_action tfid = transform_action::none;
|
||||||
|
|
||||||
if(pos == where::topbar)
|
if(pos == where::topbar)
|
||||||
|
|||||||
483
source/gui/widgets/spinbox.cpp
Normal file
483
source/gui/widgets/spinbox.cpp
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
/*
|
||||||
|
* A Spin box widget
|
||||||
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
|
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*
|
||||||
|
* @file: nana/gui/widgets/spanbox.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nana/gui/widgets/spinbox.hpp>
|
||||||
|
#include <nana/gui/widgets/skeletons/text_editor.hpp>
|
||||||
|
#include <nana/gui/element.hpp>
|
||||||
|
#include <nana/gui/timer.hpp>
|
||||||
|
|
||||||
|
namespace nana
|
||||||
|
{
|
||||||
|
namespace drawerbase
|
||||||
|
{
|
||||||
|
namespace spinbox
|
||||||
|
{
|
||||||
|
enum class buttons
|
||||||
|
{
|
||||||
|
none, increase, decrease
|
||||||
|
};
|
||||||
|
|
||||||
|
class range_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~range_interface() = default;
|
||||||
|
|
||||||
|
virtual std::wstring value() const = 0;
|
||||||
|
virtual void spin(bool increase) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class range_numeric
|
||||||
|
: public range_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
range_numeric(T vbegin, T vlast, T step)
|
||||||
|
: begin_{ vbegin }, last_{ vlast }, step_{ step }, value_{ vbegin }
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::wstring value() const override
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << value_;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void spin(bool increase) override
|
||||||
|
{
|
||||||
|
if (increase)
|
||||||
|
{
|
||||||
|
value_ += step_;
|
||||||
|
if (value_ > last_)
|
||||||
|
value_ = last_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value_ -= step_;
|
||||||
|
if (value_ < begin_)
|
||||||
|
value_ = begin_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
T begin_;
|
||||||
|
T last_;
|
||||||
|
T step_;
|
||||||
|
T value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class range_text
|
||||||
|
: public range_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
range_text(std::initializer_list<std::string> & initlist)
|
||||||
|
{
|
||||||
|
for (auto & s : initlist)
|
||||||
|
{
|
||||||
|
texts_.emplace_back(::nana::charset(s, ::nana::unicode::utf8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
range_text(std::initializer_list<std::wstring>& initlist)
|
||||||
|
: texts_(initlist)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::wstring value() const override
|
||||||
|
{
|
||||||
|
if (texts_.empty())
|
||||||
|
return{};
|
||||||
|
|
||||||
|
return texts_[pos_];
|
||||||
|
}
|
||||||
|
|
||||||
|
void spin(bool increase) override
|
||||||
|
{
|
||||||
|
if (texts_.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (increase)
|
||||||
|
{
|
||||||
|
++pos_;
|
||||||
|
if (texts_.size() <= pos_)
|
||||||
|
pos_ = texts_.size() - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--pos_;
|
||||||
|
if (texts_.size() <= pos_)
|
||||||
|
pos_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::vector<std::wstring> texts_;
|
||||||
|
std::size_t pos_{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
class implementation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
implementation()
|
||||||
|
{
|
||||||
|
//Sets a timer for continous spin when mouse button is pressed.
|
||||||
|
timer_.elapse([this]
|
||||||
|
{
|
||||||
|
range_->spin(buttons::increase == spin_stated_);
|
||||||
|
_m_text();
|
||||||
|
API::update_window(editor_->window_handle());
|
||||||
|
|
||||||
|
auto intv = timer_.interval();
|
||||||
|
if (intv > 50)
|
||||||
|
timer_.interval(intv / 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
timer_.interval(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void attach(::nana::widget& wdg, ::nana::paint::graphics& graph)
|
||||||
|
{
|
||||||
|
auto wd = wdg.handle();
|
||||||
|
graph_ = &graph;
|
||||||
|
auto scheme = static_cast<::nana::widgets::skeletons::text_editor_scheme*>(API::dev::get_scheme(wd));
|
||||||
|
editor_ = new ::nana::widgets::skeletons::text_editor(wd, graph, scheme);
|
||||||
|
editor_->multi_lines(false);
|
||||||
|
|
||||||
|
if (!range_)
|
||||||
|
range_.reset(new range_numeric<int>(0, 100, 1));
|
||||||
|
|
||||||
|
_m_text();
|
||||||
|
|
||||||
|
API::tabstop(wd);
|
||||||
|
API::eat_tabstop(wd, true);
|
||||||
|
API::effects_edge_nimbus(wd, effects::edge_nimbus::active);
|
||||||
|
API::effects_edge_nimbus(wd, effects::edge_nimbus::over);
|
||||||
|
_m_reset_text_area();
|
||||||
|
}
|
||||||
|
|
||||||
|
void detach()
|
||||||
|
{
|
||||||
|
delete editor_;
|
||||||
|
editor_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_range(std::unique_ptr<range_interface> ptr)
|
||||||
|
{
|
||||||
|
range_.swap(ptr);
|
||||||
|
|
||||||
|
_m_text();
|
||||||
|
}
|
||||||
|
|
||||||
|
void qualify(std::wstring&& prefix, std::wstring&& suffix)
|
||||||
|
{
|
||||||
|
surround_.prefix = std::move(prefix);
|
||||||
|
surround_.suffix = std::move(suffix);
|
||||||
|
|
||||||
|
if (editor_)
|
||||||
|
{
|
||||||
|
_m_text();
|
||||||
|
API::update_window(editor_->window_handle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render()
|
||||||
|
{
|
||||||
|
editor_->render(API::is_focus_window(editor_->window_handle()));
|
||||||
|
_m_draw_spins(spin_stated_);
|
||||||
|
}
|
||||||
|
|
||||||
|
::nana::widgets::skeletons::text_editor* editor() const
|
||||||
|
{
|
||||||
|
return editor_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_wheel(bool upwards)
|
||||||
|
{
|
||||||
|
range_->spin(!upwards);
|
||||||
|
_m_text();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mouse_button(const ::nana::arg_mouse& arg, bool pressed)
|
||||||
|
{
|
||||||
|
if (!pressed)
|
||||||
|
{
|
||||||
|
API::capture_window(editor_->window_handle(), false);
|
||||||
|
timer_.stop();
|
||||||
|
timer_.interval(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buttons::none != spin_stated_)
|
||||||
|
{
|
||||||
|
//Spins the value when mouse button is released
|
||||||
|
if (pressed)
|
||||||
|
{
|
||||||
|
API::capture_window(editor_->window_handle(), true);
|
||||||
|
range_->spin(buttons::increase == spin_stated_);
|
||||||
|
_m_text();
|
||||||
|
timer_.start();
|
||||||
|
}
|
||||||
|
_m_draw_spins(spin_stated_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool refreshed = false;
|
||||||
|
if (pressed)
|
||||||
|
refreshed = editor_->mouse_down(arg.left_button, arg.pos);
|
||||||
|
else
|
||||||
|
refreshed = editor_->mouse_up(arg.left_button, arg.pos);
|
||||||
|
|
||||||
|
if (refreshed)
|
||||||
|
_m_draw_spins(buttons::none);
|
||||||
|
|
||||||
|
return refreshed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mouse_move(bool left_button, const ::nana::point& pos)
|
||||||
|
{
|
||||||
|
if (editor_->mouse_move(left_button, pos))
|
||||||
|
{
|
||||||
|
editor_->reset_caret();
|
||||||
|
render();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto btn = _m_where(pos);
|
||||||
|
if (buttons::none != btn)
|
||||||
|
{
|
||||||
|
spin_stated_ = btn;
|
||||||
|
_m_draw_spins(btn);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (buttons::none != spin_stated_)
|
||||||
|
{
|
||||||
|
spin_stated_ = buttons::none;
|
||||||
|
_m_draw_spins(buttons::none);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void _m_text()
|
||||||
|
{
|
||||||
|
if (editor_)
|
||||||
|
{
|
||||||
|
std::wstring text = surround_.prefix + range_->value() + surround_.suffix;
|
||||||
|
editor_->text(std::move(text));
|
||||||
|
_m_draw_spins(spin_stated_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _m_reset_text_area()
|
||||||
|
{
|
||||||
|
auto spins_r = _m_spins_area();
|
||||||
|
if (spins_r.x == 0)
|
||||||
|
editor_->text_area({});
|
||||||
|
else
|
||||||
|
editor_->text_area({ 2, 2, graph_->width() - spins_r.width - 2, spins_r.height - 2 });
|
||||||
|
}
|
||||||
|
|
||||||
|
::nana::rectangle _m_spins_area() const
|
||||||
|
{
|
||||||
|
auto size = API::window_size(editor_->window_handle());
|
||||||
|
if (size.width > 18)
|
||||||
|
return{ static_cast<int>(size.width - 16), 0, 16, size.height };
|
||||||
|
|
||||||
|
return{ 0, 0, size.width, size.height };
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons _m_where(const ::nana::point& pos) const
|
||||||
|
{
|
||||||
|
auto spins_r = _m_spins_area();
|
||||||
|
if (spins_r.is_hit(pos))
|
||||||
|
{
|
||||||
|
if (pos.y < spins_r.y + static_cast<int>(spins_r.height / 2))
|
||||||
|
return buttons::increase;
|
||||||
|
|
||||||
|
return buttons::decrease;
|
||||||
|
}
|
||||||
|
return buttons::none;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _m_draw_spins(buttons spins)
|
||||||
|
{
|
||||||
|
auto estate = API::element_state(editor_->window_handle());
|
||||||
|
|
||||||
|
auto spin_r0 = _m_spins_area();
|
||||||
|
spin_r0.height /= 2;
|
||||||
|
|
||||||
|
auto spin_r1 = spin_r0;
|
||||||
|
spin_r1.y += static_cast<int>(spin_r0.height);
|
||||||
|
spin_r1.height = _m_spins_area().height - spin_r0.height;
|
||||||
|
|
||||||
|
::nana::color bgcolor{ 3, 65, 140 };
|
||||||
|
facade<element::arrow> arrow;
|
||||||
|
facade<element::button> button;
|
||||||
|
|
||||||
|
auto spin_state = (buttons::increase == spins ? estate : element_state::normal);
|
||||||
|
button.draw(*graph_, bgcolor, colors::white, spin_r0, spin_state);
|
||||||
|
spin_r0.x += 5;
|
||||||
|
arrow.draw(*graph_, bgcolor, colors::white, spin_r0, spin_state);
|
||||||
|
|
||||||
|
spin_state = (buttons::decrease == spins ? estate : element_state::normal);
|
||||||
|
button.draw(*graph_, bgcolor, colors::white, spin_r1, spin_state);
|
||||||
|
spin_r1.x += 5;
|
||||||
|
arrow.direction(direction::south);
|
||||||
|
arrow.draw(*graph_, bgcolor, colors::white, spin_r1, spin_state);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
::nana::paint::graphics * graph_{nullptr};
|
||||||
|
::nana::widgets::skeletons::text_editor * editor_{nullptr};
|
||||||
|
buttons spin_stated_{ buttons::none };
|
||||||
|
std::unique_ptr<range_interface> range_;
|
||||||
|
::nana::timer timer_;
|
||||||
|
|
||||||
|
struct surround_data
|
||||||
|
{
|
||||||
|
std::wstring prefix;
|
||||||
|
std::wstring suffix;
|
||||||
|
}surround_;
|
||||||
|
};
|
||||||
|
|
||||||
|
//class drawer
|
||||||
|
drawer::drawer()
|
||||||
|
: impl_(new implementation)
|
||||||
|
{}
|
||||||
|
|
||||||
|
drawer::~drawer()
|
||||||
|
{
|
||||||
|
delete impl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
implementation* drawer::impl() const
|
||||||
|
{
|
||||||
|
return impl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Overrides drawer_trigger
|
||||||
|
void drawer::attached(widget_reference wdg, graph_reference graph)
|
||||||
|
{
|
||||||
|
impl_->attach(wdg, graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer::refresh(graph_reference)
|
||||||
|
{
|
||||||
|
impl_->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer::focus(graph_reference, const arg_focus&)
|
||||||
|
{
|
||||||
|
impl_->render();
|
||||||
|
impl_->editor()->reset_caret();
|
||||||
|
API::lazy_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer::mouse_wheel(graph_reference, const arg_wheel& arg)
|
||||||
|
{
|
||||||
|
impl_->mouse_wheel(arg.upwards);
|
||||||
|
impl_->editor()->reset_caret();
|
||||||
|
API::lazy_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer::mouse_down(graph_reference, const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
if (impl_->mouse_button(arg, true))
|
||||||
|
API::lazy_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer::mouse_up(graph_reference, const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
if (impl_->mouse_button(arg, false))
|
||||||
|
API::lazy_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer::mouse_move(graph_reference, const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
if (impl_->mouse_move(arg.left_button, arg.pos))
|
||||||
|
API::lazy_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer::mouse_leave(graph_reference, const arg_mouse&)
|
||||||
|
{
|
||||||
|
impl_->render();
|
||||||
|
API::lazy_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}//end namespace drawerbase
|
||||||
|
|
||||||
|
spinbox::spinbox()
|
||||||
|
{}
|
||||||
|
|
||||||
|
spinbox::spinbox(window wd, bool visible)
|
||||||
|
{
|
||||||
|
this->create(wd, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
spinbox::spinbox(window wd, const nana::rectangle& r, bool visible)
|
||||||
|
{
|
||||||
|
this->create(wd, r, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinbox::range(int begin, int last, int step)
|
||||||
|
{
|
||||||
|
using namespace drawerbase::spinbox;
|
||||||
|
get_drawer_trigger().impl()->set_range(std::unique_ptr<range_interface>(new range_numeric<int>(begin, last, step)));
|
||||||
|
API::refresh_window(handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinbox::range(double begin, double last, double step)
|
||||||
|
{
|
||||||
|
using namespace drawerbase::spinbox;
|
||||||
|
get_drawer_trigger().impl()->set_range(std::unique_ptr<range_interface>(new range_numeric<double>(begin, last, step)));
|
||||||
|
API::refresh_window(handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinbox::range(std::initializer_list<std::string> steps_utf8)
|
||||||
|
{
|
||||||
|
using namespace drawerbase::spinbox;
|
||||||
|
get_drawer_trigger().impl()->set_range(std::unique_ptr<range_interface>(new range_text(steps_utf8)));
|
||||||
|
API::refresh_window(handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinbox::range(std::initializer_list<std::wstring> steps)
|
||||||
|
{
|
||||||
|
using namespace drawerbase::spinbox;
|
||||||
|
get_drawer_trigger().impl()->set_range(std::unique_ptr<range_interface>(new range_text(steps)));
|
||||||
|
API::refresh_window(handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinbox::qualify(std::wstring prefix, std::wstring suffix)
|
||||||
|
{
|
||||||
|
get_drawer_trigger().impl()->qualify(std::move(prefix), std::move(suffix));
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinbox::qualify(const std::string & prefix_utf8, const std::string& suffix_utf8)
|
||||||
|
{
|
||||||
|
qualify(static_cast<std::wstring>(::nana::charset(prefix_utf8, ::nana::unicode::utf8)), static_cast<std::wstring>(::nana::charset(suffix_utf8, ::nana::unicode::utf8)));
|
||||||
|
}
|
||||||
|
|
||||||
|
::nana::string spinbox::_m_caption() const
|
||||||
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
auto editor = get_drawer_trigger().impl()->editor();
|
||||||
|
return (editor ? editor->text() : nana::string());
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinbox::_m_caption(::nana::string&& text)
|
||||||
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
auto editor = get_drawer_trigger().impl()->editor();
|
||||||
|
if (editor)
|
||||||
|
{
|
||||||
|
editor->text(std::move(text));
|
||||||
|
API::refresh_window(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//end namespace nana
|
||||||
Loading…
x
Reference in New Issue
Block a user