Merge branch 'develop'

This commit is contained in:
Jinhao 2015-08-06 02:35:09 +08:00
commit c059bd256a
105 changed files with 5805 additions and 2342 deletions

View File

@ -123,7 +123,7 @@ execute_process(COMMAND ${CMAKE_COMMAND}
${CMAKE_CURRENT_SOURCE_DIR}/include/nana/)
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(NANA_SOURCE_DIR ${CMAKE_SOURCE_DIR}/source)
@ -161,3 +161,5 @@ install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib)
install(DIRECTORY ${NANA_INCLUDE_DIR}/nana DESTINATION include)
set_property( TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14 )

View File

@ -81,6 +81,7 @@
<Unit filename="../../source/gui/widgets/float_listbox.cpp" />
<Unit filename="../../source/gui/widgets/form.cpp" />
<Unit filename="../../source/gui/widgets/frame.cpp" />
<Unit filename="../../source/gui/widgets/group.cpp" />
<Unit filename="../../source/gui/widgets/label.cpp" />
<Unit filename="../../source/gui/widgets/listbox.cpp" />
<Unit filename="../../source/gui/widgets/menu.cpp" />

View File

@ -1,34 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_layout_file>
<ActiveTarget name="Debug" />
<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\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="27717" topLine="1044" />
</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\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\animation.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1164" topLine="43" />
</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">
<Cursor>
<Cursor1 position="11188" topLine="459" />
<Cursor1 position="5894" topLine="205" />
</Cursor>
</File>
<File name="..\..\source\gui\detail\native_window_interface.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
@ -36,86 +11,51 @@
<Cursor1 position="4901" topLine="171" />
</Cursor>
</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">
<Cursor>
<Cursor1 position="2244" topLine="84" />
</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">
<Cursor>
<Cursor1 position="5198" topLine="161" />
</Cursor>
</File>
<File name="..\..\source\gui\widgets\treebox.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="15535" topLine="539" />
</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">
<Cursor>
<Cursor1 position="30124" topLine="1046" />
</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">
<Cursor>
<Cursor1 position="12428" topLine="532" />
</Cursor>
</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\gui\widgets\menu.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="27717" topLine="1044" />
</Cursor>
</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\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\audio\detail\audio_device.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6256" topLine="215" />
</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\categorize.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6160" topLine="196" />
</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\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\gui\widgets\checkbox.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6998" topLine="275" />
</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\gui\widgets\combox.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="16572" topLine="610" />
</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">
<Cursor>
<Cursor1 position="457" topLine="3" />
</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" />
@ -126,9 +66,19 @@
<Cursor1 position="5022" topLine="159" />
</Cursor>
</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">
<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="5894" topLine="205" />
<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">
<Cursor>
<Cursor1 position="11188" topLine="459" />
</Cursor>
</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">
<Cursor>
<Cursor1 position="2244" topLine="84" />
</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">
@ -136,19 +86,69 @@
<Cursor1 position="587" topLine="2" />
</Cursor>
</File>
<File name="..\..\source\gui\widgets\treebox.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="15535" topLine="539" />
</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\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\listbox.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="12428" topLine="532" />
</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>
<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>
<Cursor1 position="6160" topLine="196" />
</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">
<Cursor>
<Cursor1 position="1164" topLine="43" />
</Cursor>
</File>
<File name="..\..\source\gui\widgets\checkbox.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6998" topLine="275" />
</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">
<Cursor>
<Cursor1 position="6256" topLine="215" />
</Cursor>
</File>
<File name="..\..\source\gui\widgets\combox.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="16572" topLine="610" />
</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">
<Cursor>
<Cursor1 position="457" topLine="3" />
</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\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>
</CodeBlocks_layout_file>

View File

@ -67,24 +67,32 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>../bin/vc2013/</OutDir>
<OutDir>../bin/</OutDir>
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
<SourcePath>..\..\source;$(VC_SourcePath);</SourcePath>
<TargetName>$(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)</TargetName>
<IntDir>..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
<SourcePath>..\..\source;$(VC_SourcePath);</SourcePath>
<OutDir>../bin/vc2013/</OutDir>
<OutDir>../bin/</OutDir>
<TargetName>$(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)</TargetName>
<IntDir>..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>../bin/vc2013/</OutDir>
<OutDir>../bin/</OutDir>
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
<SourcePath>..\..\source;$(VC_SourcePath);</SourcePath>
<TargetName>$(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)</TargetName>
<IntDir>..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
<SourcePath>..\..\source;$(VC_SourcePath);</SourcePath>
<OutDir>../bin/vc2013/</OutDir>
<OutDir>../bin/</OutDir>
<TargetName>$(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)</TargetName>
<IntDir>..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -102,7 +110,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<OutputFile>$(OutDir)\nana_$(ConfigurationName)_$(PlatformShortName).lib</OutputFile>
<OutputFile>$(TargetPath)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -119,7 +127,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<OutputFile>$(OutDir)\nana_$(ConfigurationName)_$(PlatformShortName).lib</OutputFile>
<OutputFile>$(TargetPath)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -141,7 +149,7 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<OutputFile>$(OutDir)\nana_$(ConfigurationName)_$(PlatformShortName).lib</OutputFile>
<OutputFile>$(TargetPath)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -162,7 +170,7 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<OutputFile>$(OutDir)\nana_$(ConfigurationName)_$(PlatformShortName).lib</OutputFile>
<OutputFile>$(TargetPath)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
@ -177,6 +185,7 @@
<ClCompile Include="..\..\source\deploy.cpp" />
<ClCompile Include="..\..\source\detail\win32\platform_spec.cpp" />
<ClCompile Include="..\..\source\exceptions.cpp" />
<ClCompile Include="..\..\source\filesystem\filesystem.cpp" />
<ClCompile Include="..\..\source\filesystem\file_iterator.cpp" />
<ClCompile Include="..\..\source\filesystem\fs_utility.cpp" />
<ClCompile Include="..\..\source\gui\animation.cpp" />
@ -213,6 +222,7 @@
<ClCompile Include="..\..\source\gui\widgets\float_listbox.cpp" />
<ClCompile Include="..\..\source\gui\widgets\form.cpp" />
<ClCompile Include="..\..\source\gui\widgets\frame.cpp" />
<ClCompile Include="..\..\source\gui\widgets\group.cpp" />
<ClCompile Include="..\..\source\gui\widgets\label.cpp" />
<ClCompile Include="..\..\source\gui\widgets\listbox.cpp" />
<ClCompile Include="..\..\source\gui\widgets\menu.cpp" />
@ -247,7 +257,130 @@
<ClCompile Include="..\..\source\traits.cpp" />
<ClCompile Include="..\..\source\unicode_bidi.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\nana\any.hpp" />
<ClInclude Include="..\..\include\nana\audio\detail\audio_device.hpp" />
<ClInclude Include="..\..\include\nana\audio\detail\audio_stream.hpp" />
<ClInclude Include="..\..\include\nana\audio\detail\buffer_preparation.hpp" />
<ClInclude Include="..\..\include\nana\audio\player.hpp" />
<ClInclude Include="..\..\include\nana\basic_types.hpp" />
<ClInclude Include="..\..\include\nana\charset.hpp" />
<ClInclude Include="..\..\include\nana\concepts.hpp" />
<ClInclude Include="..\..\include\nana\config.hpp" />
<ClInclude Include="..\..\include\nana\datetime.hpp" />
<ClInclude Include="..\..\include\nana\deploy.hpp" />
<ClInclude Include="..\..\include\nana\detail\linux_X11\msg_dispatcher.hpp" />
<ClInclude Include="..\..\include\nana\detail\linux_X11\msg_packet.hpp" />
<ClInclude Include="..\..\include\nana\detail\linux_X11\platform_spec.hpp" />
<ClInclude Include="..\..\include\nana\detail\win32\platform_spec.hpp" />
<ClInclude Include="..\..\include\nana\exceptions.hpp" />
<ClInclude Include="..\..\include\nana\extrlib\png.h" />
<ClInclude Include="..\..\include\nana\extrlib\pngconf.h" />
<ClInclude Include="..\..\include\nana\extrlib\pnglibconf.h" />
<ClInclude Include="..\..\include\nana\extrlib\zlib.h" />
<ClInclude Include="..\..\include\nana\filesystem\filesystem.hpp" />
<ClInclude Include="..\..\include\nana\filesystem\file_iterator.hpp" />
<ClInclude Include="..\..\include\nana\filesystem\fs_utility.hpp" />
<ClInclude Include="..\..\include\nana\fwd.hpp" />
<ClInclude Include="..\..\include\nana\gui.hpp" />
<ClInclude Include="..\..\include\nana\gui\animation.hpp" />
<ClInclude Include="..\..\include\nana\gui\basis.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\basic_window.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\bedrock.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\bedrock_pi_data.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\color_schemes.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\drawer.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\dynamic_drawing_object.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\effects_renderer.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\element_store.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\events_holder.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\events_operation.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\event_code.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\general_events.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\handle_manager.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\inner_fwd.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\inner_fwd_implement.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\internal_scope_guard.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\native_window_interface.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\runtime_manager.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\widget_colors.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\window_layout.hpp" />
<ClInclude Include="..\..\include\nana\gui\detail\window_manager.hpp" />
<ClInclude Include="..\..\include\nana\gui\dragger.hpp" />
<ClInclude Include="..\..\include\nana\gui\drawing.hpp" />
<ClInclude Include="..\..\include\nana\gui\effects.hpp" />
<ClInclude Include="..\..\include\nana\gui\element.hpp" />
<ClInclude Include="..\..\include\nana\gui\filebox.hpp" />
<ClInclude Include="..\..\include\nana\gui\layout_utility.hpp" />
<ClInclude Include="..\..\include\nana\gui\msgbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\notifier.hpp" />
<ClInclude Include="..\..\include\nana\gui\place.hpp" />
<ClInclude Include="..\..\include\nana\gui\programming_interface.hpp" />
<ClInclude Include="..\..\include\nana\gui\screen.hpp" />
<ClInclude Include="..\..\include\nana\gui\state_cursor.hpp" />
<ClInclude Include="..\..\include\nana\gui\timer.hpp" />
<ClInclude Include="..\..\include\nana\gui\tooltip.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\button.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\categorize.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\checkbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\combox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\date_chooser.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\detail\compset.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\detail\tree_cont.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\float_listbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\form.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\frame.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\group.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\label.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\listbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\menu.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\menubar.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\panel.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\picture.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\progress.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\scroll.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\textbase.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\textbase_export_interface.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\text_editor.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\text_editor_scheme.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\text_token_stream.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\slider.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\spinbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\tabbar.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\textbox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\toolbar.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\treebox.hpp" />
<ClInclude Include="..\..\include\nana\gui\widgets\widget.hpp" />
<ClInclude Include="..\..\include\nana\gui\wvl.hpp" />
<ClInclude Include="..\..\include\nana\internationalization.hpp" />
<ClInclude Include="..\..\include\nana\key_type.hpp" />
<ClInclude Include="..\..\include\nana\paint\detail\image_bmp.hpp" />
<ClInclude Include="..\..\include\nana\paint\detail\image_ico.hpp" />
<ClInclude Include="..\..\include\nana\paint\detail\image_impl_interface.hpp" />
<ClInclude Include="..\..\include\nana\paint\detail\image_png.hpp" />
<ClInclude Include="..\..\include\nana\paint\detail\image_processor.hpp" />
<ClInclude Include="..\..\include\nana\paint\detail\image_process_provider.hpp" />
<ClInclude Include="..\..\include\nana\paint\detail\native_paint_interface.hpp" />
<ClInclude Include="..\..\include\nana\paint\gadget.hpp" />
<ClInclude Include="..\..\include\nana\paint\graphics.hpp" />
<ClInclude Include="..\..\include\nana\paint\image.hpp" />
<ClInclude Include="..\..\include\nana\paint\image_process_interface.hpp" />
<ClInclude Include="..\..\include\nana\paint\image_process_selector.hpp" />
<ClInclude Include="..\..\include\nana\paint\pixel_buffer.hpp" />
<ClInclude Include="..\..\include\nana\paint\text_renderer.hpp" />
<ClInclude Include="..\..\include\nana\pat\cloneable.hpp" />
<ClInclude Include="..\..\include\nana\std_condition_variable.hpp" />
<ClInclude Include="..\..\include\nana\std_mutex.hpp" />
<ClInclude Include="..\..\include\nana\std_thread.hpp" />
<ClInclude Include="..\..\include\nana\system\dataexch.hpp" />
<ClInclude Include="..\..\include\nana\system\platform.hpp" />
<ClInclude Include="..\..\include\nana\system\shared_wrapper.hpp" />
<ClInclude Include="..\..\include\nana\system\timepiece.hpp" />
<ClInclude Include="..\..\include\nana\threads\pool.hpp" />
<ClInclude Include="..\..\include\nana\traits.hpp" />
<ClInclude Include="..\..\include\nana\unicode_bidi.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -58,6 +58,51 @@
<Filter Include="Source Files\nana\threads">
<UniqueIdentifier>{e95b4a72-643f-4416-af95-b0bbaf7f0c57}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\gui">
<UniqueIdentifier>{d421a05b-b868-4c3d-bdac-ff57d09f8d07}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\gui\widgets">
<UniqueIdentifier>{64c22f90-dce2-40dc-be98-edc9fe8951e8}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\gui\detail">
<UniqueIdentifier>{91301ff5-79ac-40cc-a6db-bca2097ea763}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\gui\widgets\detail">
<UniqueIdentifier>{81c62a28-ef5f-43f7-a6ce-e6c186cb411a}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\gui\widgets\skeletons">
<UniqueIdentifier>{4a1db6f0-a4ee-4514-8e89-54ef9d52e3b8}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\detail">
<UniqueIdentifier>{c92e890a-ffd5-4efd-8b37-78ed9bbea1e1}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\detail\win32">
<UniqueIdentifier>{63401f37-26a3-423e-87e6-6840344c3056}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\detail\linux_X11">
<UniqueIdentifier>{61385c08-f06b-4cf3-8e05-9b47d546164b}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\extrlib">
<UniqueIdentifier>{e9eadc97-4a14-4a4e-bb52-52d3a20e2693}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\filesystem">
<UniqueIdentifier>{5667eac1-0887-4936-9502-eac4dd8c1c1d}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\paint">
<UniqueIdentifier>{e6c4a4d9-b4b5-4c56-bb2a-486f3f777ecb}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\paint\detail">
<UniqueIdentifier>{ac132633-f80c-4983-8e47-fa7fc17f666e}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\pat">
<UniqueIdentifier>{ee3e9e63-7221-409e-9659-25864e576e16}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\system">
<UniqueIdentifier>{ef87057b-dff2-40aa-a05e-9dcd0b335c30}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\threads">
<UniqueIdentifier>{8ea232cf-bd7c-47e3-a694-6a8898b677d7}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\source\audio\detail\audio_device.cpp">
@ -74,6 +119,9 @@
</ClCompile>
<ClCompile Include="..\..\source\detail\win32\platform_spec.cpp">
<Filter>Source Files\nana\detail\win32</Filter>
</ClCompile>
<ClCompile Include="..\..\source\filesystem\filesystem.cpp">
<Filter>Source Files\nana\filesystem</Filter>
</ClCompile>
<ClCompile Include="..\..\source\filesystem\file_iterator.cpp">
<Filter>Source Files\nana\filesystem</Filter>
@ -301,4 +349,374 @@
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
</ItemGroup>
</Project>
<ItemGroup>
<ClCompile Include="..\..\source\gui\widgets\group.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\nana\gui\widgets\button.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\categorize.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\checkbox.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\combox.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\date_chooser.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\float_listbox.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\form.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\frame.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\label.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\listbox.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\menu.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\menubar.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\panel.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\picture.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\progress.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\scroll.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\slider.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\spinbox.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\tabbar.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\textbox.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\toolbar.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\treebox.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\widget.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\basic_window.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\bedrock.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\bedrock_pi_data.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\color_schemes.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\drawer.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\dynamic_drawing_object.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\effects_renderer.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\element_store.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\event_code.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\events_holder.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\events_operation.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\general_events.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\handle_manager.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\inner_fwd.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\inner_fwd_implement.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\internal_scope_guard.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\native_window_interface.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\runtime_manager.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\widget_colors.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\window_layout.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\detail\window_manager.hpp">
<Filter>Header Files\gui\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\animation.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\basis.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\dragger.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\drawing.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\effects.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\element.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\filebox.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\layout_utility.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\msgbox.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\notifier.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\place.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\programming_interface.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\screen.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\state_cursor.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\timer.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\tooltip.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\wvl.hpp">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\detail\compset.hpp">
<Filter>Header Files\gui\widgets\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\detail\tree_cont.hpp">
<Filter>Header Files\gui\widgets\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\text_editor.hpp">
<Filter>Header Files\gui\widgets\skeletons</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\text_editor_scheme.hpp">
<Filter>Header Files\gui\widgets\skeletons</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\text_token_stream.hpp">
<Filter>Header Files\gui\widgets\skeletons</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\textbase.hpp">
<Filter>Header Files\gui\widgets\skeletons</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\skeletons\textbase_export_interface.hpp">
<Filter>Header Files\gui\widgets\skeletons</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\any.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\basic_types.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\charset.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\concepts.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\config.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\datetime.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\deploy.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\exceptions.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\fwd.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\internationalization.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\key_type.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\std_condition_variable.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\std_mutex.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\std_thread.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\traits.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\unicode_bidi.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\audio\detail\audio_device.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\audio\detail\audio_stream.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\audio\detail\buffer_preparation.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\audio\player.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\detail\linux_X11\msg_dispatcher.hpp">
<Filter>Header Files\detail\linux_X11</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\detail\linux_X11\msg_packet.hpp">
<Filter>Header Files\detail\linux_X11</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\detail\linux_X11\platform_spec.hpp">
<Filter>Header Files\detail\linux_X11</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\detail\win32\platform_spec.hpp">
<Filter>Header Files\detail\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\extrlib\png.h">
<Filter>Header Files\extrlib</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\extrlib\pngconf.h">
<Filter>Header Files\extrlib</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\extrlib\pnglibconf.h">
<Filter>Header Files\extrlib</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\extrlib\zlib.h">
<Filter>Header Files\extrlib</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\filesystem\filesystem.hpp">
<Filter>Header Files\filesystem</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\filesystem\file_iterator.hpp">
<Filter>Header Files\filesystem</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\filesystem\fs_utility.hpp">
<Filter>Header Files\filesystem</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\gadget.hpp">
<Filter>Header Files\paint</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\graphics.hpp">
<Filter>Header Files\paint</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\image.hpp">
<Filter>Header Files\paint</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\image_process_interface.hpp">
<Filter>Header Files\paint</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\image_process_selector.hpp">
<Filter>Header Files\paint</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\pixel_buffer.hpp">
<Filter>Header Files\paint</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\text_renderer.hpp">
<Filter>Header Files\paint</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\detail\image_ico.hpp">
<Filter>Header Files\paint\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\detail\image_impl_interface.hpp">
<Filter>Header Files\paint\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\detail\image_png.hpp">
<Filter>Header Files\paint\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\detail\image_process_provider.hpp">
<Filter>Header Files\paint\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\detail\image_processor.hpp">
<Filter>Header Files\paint\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\detail\native_paint_interface.hpp">
<Filter>Header Files\paint\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\paint\detail\image_bmp.hpp">
<Filter>Header Files\paint\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\pat\cloneable.hpp">
<Filter>Header Files\pat</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\system\dataexch.hpp">
<Filter>Header Files\system</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\system\platform.hpp">
<Filter>Header Files\system</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\system\shared_wrapper.hpp">
<Filter>Header Files\system</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\system\timepiece.hpp">
<Filter>Header Files\system</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\threads\pool.hpp">
<Filter>Header Files\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\gui\widgets\group.hpp">
<Filter>Header Files\gui\widgets</Filter>
</ClInclude>
</ItemGroup>
</Project>

28
build/vc2015/nana.sln Normal file
View File

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22823.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nana", "nana.vcxproj", "{25B21068-491B-4A9F-B99F-6C27BF31BAAD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Debug|x64.ActiveCfg = Debug|x64
{25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Debug|x64.Build.0 = Debug|x64
{25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Debug|x86.ActiveCfg = Debug|Win32
{25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Debug|x86.Build.0 = Debug|Win32
{25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Release|x64.ActiveCfg = Release|x64
{25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Release|x64.Build.0 = Release|x64
{25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Release|x86.ActiveCfg = Release|Win32
{25B21068-491B-4A9F-B99F-6C27BF31BAAD}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

264
build/vc2015/nana.vcxproj Normal file
View File

@ -0,0 +1,264 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{25B21068-491B-4A9F-B99F-6C27BF31BAAD}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>nana</RootNamespace>
<TargetPlatformVersion>8.1</TargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>../bin/</OutDir>
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
<SourcePath>..\..\source;$(VC_SourcePath);</SourcePath>
<TargetName>$(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)</TargetName>
<IntDir>..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
<SourcePath>..\..\source;$(VC_SourcePath);</SourcePath>
<OutDir>../bin/</OutDir>
<TargetName>$(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)</TargetName>
<IntDir>..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>../bin/</OutDir>
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
<SourcePath>..\..\source;$(VC_SourcePath);</SourcePath>
<TargetName>$(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)</TargetName>
<IntDir>..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
<SourcePath>..\..\source;$(VC_SourcePath);</SourcePath>
<OutDir>../bin/</OutDir>
<TargetName>$(ProjectName)_$(PlatformToolset)_$(Configuration)_$(PlatformShortName)</TargetName>
<IntDir>..\..\..\temp\$(ProjectName)\$(PlatformToolset)_$(Configuration)_$(PlatformShortName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<OutputFile>$(TargetPath)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<OutputFile>$(TargetPath)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<OutputFile>$(TargetPath)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<OutputFile>$(TargetPath)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\source\any.cpp" />
<ClCompile Include="..\..\source\audio\detail\audio_device.cpp" />
<ClCompile Include="..\..\source\audio\detail\audio_stream.cpp" />
<ClCompile Include="..\..\source\audio\detail\buffer_preparation.cpp" />
<ClCompile Include="..\..\source\audio\player.cpp" />
<ClCompile Include="..\..\source\basic_types.cpp" />
<ClCompile Include="..\..\source\charset.cpp" />
<ClCompile Include="..\..\source\datetime.cpp" />
<ClCompile Include="..\..\source\deploy.cpp" />
<ClCompile Include="..\..\source\detail\win32\platform_spec.cpp" />
<ClCompile Include="..\..\source\exceptions.cpp" />
<ClCompile Include="..\..\source\filesystem\filesystem.cpp" />
<ClCompile Include="..\..\source\filesystem\file_iterator.cpp" />
<ClCompile Include="..\..\source\filesystem\fs_utility.cpp" />
<ClCompile Include="..\..\source\gui\animation.cpp" />
<ClCompile Include="..\..\source\gui\basis.cpp" />
<ClCompile Include="..\..\source\gui\detail\basic_window.cpp" />
<ClCompile Include="..\..\source\gui\detail\bedrock_pi.cpp" />
<ClCompile Include="..\..\source\gui\detail\color_schemes.cpp" />
<ClCompile Include="..\..\source\gui\detail\drawer.cpp" />
<ClCompile Include="..\..\source\gui\detail\element_store.cpp" />
<ClCompile Include="..\..\source\gui\detail\events_operation.cpp" />
<ClCompile Include="..\..\source\gui\detail\native_window_interface.cpp" />
<ClCompile Include="..\..\source\gui\detail\win32\bedrock.cpp" />
<ClCompile Include="..\..\source\gui\detail\window_layout.cpp" />
<ClCompile Include="..\..\source\gui\detail\window_manager.cpp" />
<ClCompile Include="..\..\source\gui\dragger.cpp" />
<ClCompile Include="..\..\source\gui\drawing.cpp" />
<ClCompile Include="..\..\source\gui\effects.cpp" />
<ClCompile Include="..\..\source\gui\element.cpp" />
<ClCompile Include="..\..\source\gui\filebox.cpp" />
<ClCompile Include="..\..\source\gui\layout_utility.cpp" />
<ClCompile Include="..\..\source\gui\msgbox.cpp" />
<ClCompile Include="..\..\source\gui\notifier.cpp" />
<ClCompile Include="..\..\source\gui\place.cpp" />
<ClCompile Include="..\..\source\gui\programming_interface.cpp" />
<ClCompile Include="..\..\source\gui\screen.cpp" />
<ClCompile Include="..\..\source\gui\state_cursor.cpp" />
<ClCompile Include="..\..\source\gui\timer.cpp" />
<ClCompile Include="..\..\source\gui\tooltip.cpp" />
<ClCompile Include="..\..\source\gui\widgets\button.cpp" />
<ClCompile Include="..\..\source\gui\widgets\categorize.cpp" />
<ClCompile Include="..\..\source\gui\widgets\checkbox.cpp" />
<ClCompile Include="..\..\source\gui\widgets\combox.cpp" />
<ClCompile Include="..\..\source\gui\widgets\date_chooser.cpp" />
<ClCompile Include="..\..\source\gui\widgets\float_listbox.cpp" />
<ClCompile Include="..\..\source\gui\widgets\form.cpp" />
<ClCompile Include="..\..\source\gui\widgets\frame.cpp" />
<ClCompile Include="..\..\source\gui\widgets\group.cpp" />
<ClCompile Include="..\..\source\gui\widgets\label.cpp" />
<ClCompile Include="..\..\source\gui\widgets\listbox.cpp" />
<ClCompile Include="..\..\source\gui\widgets\menu.cpp" />
<ClCompile Include="..\..\source\gui\widgets\menubar.cpp" />
<ClCompile Include="..\..\source\gui\widgets\panel.cpp" />
<ClCompile Include="..\..\source\gui\widgets\picture.cpp" />
<ClCompile Include="..\..\source\gui\widgets\progress.cpp" />
<ClCompile Include="..\..\source\gui\widgets\scroll.cpp" />
<ClCompile Include="..\..\source\gui\widgets\skeletons\text_editor.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\textbox.cpp" />
<ClCompile Include="..\..\source\gui\widgets\toolbar.cpp" />
<ClCompile Include="..\..\source\gui\widgets\treebox.cpp" />
<ClCompile Include="..\..\source\gui\widgets\widget.cpp" />
<ClCompile Include="..\..\source\gui\wvl.cpp" />
<ClCompile Include="..\..\source\internationalization.cpp" />
<ClCompile Include="..\..\source\paint\detail\image_process_provider.cpp" />
<ClCompile Include="..\..\source\paint\detail\native_paint_interface.cpp" />
<ClCompile Include="..\..\source\paint\gadget.cpp" />
<ClCompile Include="..\..\source\paint\graphics.cpp" />
<ClCompile Include="..\..\source\paint\image.cpp" />
<ClCompile Include="..\..\source\paint\image_process_selector.cpp" />
<ClCompile Include="..\..\source\paint\pixel_buffer.cpp" />
<ClCompile Include="..\..\source\paint\text_renderer.cpp" />
<ClCompile Include="..\..\source\system\dataexch.cpp" />
<ClCompile Include="..\..\source\system\platform.cpp" />
<ClCompile Include="..\..\source\system\shared_wrapper.cpp" />
<ClCompile Include="..\..\source\system\timepiece.cpp" />
<ClCompile Include="..\..\source\threads\pool.cpp" />
<ClCompile Include="..\..\source\traits.cpp" />
<ClCompile Include="..\..\source\unicode_bidi.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,310 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Source Files\nana">
<UniqueIdentifier>{b0bd11b1-bcbb-4e05-885e-44295bc1a7bb}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\audio">
<UniqueIdentifier>{aab16aa3-c8d4-4495-8606-1b21ae739ee5}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\audio\detail">
<UniqueIdentifier>{c395f107-7102-415b-a019-54e7cf3575af}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\detail">
<UniqueIdentifier>{e2569be2-9e68-477d-8b59-e248595de6c7}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\detail\win32">
<UniqueIdentifier>{52ed7f8e-fa48-495e-af1f-4df013205a35}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\filesystem">
<UniqueIdentifier>{87d14798-9015-4162-b9ab-72c741cff063}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\gui">
<UniqueIdentifier>{4f8e7d23-9fe1-4409-bb03-2bd0809e606b}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\gui\detail">
<UniqueIdentifier>{85c9c1bb-d87b-4481-bf3c-7425f680a12d}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\gui\detail\win32">
<UniqueIdentifier>{8058b530-86ec-4d72-890d-345aa30db056}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\gui\widgets">
<UniqueIdentifier>{87b124cb-408d-460b-a81b-8a788bbae0d9}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\gui\widgets\skeletons">
<UniqueIdentifier>{b10db2f1-0542-421a-9e1d-4357e3be5f68}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\paint">
<UniqueIdentifier>{59f186c8-f5f8-4499-8e19-f278d4754220}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\paint\detail">
<UniqueIdentifier>{5acf1733-47b2-4872-a105-66c7ad15cd39}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\system">
<UniqueIdentifier>{a81fa10e-1274-44e0-92a0-434fa28f89ae}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nana\threads">
<UniqueIdentifier>{e95b4a72-643f-4416-af95-b0bbaf7f0c57}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\source\audio\detail\audio_device.cpp">
<Filter>Source Files\nana\audio\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\audio\detail\audio_stream.cpp">
<Filter>Source Files\nana\audio\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\audio\detail\buffer_preparation.cpp">
<Filter>Source Files\nana\audio\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\audio\player.cpp">
<Filter>Source Files\nana\audio</Filter>
</ClCompile>
<ClCompile Include="..\..\source\detail\win32\platform_spec.cpp">
<Filter>Source Files\nana\detail\win32</Filter>
</ClCompile>
<ClCompile Include="..\..\source\filesystem\file_iterator.cpp">
<Filter>Source Files\nana\filesystem</Filter>
</ClCompile>
<ClCompile Include="..\..\source\filesystem\fs_utility.cpp">
<Filter>Source Files\nana\filesystem</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\win32\bedrock.cpp">
<Filter>Source Files\nana\gui\detail\win32</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\basic_window.cpp">
<Filter>Source Files\nana\gui\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\drawer.cpp">
<Filter>Source Files\nana\gui\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\native_window_interface.cpp">
<Filter>Source Files\nana\gui\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\window_manager.cpp">
<Filter>Source Files\nana\gui\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\skeletons\text_editor.cpp">
<Filter>Source Files\nana\gui\widgets\skeletons</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\button.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\categorize.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\checkbox.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\combox.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\date_chooser.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\float_listbox.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\form.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\frame.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\label.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\listbox.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\menu.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\menubar.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\panel.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\picture.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\progress.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\scroll.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\slider.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\tabbar.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\textbox.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\toolbar.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\treebox.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\widget.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\animation.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\basis.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\dragger.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\drawing.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\effects.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\element.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\filebox.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\layout_utility.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\msgbox.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\place.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\programming_interface.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\timer.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\tooltip.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\wvl.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\paint\detail\image_process_provider.cpp">
<Filter>Source Files\nana\paint\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\paint\detail\native_paint_interface.cpp">
<Filter>Source Files\nana\paint\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\paint\gadget.cpp">
<Filter>Source Files\nana\paint</Filter>
</ClCompile>
<ClCompile Include="..\..\source\paint\graphics.cpp">
<Filter>Source Files\nana\paint</Filter>
</ClCompile>
<ClCompile Include="..\..\source\paint\image.cpp">
<Filter>Source Files\nana\paint</Filter>
</ClCompile>
<ClCompile Include="..\..\source\paint\image_process_selector.cpp">
<Filter>Source Files\nana\paint</Filter>
</ClCompile>
<ClCompile Include="..\..\source\paint\pixel_buffer.cpp">
<Filter>Source Files\nana\paint</Filter>
</ClCompile>
<ClCompile Include="..\..\source\paint\text_renderer.cpp">
<Filter>Source Files\nana\paint</Filter>
</ClCompile>
<ClCompile Include="..\..\source\system\dataexch.cpp">
<Filter>Source Files\nana\system</Filter>
</ClCompile>
<ClCompile Include="..\..\source\system\platform.cpp">
<Filter>Source Files\nana\system</Filter>
</ClCompile>
<ClCompile Include="..\..\source\system\shared_wrapper.cpp">
<Filter>Source Files\nana\system</Filter>
</ClCompile>
<ClCompile Include="..\..\source\system\timepiece.cpp">
<Filter>Source Files\nana\system</Filter>
</ClCompile>
<ClCompile Include="..\..\source\threads\pool.cpp">
<Filter>Source Files\nana\threads</Filter>
</ClCompile>
<ClCompile Include="..\..\source\any.cpp">
<Filter>Source Files\nana</Filter>
</ClCompile>
<ClCompile Include="..\..\source\basic_types.cpp">
<Filter>Source Files\nana</Filter>
</ClCompile>
<ClCompile Include="..\..\source\charset.cpp">
<Filter>Source Files\nana</Filter>
</ClCompile>
<ClCompile Include="..\..\source\datetime.cpp">
<Filter>Source Files\nana</Filter>
</ClCompile>
<ClCompile Include="..\..\source\deploy.cpp">
<Filter>Source Files\nana</Filter>
</ClCompile>
<ClCompile Include="..\..\source\exceptions.cpp">
<Filter>Source Files\nana</Filter>
</ClCompile>
<ClCompile Include="..\..\source\traits.cpp">
<Filter>Source Files\nana</Filter>
</ClCompile>
<ClCompile Include="..\..\source\unicode_bidi.cpp">
<Filter>Source Files\nana</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\window_layout.cpp">
<Filter>Source Files\nana\gui\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\element_store.cpp">
<Filter>Source Files\nana\gui\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\bedrock_pi.cpp">
<Filter>Source Files\nana\gui\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\events_operation.cpp">
<Filter>Source Files\nana\gui\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\notifier.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\state_cursor.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\internationalization.cpp">
<Filter>Source Files\nana</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\detail\color_schemes.cpp">
<Filter>Source Files\nana\gui\detail</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\screen.cpp">
<Filter>Source Files\nana\gui</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\spinbox.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\source\filesystem\filesystem.cpp">
<Filter>Source Files\nana\filesystem</Filter>
</ClCompile>
<ClCompile Include="..\..\source\gui\widgets\group.cpp">
<Filter>Source Files\nana\gui\widgets</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -12,19 +12,19 @@ namespace nana{ namespace audio{
#pragma pack(1)
struct master_riff_chunk
{
unsigned long ckID; //"RIFF"
unsigned long cksize;
unsigned long waveID; //"WAVE"
unsigned ckID; //"RIFF"
unsigned cksize;
unsigned waveID; //"WAVE"
};
struct format_chunck
{
unsigned long ckID; //"fmt "
unsigned long cksize;
unsigned ckID; //"fmt "
unsigned cksize;
unsigned short wFormatTag;
unsigned short nChannels;
unsigned long nSamplePerSec;
unsigned long nAvgBytesPerSec;
unsigned nSamplePerSec;
unsigned nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short wBitsPerSample;
};
@ -32,19 +32,19 @@ namespace nana{ namespace audio{
#elif defined(NANA_LINUX)
struct master_riff_chunk
{
unsigned long ckID; //"RIFF"
unsigned long cksize;
unsigned long waveID; //"WAVE"
unsigned ckID; //"RIFF"
unsigned cksize;
unsigned waveID; //"WAVE"
}__attribute__((packed));
struct format_chunck
{
unsigned long ckID; //"fmt "
unsigned long cksize;
unsigned ckID; //"fmt "
unsigned cksize;
unsigned short wFormatTag;
unsigned short nChannels;
unsigned long nSamplePerSec;
unsigned long nAvgBytesPerSec;
unsigned nSamplePerSec;
unsigned nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short wBitsPerSample;
}__attribute__((packed));
@ -55,8 +55,8 @@ namespace nana{ namespace audio{
{
struct chunck
{
unsigned long ckID;
unsigned long cksize;
unsigned ckID;
unsigned cksize;
};
public:
bool open(const nana::string& file);

View File

@ -4,7 +4,10 @@
#include <nana/deploy.hpp>
namespace nana{ namespace audio
{ /// play an audio file in Windows WAV format
{ /// class player
/// \brief play an audio file in PCM Windows WAV format
///
/// \include audio_player.cpp
class player
: private nana::noncopyable
{

View File

@ -306,7 +306,7 @@ namespace nana
color(unsigned red, unsigned green, unsigned blue, double alpha);
/// Initializes the color with a CSS-like rgb string.
color(std::string css_rgb);
explicit color(std::string css_rgb);
color& alpha(double); ///< Sets alpha channel
color& from_rgb(unsigned red, unsigned green, unsigned blue); ///< immutable alpha channel
@ -406,10 +406,10 @@ namespace nana
struct rectangle
{
rectangle(); ///< a zero-size rectangle at (0, 0).
rectangle(); ///< a zero-size rectangle at (0, 0).
rectangle(int x, int y, unsigned width, unsigned height);
rectangle(const size &); ///< a rectangle with specified size at coordinate (0, 0).
rectangle(const point&, const size& = size());
explicit rectangle(const size &); ///< a rectangle with specified size at coordinate (0, 0).
explicit rectangle(const point&, const size& = size());
bool operator==(const rectangle& rhs) const;
bool operator!=(const rectangle& rhs) const;

View File

@ -13,6 +13,26 @@
#ifndef NANA_CONFIG_HPP
#define NANA_CONFIG_HPP
#if defined(_MSC_VER)
#define _SCL_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#pragma warning(disable : 4996)
#if (_MSC_VER < 1900)
// is this a good idea?
#define NOT_IMPLEMENTED_KEYWORD_noexcept
#endif // _MSC_VER < 1900
#if (_MSC_VER == 1900)
// google: break any code that tries to use codecvt<char16_t> or codecvt<char32_t>.
// google: It appears the C++ libs haven't been compiled with native char16_t/char32_t support.
// google: Those definitions are for codecvt<wchar_t>::id, codecvt<unsigned short>::id and codecvt<char>::id respectively.
// However, the codecvt<char16_t>::id and codecvt<char32_t>::id definitions aren't there, and indeed, if you look at locale0.cpp in the CRT source code you'll see they're not defined at all.
// google: That's a known issue, tracked by an active bug (DevDiv#1060849). We were able to update the STL's headers in response to char16_t/char32_t, but we still need to update the separately compiled sources.
#define STD_CODECVT_NOT_SUPPORTED
#endif // _MSC_VER == 1900
#endif // _MSVC
//Select platform automatically
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
//Windows:
@ -35,7 +55,7 @@
#define PLATFORM_SPEC_HPP <nana/detail/linux_X11/platform_spec.hpp>
#define STD_CODECVT_NOT_SUPPORTED
#else
# static_assert(false, "Only Windows and Unix are support now");
# static_assert(false, "Only Windows and Unix are supported now");
#endif
#if defined(NANA_MINGW) || defined(NANA_LINUX)

View File

@ -55,6 +55,13 @@ namespace detail
unsigned ignore; //determinate that pos or size would be ignored.
};
struct map_thread
{
rectangle update_area;
bool ignore_update_area;
bool forced;
};
enum
{
tray = 0x501,
@ -165,6 +172,12 @@ namespace detail
HMODULE ole32_;
};
struct window_icons
{
::nana::paint::image sml_icon;
::nana::paint::image big_icon;
};
platform_spec();
const font_ptr_t& default_native_font() const;
@ -175,11 +188,11 @@ namespace detail
static platform_spec& instance();
void keep_window_icon(native_window_type, const nana::paint::image&);
void keep_window_icon(native_window_type, const paint::image&sml_icon, const paint::image& big_icon);
void release_window_icon(native_window_type);
private:
font_ptr_t def_font_ptr_;
std::map<native_window_type, nana::paint::image> iconbase_;
std::map<native_window_type, window_icons> iconbase_;
};
}//end namespace detail

View File

@ -0,0 +1,468 @@
/*
* A ISO C++ filesystem Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/filesystem/filesystem.hpp
* @description:
* file_iterator is a toolkit for applying each file and directory in a
* specified path.
* Modiffied by Ariel Vina-Rodriguez:
* Now mimic std::experimental::filesystem::v1 (boost v3)
* and need VC2015 or a C++11 compiler. With a few correction will be compiler by VC2013
*/
// http://en.cppreference.com/w/cpp/experimental/fs
// http://cpprocks.com/introduction-to-tr2-filesystem-library-in-vs2012/ --- TR2 filesystem in VS2012
// https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.140%29.aspx --- C++ 14, the <filesystem> header VS2015
// https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.120%29.aspx --- <filesystem> header VS2013
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf --- last pdf of std draft N4100 2014-07-04
// http://cplusplus.github.io/filesystem-ts/working-draft.html --- in html format
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4099.html --- in html format
// http://article.gmane.org/gmane.comp.lib.boost.devel/256220 --- The filesystem TS unanimously approved by ISO.
// http://theboostcpplibraries.com/boost.filesystem --- Boost docs
// http://www.boost.org/doc/libs/1_58_0/libs/filesystem/doc/index.htm ---
// http://www.boost.org/doc/libs/1_34_0/libs/filesystem/doc/index.htm
// http://www.boost.org/doc/libs/1_58_0/boost/filesystem.hpp
// https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.200x --- Table 1.4. g++ C++ Technical Specifications Implementation Status
#ifndef NANA_FILESYSTEM_HPP
#define NANA_FILESYSTEM_HPP
#include <iterator>
#include <memory>
#include <chrono>
#include <cstddef>
#include <nana/deploy.hpp>
#ifdef NANA_WINDOWS
#include <windows.h>
typedef HANDLE find_handle_t;
#elif defined(NANA_LINUX)
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
typedef DIR* find_handle_t;
#endif
// namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
namespace nana { namespace experimental
{
namespace filesystem
{
enum class file_type
{
none = 0, ///< has not been determined or an error occurred while trying to determine
not_found = -1, ///< Pseudo-type: file was not found. Is not considered an error
regular = 1,
directory = 2 ,
symlink =3, ///< Symbolic link file
block =4, ///< Block special file
character= 5 , ///< Character special file
fifo = 6 , ///< FIFO or pipe file
socket =7,
unknown= 8 ///< The file does exist, but is of an operating system dependent type not covered by any of the other
};
enum class perms
{
none =0, ///< There are no permissions set for the file.
unknown = 0xFFFF ///< not known, such as when a file_status object is created without specifying the permissions
};
//enum class copy_options;
//enum class directory_options;
// class filesystem_error;
enum class error { none = 0 }; // deprecate ??
struct attribute // deprecate ??
{
uintmax_t size {};
bool directory{};
tm modified {};
attribute() {} ;
attribute( uintmax_t size, bool is_directory) :size{size}, directory{is_directory} {}
};
struct space_info
{
uintmax_t capacity;
uintmax_t free;
uintmax_t available;
};
using file_time_type = std::chrono::time_point< std::chrono::system_clock>;// trivial-clock> ;
class file_status
{
file_type m_ft = file_type::none;
perms m_prms = perms::unknown;
public:
explicit file_status(file_type ft = file_type::none, perms prms = perms::unknown)
:m_ft{ft}, m_prms{prms}
{}
file_status(const file_status& fs) : m_ft{fs.m_ft}, m_prms{fs.m_prms}{} // = default;
file_status(file_status&& fs) : m_ft{fs.m_ft}, m_prms{fs.m_prms}{} // = default;
~file_status(){};
file_status& operator=(const file_status&) = default;
file_status& operator=(file_status&&fs) // = default;
{
m_ft=fs.m_ft; m_prms = fs.m_prms;
return *this;
}
// observers
file_type type() const { return m_ft;}
perms permissions() const { return m_prms;}
// modifiers
void type (file_type ft) { m_ft=ft ;}
void permissions(perms prms) { m_prms = prms; }
};
/// concerned only with lexical and syntactic aspects and does not necessarily exist in
/// external storage, and the pathname is not necessarily valid for the current operating system
/// or for a particular file system
/// A sequence of elements that identify the location of a file within a filesystem.
/// The elements are the:
/// rootname (opt), root-directory (opt), and an optional sequence of filenames.
/// The maximum number of elements in the sequence is operating system dependent.
class path
{
public:
path();
path(const nana::string&);
bool empty() const;
path root() const;
file_type what() const;
nana::string filename() const;
#if defined(NANA_WINDOWS)
public:
nana::string to_string() const { return text_; }
operator nana::string() const { return text_; }
private:
nana::string text_;
#else
public:
std::string to_string() const { return text_; }
operator std::string() const { return text_; }
private:
std::string text_;
#endif
};
struct directory_entry
{
using path_type = filesystem::path;
path_type m_path;
attribute attr{};
//file_status m_status;
directory_entry(){}
directory_entry(const path_type& p, bool is_directory, uintmax_t size)
:m_path{p}, attr{size, is_directory}
{}
void assign (const path_type& p){ m_path=p;}
void replace_filename(const path_type& p){ m_path=p;}
//file_status status() const;
operator const path_type&() const {return m_path;};
const path_type& path() const {return m_path;}
};
/// an iterator for a sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator
//template<typename FileInfo>
class directory_iterator :public std::iterator<std::input_iterator_tag, directory_entry>
{
public:
using value_type = directory_entry ;
typedef ptrdiff_t difference_type;
typedef const directory_entry* pointer;
typedef const directory_entry& reference;
typedef std::input_iterator_tag iterator_category;
directory_iterator():end_(true), handle_(nullptr){}
directory_iterator(const nana::string& file_path) { _m_prepare(file_path); }
directory_iterator(const path& file_path) { _m_prepare(file_path.filename()); }
const value_type&
operator*() const { return value_; }
const value_type*
operator->() const { return &(operator*()); }
directory_iterator& operator++()
{ _m_read(); return *this; }
directory_iterator operator++(int)
{
directory_iterator tmp = *this;
_m_read();
return tmp;
}
bool equal(const directory_iterator& x) const
{
if(end_ && (end_ == x.end_)) return true;
return (value_.path().filename() == x.value_.path().filename());
}
// enable directory_iterator range-based for statements
directory_iterator begin( ) { return *this; }
directory_iterator end( ) { return {}; }
private:
template<typename Char>
static bool _m_ignore(const Char * p)
{
while(*p == '.')
++p;
return (*p == 0);
}
void _m_prepare(const nana::string& file_path)
{
#if defined(NANA_WINDOWS)
path_ = file_path;
auto pat = file_path;
DWORD attr = ::GetFileAttributes(pat.data());
if((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY))
pat += STR("\\*");
::HANDLE handle = ::FindFirstFile(pat.data(), &wfd_);
if(handle == INVALID_HANDLE_VALUE)
{
end_ = true;
return;
}
while(_m_ignore(wfd_.cFileName))
{
if(::FindNextFile(handle, &wfd_) == 0)
{
end_ = true;
::FindClose(handle);
return;
}
}
value_ = value_type(path(wfd_.cFileName),
(FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
wfd_.nFileSizeLow);
#elif defined(NANA_LINUX)
path_ = nana::charset(file_path);
if(path_.size() && (path_[path_.size() - 1] != '/'))
path_ += '/';
find_handle_t handle = opendir(path_.c_str());
end_ = true;
if(handle)
{
struct dirent * dnt = readdir(handle);
if(dnt)
{
while(_m_ignore(dnt->d_name))
{
dnt = readdir(handle);
if(dnt == 0)
{
closedir(handle);
return;
}
}
struct stat fst;
bool is_directory = false;
unsigned size = 0;
if(stat((path_ + dnt->d_name).c_str(), &fst) == 0)
{
is_directory = (0 != S_ISDIR(fst.st_mode));
size = fst.st_size;
}
value_ = value_type(static_cast<nana::string>(nana::charset(dnt->d_name)), is_directory, size);
end_ = false;
}
}
#endif
if(false == end_)
{
find_ptr_ = std::shared_ptr<find_handle_t>(new find_handle_t(handle), inner_handle_deleter());
handle_ = handle;
}
}
void _m_read()
{
if(handle_)
{
#if defined(NANA_WINDOWS)
if(::FindNextFile(handle_, &wfd_) != 0)
{
while(_m_ignore(wfd_.cFileName))
{
if(::FindNextFile(handle_, &wfd_) == 0)
{
end_ = true;
return;
}
}
value_ = value_type(path(wfd_.cFileName),
(FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
wfd_.nFileSizeLow);
}
else
end_ = true;
#elif defined(NANA_LINUX)
struct dirent * dnt = readdir(handle_);
if(dnt)
{
while(_m_ignore(dnt->d_name))
{
dnt = readdir(handle_);
if(dnt == 0)
{
end_ = true;
return;
}
}
nana::string d_name = nana::charset(dnt->d_name);
struct stat fst;
if(stat((path_ + "/" + dnt->d_name).c_str(), &fst) == 0)
value_ = value_type(std::move(d_name), (0 != S_ISDIR(fst.st_mode)), fst.st_size);
else
value_.m_path = path(std::move(d_name));
}
else
end_ = true;
#endif
}
}
private:
struct inner_handle_deleter
{
void operator()(find_handle_t * handle)
{
if(handle && *handle)
{
#if defined(NANA_WINDOWS)
::FindClose(*handle);
#elif defined(NANA_LINUX)
::closedir(*handle);
#endif
}
delete handle;
}
};
private:
bool end_{false};
#if defined(NANA_WINDOWS)
WIN32_FIND_DATA wfd_;
nana::string path_;
#elif defined(NANA_LINUX)
std::string path_;
#endif
std::shared_ptr<find_handle_t> find_ptr_;
find_handle_t handle_{nullptr};
value_type value_;
};
//class recursive_directory_iterator;
//// enable recursive_directory_iterator range-based for statements
//recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
//recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
//template<typename Value_Type>
inline bool operator==(const directory_iterator/*<Value_Type>*/ & x, const directory_iterator/*<Value_Type>*/ & y)
{
return x.equal(y);
}
//template<typename Value_Type>
inline bool operator!=(const directory_iterator/*<Value_Type>*/ & x, const directory_iterator/*<Value_Type>*/ & y)
{
return !x.equal(y);
}
// file_status status(const path& p);
bool file_attrib(const nana::string& file, attribute&);
inline bool is_directory(file_status s) { return s.type() == file_type::directory ;}
inline bool is_directory(const path& p) { return directory_iterator(p)->attr.directory; }//works??
inline bool is_directory(const directory_entry& d) { return d.attr.directory; }
//bool is_directory(const path& p, error_code& ec) noexcept;
//bool is_regular_file(file_status s) noexcept;
inline bool is_empty(const path& p)
{
directory_iterator d(p) ;
return d->attr.directory ? d == directory_iterator()
: d->attr.size == 0;
}
//bool is_empty(const path& p, error_code& ec) noexcept;
uintmax_t file_size(const nana::string& file); // deprecate?
inline uintmax_t file_size(const path& p){return file_size(p.filename());}
//uintmax_t file_size(const path& p, error_code& ec) noexcept;
//long long filesize(const nana::string& file);
bool create_directories(const path& p);
//bool create_directories(const path& p, error_code& ec) noexcept;
bool create_directory(const path& p);
//bool create_directory(const path& p, error_code& ec) noexcept;
bool create_directory(const path& p, const path& attributes);
//bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept;
bool create_directory(const nana::string& dir, bool & if_exist);
inline bool create_directory(const path& p, bool & if_exist)
{
return create_directory(p.filename(), if_exist);
};
bool modified_file_time(const nana::string& file, struct tm&);
nana::string path_user();
path current_path();
//path current_path(error_code& ec);
void current_path(const path& p);
//void current_path(const path& p, error_code& ec) noexcept;
//nana::string path_current();
//bool remove(const path& p);
//bool remove(const path& p, error_code& ec) noexcept;
bool rmfile(const nana::char_t* file);
//uintmax_t remove_all(const path& p);
//uintmax_t remove_all(const path& p, error_code& ec) noexcept;
bool rmdir(const nana::char_t* dir, bool fails_if_not_empty);
nana::string root(const nana::string& path);
}//end namespace filesystem
} //end namespace experimental
}//end namespace nana
#endif

View File

@ -84,6 +84,7 @@ namespace nana
end_of_medium = 0x19, //Ctrl+Y
substitute = 0x1A, //Ctrl+Z
escape = 0x1B,
space = 0x20, //Space
//The following names are intuitive name of ASCII control codes
select_all = start_of_headline,

View File

@ -15,17 +15,21 @@
#include "drawer.hpp"
#include "events_holder.hpp"
#include "widget_colors.hpp"
#include "widget_notifier_interface.hpp"
#include <nana/basic_types.hpp>
#include <nana/system/platform.hpp>
#include <nana/gui/effects.hpp>
#include <memory>
namespace nana{
class widget; //declaration ofr nana/widgets/widget.hpp
namespace detail
{
struct basic_window;
enum class visible_state
{
invisible, visible, displayed
};
class caret_descriptor
{
public:
@ -42,17 +46,13 @@ namespace detail
bool visible() const;
::nana::size size() const;
void size(const ::nana::size&);
void update();
private:
void _m_visible(bool isshow);
private:
core_window_t* wd_;
::nana::point point_;
::nana::size size_;
::nana::size paint_size_;
bool visible_;
bool real_visible_state_;
visible_state visible_state_;
bool out_of_range_;
::nana::rectangle effective_range_;
};//end class caret_descriptor
@ -76,11 +76,6 @@ namespace detail
{
using container = std::vector<basic_window*>;
struct root_context
{
bool focus_changed;
};
enum class update_state
{
none, lazy, refresh
@ -94,11 +89,11 @@ namespace detail
//basic_window
//@brief: constructor for the root window
basic_window(basic_window* owner, widget*, category::root_tag**);
basic_window(basic_window* owner, std::unique_ptr<widget_notifier_interface>&&, category::root_tag**);
template<typename Category>
basic_window(basic_window* parent, const rectangle& r, widget* wdg, Category**)
: widget_ptr(wdg), other(Category::value)
basic_window(basic_window* parent, std::unique_ptr<widget_notifier_interface>&& wdg_notifier, const rectangle& r, Category**)
: widget_notifier(std::move(wdg_notifier)), other(Category::value)
{
drawer.bind(this);
if(parent)
@ -118,9 +113,13 @@ namespace detail
bool is_ancestor_of(const basic_window* wd) const;
bool visible_parents() const;
bool displayed() const;
bool belong_to_lazy() const;
const basic_window * child_caret() const; //Returns a child which owns a caret
bool is_draw_through() const; ///< Determines whether it is a draw-through window.
basic_window * seek_non_lite_widget_ancestor() const;
public:
//Override event_holder
bool set_events(const std::shared_ptr<general_events>&) override;
@ -151,7 +150,7 @@ namespace detail
basic_window* root_widget; //A pointer refers to the root basic window, if the window is a root, the pointer refers to itself.
paint::graphics* root_graph; //Refer to the root buffer graphics
cursor predef_cursor;
widget* const widget_ptr;
std::unique_ptr<widget_notifier_interface> widget_notifier;
struct flags_type
{
@ -165,9 +164,10 @@ namespace detail
bool dropable :1; //Whether the window has make mouse_drop event.
bool fullscreen :1; //When the window is maximizing whether it fit for fullscreen.
bool borderless :1;
bool make_bground_declared : 1; //explicitly make bground for bground effects
bool ignore_menubar_focus : 1; //A flag indicates whether the menubar sets the focus.
unsigned Reserved :20;
bool make_bground_declared : 1; //explicitly make bground for bground effects
bool ignore_menubar_focus : 1; //A flag indicates whether the menubar sets the focus.
bool ignore_mouse_focus : 1; //A flag indicates whether the widget accepts focus when clicking on it
unsigned Reserved :19;
unsigned char tab; //indicate a window that can receive the keyboard TAB
mouse_action action;
}flags;
@ -202,7 +202,6 @@ namespace detail
std::vector<edge_nimbus_action> effects_edge_nimbus;
basic_window* focus{nullptr};
basic_window* menubar{nullptr};
root_context context;
bool ime_enabled{false};
#if defined(NANA_WINDOWS)
cursor running_cursor{ nana::cursor::arrow };
@ -210,7 +209,7 @@ namespace detail
cursor state_cursor{nana::cursor::arrow};
basic_window* state_cursor_window{ nullptr };
std::function<void()> draw_through; ///< A draw through renderer for root widgets.
std::function<void()> draw_through; // A draw through renderer for root widgets.
};
const category::flags category;

View File

@ -40,9 +40,11 @@ namespace detail
struct thread_context;
class flag_guard;
~bedrock();
void pump_event(window, bool is_modal);
void map_thread_root_buffer(core_window_t*, bool forced);
void map_thread_root_buffer(core_window_t*, bool forced, const rectangle* update_area = nullptr);
static int inc_window(unsigned tid = 0);
thread_context* open_thread_context(unsigned tid = 0);
thread_context* get_thread_context(unsigned tid = 0);

View File

@ -23,12 +23,18 @@ namespace nana
{
class widget;
namespace detail
{
class drawer;
}
class drawer_trigger
: ::nana::noncopyable, ::nana::nonmovable
{
friend class detail::drawer;
public:
typedef widget& widget_reference;
typedef paint::graphics& graph_reference;
using widget_reference = widget&;
using graph_reference = paint::graphics&;
virtual ~drawer_trigger();
virtual void attached(widget_reference, graph_reference); //none-const
@ -40,7 +46,7 @@ namespace nana
virtual void resizing(graph_reference, const arg_resizing&);
virtual void resized(graph_reference, const arg_resized&);
virtual void move(graph_reference, const arg_move&);
virtual void click(graph_reference, const arg_mouse&);
virtual void click(graph_reference, const arg_click&);
virtual void dbl_click(graph_reference, const arg_mouse&);
virtual void mouse_enter(graph_reference, const arg_mouse&);
virtual void mouse_move(graph_reference, const arg_mouse&);
@ -56,10 +62,11 @@ namespace nana
virtual void key_release(graph_reference, const arg_keyboard&);
virtual void shortkey(graph_reference, const arg_keyboard&);
void _m_reset_overrided();
bool _m_overrided() const;
private:
bool overrided_{false};
void _m_reset_overrided();
bool _m_overrided(event_code) const;
private:
unsigned overrided_{ 0xFFFFFFFF };
};
namespace detail
@ -83,7 +90,7 @@ namespace nana
enum class method_state
{
unknown,
pending,
overrided,
not_overrided
};
@ -93,7 +100,7 @@ namespace nana
void bind(basic_window*);
void typeface_changed();
void click(const arg_mouse&);
void click(const arg_click&);
void dbl_click(const arg_mouse&);
void mouse_enter(const arg_mouse&);
void mouse_move(const arg_mouse&);
@ -110,7 +117,7 @@ namespace nana
void key_char(const arg_keyboard&);
void key_release(const arg_keyboard&);
void shortkey(const arg_keyboard&);
void map(window, bool forced); //Copy the root buffer to screen
void map(window, bool forced, const rectangle* update_area = nullptr); //Copy the root buffer to screen
void refresh();
drawer_trigger* realizer() const;
void attached(widget&, drawer_trigger&);
@ -128,31 +135,27 @@ namespace nana
template<typename Arg, typename Mfptr>
void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr)
{
if (realizer_)
const int pos = static_cast<int>(evt_code);
if (realizer_ && (method_state::not_overrided != mth_state_[pos]))
{
const int pos = static_cast<int>(evt_code);
if (method_state::not_overrided != mth_state_[pos])
_m_bground_pre();
if (method_state::pending == mth_state_[pos])
{
_m_bground_pre();
(realizer_->*mfptr)(graphics, arg);
//Check realizer, when the window is closed in that event handler, the drawer will be
//detached and realizer will be a nullptr
if(realizer_)
mth_state_[pos] = (realizer_->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided);
}
else
(realizer_->*mfptr)(graphics, arg);
if (method_state::unknown == mth_state_[pos])
{
realizer_->_m_reset_overrided();
(realizer_->*mfptr)(graphics, arg);
//Check realizer, when the window is closed in that event handler, the drawer will be
//detached and realizer will be a nullptr
if(realizer_)
mth_state_[pos] = (realizer_->_m_overrided() ? method_state::overrided : method_state::not_overrided);
}
else
(realizer_->*mfptr)(graphics, arg);
if (_m_lazy_decleared())
{
_m_draw_dynamic_drawing_object();
_m_bground_end();
}
if (_m_lazy_decleared())
{
_m_draw_dynamic_drawing_object();
_m_bground_end();
}
}
}

View File

@ -13,9 +13,9 @@ namespace nana{
{
edge_nimbus_renderer() = default;
public:
typedef CoreWindow core_window_t;
typedef window_layout window_layer;
typedef nana::paint::graphics & graph_reference;
using core_window_t = CoreWindow;
using window_layer = window_layout;
using graph_reference = ::nana::paint::graphics&;
static edge_nimbus_renderer& instance()
{
@ -23,37 +23,69 @@ namespace nana{
return object;
}
std::size_t weight() const
unsigned weight() const
{
return 2;
}
bool render(core_window_t * wd, bool forced)
void erase(core_window_t* wd)
{
bool rendered = false;
if (effects::edge_nimbus::none == wd->effect.edge_nimbus)
return;
core_window_t * root_wd = wd->root_widget;
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
if(nimbus.size())
for (auto i = nimbus.begin(); i != nimbus.end(); ++i)
{
core_window_t * focused = root_wd->other.attribute.root->focus;
native_window_type native = root_wd->root;
std::size_t pixels = weight();
if (i->window == wd)
{
auto pixels = weight();
rectangle r{wd->pos_root, wd->dimension};
r.x -= static_cast<int>(pixels);
r.y -= static_cast<int>(pixels);
r.width += static_cast<unsigned>(pixels << 1);
r.height += static_cast<unsigned>(pixels << 1);
root_wd->root_graph->paste(root_wd->root, r, r.x, r.y);
nimbus.erase(i);
break;
}
}
}
void render(core_window_t * wd, bool forced, const rectangle* update_area = nullptr)
{
bool copy_separately = true;
std::vector<std::pair<rectangle, core_window_t*>> rd_set;
if (wd->root_widget->other.attribute.root->effects_edge_nimbus.size())
{
auto root_wd = wd->root_widget;
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
auto focused = root_wd->other.attribute.root->focus;
const unsigned pixels = weight();
auto graph = root_wd->root_graph;
std::vector<core_window_t*> erase;
std::vector<std::pair<rectangle,core_window_t*>> rd_set;
nana::rectangle r;
for(auto & action : nimbus)
{
if(_m_edge_nimbus(focused, action.window) && window_layer::read_visual_rectangle(action.window, r))
{
if(action.window == wd)
rendered = true;
if (action.window == wd)
{
if (update_area)
::nana::overlap(*update_area, rectangle(r), r);
copy_separately = false;
}
//Avoiding duplicated rendering. If the window is declared to lazy refresh, it should be rendered.
if ((forced && (action.window == wd)) || !action.rendered || (action.window->other.upd_state == core_window_t::update_state::refresh))
if ((forced && (action.window == wd)) || (focused == action.window) || !action.rendered || (action.window->other.upd_state == core_window_t::update_state::refresh))
{
rd_set.emplace_back(r, action.window);
action.rendered = true;
@ -62,29 +94,36 @@ namespace nana{
else if(action.rendered)
{
action.rendered = false;
erase.push_back(action.window);
if (action.window == wd)
copy_separately = false;
::nana::rectangle erase_r(
action.window->pos_root.x - static_cast<int>(pixels),
action.window->pos_root.y - static_cast<int>(pixels),
static_cast<unsigned>(action.window->dimension.width + (pixels << 1)),
static_cast<unsigned>(action.window->dimension.height + (pixels << 1))
);
graph->paste(root_wd->root, erase_r, erase_r.x, erase_r.y);
}
}
//Erase
for(auto el : erase)
{
if(el == wd)
rendered = true;
r.x = el->pos_root.x - static_cast<int>(pixels);
r.y = el->pos_root.y - static_cast<int>(pixels);
r.width = static_cast<unsigned>(el->dimension.width + (pixels << 1));
r.height = static_cast<unsigned>(el->dimension.height + (pixels << 1));
graph->paste(native, r, r.x, r.y);
}
//Render
for (auto & rd : rd_set)
_m_render_edge_nimbus(rd.second, rd.first);
}
return rendered;
if (copy_separately)
{
rectangle vr;
if (window_layer::read_visual_rectangle(wd, vr))
{
if (update_area)
::nana::overlap(*update_area, rectangle(vr), vr);
wd->root_graph->paste(wd->root, vr, vr.x, vr.y);
}
}
//Render
for (auto & rd : rd_set)
_m_render_edge_nimbus(rd.second, rd.first);
}
private:
static bool _m_edge_nimbus(core_window_t * focused_wd, core_window_t * wd)
@ -98,13 +137,13 @@ namespace nana{
void _m_render_edge_nimbus(core_window_t* wd, const nana::rectangle & visual)
{
nana::rectangle r(visual);
auto r = visual;
r.pare_off(-static_cast<int>(weight()));
nana::rectangle good_r;
if(overlap(r, wd->root_graph->size(), good_r))
rectangle good_r;
if (overlap(r, rectangle{ wd->root_graph->size() }, good_r))
{
if( (good_r.x < wd->pos_root.x) || (good_r.y < wd->pos_root.y) ||
(good_r.x + good_r.width > visual.x + visual.width) || (good_r.y + good_r.height > visual.y + visual.height))
if ((good_r.x < wd->pos_root.x) || (good_r.y < wd->pos_root.y) ||
(good_r.right() > visual.right()) || (good_r.bottom() > visual.bottom()))
{
auto graph = wd->root_graph;
nana::paint::pixel_buffer pixbuf(graph->handle(), r);
@ -131,7 +170,7 @@ namespace nana{
pixbuf.pixel(0, r.height - 1, px2);
pixbuf.pixel(r.width - 1, r.height - 1, px3);
pixbuf.paste(wd->root, r.x, r.y);
pixbuf.paste(wd->root, { r.x, r.y });
std::vector<typename window_layer::wd_rectangle> overlaps;
if(window_layer::read_overlaps(wd, visual, overlaps))

View File

@ -46,7 +46,7 @@ namespace nana
class event_arg
{
public:
virtual ~event_arg();
virtual ~event_arg() = default;
/// ignorable handlers behind the current one in a chain of event handlers will not get called.
void stop_propagation() const;
@ -425,11 +425,19 @@ namespace nana
event_code evt_code; ///<
::nana::window window_handle; ///< A handle to the event window
::nana::point pos; ///< cursor position in the event window
::nana::mouse button; ///< indicates a button which triggers the event
bool left_button; ///< mouse left button is pressed?
bool mid_button; ///< mouse middle button is pressed?
bool right_button; ///< mouse right button is pressed?
bool shift; ///< keyboard Shift is pressed?
bool ctrl; ///< keyboard Ctrl is pressed?
/// Checks if left button is operated,
bool is_left_button() const
{
return (event_code::mouse_move == evt_code ? left_button : (mouse::left_button == button));
}
};
/// in arg_wheel event_code is event_code::mouse_wheel
@ -510,31 +518,37 @@ namespace nana
::nana::window window_handle; ///< A handle to the event window
};
struct arg_click : public event_arg
{
::nana::window window_handle; ///< A handle to the event window
bool by_mouse; ///< Determines whether the event is emitted by clicking mouse button
};
/// provides some fundamental events that every widget owns.
struct general_events
{
virtual ~general_events(){}
basic_event<arg_mouse> mouse_enter; ///< the cursor enters the window
basic_event<arg_mouse> mouse_move; ///< the cursor moves on the window
basic_event<arg_mouse> mouse_leave; ///< the cursor leaves the window
basic_event<arg_mouse> mouse_down; ///< the user presses the mouse button
basic_event<arg_mouse> mouse_up; ///< the user presses the mouse button
basic_event<arg_mouse> click; ///< the window is clicked, but occurs after mouse_down and before mouse_up
basic_event<arg_mouse> dbl_click; ///< the window is double clicked
basic_event<arg_wheel> mouse_wheel; ///< the mouse wheel rotates while the window has focus
basic_event<arg_mouse> mouse_enter; ///< the cursor enters the window
basic_event<arg_mouse> mouse_move; ///< the cursor moves on the window
basic_event<arg_mouse> mouse_leave; ///< the cursor leaves the window
basic_event<arg_mouse> mouse_down; ///< the user presses the mouse button
basic_event<arg_mouse> mouse_up; ///< the user presses the mouse button
basic_event<arg_click> click; ///< the window is clicked, but occurs after mouse_down and before mouse_up
basic_event<arg_mouse> dbl_click; ///< the window is double clicked
basic_event<arg_wheel> mouse_wheel; ///< the mouse wheel rotates while the window has focus
basic_event<arg_dropfiles> mouse_dropfiles; ///< the mouse drops some external data while the window enable accepting files
basic_event<arg_expose> expose; ///< the visibility changes
basic_event<arg_focus> focus; ///< the window receives or loses keyboard focus
basic_event<arg_expose> expose; ///< the visibility changes
basic_event<arg_focus> focus; ///< the window receives or loses keyboard focus
basic_event<arg_keyboard> key_press; ///< a key is pressed while the window has focus. event code is event_code::key_press
basic_event<arg_keyboard> key_release; ///< a key is released while the window has focus. event code is event_code::key_release
basic_event<arg_keyboard> key_char; ///< a character, whitespace or backspace is pressed. event code is event_code::key_char
basic_event<arg_keyboard> shortkey; ///< a defined short key is pressed. event code is event_code::shortkey
basic_event<arg_keyboard> key_char; ///< a character, whitespace or backspace is pressed. event code is event_code::key_char
basic_event<arg_keyboard> shortkey; ///< a defined short key is pressed. event code is event_code::shortkey
basic_event<arg_move> move; ///< the window changes position
basic_event<arg_resizing> resizing; ///< the window is changing its size
basic_event<arg_resized> resized; ///< the window is changing its size
basic_event<arg_move> move; ///< the window changes position
basic_event<arg_resizing> resizing; ///< the window is changing its size
basic_event<arg_resized> resized; ///< the window is changing its size
basic_event<arg_destroy> destroy; ///< the window is destroyed, but occurs when all children have been destroyed
basic_event<arg_destroy> destroy; ///< the window is destroyed, but occurs when all children have been destroyed
};
namespace detail

View File

@ -1,7 +1,7 @@
/*
* Inner Forward Declaration
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
* 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
@ -19,37 +19,6 @@
namespace nana{
namespace detail
{
struct signals
{
enum class code
{
caption,
read_caption,
destroy,
size,
end
};
union
{
const nana::char_t* caption;
nana::string * str;
struct
{
unsigned width;
unsigned height;
}size;
}info;
};
class signal_invoker_interface
{
public:
virtual ~signal_invoker_interface()
{}
virtual void call_signal(signals::code, const signals&) = 0;
};
}
}
#endif //NANA_GUI_INNER_FWD_HPP

View File

@ -121,7 +121,6 @@ namespace nana{
{
core_window_t* pressed{nullptr}; //The handle to a window which is being pressed
core_window_t* hovered{nullptr}; //the latest window that mouse moved
bool tabstop_focus_changed{false}; //KeyDown may set it true, if it is true KeyChar will ignore the message
}condition;
root_misc(core_window_t * wd, unsigned width, unsigned height)
@ -170,34 +169,6 @@ namespace nana{
std::map<native_window_type, root_misc> table_;
};
class signal_manager
{
typedef basic_window core_window_t;
public:
void make(core_window_t* wd, signal_invoker_interface* si)
{
if (si)
table_[wd].reset(si);
else
table_.erase(wd);
}
void umake(core_window_t * wd)
{
table_.erase(wd);
}
void call_signal(core_window_t * wd, signals::code code, const signals& s)
{
auto i = table_.find(wd);
if (i != table_.end())
i->second->call_signal(code, s);
}
private:
std::map<core_window_t*, std::unique_ptr<signal_invoker_interface>> table_;
};
}
}//end namespace nana
#endif //NANA_GUI_INNER_FWD_IMPLEMENT_HPP

View File

@ -44,7 +44,8 @@ namespace detail
#endif
static void enable_dropfiles(native_window_type, bool);
static void enable_window(native_window_type, bool);
static bool window_icon(native_window_type, const paint::image&);
// (On Windows) The system displays the large icon in the ALT+TAB dialog box, and the small icon in the window caption.
static bool window_icon(native_window_type, const paint::image& big_icon, const paint::image& small_icon);
static void activate_owner(native_window_type);
static void activate_window(native_window_type);
static void close_window(native_window_type);

View File

@ -0,0 +1,39 @@
/*
* Widget Notifier Interface
* 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/detail/widget_notifier_interface.hpp
*/
#ifndef NANA_GUI_DETAIL_WIDGET_NOTIFIER_INTERFACE_HEADER
#define NANA_GUI_DETAIL_WIDGET_NOTIFIER_INTERFACE_HEADER
#include <memory>
#include <string>
namespace nana
{
class widget; //forward declaration
namespace detail
{
class widget_notifier_interface
{
public:
virtual ~widget_notifier_interface() = default;
static std::unique_ptr<widget_notifier_interface> get_notifier(widget*); //defined in nana/gui/widgets/widget.cpp
virtual widget* widget_ptr() const = 0;
virtual void destroy() = 0;
virtual std::wstring caption() = 0;
virtual void caption(std::wstring) = 0;
};
}
}
#endif

View File

@ -42,24 +42,7 @@ namespace nana
namespace nana{
namespace detail
{
template<typename T>
class signal_invoker_mf
: public signal_invoker_interface
{
public:
signal_invoker_mf(T& obj, void(T::*mf)(signals::code, const signals&))
: obj_(obj),
mf_(mf)
{}
void call_signal(signals::code code, const signals& s) override
{
(obj_.*mf_)(code, s);
}
private:
T& obj_;
void(T::*mf_)(signals::code, const signals&);
};
class widget_notifier_interface; //forward declaration
struct root_misc;
@ -87,13 +70,11 @@ namespace detail
std::vector<thr_refcnt> stack_;
};
public:
typedef native_window_type native_window;
typedef revertible_mutex mutex_type;
using native_window = native_window_type;
using mutex_type = revertible_mutex;
typedef basic_window core_window_t;
typedef std::vector<core_window_t*> cont_type;
typedef window_layout wndlayout_type;
using core_window_t = basic_window;
using window_layer = window_layout;
window_manager();
~window_manager();
@ -103,16 +84,7 @@ namespace detail
mutex_type & internal_lock() const;
void all_handles(std::vector<core_window_t*>&) const;
template<typename T, typename Concept>
void attach_signal(core_window_t* wd, T& obj, void(Concept::*mf)(signals::code, const signals&))
{
return _m_attach_signal(wd, new signal_invoker_mf<Concept>(obj, mf));
}
void signal_fire_caption(core_window_t*, const nana::char_t*);
nana::string signal_fire_caption(core_window_t*);
void event_filter(core_window_t*, bool is_make, event_code);
void default_icon(const nana::paint::image&);
bool available(core_window_t*);
bool available(core_window_t *, core_window_t*);
@ -121,6 +93,7 @@ namespace detail
core_window_t* create_root(core_window_t*, bool nested, rectangle, const appearance&, widget*);
core_window_t* create_widget(core_window_t*, const rectangle&, bool is_lite, widget*);
core_window_t* create_frame(core_window_t*, const rectangle&, widget*);
bool insert_frame(core_window_t* frame, native_window);
bool insert_frame(core_window_t* frame, core_window_t*);
void close(core_window_t*);
@ -133,7 +106,8 @@ namespace detail
//@brief: Delete window handle, the handle type must be a root and a frame.
void destroy_handle(core_window_t*);
void icon(core_window_t*, const paint::image&);
void default_icon(const paint::image& small_icon, const paint::image& big_icon);
void icon(core_window_t*, const paint::image& small_icon, const paint::image& big_icon);
//show
//@brief: show or hide a window
@ -150,9 +124,9 @@ namespace detail
core_window_t* root(native_window_type) const;
//Copy the root buffer that wnd specified into DeviceContext
void map(core_window_t*, bool forced);
void map(core_window_t*, bool forced, const rectangle* update_area = nullptr);
bool update(core_window_t*, bool redraw, bool force);
bool update(core_window_t*, bool redraw, bool force, const rectangle* update_area = nullptr);
void refresh_tree(core_window_t*);
bool do_lazy_refresh(core_window_t*, bool force_copy_to_screen);
@ -188,7 +162,6 @@ namespace detail
core_window_t* find_shortkey(native_window_type, unsigned long key);
private:
void _m_attach_signal(core_window_t*, signal_invoker_interface*);
void _m_disengage(core_window_t*, core_window_t* for_new);
void _m_destroy(core_window_t*);
void _m_move_core(core_window_t*, const point& delta);
@ -200,8 +173,6 @@ namespace detail
struct wdm_private_impl;
wdm_private_impl * const impl_;
signals signals_;
struct attribute
{
struct captured

View File

@ -1,14 +1,13 @@
/*
* Utility Implementation
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/layout_utility.hpp
*
*
*/
#ifndef NANA_GUI_LAYOUT_UTILITY_HPP

View File

@ -48,13 +48,6 @@ namespace API
//@brief: The interfaces defined in namespace dev are used for developing the nana.gui
namespace dev
{
template<typename Object, typename Concept>
void attach_signal(window wd, Object& object, void (Concept::*f)(::nana::detail::signals::code, const ::nana::detail::signals&))
{
using namespace ::nana::detail;
bedrock::instance().wd_manager.attach_signal(reinterpret_cast<bedrock::core_window_t*>(wd), object, f);
}
bool set_events(window, const std::shared_ptr<general_events>&);
template<typename Scheme>
@ -68,7 +61,7 @@ namespace API
widget_colors* get_scheme(window);
void attach_drawer(widget&, drawer_trigger&);
nana::string window_caption(window);
nana::string window_caption(window) throw();
void window_caption(window, nana::string);
window create_window(window, bool nested, const rectangle&, const appearance&, widget* attached);
@ -119,10 +112,12 @@ namespace API
}
}
void window_icon_default(const paint::image&);
void window_icon(window, const paint::image&);
void window_icon_default(const paint::image& small_icon, const paint::image& big_icon = {});
void window_icon(window, const paint::image& small_icon, const paint::image& big_icon = {});
bool empty_window(window); ///< Determines whether a window is existing.
bool is_window(window); ///< Determines whether a window is existing, equal to !empty_window.
bool is_destroying(window); ///< Determines whether a window is destroying
void enable_dropfiles(window, bool);
/// \brief Retrieves the native window of a Nana.GUI window.
@ -300,6 +295,9 @@ namespace API
nana::mouse_action mouse_action(window);
nana::element_state element_state(window);
bool ignore_mouse_focus(window, bool ignore); ///< Enables/disables the mouse focus, it returns the previous state
bool ignore_mouse_focus(window); ///< Determines whether the mouse focus is enabled
}//end namespace API
}//end namespace nana

View File

@ -34,27 +34,38 @@ namespace nana
virtual const ::nana::rectangle& workarea() const = 0;
};
/// Provides some functions to get the metrics of the monitors \include screen.cpp
class screen
{
struct implement;
public:
static ::nana::size desktop_size();
static ::nana::size primary_monitor_size();
/// gets the size in pixel of the whole virtual desktop
static ::nana::size desktop_size();
/// gets the resolution in pixel of the primary monitor,
/// if there is only one monitor installed in the system,
/// the return value of primary_monitor_size is equal to desktop_size's.
static ::nana::size primary_monitor_size();
screen();
/// Reload has no preconditions, it's safe to call on moved-from
void reload();
/// Returns the number of display monitors
/// Returns the number of display monitors installed in the system
std::size_t count() const;
/// gets the display monitor that contains the specified point
display& from_point(const point&);
/// gets the display monitor that contains the specified window
display& from_window(window);
display& get_display(std::size_t index) const;
display& get_primary() const;
/// applies a given function to all display monitors
void for_each(std::function<void(display&)>) const;
private:
std::shared_ptr<implement> impl_;

View File

@ -15,7 +15,6 @@
#include "widget.hpp"
#include <nana/gui/element.hpp>
namespace nana{
namespace drawerbase
{
@ -46,12 +45,13 @@ namespace nana{
void mouse_up(graph_reference, const arg_mouse&) override;
void key_char(graph_reference, const arg_keyboard&) override;
void key_press(graph_reference, const arg_keyboard&) override;
void key_release(graph_reference, const arg_keyboard&) override;
void focus(graph_reference, const arg_focus&) override;
private:
void _m_draw(graph_reference);
void _m_draw_title(graph_reference, bool enabled);
void _m_draw_background(graph_reference);
void _m_draw_border(graph_reference);
void _m_press(graph_reference, bool);
private:
widget* wdg_{nullptr};
paint::graphics* graph_{nullptr};
@ -101,8 +101,6 @@ namespace nana{
bool transparent() const;
button& edge_effects(bool enable);
private:
void _m_shortkey();
private:
//Overrides widget virtual functions
void _m_complete_creation() override;

View File

@ -37,7 +37,6 @@ namespace drawerbase
public:
implement * impl() const;
private:
void _m_draw(graph_reference);
void _m_draw_background(graph_reference);
void _m_draw_checkbox(graph_reference, unsigned first_line_height);
void _m_draw_title(graph_reference);
@ -89,7 +88,7 @@ namespace drawerbase
std::size_t checked() const; ///< Retrieves the index of the checkbox which is checked.
std::size_t size() const;
private:
void _m_checked(const arg_mouse&);
void _m_checked(const arg_click&);
void _m_destroy(const arg_destroy&);
private:
std::vector<element_tag> ui_container_;

View File

@ -3,8 +3,8 @@
* 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
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/widgets/combox.hpp
@ -43,7 +43,7 @@ namespace nana
};
class drawer_impl;
class trigger
: public drawer_trigger
{
@ -101,7 +101,7 @@ namespace nana
throw std::runtime_error("combox::item_proxy.value<T>() invalid type of value");
return *p;
}
template<typename T>
item_proxy& value(const T& t)
{
@ -169,7 +169,7 @@ namespace nana
combox(window, nana::string, bool visible = true);
combox(window, const nana::char_t*, bool visible = true);
combox(window, const rectangle& r = rectangle(), bool visible = true);
void clear();
void editable(bool);
bool editable() const;
@ -209,8 +209,8 @@ namespace nana
_m_erase(p.get());
}
/// \brief Set user-defined item renderer object.
/// It is an address therefore the user should not destroy the renderer object
/// \brief Set user-defined item renderer object.
/// It is an address therefore the user should not destroy the renderer object
/// after it is set to the combox. Passing null_ptr cancels the user-defined renderer object.
void renderer(item_renderer*);
@ -224,7 +224,7 @@ namespace nana
const drawerbase::combox::drawer_impl& _m_impl() const;
private:
//Overrides widget's virtual functions
nana::string _m_caption() const override;
nana::string _m_caption() const throw() override;
void _m_caption(nana::string&&) override;
nana::any * _m_anyobj(std::size_t pos, bool alloc_if_empty) const override;
};

View File

@ -45,7 +45,6 @@ namespace nana
void week_name(unsigned index, const nana::string&);
private:
where _m_pos_where(graph_reference, const ::nana::point& pos);
void _m_draw(graph_reference);
void _m_draw_topbar(graph_reference);
void _m_make_drawing_basis(drawing_basis&, graph_reference, const nana::point& refpos);
void _m_draw_pos(drawing_basis &, graph_reference, int x, int y, const nana::string&, bool primary, bool sel);

View File

@ -0,0 +1,85 @@
/**
* A Inline Widget Interface Definition
* 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/detail/inline_widget.hpp
*
*/
#ifndef NANA_GUI_INLINE_WIDGETS_HPP
#define NANA_GUI_INLINE_WIDGETS_HPP
#include "../../basis.hpp"
namespace nana
{
namespace detail
{
template<typename Index, typename Value>
class inline_widget_indicator
{
public:
/// A type to index a item
using index_type = Index;
/// A type to the value of the item
using value_type = Value;
/// The destructor
virtual ~inline_widget_indicator() = default;
/// Returns the host widget of the indicator
virtual ::nana::widget& host() const = 0;
/// Modifies the value of a item specified by pos
virtual void modify(index_type pos, const value_type&) const = 0;
/// Sends a signal that a specified item is selected
virtual void selected(index_type) = 0;
/// Sends a signal that a specified item is hovered
virtual void hovered(index_type) = 0;
};
template<typename Index, typename Value>
class inline_widget_notifier_interface
{
public:
/// A type to index a item
using index_type = Index;
/// A type to the value of the item
using value_type = Value;
/// A typedef name of a inline widget indicator
using inline_indicator = inline_widget_indicator<index_type, value_type>;
/// A type to the notifier interface that will be refered by the abstract factory pattern
using factory_interface = inline_widget_notifier_interface;
/// The destructor
virtual ~inline_widget_notifier_interface() = default;
/// A message to create the inline widget
virtual void create(window) = 0;
/// A message to activate the inline widget to attach a specified item
virtual void activate(inline_indicator&, index_type) = 0;
/// A message to resize the inline widget
virtual void resize(const size&) = 0;
/// A message to set the value from the item
virtual void set(const value_type&) = 0;
/// Determines whether to draw the background of the widget
virtual bool whether_to_draw() const = 0;
}; //end class inline_widget_notifier_interface
}
}
#endif

View File

@ -0,0 +1,89 @@
/**
* A Inline Widget Manager Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/widgets/detail/inline_widget_manager.hpp
*
*/
#ifndef NANA_GUI_INLINE_WIDGET_MANAGER_HPP
#define NANA_GUI_INLINE_WIDGET_MANAGER_HPP
#include "inline_widget.hpp"
#include <nana/pat/abstract_factory.hpp>
#include "../panel.hpp"
#include <vector>
namespace nana
{
namespace detail
{
template<typename Index, typename Value>
class inline_widget_manager
{
using index_type = Index;
using value_type = Value;
using indicator_type = inline_widget_indicator<value_type>;
using inline_widget = inline_widget_interface<index_type, value_type>;
using factory = pat::abstract_factory<inline_widget>;
struct widget_holder
{
panel<false> docker;
std::unique_ptr<inline_widget> widget_ptr;
};
public:
void set_window(window wd)
{
window_handle_ = wd;
}
void set_factory(std::unique_ptr<factory> fac)
{
factory_.swap(fac);
}
void place(point pos, const size& dimension, const size & visible_size, const indicator_type& indicator, index_type index)
{
auto holder = _m_append();
holder->docker.move({ pos, visible_size });
holder->widget_ptr->move({ point(), dimension });
holder->widget_ptr->activate(indicator, index);
}
private:
widget_holder* _m_append()
{
if (swap_widgets_.empty())
{
widgets_.emplace_back();
widgets_.back().swap(swap_widgets_.back());
swap_widgets_.pop_back();
}
else
{
widgets_.emplace_back(new widget_holder);
auto & holder = widgets_.back();
holder->docker.create(window_handle_, false);
holder->widget_ptr.swap(factory_->create());
holder->widget_ptr->create(holder->docker->handle());
}
return widgets_.back().get();
}
private:
window window_handle_{nullptr};
std::unique_ptr<factory> factory_;
std::vector<std::unique_ptr<widget_holder>> widgets_;
std::vector<std::unique_ptr<widget_holder>> swap_widgets_;
};
}
}
#endif

View File

@ -0,0 +1,87 @@
/**
* A group widget implementation
* Nana C++ Library(http://www.nanaro.org)
* Copyright(C) 2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/widgets/group.hpp
*
* @Author: Stefan Pfeifer(st-321), Ariel Vina-Rodriguez (qPCR4vir)
*
* @brief group is a widget used to visually group and layout other widgets.
*/
#ifndef NANA_GUI_WIDGETS_GROUP_HPP
#define NANA_GUI_WIDGETS_GROUP_HPP
#include <nana/gui/place.hpp>
#include <nana/gui/widgets/panel.hpp>
namespace nana{
class group
: public panel<true>
{
struct implement;
public:
using field_reference = place::field_reference;
/// The default construction
group();
/// The construction that creates the widget
group(window parent, const rectangle& = {}, bool visible = true);
/// The construction that creates the widget and set the titel or caption
group(window parent, ///< a handle to the parent
::nana::string titel, ///< caption of the group
bool formatted = false, ///< Enable/disable the formatted text for the title
unsigned gap = 2, ///< betwen the content and the external limit
const rectangle& r = {} ,
bool visible = true
);
/// The destruction
~group();
/// Adds an option for user selection
group& add_option(::nana::string);
/// Enables/disables the radio mode which is single selection
group& radio_mode(bool);
/// Returns the index of option in radio_mode, it throws a logic_error if radio_mode is false.
std::size_t option() const;
/// Determines whether a specified option is checked, it throws an out_of_range if !(pos < number of options)
bool option_checked(std::size_t pos) const;
group& enable_format_caption(bool format);
group& collocate() throw();
group& div(const char* div_str) throw();
field_reference operator[](const char* field);
template<typename Widget, typename ...Args>
Widget* create_child(const char* field, Args && ... args)
{
auto wdg = new Widget(handle(), std::forward<Args>(args)...);
_m_add_child(field, wdg);
return wdg;
}
private:
void _m_add_child(const char* field, widget*);
void _m_init();
void _m_complete_creation() override;
::nana::string _m_caption() const throw() override;
void _m_caption(::nana::string&&) override;
private:
std::unique_ptr<implement> impl_;
};
}//end namespace nana
#endif

View File

@ -40,7 +40,7 @@ namespace nana
void refresh(graph_reference) override;
void mouse_move(graph_reference, const arg_mouse&) override;
void mouse_leave(graph_reference, const arg_mouse&) override;
void click(graph_reference, const arg_mouse&) override;
void click(graph_reference, const arg_click&) override;
private:
impl_t * impl_;
};
@ -58,14 +58,15 @@ namespace nana
label();
label(window, bool visible);
label(window, const nana::string& text, bool visible = true);
label(window, const nana::char_t* text, bool visible = true);
label(window, const rectangle& = {}, bool visible = true);
label& transparent(bool); ///< Switchs the label widget to the transparent background mode.
bool transparent() const;
bool transparent() const throw();
label& format(bool); ///< Switches the format mode of the widget.
label& add_format_listener(std::function<void(command, const nana::string&)>);
/// \briefReturn the size of the text. If *allowed_width_in_pixel* is not zero, returns a
label& click_for(window associated_window) throw(); // as same as the "for" attribute of a label
/// Returns the size of the text. If *allowed_width_in_pixel* is not zero, returns a
/// "corrected" size that changes lines to fit the text into the specified width
nana::size measure(unsigned allowed_width_in_pixel) const;

View File

@ -15,9 +15,10 @@
#ifndef NANA_GUI_WIDGETS_LISTBOX_HPP
#define NANA_GUI_WIDGETS_LISTBOX_HPP
#include "widget.hpp"
#include "detail/inline_widget.hpp"
#include <nana/pat/abstract_factory.hpp>
#include <nana/concepts.hpp>
#include <nana/key_type.hpp>
//#include <nana/paint/graphics.hpp>
#include <functional>
#include <initializer_list>
@ -29,7 +30,58 @@ namespace nana
{
namespace listbox
{
using size_type = std::size_t ;
using size_type = std::size_t;
/// usefull for both absolute and display (sorted) positions
struct index_pair
{
size_type cat; //The pos of category
size_type item; //the pos of item in a category.
index_pair(size_type cat_pos = 0, size_type item_pos = 0)
: cat(cat_pos),
item(item_pos)
{}
bool empty() const
{
return (npos == cat);
}
void set_both(size_type n)
{
cat = item = n;
}
bool is_category() const
{
return (npos != cat && npos == item);
}
bool is_item() const
{
return (npos != cat && npos != item);
}
bool operator==(const index_pair& r) const
{
return (r.cat == cat && r.item == item);
}
bool operator!=(const index_pair& r) const
{
return !this->operator==(r);
}
bool operator>(const index_pair& r) const
{
return (cat > r.cat) || (cat == r.cat && item > r.item);
}
};
using selection = std::vector<index_pair>;
using inline_notifier_interface = detail::inline_widget_notifier_interface<index_pair, std::wstring>;
struct cell
{
@ -114,58 +166,13 @@ namespace nana
std::size_t pos_{0};
};
/// usefull for both absolute and display (sorted) positions
struct index_pair
{
size_type cat; //The pos of category
size_type item; //the pos of item in a category.
index_pair(size_type cat_pos = 0, size_type item_pos = 0)
: cat(cat_pos),
item(item_pos)
{}
bool empty() const
{
return (npos == cat);
}
void set_both(size_type n)
{
cat = item = n;
}
bool is_category() const
{
return (npos != cat && npos == item);
}
bool is_item() const
{
return (npos != cat && npos != item);
}
bool operator==(const index_pair& r) const
{
return (r.cat == cat && r.item == item);
}
bool operator!=(const index_pair& r) const
{
return !this->operator==(r);
}
bool operator>(const index_pair& r) const
{
return (cat > r.cat) || (cat == r.cat && item > r.item);
}
};
typedef std::vector<index_pair> selection;
//struct essence_t
//@brief: this struct gives many data for listbox,
// the state of the struct does not effect on member funcions, therefore all data members are public.
/// struct essence_t
///@brief: this struct gives many data for listbox,
/// the state of the struct does not effect on member funcions, therefore all data members are public.
struct essence_t;
struct category_t;
@ -344,6 +351,8 @@ namespace nana
: public std::iterator < std::input_iterator_tag, cat_proxy >
{
public:
using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface;
cat_proxy() = default;
cat_proxy(essence_t*, size_type pos);
cat_proxy(essence_t*, category_t*);
@ -366,13 +375,17 @@ namespace nana
return iter;
}
void append(std::initializer_list<nana::string>);
/// Appends one item at the end of this category with the specifies text in the column fields
void append(std::initializer_list<nana::string>);
size_type columns() const;
cat_proxy& text(nana::string);
nana::string text() const;
cat_proxy & select(bool);
bool selected() const;
/// Behavior of a container
void push_back(nana::string);
@ -423,6 +436,8 @@ namespace nana
/// Behavior of Iterator
bool operator!=(const cat_proxy&) const;
void inline_factory(size_type column, pat::cloneable<pat::abstract_factory<inline_notifier_interface>> factory);
private:
void _m_append(std::vector<cell> && cells);
void _m_cat_by_pos();
@ -473,16 +488,54 @@ namespace nana
color_proxy header_grabbed{ static_cast<color_rgb>(0x8BD6F6)};
color_proxy header_floated{ static_cast<color_rgb>(0xBABBBC)};
color_proxy item_selected{ static_cast<color_rgb>(0xD5EFFC) };
unsigned max_header_width{3000}, /// \todo how to implement some geometrical parameters ??
ext_w = 5;
};
}
}//end namespace drawerbase
/*! \brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items.
/*! \class listbox
\brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items.
A category is a text with can be \a selected, \a checked and \a expanded to show the items.
An item is formed by \a column-fields, each corresponding to one of the \a headers.
An item can be \a selected and \a checked.
The user can \a drag the header to \a reisize it or to \a reorganize it.
By \a clicking on a header the list get \a reordered, first up, and then down alternatively.
The user can \a drag the header to \a resize it or to \a reorganize it.
By \a clicking on one header the list get \a reordered, first up, and then down alternatively.
1. The resolver is used to resolute an object of the specified type for a listbox item.
3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0.
4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement:
Irreflexivity (comp(x, x) returns false)
and
antisymmetry(comp(a, b) != comp(b, a) returns true)
A simple example.
bool sort_compare( const nana::string& s1, nana::any*,
const nana::string& s2, nana::any*, bool reverse)
{
return (reverse ? s1 > s2 : s1 < s2);
}
listbox.set_sort_compare(0, sort_compare);
The listbox supports attaching a customer's object for each item, therefore the items can be
sorted by comparing these customer's object.
bool sort_compare( const nana::string&, nana::any* o1,
const nana::string&, nana::any* o2, bool reverse)
{
if(o1 && o2) //some items may not attach a customer object.
{
int * i1 = o1->get<int>();
int * i2 = o2->get<int>();
return (i1 && i2 && (reverse ? *i1 > *i2 : *i1 < *i2));
;//some types may not be int.
}
return false;
}
listbox.anyobj(0, 0, 10); //the type of customer's object is int.
listbox.anyobj(0, 0, 20);
\todo doc: actualize this example listbox.at(0)...
\see nana::drawerbase::listbox::cat_proxy
\see nana::drawerbase::listbox::item_proxy
\example listbox_Resolver.cpp
*/
class listbox
: public widget_object<category::widget_tag, drawerbase::listbox::trigger, drawerbase::listbox::listbox_events, drawerbase::listbox::scheme>,
@ -499,19 +552,23 @@ By \a clicking on a header the list get \a reordered, first up, and then down al
using cell = drawerbase::listbox::cell;
using export_options= drawerbase::listbox::export_options;
using columns_indexs= drawerbase::listbox::size_type;
using inline_notifier_interface = drawerbase::listbox::inline_notifier_interface;
public:
listbox() = default;
listbox(window, bool visible);
listbox(window, const rectangle& = {}, bool visible = true);
void auto_draw(bool); ///<Set state: Redraw automatically after an operation?
void auto_draw(bool); ///< Set state: Redraw automatically after an operation?
void append_header(nana::string, unsigned width = 120);///<Appends a new column with a header text and the specified width at the end
listbox& header_width(size_type pos, unsigned pixels);
unsigned header_width(size_type pos) const;
/// Appends a new column with a header text and the specified width at the end, and return it position
size_type append_header(nana::string header_text, unsigned width = 120);
listbox& header_width(size_type position, unsigned pixels);
unsigned header_width(size_type position) const;
unsigned auto_width(size_type position, unsigned max=3000);
cat_proxy append(nana::string); ///<Appends a new category at the end
void append(std::initializer_list<nana::string>); ///<Appends categories at the end
cat_proxy append(nana::string); ///< Appends a new category at the end
void append(std::initializer_list<nana::string>); ///< Appends categories at the end
cat_proxy insert(cat_proxy, nana::string);
cat_proxy at(size_type pos) const;

View File

@ -108,7 +108,7 @@ namespace nana
virtual void background(graph_reference, window) = 0;
virtual void item(graph_reference, const nana::rectangle&, const attr&) = 0;
virtual void item_image(graph_reference, const nana::point&, const paint::image&) = 0;
virtual void item_image(graph_reference, const nana::point&, unsigned image_px, const paint::image&) = 0;
virtual void item_text(graph_reference, const nana::point&, const nana::string&, unsigned text_pixels, const attr&) = 0;
virtual void sub_arrow(graph_reference, const nana::point&, unsigned item_pixels, const attr&) = 0;
};

View File

@ -67,7 +67,6 @@ namespace nana
bool _m_close_menu();
std::size_t _m_item_by_pos(const ::nana::point&);
bool _m_track_mouse(const ::nana::point&);
void _m_draw();
private:
widget *widget_;
nana::paint::graphics *graph_;

View File

@ -30,11 +30,12 @@ namespace nana
unsigned Max(unsigned);
void unknown(bool);
bool unknown() const;
bool stop(bool s = true);
bool stopped() const;
private:
void attached(widget_reference, graph_reference) override;
void refresh(graph_reference) override;
private:
void _m_draw();
void _m_draw_box(graph_reference);
void _m_draw_progress(graph_reference);
bool _m_check_changing(unsigned) const;
@ -45,6 +46,7 @@ namespace nana
nana::paint::graphics* graph_{nullptr};
unsigned draw_width_{static_cast<unsigned>(-1)};
bool unknown_{false};
bool stop_{false};
unsigned max_{100};
unsigned value_{0};
}; //end class drawer
@ -67,6 +69,8 @@ namespace nana
unsigned amount(unsigned value);
void unknown(bool);
bool unknown() const;
bool stop(bool s=true); ///< request stop or cancel and return previus stop status
bool stopped() const;
};
}//end namespace nana
#endif

View File

@ -19,16 +19,15 @@
namespace nana
{
template<bool Vert> class scroll;
template<bool Vert> class scroll; //forward declaration
template<bool Vert>
struct arg_scroll
: public event_arg
{
scroll<Vert> & widget;
window window_handle;
arg_scroll(scroll<Vert> & wdg)
: widget(wdg)
arg_scroll(window wd)
: window_handle{ wd }
{}
};
@ -36,11 +35,10 @@ namespace nana
{
namespace scroll
{
template<bool Vert>
struct scroll_events
: public general_events
{
basic_event<arg_scroll<Vert>> value_changed;
basic_event<arg_scroll> value_changed;
};
enum class buttons
@ -313,7 +311,7 @@ namespace nana
private:
void _m_emit_value_changed()
{
widget_->events().value_changed.emit(::nana::arg_scroll<Vertical>(*widget_));
widget_->events().value_changed.emit({ widget_->handle() });
}
void _m_tick()
@ -335,7 +333,7 @@ namespace nana
/// Provides a way to display an object which is larger than the window's client area.
template<bool Vertical>
class scroll // add a widget scheme?
: public widget_object<category::widget_tag, drawerbase::scroll::trigger<Vertical>, drawerbase::scroll::scroll_events<Vertical>>
: public widget_object<category::widget_tag, drawerbase::scroll::trigger<Vertical>, drawerbase::scroll::scroll_events>
{
typedef widget_object<category::widget_tag, drawerbase::scroll::trigger<Vertical> > base_type;
public:
@ -448,7 +446,6 @@ namespace nana
{
return this->make_step(forward, range() - 1);
}
};//end class scroll
}//end namespace nana
#endif

View File

@ -157,8 +157,8 @@ namespace nana{ namespace widgets
void set_accept(std::function<bool(char_type)>);
void set_accept(accepts);
bool respond_char(char_type);
bool respond_key(char_type);
bool respond_char(const arg_keyboard& arg);
bool respond_key(const arg_keyboard& arg);
void typeface_changed();
@ -231,13 +231,14 @@ namespace nana{ namespace widgets
void move_ns(bool to_north); //Moves up and down
void move_left();
void move_right();
nana::upoint mouse_caret(const point& screen_pos);
nana::upoint caret() const;
upoint mouse_caret(const point& screen_pos);
upoint caret() const;
point caret_screen_pos() const;
bool scroll(bool upwards, bool vertical);
bool mouse_enter(bool);
bool mouse_down(bool left_button, const point& screen_pos);
bool mouse_down(::nana::mouse, const point& screen_pos);
bool mouse_move(bool left_button, const point& screen_pos);
bool mouse_up(bool left_button, const point& screen_pos);
bool mouse_up(::nana::mouse, const point& screen_pos);
skeletons::textbase<nana::char_t>& textbase();
const skeletons::textbase<nana::char_t>& textbase() const;
@ -286,6 +287,8 @@ namespace nana{ namespace widgets
unsigned _m_char_by_pixels(const nana::char_t*, std::size_t len, unsigned* pxbuf, int str_px, int pixels, bool is_rtl);
unsigned _m_pixels_by_char(const nana::string&, std::size_t pos) const;
static bool _m_is_right_text(const unicode_bidi::entity&);
void _handle_move_key(const arg_keyboard& arg);
private:
std::unique_ptr<editor_behavior_interface> behavior_;
undoable<command> undo_;

View File

@ -574,9 +574,9 @@ namespace nana{ namespace widgets{ namespace skeletons
virtual void nontext_render(graph_reference graph, int x, int y) override
{
if(size_ != image_.size())
image_.stretch(image_.size(), graph, nana::rectangle(x, y, size_.width, size_.height));
image_.stretch(::nana::rectangle{ image_.size() }, graph, nana::rectangle(x, y, size_.width, size_.height));
else
image_.paste(graph, x, y);
image_.paste(graph, point{ x, y });
}
virtual const nana::size & size() const override

View File

@ -106,7 +106,7 @@ namespace nana
void modifier(std::wstring prefix, std::wstring suffix);
void modifier(const std::string & prefix_utf8, const std::string& suffix_utf8);
private:
::nana::string _m_caption() const;
::nana::string _m_caption() const throw();
void _m_caption(::nana::string&&);
}; //end class spinbox

View File

@ -144,12 +144,15 @@ namespace nana
bool saved() const;
/// Read the text from a specified line. It returns true for success.
bool getline(std::size_t line_index, nana::string&) const;
bool getline(std::size_t pos, nana::string&) const;
/// Gets the caret position
bool caret_pos(point& pos, bool text_coordinate) const;
/// Appends an string. If `at_caret` is `true`, the string is inserted at the position of caret, otherwise, it is appended at end of the textbox.
textbox& append(const nana::string& text, bool at_caret);
/// Determine wheter the text is line wrapped.
/// Determine wheter the text is line wrapped.
bool line_wrapped() const;
textbox& line_wrapped(bool);
@ -187,7 +190,7 @@ namespace nana
void erase_keyword(const nana::string& kw);
protected:
//Overrides widget's virtual functions
::nana::string _m_caption() const override;
::nana::string _m_caption() const throw() override;
void _m_caption(::nana::string&&) override;
void _m_typeface(const paint::font&) override;
};

View File

@ -14,7 +14,6 @@
#define NANA_GUI_WIDGET_TOOLBAR_HPP
#include "widget.hpp"
#include <vector>
namespace nana
{
@ -39,10 +38,10 @@ namespace nana
basic_event<arg_toolbar> selected; ///< A mouse click on a control button.
basic_event<arg_toolbar> enter; ///< The mouse enters a control button.
basic_event<arg_toolbar> leave; ///< The mouse leaves a control button.
};
struct item_type;
class item_container;
class drawer
: public drawer_trigger
@ -50,15 +49,12 @@ namespace nana
struct drawer_impl_type;
public:
typedef std::size_t size_type;
using size_type = std::size_t;
drawer();
~drawer();
void append(const nana::string&, const nana::paint::image&);
void append();
bool enable(size_type) const;
bool enable(size_type, bool);
item_container& items() const;
void scale(unsigned);
private:
void refresh(graph_reference) override;
@ -69,32 +65,28 @@ namespace nana
void mouse_down(graph_reference, const arg_mouse&) override;
void mouse_up(graph_reference, const arg_mouse&) override;
private:
size_type _m_which(int x, int y, bool want_if_disabled) const;
void _m_draw_background(const ::nana::color&);
void _m_draw();
void _m_owner_sized(const arg_resized&);
private:
void _m_fill_pixels(item_type*, bool force);
size_type _m_which(point, bool want_if_disabled) const;
void _m_calc_pixels(item_type*, bool force);
private:
::nana::toolbar* widget_;
::nana::paint::graphics* graph_;
drawer_impl_type* impl_;
};
}//end namespace toolbar
}//end namespace drawerbase
/// Control bar that contains buttons for controlling
class toolbar
: public widget_object<category::widget_tag, drawerbase::toolbar::drawer, drawerbase::toolbar::toolbar_events>
{
public:
typedef std::size_t size_type; ///< A type to count the number of elements.
using size_type = std::size_t; ///< A type to count the number of elements.
toolbar() = default;
toolbar(window, bool visible);
toolbar(window, const rectangle& = rectangle(), bool visible = true);
void append(); ///< Adds a separator.
void separate(); ///< Adds a separator.
void append(const nana::string& text, const nana::paint::image& img); ///< Adds a control button.
void append(const nana::string& text); ///< Adds a control button.
bool enable(size_type index) const;

View File

@ -12,20 +12,26 @@
#ifndef NANA_GUI_WIDGET_HPP
#define NANA_GUI_WIDGET_HPP
#include <nana/traits.hpp>
#include "../basis.hpp"
#include "../programming_interface.hpp"
#include <nana/internationalization.hpp>
#include <nana/gui/detail/drawer.hpp>
#include <nana/gui/layout_utility.hpp>
#include <functional>
namespace nana
{
namespace detail
{
//Forward declaration of widget_notifier_interface
class widget_notifier_interface;
}
/// Abstract class for defining the capacity interface.
class widget
: nana::noncopyable, nana::nonmovable
{
friend class detail::widget_notifier_interface;
class notifier;
typedef void(*dummy_bool_type)(widget* (*)(const widget&));
public:
virtual ~widget() = default;
@ -35,9 +41,9 @@ namespace nana
window parent() const;
nana::string caption() const;
nana::string caption() const throw();
void caption(std::string utf8);
void caption(nana::string);
void caption(std::wstring);
template<typename ...Args>
void i18n(std::string msgid, Args&&... args)
@ -70,6 +76,7 @@ namespace nana
point pos() const;
void move(int x, int y);
void move(const point&);
void move(const rectangle&);
void fgcolor(const nana::color&);
@ -88,12 +95,17 @@ namespace nana
operator dummy_bool_type() const;
operator window() const;
protected:
std::unique_ptr<::nana::detail::widget_notifier_interface> _m_wdg_notifier();
private:
virtual void _m_notify_destroy() = 0;
protected:
//protected members, a derived class must call this implementation if it overrides an implementation
virtual void _m_complete_creation();
virtual general_events& _m_get_general_events() const = 0;
virtual nana::string _m_caption() const;
virtual nana::string _m_caption() const throw();
virtual void _m_caption(nana::string&&);
virtual nana::cursor _m_cursor() const;
virtual void _m_cursor(nana::cursor);
@ -152,7 +164,6 @@ namespace nana
handle_ = API::dev::create_widget(parent_wd, r, this);
API::dev::set_events(handle_, events_);
API::dev::set_scheme(handle_, scheme_.get());
API::dev::attach_signal(handle_, *this, &widget_object::signal);
API::dev::attach_drawer(*this, trigger_);
if(visible)
API::show_window(handle_, true);
@ -193,29 +204,15 @@ namespace nana
return trigger_;
}
private:
void signal(detail::signals::code code, const detail::signals& sig)
{
typedef detail::signals::code codes;
switch(code)
{
case codes::caption:
this->_m_caption(sig.info.caption);
break;
case codes::read_caption:
*sig.info.str = this->_m_caption();
break;
case codes::destroy:
handle_ = nullptr;
break;
default:
break;
}
}
general_events& _m_get_general_events() const override
{
return *events_;
}
void _m_notify_destroy() override final
{
handle_ = nullptr;
}
private:
window handle_{nullptr};
DrawerTrigger trigger_;
@ -276,29 +273,15 @@ namespace nana
return *scheme_;
}
private:
void signal(detail::signals::code code, const detail::signals& sig)
{
typedef detail::signals::code codes;
switch(code)
{
case codes::caption:
this->_m_caption(sig.info.caption);
break;
case codes::read_caption:
*sig.info.str = this->_m_caption();
break;
case codes::destroy:
handle_ = nullptr;
break;
default:
break;
}
}
general_events& _m_get_general_events() const override
{
return *events_;
}
void _m_notify_destroy() override final
{
handle_ = nullptr;
}
private:
window handle_{nullptr};
std::shared_ptr<Events> events_;
@ -430,25 +413,6 @@ namespace nana
return trigger_;
}
private:
void signal(detail::signals::code code, const detail::signals& sig)
{
typedef detail::signals::code codes;
switch(code)
{
case codes::caption:
this->_m_caption(sig.info.caption);
break;
case codes::read_caption:
*sig.info.str = this->_m_caption();
break;
case codes::destroy:
handle_ = nullptr;
break;
default:
break;
}
}
void _m_bind_and_attach()
{
events_ = std::make_shared<Events>();
@ -456,7 +420,6 @@ namespace nana
scheme_ = API::dev::make_scheme<scheme_type>();
API::dev::set_scheme(handle_, scheme_.get());
API::dev::attach_signal(handle_, *this, &widget_object::signal);
API::dev::attach_drawer(*this, trigger_);
}
@ -464,6 +427,11 @@ namespace nana
{
return *events_;
}
void _m_notify_destroy() override final
{
handle_ = nullptr;
}
private:
window handle_;
DrawerTrigger trigger_;
@ -511,7 +479,6 @@ namespace nana
handle_ = API::dev::create_frame(parent_wd, r, this);
API::dev::set_events(handle_, events_);
API::dev::set_scheme(handle_, scheme_.get());
API::dev::attach_signal(handle_, *this, &widget_object::signal);
API::show_window(handle_, visible);
this->_m_complete_creation();
}
@ -533,29 +500,15 @@ namespace nana
return nullptr;
}
void signal(detail::signals::code code, const detail::signals& sig)
{
typedef detail::signals::code codes;
switch(code)
{
case codes::caption:
this->_m_caption(sig.info.caption);
break;
case codes::read_caption:
*sig.info.str = this->_m_caption();
break;
case codes::destroy:
handle_ = nullptr;
break;
default:
break;
}
}
general_events& _m_get_general_events() const override
{
return *events_;
}
void _m_notify_destroy() override final
{
handle_ = nullptr;
}
private:
window handle_{nullptr};
std::shared_ptr<Events> events_;

View File

@ -16,11 +16,12 @@ namespace nana{ namespace paint{
typedef nana::paint::graphics& graph_reference;
virtual ~image_impl_interface() = 0; //The destructor is defined in ../image.cpp
virtual bool open(const nana::char_t* filename) = 0;
virtual bool open(const void* data, std::size_t bytes) = 0; // reads image from memory
virtual bool alpha_channel() const = 0;
virtual bool empty() const = 0;
virtual void close() = 0;
virtual nana::size size() const = 0;
virtual void paste(const nana::rectangle& src_r, graph_reference dst, int x, int y) const = 0;
virtual void paste(const nana::rectangle& src_r, graph_reference dst, const point& p_dst) const = 0;
virtual void stretch(const nana::rectangle& src_r, graph_reference dst, const nana::rectangle& r) const = 0;
};//end class image::image_impl_interface
}//end namespace paint

View File

@ -130,7 +130,7 @@ namespace nana
void setsta(); ///< Clears the status if the graphics object had been changed
void set_changed();
void release();
void save_as_file(const char*);
void save_as_file(const char*) const; // saves image as a bitmap file
void set_color(const ::nana::color&);
void set_text_color(const ::nana::color&);

View File

@ -37,13 +37,16 @@ namespace paint
image& operator=(const image& rhs);
image& operator=(image&&);
bool open(const nana::string& filename);
/// Opens an icon from a specified buffer
bool open_icon(const void* data, std::size_t bytes);
bool empty() const;
operator unspecified_bool_t() const;
void close();
bool alpha() const;
nana::size size() const;
void paste(graphics& dst, int x, int y) const;
void paste(graphics& dst, const point& p_dst) const;
void paste(const nana::rectangle& r_src, graphics& dst, const point& p_dst) const;///< Paste the area of picture specified by r_src into the destination graphics specified by dst at position p_dst.
void stretch(const nana::rectangle& r_src, graphics& dst, const nana::rectangle& r_dst) const;///<Paste the picture into the dst, stretching or compressing the picture to fit the given area.
private:

View File

@ -76,9 +76,9 @@ namespace nana{ namespace paint
pixel_color_t pixel(int x, int y) const;
void pixel(int x, int y, pixel_color_t);
void paste(drawable_type, int x, int y) const;
void paste(const nana::rectangle& s_r, drawable_type, int x, int y) const;
void paste(native_window_type, int x, int y) const;
void paste(drawable_type, const point& p_dst) const;
void paste(const nana::rectangle& s_r, drawable_type, const point& p_dst) const;
void paste(native_window_type, const point& p_dst) const;
void stretch(const std::string& name);
void stretch(const nana::rectangle& s_r, drawable_type, const nana::rectangle& r) const;
void blend(const std::string& name);

View File

@ -0,0 +1,63 @@
/*
* A Generic Abstract Factory Pattern Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/pat/abstract_factory.hpp
* @description: A generic easy-to-use abstract factory pattern implementation
*/
#ifndef NANA_PAT_ABSFACTORY_HPP
#define NANA_PAT_ABSFACTORY_HPP
#include <memory>
namespace nana
{
namespace pat
{
namespace detail
{
//A Base class for abstract factory, avoids decorated name length exceeding for a class template.
class abstract_factory_base
{
public:
virtual ~abstract_factory_base() = default;
};
}
template<typename Interface>
class abstract_factory
: public detail::abstract_factory_base
{
public:
using interface_type = Interface;
virtual ~abstract_factory() = default;
virtual std::unique_ptr<interface_type> create() = 0;
};
namespace detail
{
template<typename T, typename Interface>
class abs_factory
: public abstract_factory<Interface>
{
std::unique_ptr<Interface> create() override
{
return std::unique_ptr<Interface>{ new T };
}
};
}//end namespace detail
template<typename Type>
pat::cloneable<abstract_factory<typename Type::factory_interface>> make_factory()
{
return detail::abs_factory<Type, typename Type::factory_interface>();
}
}//end namespace pat
}//end namespace nana
#endif

View File

@ -8,17 +8,20 @@ namespace nana{ namespace audio
//class audio_stream
bool audio_stream::open(const nana::string& file)
{
fs_.open(static_cast<std::string>(nana::charset(file)), std::ios::binary);
fs_.open(static_cast<std::string>(charset(file)), std::ios::binary);
if(fs_)
{
wave_spec::master_riff_chunk riff;
fs_.read(reinterpret_cast<char*>(&riff), sizeof(riff));
if(riff.ckID == *reinterpret_cast<const unsigned long*>("RIFF") && riff.waveID == *reinterpret_cast<const unsigned long*>("WAVE"))
if(riff.ckID == *reinterpret_cast<const unsigned*>("RIFF") && riff.waveID == *reinterpret_cast<const unsigned*>("WAVE"))
{
fs_.read(reinterpret_cast<char*>(&ck_format_), sizeof(ck_format_));
if(ck_format_.ckID == *reinterpret_cast<const unsigned long*>("fmt ") && ck_format_.wFormatTag == 1) //Only support PCM format
if(ck_format_.ckID == *reinterpret_cast<const unsigned*>("fmt ") && ck_format_.wFormatTag == 1) //Only support PCM format
{
std::size_t cksize = _m_locate_chunck(*reinterpret_cast<const unsigned long*>("data"));
if (ck_format_.cksize > 16)
fs_.seekg(ck_format_.cksize - 16, std::ios::cur);
std::size_t cksize = _m_locate_chunck(*reinterpret_cast<const unsigned*>("data"));
if(cksize)
{
pcm_data_pos_ = static_cast<std::size_t>(fs_.tellg());
@ -77,7 +80,7 @@ namespace nana{ namespace audio
if(ck.ckID == ckID)
return ck.cksize;
if(ck.ckID == *reinterpret_cast<const unsigned long*>("data"))
if(ck.ckID == *reinterpret_cast<const unsigned*>("data"))
fs_.seekg(ck.cksize + (ck.cksize & 1 ? 1 : 0), std::ios::cur);
else
fs_.seekg(ck.cksize, std::ios::cur);
@ -88,4 +91,4 @@ namespace nana{ namespace audio
}//end namespace detail
}//end namespace audio
}//end namespace nana
}//end namespace nana

View File

@ -799,7 +799,7 @@ namespace nana
switch(utf_x_)
{
case unicode::utf8:
#if defined(NANA_MINGW)
#if defined(NANA_WINDOWS)
strbuf = detail::utf8_to_utf16(data_, true);
detail::put_utf16char(strbuf, 0, true);
#else
@ -808,7 +808,7 @@ namespace nana
#endif
break;
case unicode::utf16:
#if defined(NANA_MINGW)
#if defined(NANA_WINDOWS)
strbuf = data_;
detail::put_utf16char(strbuf, 0, true);
#else
@ -817,7 +817,7 @@ namespace nana
#endif
break;
case unicode::utf32:
#if defined(NANA_MINGW)
#if defined(NANA_WINDOWS)
strbuf = detail::utf32_to_utf16(data_);
detail::put_utf16char(strbuf, 0, true);
#else
@ -907,21 +907,21 @@ namespace nana
switch(utf_x_)
{
case unicode::utf8:
#if defined(NANA_MINGW)
#if defined(NANA_WINDOWS)
bytes = detail::utf8_to_utf16(data_, true);
#else
bytes = detail::utf8_to_utf32(data_, true);
#endif
break;
case unicode::utf16:
#if defined(NANA_MINGW)
#if defined(NANA_WINDOWS)
bytes = data_;
#else
bytes = detail::utf16_to_utf32(data_);
#endif
break;
case unicode::utf32:
#if defined(NANA_MINGW)
#if defined(NANA_WINDOWS)
bytes = detail::utf32_to_utf16(data_);
#else
bytes = data_;
@ -984,19 +984,19 @@ namespace nana
switch(encoding)
{
case unicode::utf8:
#if defined(NANA_MINGW)
#if defined(NANA_WINDOWS)
return detail::utf16_to_utf8(std::string(reinterpret_cast<const char*>(data_.c_str()), data_.size() * sizeof(wchar_t)));
#else
return detail::utf32_to_utf8(std::string(reinterpret_cast<const char*>(data_.c_str()), data_.size() * sizeof(wchar_t)));
#endif
case unicode::utf16:
#if defined(NANA_MINGW)
#if defined(NANA_WINDOWS)
return std::string(reinterpret_cast<const char*>(data_.c_str()), data_.size() * sizeof(wchar_t));
#else
return detail::utf32_to_utf16(std::string(reinterpret_cast<const char*>(data_.c_str()), data_.size() * sizeof(wchar_t)));
#endif
case unicode::utf32:
#if defined(NANA_MINGW)
#if defined(NANA_WINDOWS)
return detail::utf16_to_utf32(std::string(reinterpret_cast<const char*>(data_.c_str()), data_.size() * sizeof(wchar_t)));
#else
return std::string(reinterpret_cast<const char*>(data_.c_str()), data_.size() * sizeof(wchar_t));

View File

@ -17,7 +17,7 @@
#ifndef NANA_DETAIL_MSG_DISPATCHER_HPP
#define NANA_DETAIL_MSG_DISPATCHER_HPP
#include "msg_packet.hpp"
#include <nana/detail/linux_X11/msg_packet.hpp>
#include <nana/system/platform.hpp>
#include <list>
#include <set>

View File

@ -16,7 +16,6 @@
#include <nana/config.hpp>
#include PLATFORM_SPEC_HPP
#include <nana/detail/linux_X11/msg_dispatcher.hpp>
#include <X11/Xlocale.h>
#include <locale>
#include <map>
@ -29,6 +28,8 @@
#include <errno.h>
#include <sstream>
#include "msg_dispatcher.hpp"
namespace nana
{
namespace detail
@ -44,7 +45,7 @@ namespace detail
bool conf::open(const char* file)
{
ifs_.open(file);
return static_cast<bool>(ifs_ != 0);
return static_cast<bool>(ifs_);
}
std::string conf::value(const char* key)
@ -922,7 +923,7 @@ namespace detail
{
if(crt.visible && (false == caret_reinstate(crt)))
{
crt.rev_graph.bitblt(crt.size, crt.window, crt.pos);
crt.rev_graph.bitblt(rectangle{crt.size}, crt.window, crt.pos);
crt.rev.width = crt.size.width;
crt.rev.height = crt.size.height;
crt.rev.x = crt.pos.x;
@ -948,7 +949,7 @@ namespace detail
nana::paint::graphics * crt_graph;
if(crt.rev.width && crt.rev.height)
{
crt.rev_graph.bitblt(crt.size, root_graph, crt.pos);
crt.rev_graph.bitblt(rectangle{crt.size}, root_graph, crt.pos);
crt_graph = &crt.graph;
owns_caret = true;
}
@ -1132,7 +1133,7 @@ namespace detail
{
nana::paint::graphics & graph = iconbase_[wd];
graph.make(img.size());
img.paste(graph, 0, 0);
img.paste(graph, {});
return graph;
}

View File

@ -273,9 +273,11 @@ namespace detail
return object;
}
void platform_spec::keep_window_icon(native_window_type wd, const paint::image& img)
void platform_spec::keep_window_icon(native_window_type wd, const paint::image& sml_icon, const paint::image& big_icon)
{
iconbase_[wd] = img;
auto & icons = iconbase_[wd];
icons.sml_icon = sml_icon;
icons.big_icon = big_icon;
}
void platform_spec::release_window_icon(native_window_type wd)

View File

@ -0,0 +1,444 @@
/*
* A ISO C++ FileSystem Implementation
* 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/filesystem/filesystem.cpp
* @description:
* provide some interface for file managment
*/
#include <nana/filesystem/filesystem.hpp>
#include <vector>
#if defined(NANA_WINDOWS)
#include <windows.h>
#if defined(NANA_MINGW)
#ifndef _WIN32_IE
#define _WIN32_IE 0x0500
#endif
#endif
#include <shlobj.h>
#include <nana/datetime.hpp>
#elif defined(NANA_LINUX)
#include <nana/charset.hpp>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <cstdio>
#include <cstring>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#endif
namespace nana {
namespace experimental
{
namespace filesystem
{
//Because of No wide character version of POSIX
#if defined(NANA_LINUX)
typedef std::string string_t;
const char* splstr = "/\\";
#else
typedef nana::string string_t;
const nana::char_t* splstr = STR("/\\");
#endif
//class path
path::path() {}
path::path(const nana::string& text)
#if defined(NANA_WINDOWS)
: text_(text)
{
#else
:text_(nana::charset(text))
{
#endif
auto pos = text_.find_last_of(splstr);
for (; (pos != string_t::npos) && (pos + 1 == text_.size()); pos = text_.find_last_of(splstr))
text_.erase(pos);
}
bool path::empty() const
{
#if defined(NANA_WINDOWS)
return (::GetFileAttributes(text_.c_str()) == INVALID_FILE_ATTRIBUTES);
#elif defined(NANA_LINUX)
struct stat sta;
return (::stat(text_.c_str(), &sta) == -1);
#endif
}
path path::root() const
{
#if defined(NANA_WINDOWS)
return path(filesystem::root(text_));
#elif defined(NANA_LINUX)
return path(filesystem::root(nana::charset(text_)));
#endif
}
file_type path::what() const
{
#if defined(NANA_WINDOWS)
unsigned long attr = ::GetFileAttributes(text_.c_str());
if (INVALID_FILE_ATTRIBUTES == attr)
return file_type::not_found; //??
if (FILE_ATTRIBUTE_DIRECTORY & attr)
return file_type::directory;
return file_type::regular;
#elif defined(NANA_LINUX)
struct stat sta;
if (-1 == ::stat(text_.c_str(), &sta))
return file_type::not_found; //??
if ((S_IFDIR & sta.st_mode) == S_IFDIR)
return file_type::directory;
if ((S_IFREG & sta.st_mode) == S_IFREG)
return file_type::regular;
return file_type::none;
#endif
}
nana::string path::filename() const
{
string_t::size_type pos = text_.find_last_of(splstr);
#if defined(NANA_WINDOWS)
return text_.substr(pos + 1);
#else
return nana::charset(text_.substr(pos + 1));
#endif
}
//end class path
namespace detail
{
//rm_dir_recursive
//@brief: remove a directory, if it is not empty, recursively remove it's subfiles and sub directories
bool rm_dir_recursive(nana::string&& dir)
{
std::vector<directory_iterator::value_type> files;
nana::string path = dir;
path += '\\';
std::copy(directory_iterator(dir), directory_iterator(), std::back_inserter(files));
for (auto & f : files)
{
if (f.attr.directory)
rm_dir_recursive(path + f.path().filename());
else
rmfile((path + f.path().filename()).c_str());
}
return rmdir(dir.c_str(), true);
}
bool mkdir_helper(const nana::string& dir, bool & if_exist)
{
#if defined(NANA_WINDOWS)
if (::CreateDirectory(dir.c_str(), 0))
{
if_exist = false;
return true;
}
if_exist = (::GetLastError() == ERROR_ALREADY_EXISTS);
#elif defined(NANA_LINUX)
if (0 == ::mkdir(static_cast<std::string>(nana::charset(dir)).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
{
if_exist = false;
return true;
}
if_exist = (errno == EEXIST);
#endif
return false;
}
#if defined(NANA_WINDOWS)
void filetime_to_c_tm(FILETIME& ft, struct tm& t)
{
FILETIME local_file_time;
if (::FileTimeToLocalFileTime(&ft, &local_file_time))
{
SYSTEMTIME st;
::FileTimeToSystemTime(&local_file_time, &st);
t.tm_year = st.wYear - 1900;
t.tm_mon = st.wMonth - 1;
t.tm_mday = st.wDay;
t.tm_wday = st.wDayOfWeek - 1;
t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay);
t.tm_hour = st.wHour;
t.tm_min = st.wMinute;
t.tm_sec = st.wSecond;
}
}
#endif
}//end namespace detail
bool file_attrib(const nana::string& file, attribute& attr)
{
#if defined(NANA_WINDOWS)
WIN32_FILE_ATTRIBUTE_DATA fad;
if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &fad))
{
LARGE_INTEGER li;
li.u.LowPart = fad.nFileSizeLow;
li.u.HighPart = fad.nFileSizeHigh;
attr.size = li.QuadPart;
attr.directory = (0 != (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
detail::filetime_to_c_tm(fad.ftLastWriteTime, attr.modified);
return true;
}
#elif defined(NANA_LINUX)
struct stat fst;
if (0 == ::stat(static_cast<std::string>(nana::charset(file)).c_str(), &fst))
{
attr.size = fst.st_size;
attr.directory = (0 != (040000 & fst.st_mode));
attr.modified = *(::localtime(&fst.st_ctime));
return true;
}
#endif
return false;
}
uintmax_t file_size(const nana::string& file)
{
#if defined(NANA_WINDOWS)
//Some compilation environment may fail to link to GetFileSizeEx
typedef BOOL(__stdcall *GetFileSizeEx_fptr_t)(HANDLE, PLARGE_INTEGER);
GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast<GetFileSizeEx_fptr_t>(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx"));
if (get_file_size_ex)
{
HANDLE handle = ::CreateFile(file.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (INVALID_HANDLE_VALUE != handle)
{
LARGE_INTEGER li;
if (!get_file_size_ex(handle, &li))
li.QuadPart = 0;
::CloseHandle(handle);
return li.QuadPart;
}
}
return 0;
#elif defined(NANA_LINUX)
FILE * stream = ::fopen(static_cast<std::string>(nana::charset(file)).c_str(), "rb");
long long size = 0;
if (stream)
{
fseeko64(stream, 0, SEEK_END);
size = ftello64(stream);
fclose(stream);
}
return size;
#endif
}
bool modified_file_time(const nana::string& file, struct tm& t)
{
#if defined(NANA_WINDOWS)
WIN32_FILE_ATTRIBUTE_DATA attr;
if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &attr))
{
FILETIME local_file_time;
if (::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time))
{
SYSTEMTIME st;
::FileTimeToSystemTime(&local_file_time, &st);
t.tm_year = st.wYear - 1900;
t.tm_mon = st.wMonth - 1;
t.tm_mday = st.wDay;
t.tm_wday = st.wDayOfWeek - 1;
t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay);
t.tm_hour = st.wHour;
t.tm_min = st.wMinute;
t.tm_sec = st.wSecond;
return true;
}
}
#elif defined(NANA_LINUX)
struct stat attr;
if (0 == ::stat(static_cast<std::string>(nana::charset(file)).c_str(), &attr))
{
t = *(::localtime(&attr.st_ctime));
return true;
}
#endif
return false;
}
bool create_directory(const nana::string& path, bool & if_exist)
{
if_exist = false;
if (path.size() == 0) return false;
nana::string root;
#if defined(NANA_WINDOWS)
if (path.size() > 3 && path[1] == STR(':'))
root = path.substr(0, 3);
#elif defined(NANA_LINUX)
if (path[0] == STR('/'))
root = '/';
#endif
bool mkstat = false;
std::size_t beg = root.size();
while (true)
{
beg = path.find_first_not_of(STR("/\\"), beg);
if (beg == path.npos)
break;
std::size_t pos = path.find_first_of(STR("/\\"), beg + 1);
if (pos != path.npos)
{
root += path.substr(beg, pos - beg);
mkstat = detail::mkdir_helper(root, if_exist);
if (mkstat == false && if_exist == false)
return false;
#if defined(NANA_WINDOWS)
root += STR('\\');
#elif defined(NANA_LINUX)
root += STR('/');
#endif
}
else
{
if (beg + 1 < path.size())
{
root += path.substr(beg);
mkstat = detail::mkdir_helper(root, if_exist);
}
break;
}
beg = pos + 1;
}
return mkstat;
}
bool rmfile(const nana::char_t* file)
{
#if defined(NANA_WINDOWS)
bool ret = false;
if (file)
{
ret = (::DeleteFile(file) == TRUE);
if (!ret)
ret = (ERROR_FILE_NOT_FOUND == ::GetLastError());
}
return ret;
#elif defined(NANA_LINUX)
if (std::remove(static_cast<std::string>(nana::charset(file)).c_str()))
return (errno == ENOENT);
return true;
#endif
}
bool rmdir(const nana::char_t* dir, bool fails_if_not_empty)
{
bool ret = false;
if (dir)
{
#if defined(NANA_WINDOWS)
ret = (::RemoveDirectory(dir) == TRUE);
if (!fails_if_not_empty && (::GetLastError() == ERROR_DIR_NOT_EMPTY))
ret = detail::rm_dir_recursive(dir);
#elif defined(NANA_LINUX)
std::string mbstr = nana::charset(dir);
if (::rmdir(mbstr.c_str()))
{
if (!fails_if_not_empty && (errno == EEXIST || errno == ENOTEMPTY))
ret = detail::rm_dir_recursive(dir);
}
else
ret = true;
#endif
}
return ret;
}
nana::string root(const nana::string& path)
{
std::size_t index = path.size();
if (index)
{
const nana::char_t * str = path.c_str();
for (--index; index > 0; --index)
{
nana::char_t c = str[index];
if (c != '\\' && c != '/')
break;
}
for (--index; index > 0; --index)
{
nana::char_t c = str[index];
if (c == '\\' || c == '/')
break;
}
}
return index ? path.substr(0, index + 1) : nana::string();
}
nana::string path_user()
{
#if defined(NANA_WINDOWS)
nana::char_t path[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, path)))
return path;
#elif defined(NANA_LINUX)
const char * s = ::getenv("HOME");
if (s)
return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8);
#endif
return nana::string();
}
path current_path()
{
#if defined(NANA_WINDOWS)
nana::char_t buf[MAX_PATH];
DWORD len = ::GetCurrentDirectory(MAX_PATH, buf);
if (len)
{
if (len > MAX_PATH)
{
nana::char_t * p = new nana::char_t[len + 1];
::GetCurrentDirectory(len + 1, p);
nana::string s = p;
delete[] p;
return s;
}
return buf;
}
#elif defined(NANA_LINUX)
const char * s = ::getenv("PWD");
if (s)
return static_cast<nana::string>(nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8));
#endif
return nana::string();
}
}//end namespace filesystem
} //end namespace experimental
}//end namespace nana

View File

@ -201,14 +201,14 @@ namespace nana
case frame::kind::oneshot:
_m_render(outs, [&frmobj](paint::graphics& tar, const nana::point& pos)
{
frmobj.u.oneshot->paste(tar, pos.x, pos.y);
frmobj.u.oneshot->paste(tar, pos);
});
break;
case frame::kind::framebuilder:
good_frame_by_frmbuilder = frmobj.u.frbuilder->frbuilder(pos_in_this_frame, framegraph, framegraph_dimension);
if(good_frame_by_frmbuilder)
{
nana::rectangle r = framegraph_dimension;
nana::rectangle r(framegraph_dimension);
_m_render(outs, [&r, &framegraph](paint::graphics& tar, const nana::point& pos) mutable
{
r.x = pos.x;
@ -230,7 +230,7 @@ namespace nana
switch(frmobj.type)
{
case frame::kind::oneshot:
frmobj.u.oneshot->paste(graph, pos.x, pos.y);
frmobj.u.oneshot->paste(graph, pos);
break;
case frame::kind::framebuilder:
if(rebuild_frame)

View File

@ -7,7 +7,7 @@ namespace nana
{
//class caret_descriptor
caret_descriptor::caret_descriptor(core_window_t* wd, unsigned width, unsigned height)
:wd_(wd), size_(width, height), visible_(false), real_visible_state_(false), out_of_range_(false)
:wd_(wd), size_(width, height), visible_state_(visible_state::invisible), out_of_range_(false)
{}
caret_descriptor::~caret_descriptor()
@ -22,8 +22,8 @@ namespace nana
if(active)
{
native_interface::caret_create(wd_->root, size_);
real_visible_state_ = false;
visible_ = false;
visible_state_ = visible_state::invisible;
this->position(point_.x, point_.y);
}
else
@ -76,19 +76,26 @@ namespace nana
return point_;
}
void caret_descriptor::visible(bool isshow)
void caret_descriptor::visible(bool is_show)
{
if(visible_ != isshow)
auto pre_displayed = (visible_state::displayed == visible_state_);
if (is_show)
{
visible_ = isshow;
if(visible_ == false || false == out_of_range_)
_m_visible(isshow);
visible_state_ = visible_state::visible;
if (wd_->displayed() && (! out_of_range_))
visible_state_ = visible_state::displayed;
}
else
visible_state_ = visible_state::invisible;
if (pre_displayed != (visible_state::displayed == visible_state_))
native_interface::caret_visible(wd_->root, !pre_displayed);
}
bool caret_descriptor::visible() const
{
return visible_;
return (visible_state::invisible != visible_state_);
}
nana::size caret_descriptor::size() const
@ -101,16 +108,8 @@ namespace nana
size_ = s;
update();
if(visible_) this->visible(true);
}
void caret_descriptor::_m_visible(bool isshow)
{
if(real_visible_state_ != isshow)
{
real_visible_state_ = isshow;
native_interface::caret_visible(wd_->root, isshow);
}
if (visible_state::invisible != visible_state_)
visible(true);
}
void caret_descriptor::update()
@ -138,8 +137,8 @@ namespace nana
{
out_of_range_ = true;
if(visible_)
_m_visible(false);
if (visible_state::invisible != visible_state_)
visible(false);
}
}
else
@ -164,19 +163,22 @@ namespace nana
if(out_of_range_)
{
if(paint_size_ == size)
_m_visible(true);
if (paint_size_ == size)
visible(true);
out_of_range_ = false;
}
if(paint_size_ != size)
{
bool vs = (visible_state::invisible != visible_state_);
native_interface::caret_destroy(wd_->root);
native_interface::caret_create(wd_->root, size);
real_visible_state_ = false;
if(visible_)
_m_visible(true);
visible_state_ = visible_state::invisible;
if (vs)
visible(true);
paint_size_ = size;
}
@ -195,7 +197,6 @@ namespace nana
{
case category::root_tag::value:
attribute.root = new attr_root_tag;
attribute.root->context.focus_changed = false;
break;
case category::frame_tag::value:
attribute.frame = new attr_frame_tag;
@ -222,8 +223,8 @@ namespace nana
//basic_window
//@brief: constructor for the root window
basic_window::basic_window(basic_window* owner, widget* wdg, category::root_tag**)
: widget_ptr(wdg), other(category::root_tag::value)
basic_window::basic_window(basic_window* owner, std::unique_ptr<widget_notifier_interface>&& wdg_notifier, category::root_tag**)
: widget_notifier(std::move(wdg_notifier)), other(category::root_tag::value)
{
drawer.bind(this);
_m_init_pos_and_size(nullptr, rectangle());
@ -282,6 +283,11 @@ namespace nana
return true;
}
bool basic_window::displayed() const
{
return (visible && visible_parents());
}
bool basic_window::belong_to_lazy() const
{
for (auto wd = this; wd; wd = wd->parent)
@ -292,6 +298,26 @@ namespace nana
return false;
}
const basic_window* get_child_caret(const basic_window* wd, bool this_is_a_child)
{
if (this_is_a_child && wd->together.caret)
return wd;
for (auto child : wd->children)
{
auto caret_wd = get_child_caret(child, true);
if (caret_wd)
return caret_wd;
}
return nullptr;
}
const basic_window * basic_window::child_caret() const
{
return get_child_caret(this, false);
}
bool basic_window::is_draw_through() const
{
if (::nana::category::flags::root == this->other.category)
@ -299,6 +325,15 @@ namespace nana
return false;
}
basic_window * basic_window::seek_non_lite_widget_ancestor() const
{
auto anc = this->parent;
while (anc && (category::flags::lite_widget == anc->other.category))
anc = anc->parent;
return anc;
}
void basic_window::_m_init_pos_and_size(basic_window* parent, const rectangle& r)
{
pos_owner = pos_root = r;
@ -346,8 +381,9 @@ namespace nana
flags.refreshing = false;
flags.destroying = false;
flags.borderless = false;
flags.make_bground_declared = false;
flags.ignore_menubar_focus = false;
flags.make_bground_declared = false;
flags.ignore_menubar_focus = false;
flags.ignore_mouse_focus = false;
visible = false;

View File

@ -26,9 +26,19 @@
namespace nana
{
//class event_arg
event_arg::~event_arg(){}
//class internal_scope_guard
internal_scope_guard::internal_scope_guard()
{
detail::bedrock::instance().wd_manager.internal_lock().lock();
}
internal_scope_guard::~internal_scope_guard()
{
detail::bedrock::instance().wd_manager.internal_lock().unlock();
}
//end class internal_scope_guard
//class event_arg
void event_arg::stop_propagation() const
{
stop_propagation_ = true;
@ -52,6 +62,26 @@ namespace nana
bedrock::instance().evt_operation.cancel(evt);
}
class bedrock::flag_guard
{
public:
flag_guard(bedrock* brock, core_window_t * wd)
: brock_{ brock }, wd_(wd)
{
wd_->flags.refreshing = true;
}
~flag_guard()
{
if (brock_->wd_manager.available((wd_)))
wd_->flags.refreshing = false;
}
private:
bedrock *const brock_;
core_window_t *const wd_;
};
void bedrock::event_expose(core_window_t * wd, bool exposed)
{
if (nullptr == wd) return;
@ -63,15 +93,24 @@ namespace nana
arg.window_handle = reinterpret_cast<window>(wd);
if (emit(event_code::expose, wd, arg, false, get_thread_context()))
{
const core_window_t * caret_wd = (wd->together.caret ? wd : wd->child_caret());
if (caret_wd)
{
if (exposed)
{
if (wd->root_widget->other.attribute.root->focus == caret_wd)
caret_wd->together.caret->visible(true);
}
else
caret_wd->together.caret->visible(false);
}
if (!exposed)
{
if (category::flags::root != wd->other.category)
{
//If the wd->parent is a lite_widget then find a parent until it is not a lite_widget
wd = wd->parent;
while (category::flags::lite_widget == wd->other.category)
wd = wd->parent;
//find an ancestor until it is not a lite_widget
wd = wd->seek_non_lite_widget_ancestor();
}
else if (category::flags::frame == wd->other.category)
wd = wd_manager.find_window(wd->root, wd->pos_root.x, wd->pos_root.y);
@ -91,7 +130,7 @@ namespace nana
arg.x = x;
arg.y = y;
if (emit(event_code::move, wd, arg, false, get_thread_context()))
wd_manager.update(wd, true, true);
wd_manager.update(wd, false, true);
}
}
@ -150,9 +189,22 @@ namespace nana
auto retain = wd->together.events_ptr;
auto evts_ptr = retain.get();
//enable refreshing flag, this is a RAII class for exception-safe
flag_guard fguard(this, wd);
switch (evt_code)
{
case event_code::click:
{
auto arg = dynamic_cast<const arg_click*>(&event_arg);
if (nullptr == arg)
return;
wd->drawer.click(*arg);
if (!draw_only)
evts_ptr->click.emit(*arg);
}
break;
case event_code::dbl_click:
case event_code::mouse_enter:
case event_code::mouse_move:
@ -169,10 +221,6 @@ namespace nana
switch (evt_code)
{
case event_code::click:
drawer_event_fn = &drawer::click;
evt_addr = &evts_ptr->click;
break;
case event_code::dbl_click:
drawer_event_fn = &drawer::dbl_click;
evt_addr = &evts_ptr->dbl_click;
@ -202,9 +250,9 @@ namespace nana
}
(wd->drawer.*drawer_event_fn)(*arg);
if (!draw_only)
evt_addr->emit(*arg);
break;
}
case event_code::mouse_wheel:

View File

@ -34,99 +34,99 @@ namespace nana
void drawer_trigger::resizing(graph_reference, const arg_resizing&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::resizing));
}
void drawer_trigger::resized(graph_reference graph, const arg_resized&)
{
overrided_ = true;
overrided_ |= (1 << static_cast<int>(event_code::resized));
this->refresh(graph);
detail::bedrock::instance().thread_context_lazy_refresh();
}
void drawer_trigger::move(graph_reference, const arg_move&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::move));
}
void drawer_trigger::click(graph_reference, const arg_mouse&)
void drawer_trigger::click(graph_reference, const arg_click&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::click));
}
void drawer_trigger::dbl_click(graph_reference, const arg_mouse&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::dbl_click));
}
void drawer_trigger::mouse_enter(graph_reference, const arg_mouse&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::mouse_enter));
}
void drawer_trigger::mouse_move(graph_reference, const arg_mouse&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::mouse_move));
}
void drawer_trigger::mouse_leave(graph_reference, const arg_mouse&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::mouse_leave));
}
void drawer_trigger::mouse_down(graph_reference, const arg_mouse&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::mouse_down));
}
void drawer_trigger::mouse_up(graph_reference, const arg_mouse&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::mouse_up));
}
void drawer_trigger::mouse_wheel(graph_reference, const arg_wheel&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::mouse_wheel));
}
void drawer_trigger::mouse_dropfiles(graph_reference, const arg_dropfiles&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::mouse_drop));
}
void drawer_trigger::focus(graph_reference, const arg_focus&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::focus));
}
void drawer_trigger::key_press(graph_reference, const arg_keyboard&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::key_press));
}
void drawer_trigger::key_char(graph_reference, const arg_keyboard&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::key_char));
}
void drawer_trigger::key_release(graph_reference, const arg_keyboard&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::key_release));
}
void drawer_trigger::shortkey(graph_reference, const arg_keyboard&)
{
overrided_ = false;
overrided_ &= ~(1 << static_cast<int>(event_code::shortkey));
}
void drawer_trigger::_m_reset_overrided()
{
overrided_ = true;
overrided_ = 0xFFFFFFFF;
}
bool drawer_trigger::_m_overrided() const
bool drawer_trigger::_m_overrided(event_code evt_code) const
{
return overrided_;
return 0 != (overrided_ & (1 << static_cast<int>(evt_code)));
}
//end class drawer_trigger
@ -155,7 +155,7 @@ namespace nana
realizer_->typeface_changed(graphics);
}
void drawer::click(const arg_mouse& arg)
void drawer::click(const arg_click& arg)
{
_m_emit(event_code::click, arg, &drawer_trigger::click);
}
@ -240,12 +240,12 @@ namespace nana
_m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey);
}
void drawer::map(window wd, bool forced) //Copy the root buffer to screen
void drawer::map(window wd, bool forced, const rectangle* update_area) //Copy the root buffer to screen
{
if(wd)
{
bedrock_type::core_window_t* iwd = reinterpret_cast<bedrock_type::core_window_t*>(wd);
bedrock_type::core_window_t * caret_wd = iwd->root_widget->other.attribute.root->focus;
auto iwd = reinterpret_cast<bedrock_type::core_window_t*>(wd);
auto caret_wd = iwd->root_widget->other.attribute.root->focus;
bool owns_caret = (caret_wd && (caret_wd->together.caret) && (caret_wd->together.caret->visible()));
@ -262,12 +262,7 @@ namespace nana
#endif
}
if (false == edge_nimbus_renderer_t::instance().render(iwd, forced))
{
nana::rectangle vr;
if(bedrock_type::window_manager_t::wndlayout_type::read_visual_rectangle(iwd, vr))
iwd->root_graph->paste(iwd->root, vr, vr.x, vr.y);
}
edge_nimbus_renderer_t::instance().render(iwd, forced, update_area);
if(owns_caret)
{
@ -302,9 +297,10 @@ namespace nana
void drawer::attached(widget& wd, drawer_trigger& realizer)
{
for (auto i = std::begin(mth_state_), end = std::end(mth_state_); i != end; ++i)
*i = method_state::unknown;
*i = method_state::pending;
realizer_ = &realizer;
realizer._m_reset_overrided();
realizer.attached(wd, graphics);
}
@ -368,7 +364,7 @@ namespace nana
void drawer::_m_bground_end()
{
if(core_window_->effect.bground && core_window_->effect.bground_fade_rate >= 0.01)
core_window_->other.glass_buffer.blend(core_window_->other.glass_buffer.size(), graphics, nana::point(), core_window_->effect.bground_fade_rate);
core_window_->other.glass_buffer.blend(::nana::rectangle{ core_window_->other.glass_buffer.size() }, graphics, nana::point(), core_window_->effect.bground_fade_rate);
}
void drawer::_m_draw_dynamic_drawing_object()

View File

@ -23,16 +23,6 @@
namespace nana
{
//class internal_scope_guard
internal_scope_guard::internal_scope_guard()
{
detail::bedrock::instance().wd_manager.internal_lock().lock();
}
internal_scope_guard::~internal_scope_guard()
{
detail::bedrock::instance().wd_manager.internal_lock().unlock();
}
//end class internal_scope_guard
namespace detail
{
#pragma pack(1)
@ -138,11 +128,6 @@ namespace detail
//here is the definition of this object
bedrock bedrock::bedrock_object;
inline window mycast(bedrock::core_window_t* wd)
{
return reinterpret_cast<window>(wd);
}
Window event_window(const XEvent& event)
{
switch(event.type)
@ -167,7 +152,7 @@ namespace detail
delete impl_;
}
void bedrock::map_thread_root_buffer(core_window_t*, bool forced)
void bedrock::map_thread_root_buffer(core_window_t*, bool forced, const rectangle*)
{
//GUI in X11 is thread-independent, so no implementation.
}
@ -457,62 +442,53 @@ namespace detail
void assign_arg(arg_mouse& arg, basic_window* wd, unsigned msg, const XEvent& evt)
{
arg.window_handle = reinterpret_cast<window>(wd);
arg.button = ::nana::mouse::any_button;
int mask_state = 0;
if (ButtonPress == msg || ButtonRelease == msg)
{
mask_state = evt.xbutton.state;
if (evt.xbutton.button != Button4 && evt.xbutton.button != Button5)
{
arg.evt_code = (ButtonPress == msg ? event_code::mouse_down : event_code::mouse_up);
arg.pos.x = evt.xbutton.x - wd->pos_root.x;
arg.pos.y = evt.xbutton.y - wd->pos_root.y;
arg.left_button = arg.mid_button = arg.right_button = false;
arg.shift = arg.ctrl = false;
switch (evt.xbutton.button)
{
case Button1:
arg.left_button = true;
arg.button = ::nana::mouse::left_button;
break;
case Button2:
arg.mid_button = true;
arg.button = ::nana::mouse::middle_button;
break;
case Button3:
arg.right_button = true;
arg.button = ::nana::mouse::right_button;
break;
}
}
}
else if (msg == MotionNotify)
{
mask_state = evt.xmotion.state;
arg.evt_code = event_code::mouse_move;
arg.pos.x = evt.xmotion.x - wd->pos_root.x;
arg.pos.y = evt.xmotion.y - wd->pos_root.y;
arg.left_button = arg.mid_button = arg.right_button = false;
arg.shift = evt.xmotion.state & ShiftMask;
arg.ctrl = evt.xmotion.state & ControlMask;
if (evt.xmotion.state & Button1Mask)
arg.left_button = true;
else if (evt.xmotion.state & Button2Mask)
arg.right_button = true;
else if (evt.xmotion.state & Button3Mask)
arg.mid_button = true;
}
else if (EnterNotify == msg)
{
mask_state = evt.xcrossing.state;
arg.evt_code = event_code::mouse_enter;
arg.pos.x = evt.xcrossing.x - wd->pos_root.x;
arg.pos.y = evt.xcrossing.y - wd->pos_root.y;
arg.left_button = arg.mid_button = arg.right_button = false;
arg.shift = evt.xcrossing.state & ShiftMask;
arg.ctrl = evt.xcrossing.state & ControlMask;
if (evt.xcrossing.state & Button1Mask)
arg.left_button = true;
else if (evt.xcrossing.state & Button2Mask)
arg.right_button = true;
else if (evt.xcrossing.state & Button3Mask)
arg.mid_button = true;
}
arg.left_button = ((Button1Mask & mask_state) != 0) || (::nana::mouse::left_button == arg.button) ;
arg.right_button = ((Button2Mask & mask_state) != 0) || (::nana::mouse::right_button == arg.button);
arg.mid_button = ((Button3Mask & mask_state) != 0) || (::nana::mouse::middle_button == arg.button);
arg.shift = (ShiftMask & mask_state);
arg.ctrl = (ControlMask & mask_state);
}
void assign_arg(arg_focus& arg, basic_window* wd, native_window_type recv, bool getting)
@ -664,7 +640,6 @@ namespace detail
auto focus = msgwnd->other.attribute.root->focus;
if(focus && focus->together.caret)
focus->together.caret->set_active(true);
msgwnd->root_widget->other.attribute.root->context.focus_changed = true;
arg_focus arg;
arg.window_handle = reinterpret_cast<window>(focus);
@ -724,17 +699,20 @@ namespace detail
bool dbl_click = (last_mouse_down_window == msgwnd) && (xevent.xbutton.time - last_mouse_down_time <= 400);
last_mouse_down_time = xevent.xbutton.time;
last_mouse_down_window = msgwnd;
auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window);
if(new_focus)
if (Button1 == xevent.xbutton.button) //Sets the focus only if left button is pressed
{
context.event_window = new_focus;
auto kill_focus = brock.wd_manager.set_focus(new_focus, false);
if(kill_focus != new_focus)
brock.wd_manager.do_lazy_refresh(kill_focus, false);
auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window);
if (new_focus && !new_focus->flags.ignore_mouse_focus)
{
context.event_window = new_focus;
auto kill_focus = brock.wd_manager.set_focus(new_focus, false);
if (kill_focus != new_focus)
brock.wd_manager.do_lazy_refresh(kill_focus, false);
}
}
auto retain = msgwnd->together.events_ptr;
msgwnd->root_widget->other.attribute.root->context.focus_changed = false;
context.event_window = msgwnd;
pressed_wd = nullptr;
@ -748,7 +726,7 @@ namespace detail
{
pressed_wd = msgwnd;
//If a root window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event.
if(msgwnd->root_widget->other.attribute.root->context.focus_changed)
if (msgwnd->root != native_interface::get_focus_window())
{
//call the drawer mouse up event for restoring the surface graphics
msgwnd->flags.action = mouse_action::normal;
@ -796,10 +774,12 @@ namespace detail
bool fire_click = false;
if(msgwnd == pressed_wd)
{
if(msgwnd->flags.enabled && hit)
if((arg.button == ::nana::mouse::left_button) && hit)
{
msgwnd->flags.action = mouse_action::over;
arg.evt_code = event_code::click;
arg_click arg;
arg.window_handle = reinterpret_cast<window>(msgwnd);
arg.by_mouse = true;
emit_drawer(&drawer::click, msgwnd, arg, &context);
fire_click = true;
}
@ -819,7 +799,9 @@ namespace detail
if(fire_click)
{
arg.evt_code = event_code::click;
arg_click arg;
arg.window_handle = reinterpret_cast<window>(msgwnd);
arg.by_mouse = true;
evt_ptr->click.emit(arg);
}
@ -831,7 +813,9 @@ namespace detail
}
else if(fire_click)
{
arg.evt_code = event_code::click;
arg_click arg;
arg.window_handle = reinterpret_cast<window>(msgwnd);
arg.by_mouse = true;
msgwnd->together.events_ptr->click.emit(arg);
}
brock.wd_manager.do_lazy_refresh(msgwnd, false);
@ -937,11 +921,10 @@ namespace detail
if(msgwnd->visible && (msgwnd->root_graph->empty() == false))
{
nana::detail::platform_scope_guard psg;
nana::detail::drawable_impl_type* drawer_impl = msgwnd->root_graph->handle();
::XCopyArea(display, drawer_impl->pixmap, reinterpret_cast<Window>(native_window), drawer_impl->context,
xevent.xexpose.x, xevent.xexpose.y,
xevent.xexpose.width, xevent.xexpose.height,
xevent.xexpose.x, xevent.xexpose.y);
//Don't copy root_graph to the window directly, otherwise the edge nimbus effect will be missed.
::nana::rectangle update_area(xevent.xexpose.x, xevent.xexpose.y, xevent.xexpose.width, xevent.xexpose.height);
if (!update_area.empty())
msgwnd->drawer.map(reinterpret_cast<window>(msgwnd), true, &update_area);
}
break;
case KeyPress:
@ -1027,12 +1010,11 @@ namespace detail
{
arg_keyboard argkey;
brock.get_key_state(argkey);
auto the_next = brock.wd_manager.tabstop(msgwnd, !argkey.shift);
if(the_next)
auto tstop_wd = brock.wd_manager.tabstop(msgwnd, !argkey.shift);
if (tstop_wd)
{
brock.wd_manager.set_focus(the_next, false);
brock.wd_manager.do_lazy_refresh(the_next, true);
root_runtime->condition.tabstop_focus_changed = true;
brock.wd_manager.set_focus(tstop_wd, false);
brock.wd_manager.do_lazy_refresh(tstop_wd, true);
}
}
else if(keyboard::alt == keychar)
@ -1068,6 +1050,16 @@ namespace detail
arg.window_handle = reinterpret_cast<window>(msgwnd);
brock.emit(event_code::key_press, msgwnd, arg, true, &context);
if((XLookupKeySym == status) && (brock.wd_manager.available(msgwnd)))
{
//call key_char event if status is XLookupKeySym to avaid calling key_char
//twice, because the status would be equal to XLookupChars if the input method is
//enabled for the window.
arg.ignore = false;
arg.evt_code = event_code::key_char;
brock.emit(event_code::key_char, msgwnd, arg, true, & context);
}
if(msgwnd->root_widget->other.attribute.root->menubar == msgwnd)
{
int cmd = (menu_wd && (keyboard::escape == static_cast<nana::char_t>(arg.key)) ? 1 : 0 );
@ -1081,6 +1073,7 @@ namespace detail
break;
}
case XLookupChars:
if (msgwnd->flags.enabled)
{
const ::nana::char_t* charbuf;
#if defined(NANA_UNICODE)
@ -1097,6 +1090,10 @@ namespace detail
arg.ignore = false;
arg.key = charbuf[i];
// When tab is pressed, only tab-eating mode is allowed
if ((keyboard::tab == arg.key) && !(msgwnd->flags.tab & tab_type::eating))
continue;
if(context.is_alt_pressed)
{
arg.ctrl = arg.shift = false;
@ -1145,7 +1142,9 @@ namespace detail
brock.get_key_state(arg);
brock.emit(event_code::key_release, msgwnd, arg, true, &context);
}
brock.delay_restore(2); //Restores while key release
if (context.platform.keychar < keyboard::os_arrow_left || keyboard::os_arrow_down < context.platform.keychar)
brock.delay_restore(2); //Restores while key release
}
else
{

View File

@ -21,7 +21,7 @@
#include <mutex>
#endif
#include <map>
#include <nana/paint/detail/image_ico.hpp>
#include "../../paint/detail/image_ico.hpp"
#elif defined(NANA_X11)
#include <nana/system/platform.hpp>
#include <nana/gui/detail/bedrock.hpp>
@ -174,7 +174,7 @@ namespace nana{
}
}
#endif
return primary_monitor_size();
return rectangle{ primary_monitor_size() };
}
//platform-dependent
@ -509,20 +509,25 @@ namespace nana{
#endif
}
bool native_interface::window_icon(native_window_type wd, const nana::paint::image& img)
bool native_interface::window_icon(native_window_type wd, const nana::paint::image& sml_icon, const ::nana::paint::image& big_icon)
{
#if defined(NANA_WINDOWS)
HICON ico = paint::image_accessor::icon(img);
if(ico)
HICON sml_handle = paint::image_accessor::icon(sml_icon);
HICON big_handle = paint::image_accessor::icon(big_icon);
if(sml_handle || big_handle)
{
nana::detail::platform_spec::instance().keep_window_icon(wd, img);
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(ico));
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_SMALL, reinterpret_cast<WPARAM>(ico));
nana::detail::platform_spec::instance().keep_window_icon(wd, sml_icon, big_icon);
if (sml_handle)
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_SMALL, reinterpret_cast<WPARAM>(sml_handle));
if (big_handle)
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(big_handle));
return true;
}
#elif defined(NANA_X11)
if(wd && (false == img.empty()))
if(wd && (!sml_icon.empty() || !big_icon.empty()))
{
auto & img = (sml_icon.empty() ? big_icon : sml_icon);
const nana::paint::graphics & graph = restrict::spec.keep_window_icon(wd, img);
XWMHints hints;
@ -537,6 +542,32 @@ namespace nana{
return false;
}
/*
bool native_interface::window_icon(native_window_type wd, const paint::image& big_icon, const paint::image& small_icon) //deprecated
{
#if defined(NANA_WINDOWS)
HICON h_big_icon = paint::image_accessor::icon(big_icon);
HICON h_small_icon = paint::image_accessor::icon(small_icon);
if (h_big_icon || h_small_icon)
{
nana::detail::platform_spec::instance().keep_window_icon(wd, (!big_icon.empty() ? big_icon : small_icon));
if (h_big_icon) {
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(h_big_icon));
}
if (h_small_icon) {
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_SMALL, reinterpret_cast<WPARAM>(h_small_icon));
}
return true;
}
#elif defined(NANA_X11)
return window_icon(wd, big_icon);
#endif
return false;
}
*/
void native_interface::activate_owner(native_window_type wd)
{
#if defined(NANA_WINDOWS)

View File

@ -41,16 +41,6 @@ namespace nana
{
void notifications_window_proc(HWND wd, WPARAM wparam, LPARAM lparam); //Defined in notifier.cpp
//class internal_scope_guard
internal_scope_guard::internal_scope_guard()
{
detail::bedrock::instance().wd_manager.internal_lock().lock();
}
internal_scope_guard::~internal_scope_guard()
{
detail::bedrock::instance().wd_manager.internal_lock().unlock();
}
//end class internal_scope_guard
namespace detail
{
namespace restrict
@ -338,9 +328,14 @@ namespace detail
return bedrock_object;
}
void bedrock::map_thread_root_buffer(core_window_t* wd, bool forced)
void bedrock::map_thread_root_buffer(core_window_t* wd, bool forced, const rectangle* update_area)
{
::PostMessage(reinterpret_cast<HWND>(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast<WPARAM>(wd), static_cast<LPARAM>(forced ? TRUE : FALSE));
auto stru = reinterpret_cast<detail::messages::map_thread*>(::HeapAlloc(::GetProcessHeap(), 0, sizeof(detail::messages::map_thread)));
if (stru)
{
if (FALSE == ::PostMessage(reinterpret_cast<HWND>(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast<WPARAM>(wd), reinterpret_cast<LPARAM>(stru)))
::HeapFree(::GetProcessHeap(), 0, stru);
}
}
void interior_helper_for_menu(MSG& msg, native_window_type menu_window)
@ -358,7 +353,7 @@ namespace detail
void bedrock::pump_event(window modal_window, bool is_modal)
{
const unsigned tid = ::GetCurrentThreadId();
thread_context * context = this->open_thread_context(tid);
auto context = this->open_thread_context(tid);
if(0 == context->window_count)
{
//test if there is not a window
@ -490,46 +485,63 @@ namespace detail
void assign_arg(nana::arg_mouse& arg, basic_window* wd, unsigned msg, const parameter_decoder& pmdec)
{
arg.window_handle = reinterpret_cast<window>(wd);
//event code
bool set_key_state = true;
switch (msg)
{
case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP:
case WM_LBUTTONDOWN:
arg.button = ::nana::mouse::left_button;
arg.evt_code = event_code::mouse_down;
break;
case WM_RBUTTONDOWN:
arg.button = ::nana::mouse::right_button;
arg.evt_code = event_code::mouse_down;
break;
case WM_MBUTTONDOWN:
arg.button = ::nana::mouse::middle_button;
arg.evt_code = event_code::mouse_down;
break;
case WM_LBUTTONUP:
arg.button = ::nana::mouse::left_button;
arg.evt_code = event_code::mouse_up;
break;
case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK:
case WM_RBUTTONUP:
arg.button = ::nana::mouse::right_button;
arg.evt_code = event_code::mouse_up;
break;
case WM_MBUTTONUP:
arg.button = ::nana::mouse::middle_button;
arg.evt_code = event_code::mouse_up;
break;
case WM_LBUTTONDBLCLK:
arg.button = ::nana::mouse::left_button;
arg.evt_code = (wd->flags.dbl_click ? event_code::dbl_click : event_code::mouse_down);
break;
case WM_MBUTTONDBLCLK:
arg.button = ::nana::mouse::middle_button;
arg.evt_code = (wd->flags.dbl_click ? event_code::dbl_click : event_code::mouse_down);
break;
case WM_RBUTTONDBLCLK:
arg.button = ::nana::mouse::right_button;
arg.evt_code = (wd->flags.dbl_click ? event_code::dbl_click : event_code::mouse_down);
break;
case WM_MOUSEMOVE:
arg.button = ::nana::mouse::any_button;
arg.evt_code = event_code::mouse_move;
break;
default:
set_key_state = false;
}
//event arguments
switch (msg)
if (set_key_state)
{
case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN:
arg.evt_code = event_code::mouse_down;
case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP:
case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK:
case WM_MOUSEMOVE:
arg.pos.x = pmdec.mouse.x - wd->pos_root.x;
arg.pos.y = pmdec.mouse.y - wd->pos_root.y;
arg.shift = pmdec.mouse.button.shift;
arg.ctrl = pmdec.mouse.button.ctrl;
switch (msg)
{
case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP:
arg.left_button = (WM_LBUTTONUP == msg);
arg.right_button = (WM_RBUTTONUP == msg);
arg.mid_button = (WM_MBUTTONUP == msg);
break;
default:
arg.left_button = pmdec.mouse.button.left;
arg.mid_button = pmdec.mouse.button.middle;
arg.right_button = pmdec.mouse.button.right;
}
break;
arg.left_button = pmdec.mouse.button.left;
arg.mid_button = pmdec.mouse.button.middle;
arg.right_button = pmdec.mouse.button.right;
}
}
@ -591,8 +603,12 @@ namespace detail
}
return true;
case nana::detail::messages::map_thread_root_buffer:
bedrock.wd_manager.map(reinterpret_cast<bedrock::core_window_t*>(wParam), (TRUE == lParam));
::UpdateWindow(wd);
{
auto stru = reinterpret_cast<detail::messages::map_thread*>(lParam);
bedrock.wd_manager.map(reinterpret_cast<bedrock::core_window_t*>(wParam), stru->forced, (stru->ignore_update_area ? nullptr : &stru->update_area));
::UpdateWindow(wd);
::HeapFree(::GetProcessHeap(), 0, stru);
}
return true;
case nana::detail::messages::remote_thread_move_window:
{
@ -863,8 +879,6 @@ namespace detail
if(focus && focus->together.caret)
focus->together.caret->set_active(true);
msgwnd->root_widget->other.attribute.root->context.focus_changed = true;
arg_focus arg;
assign_arg(arg, focus, native_window, true);
if (!brock.emit(event_code::focus, focus, arg, true, &context))
@ -888,9 +902,6 @@ namespace detail
//wParam indicates a handle of window that receives the focus.
brock.close_menu_if_focus_other_window(reinterpret_cast<native_window_type>(wParam));
}
//focus_changed means that during an event procedure if the focus is changed
if(brock.wd_manager.available(msgwnd))
msgwnd->root_widget->other.attribute.root->context.focus_changed = true;
def_window_proc = true;
break;
@ -905,8 +916,12 @@ namespace detail
msgwnd = brock.wd_manager.find_window(native_window, pmdec.mouse.x, pmdec.mouse.y);
if(msgwnd && msgwnd->flags.enabled)
{
if(msgwnd->flags.take_active)
brock.wd_manager.set_focus(msgwnd, false);
if (msgwnd->flags.take_active && !msgwnd->flags.ignore_mouse_focus)
{
auto killed = brock.wd_manager.set_focus(msgwnd, false);
if (killed != msgwnd)
brock.wd_manager.do_lazy_refresh(killed, false);
}
arg_mouse arg;
assign_arg(arg, msgwnd, message, pmdec);
@ -934,14 +949,15 @@ namespace detail
if(msgwnd->flags.enabled)
{
pressed_wd = msgwnd;
auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window);
if(new_focus)
if (WM_LBUTTONDOWN == message) //Sets focus only if left button is pressed
{
auto kill_focus = brock.wd_manager.set_focus(new_focus, false);
if(kill_focus != new_focus)
auto new_focus = (msgwnd->flags.take_active ? msgwnd : msgwnd->other.active_window);
if (new_focus && (!new_focus->flags.ignore_mouse_focus))
{
brock.wd_manager.do_lazy_refresh(kill_focus, false);
msgwnd->root_widget->other.attribute.root->context.focus_changed = false;
auto kill_focus = brock.wd_manager.set_focus(new_focus, false);
if (kill_focus != new_focus)
brock.wd_manager.do_lazy_refresh(kill_focus, false);
}
}
@ -953,7 +969,7 @@ namespace detail
if (brock.emit(event_code::mouse_down, msgwnd, arg, true, &context))
{
//If a root_window is created during the mouse_down event, Nana.GUI will ignore the mouse_up event.
if(msgwnd->root_widget->other.attribute.root->context.focus_changed)
if (msgwnd->root != native_interface::get_focus_window())
{
auto pos = native_interface::cursor_position();
auto rootwd = native_interface::find_window(pos.x, pos.y);
@ -989,15 +1005,15 @@ namespace detail
nana::arg_mouse arg;
assign_arg(arg, msgwnd, message, pmdec);
const bool hit = msgwnd->dimension.is_hit(arg.pos);
bool fire_click = false;
if(msgwnd == pressed_wd)
if (msgwnd->dimension.is_hit(arg.pos))
{
if(msgwnd->flags.enabled && hit)
msgwnd->flags.action = mouse_action::over;
if (::nana::mouse::left_button == arg.button)
{
msgwnd->flags.action = mouse_action::over;
arg.evt_code = event_code::click;
arg_click arg;
arg.window_handle = reinterpret_cast<window>(msgwnd);
arg.by_mouse = true;
emit_drawer(&drawer::click, msgwnd, arg, &context);
fire_click = true;
}
@ -1006,15 +1022,14 @@ namespace detail
//Do mouse_up, this handle may be closed by click handler.
if(brock.wd_manager.available(msgwnd) && msgwnd->flags.enabled)
{
if(hit)
msgwnd->flags.action = mouse_action::over;
arg.evt_code = event_code::mouse_up;
emit_drawer(&drawer::mouse_up, msgwnd, arg, &context);
if (fire_click)
{
arg.evt_code = event_code::click;
arg_click arg;
arg.window_handle = reinterpret_cast<window>(msgwnd);
arg.by_mouse = true;
retain->click.emit(arg);
}
@ -1026,7 +1041,9 @@ namespace detail
}
else if (fire_click)
{
arg.evt_code = event_code::click;
arg_click arg;
arg.window_handle = reinterpret_cast<window>(msgwnd);
arg.by_mouse = true;
retain->click.emit(arg);
}
brock.wd_manager.do_lazy_refresh(msgwnd, false);
@ -1288,28 +1305,22 @@ namespace detail
brock.event_move(msgwnd, (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam));
break;
case WM_PAINT:
if (msgwnd->is_draw_through())
{
msgwnd->other.attribute.root->draw_through();
::PAINTSTRUCT ps;
::BeginPaint(root_window, &ps);
::EndPaint(root_window, &ps);
}
else
{
::PAINTSTRUCT ps;
::HDC dc = ::BeginPaint(root_window, &ps);
if((ps.rcPaint.left != ps.rcPaint.right) && (ps.rcPaint.bottom != ps.rcPaint.top))
if (msgwnd->is_draw_through())
{
::BitBlt(dc,
ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top,
reinterpret_cast<HDC>(msgwnd->root_graph->handle()->context),
ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
msgwnd->other.attribute.root->draw_through();
}
else
{
//Don't copy root_graph to the window directly, otherwise the edge nimbus effect will be missed.
::nana::rectangle update_area(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top);
if (!update_area.empty())
msgwnd->drawer.map(reinterpret_cast<window>(msgwnd), true, &update_area);
}
::EndPaint(root_window, &ps);
}
}
break;
case WM_SYSCHAR:
def_window_proc = true;
@ -1391,15 +1402,16 @@ namespace detail
if(msgwnd)
{
if((wParam == 9) && (false == (msgwnd->flags.tab & tab_type::eating))) //Tab
if((wParam == 9) && (!msgwnd->visible || (false == (msgwnd->flags.tab & tab_type::eating)))) //Tab
{
auto the_next = brock.wd_manager.tabstop(msgwnd, (::GetKeyState(VK_SHIFT) >= 0));
if(the_next)
bool is_forward = (::GetKeyState(VK_SHIFT) >= 0);
auto tstop_wd = brock.wd_manager.tabstop(msgwnd, is_forward);
if (tstop_wd)
{
brock.wd_manager.set_focus(the_next, false);
brock.wd_manager.set_focus(tstop_wd, false);
brock.wd_manager.do_lazy_refresh(msgwnd, false);
brock.wd_manager.do_lazy_refresh(the_next, true);
root_runtime->condition.tabstop_focus_changed = true;
brock.wd_manager.do_lazy_refresh(tstop_wd, true);
}
}
else
@ -1428,9 +1440,10 @@ namespace detail
break;
case WM_CHAR:
msgwnd = brock.focus();
if(false == root_runtime->condition.tabstop_focus_changed)
if (msgwnd && msgwnd->flags.enabled)
{
if(msgwnd && msgwnd->flags.enabled)
// When tab is pressed, only tab-eating mode is allowed
if ((9 != wParam) || (msgwnd->flags.tab & tab_type::eating))
{
arg_keyboard arg;
arg.evt_code = event_code::key_char;
@ -1446,8 +1459,6 @@ namespace detail
brock.wd_manager.do_lazy_refresh(msgwnd, false);
}
}
else
root_runtime->condition.tabstop_focus_changed = false;
return 0;
case WM_KEYUP:
if(wParam != 18) //MUST NOT BE AN ALT
@ -1467,7 +1478,10 @@ namespace detail
else
brock.set_keyboard_shortkey(false);
brock.delay_restore(2); //Restores while key release
//Do delay restore if key is not arrow_left/right/up/down, otherwise
//A menubar will be restored if the item is empty(not have a menu item)
if (wParam < 37 || 40 < wParam)
brock.delay_restore(2); //Restores while key release
break;
case WM_CLOSE:
{
@ -1490,9 +1504,7 @@ namespace detail
brock.erase_menu(false);
brock.delay_restore(3); //Restores if delay_restore not decleared
}
brock.wd_manager.destroy(msgwnd);
nana::detail::platform_spec::instance().release_window_icon(msgwnd->root);
break;
case WM_NCDESTROY:
@ -1523,15 +1535,10 @@ namespace detail
return ::DefWindowProc(root_window, message, wParam, lParam);
}
nana::category::flags bedrock::category(core_window_t* wd)
::nana::category::flags bedrock::category(core_window_t* wd)
{
if(wd)
{
internal_scope_guard isg;
if(wd_manager.available(wd))
return wd->other.category;
}
return nana::category::flags::super;
internal_scope_guard lock;
return (wd_manager.available(wd) ? wd->other.category : ::nana::category::flags::super);
}
auto bedrock::focus() ->core_window_t*
@ -1542,13 +1549,8 @@ namespace detail
native_window_type bedrock::root(core_window_t* wd)
{
if(wd)
{
internal_scope_guard isg;
if(wd_manager.available(wd))
return wd->root;
}
return nullptr;
internal_scope_guard lock;
return (wd_manager.available(wd) ? wd->root : nullptr);
}
void bedrock::set_menubar_taken(core_window_t* wd)

View File

@ -1,7 +1,7 @@
/*
* Window Layout Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
* 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
@ -24,12 +24,13 @@ namespace nana
//class window_layout
void window_layout::paint(core_window_t* wd, bool is_redraw, bool is_child_refreshed)
{
if (wd->flags.refreshing || wd->drawer.graphics.empty())
return;
if (nullptr == wd->effect.bground)
{
if (is_redraw)
{
if (wd->flags.refreshing) return;
wd->flags.refreshing = true;
wd->drawer.refresh();
wd->flags.refreshing = false;
@ -42,6 +43,10 @@ namespace nana
bool window_layout::maproot(core_window_t* wd, bool have_refreshed, bool is_child_refreshed)
{
auto check_opaque = wd->seek_non_lite_widget_ancestor();
if (check_opaque && check_opaque->flags.refreshing)
return true;
nana::rectangle vr;
if (read_visual_rectangle(wd, vr))
{
@ -56,7 +61,6 @@ namespace nana
if (wd->parent)
{
std::vector<wd_rectangle> blocks;
blocks.reserve(10);
if (read_overlaps(wd, vr, blocks))
{
nana::point p_src;
@ -96,7 +100,7 @@ namespace nana
// The result is a rectangle that is a visible area for its ancesters.
bool window_layout::read_visual_rectangle(core_window_t* wd, nana::rectangle& visual)
{
if (false == wd->visible) return false;
if (! wd->displayed()) return false;
visual = rectangle{ wd->pos_root, wd->dimension };
@ -205,7 +209,7 @@ namespace nana
beg = beg->parent;
}
glass_buffer.bitblt(wd->dimension, beg->drawer.graphics, wd->pos_root - beg->pos_root);
glass_buffer.bitblt(::nana::rectangle{ wd->dimension }, beg->drawer.graphics, wd->pos_root - beg->pos_root);
nana::rectangle r(wd->pos_owner, wd->dimension);
for (auto i = layers.rbegin(), layers_rend = layers.rend(); i != layers_rend; ++i)
@ -235,7 +239,7 @@ namespace nana
}
}
else
glass_buffer.bitblt(wd->dimension, wd->parent->drawer.graphics, wd->pos_owner);
glass_buffer.bitblt(::nana::rectangle{ wd->dimension }, wd->parent->drawer.graphics, wd->pos_owner);
const rectangle r_of_wd{ wd->pos_owner, wd->dimension };
for (auto child : wd->parent->children)
@ -351,7 +355,7 @@ namespace nana
nana::rectangle r_of_sigwd(sigwd->pos_root, sigwd->dimension);
for (auto wd : data_sect.effects_bground_windows)
{
if (wd == sigwd || !wd->visible || !wd->visible_parents() ||
if (wd == sigwd || !wd->displayed() ||
(false == overlap(nana::rectangle{ wd->pos_root, wd->dimension }, r_of_sigwd)))
continue;

View File

@ -1,7 +1,7 @@
/*
* Window Manager Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
* 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
@ -42,8 +42,8 @@ namespace detail
{
root_register misc_register;
handle_manager<core_window_t*, window_manager, window_handle_deleter> wd_register;
signal_manager signal;
paint::image default_icon;
paint::image default_icon_big;
paint::image default_icon_small;
};
//end struct wdm_private_impl
@ -171,22 +171,6 @@ namespace detail
impl_->wd_register.all(v);
}
void window_manager::signal_fire_caption(core_window_t* wd, const nana::char_t* str)
{
detail::signals sig;
sig.info.caption = str;
impl_->signal.call_signal(wd, signals::code::caption, sig);
}
nana::string window_manager::signal_fire_caption(core_window_t* wd)
{
nana::string str;
detail::signals sig;
sig.info.str = &str;
impl_->signal.call_signal(wd, signals::code::read_caption, sig);
return str;
}
void window_manager::event_filter(core_window_t* wd, bool is_make, event_code evtid)
{
switch(evtid)
@ -199,11 +183,6 @@ namespace detail
}
}
void window_manager::default_icon(const paint::image& img)
{
impl_->default_icon = img;
}
bool window_manager::available(core_window_t* wd)
{
return impl_->wd_register.available(wd);
@ -224,10 +203,10 @@ namespace detail
return false;
}
window_manager::core_window_t* window_manager::create_root(core_window_t* owner, bool nested, rectangle r, const appearance& app, widget * wdg)
window_manager::core_window_t* window_manager::create_root(core_window_t* owner, bool nested, rectangle r, const appearance& app, widget* wdg)
{
native_window_type native = nullptr;
if(owner)
if (owner)
{
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
@ -244,9 +223,9 @@ namespace detail
}
auto result = native_interface::create_window(native, nested, r, app);
if(result.native_handle)
if (result.native_handle)
{
core_window_t* wd = new core_window_t(owner, wdg, (category::root_tag**)nullptr);
core_window_t* wd = new core_window_t(owner, widget_notifier_interface::get_notifier(wdg), (category::root_tag**)nullptr);
wd->flags.take_active = !app.no_activate;
wd->title = native_interface::window_caption(result.native_handle);
@ -260,11 +239,11 @@ namespace detail
wd->bind_native_window(result.native_handle, result.width, result.height, result.extra_width, result.extra_height, value->root_graph);
impl_->wd_register.insert(wd, wd->thread_id);
if(owner && owner->other.category == category::frame_tag::value)
if (owner && owner->other.category == category::frame_tag::value)
insert_frame(owner, wd);
bedrock::inc_window(wd->thread_id);
this->icon(wd, impl_->default_icon);
this->icon(wd, impl_->default_icon_small, impl_->default_icon_big);
return wd;
}
return nullptr;
@ -277,7 +256,7 @@ namespace detail
if (impl_->wd_register.available(parent) == false) return nullptr;
core_window_t * wd = new core_window_t(parent, r, wdg, (category::frame_tag**)nullptr);
core_window_t * wd = new core_window_t(parent, widget_notifier_interface::get_notifier(wdg), r, (category::frame_tag**)nullptr);
wd->frame_window(native_interface::create_child_window(parent->root, rectangle(wd->pos_root.x, wd->pos_root.y, r.width, r.height)));
impl_->wd_register.insert(wd, wd->thread_id);
@ -324,11 +303,13 @@ namespace detail
if (impl_->wd_register.available(parent) == false)
throw std::invalid_argument("invalid parent/owner handle");
auto wdg_notifier = widget_notifier_interface::get_notifier(wdg);
core_window_t * wd;
if(is_lite)
wd = new core_window_t(parent, r, wdg, (category::lite_widget_tag**)nullptr);
if (is_lite)
wd = new core_window_t(parent, std::move(wdg_notifier), r, (category::lite_widget_tag**)nullptr);
else
wd = new core_window_t(parent, r, wdg, (category::widget_tag**)nullptr);
wd = new core_window_t(parent, std::move(wdg_notifier), r, (category::widget_tag**)nullptr);
impl_->wd_register.insert(wd, wd->thread_id);
return wd;
}
@ -358,8 +339,8 @@ namespace detail
//before the window_manager destroyes the window, and then, window_manager detaches the
//non-existing drawer_trigger which is destroyed by destruction of widget. Crash!
wd->drawer.detached();
impl_->signal.call_signal(wd, signals::code::destroy, signals_);
impl_->signal.umake(wd);
wd->widget_notifier->destroy();
native_interface::close_window(wd->root);
}
@ -372,21 +353,26 @@ namespace detail
//@brief: Delete the window handle
void window_manager::destroy(core_window_t* wd)
{
core_window_t* parent = nullptr;
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd) == false) return;
rectangle update_area(wd->pos_owner, wd->dimension);
auto parent = wd->parent;
if (parent)
utl::erase(parent->children, wd);
_m_destroy(wd);
while (parent && (parent->other.category == ::nana::category::flags::lite_widget))
{
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd) == false) return;
if (wd->parent)
{
parent = wd->parent;
utl::erase(wd->parent->children, wd);
}
_m_destroy(wd);
update_area.x += parent->pos_owner.x;
update_area.y += parent->pos_owner.y;
parent = parent->parent;
}
update(parent, false, false);
update(parent, false, false, &update_area);
}
//destroy_handle
@ -404,15 +390,21 @@ namespace detail
}
}
void window_manager::icon(core_window_t* wd, const paint::image& img)
void window_manager::default_icon(const nana::paint::image& small, const nana::paint::image& big)
{
if(false == img.empty())
impl_->default_icon_big = big;
impl_->default_icon_small = small;
}
void window_manager::icon(core_window_t* wd, const paint::image& small_icon, const paint::image& big_icon)
{
if(!big_icon.empty() || !small_icon.empty())
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd))
{
if(wd->other.category == category::root_tag::value)
native_interface::window_icon(wd->root, img);
native_interface::window_icon(wd->root, small_icon, big_icon);
}
}
}
@ -423,35 +415,34 @@ namespace detail
{
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd))
if (!impl_->wd_register.available(wd))
return false;
if(visible != wd->visible)
{
if(visible != wd->visible)
native_window_type nv = nullptr;
switch(wd->other.category)
{
native_window_type nv = nullptr;
switch(wd->other.category)
{
case category::root_tag::value:
nv = wd->root; break;
case category::frame_tag::value:
nv = wd->other.attribute.frame->container; break;
default: //category::widget_tag, category::lite_widget_tag
break;
}
if(visible && wd->effect.bground)
wndlayout_type::make_bground(wd);
//Don't set the visible attr of a window if it is a root.
//The visible attr of a root will be set in the expose event.
if(category::root_tag::value != wd->other.category)
bedrock::instance().event_expose(wd, visible);
if(nv)
native_interface::show_window(nv, visible, wd->flags.take_active);
case category::root_tag::value:
nv = wd->root; break;
case category::frame_tag::value:
nv = wd->other.attribute.frame->container; break;
default: //category::widget_tag, category::lite_widget_tag
break;
}
return true;
if(visible && wd->effect.bground)
window_layer::make_bground(wd);
//Don't set the visible attr of a window if it is a root.
//The visible attr of a root will be set in the expose event.
if(category::flags::root != wd->other.category)
bedrock::instance().event_expose(wd, visible);
if(nv)
native_interface::show_window(nv, visible, wd->flags.take_active);
}
return false;
return true;
}
window_manager::core_window_t* window_manager::find_window(native_window_type root, int x, int y)
@ -489,9 +480,6 @@ namespace detail
wd->pos_owner.y = y;
_m_move_core(wd, delta);
if(wd->together.caret && wd->together.caret->visible())
wd->together.caret->update();
auto &brock = bedrock::instance();
arg_move arg;
arg.window_handle = reinterpret_cast<window>(wd);
@ -518,7 +506,7 @@ namespace detail
auto & brock = bedrock::instance();
bool moved = false;
const bool size_changed = (r.width != wd->dimension.width || r.height != wd->dimension.height);
if(wd->other.category != category::root_tag::value)
if(category::flags::root != wd->other.category)
{
//Move child widgets
if(r.x != wd->pos_owner.x || r.y != wd->pos_owner.y)
@ -529,9 +517,6 @@ namespace detail
_m_move_core(wd, delta);
moved = true;
if(wd->together.caret && wd->together.caret->visible())
wd->together.caret->update();
arg_move arg;
arg.window_handle = reinterpret_cast<window>(wd);
arg.x = r.x;
@ -640,7 +625,7 @@ namespace detail
if(wd->effect.bground && wd->parent)
{
wd->other.glass_buffer.make(sz);
wndlayout_type::make_bground(wd);
window_layer::make_bground(wd);
}
}
}
@ -672,7 +657,7 @@ namespace detail
}
//Copy the root buffer that wnd specified into DeviceContext
void window_manager::map(core_window_t* wd, bool forced)
void window_manager::map(core_window_t* wd, bool forced, const rectangle* update_area)
{
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
@ -680,12 +665,12 @@ namespace detail
{
//Copy the root buffer that wd specified into DeviceContext
#if defined(NANA_LINUX)
wd->drawer.map(reinterpret_cast<window>(wd), forced);
wd->drawer.map(reinterpret_cast<window>(wd), forced, update_area);
#elif defined(NANA_WINDOWS)
if(nana::system::this_thread_id() == wd->thread_id)
wd->drawer.map(reinterpret_cast<window>(wd), forced);
wd->drawer.map(reinterpret_cast<window>(wd), forced, update_area);
else
bedrock::instance().map_thread_root_buffer(wd, forced);
bedrock::instance().map_thread_root_buffer(wd, forced, update_area);
#endif
}
}
@ -694,26 +679,28 @@ namespace detail
//@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
// 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 forced)
bool window_manager::update(core_window_t* wd, bool redraw, bool forced, const rectangle* update_area)
{
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd) == false) return false;
if (wd->visible && wd->visible_parents())
if (wd->displayed())
{
if(forced || (false == wd->belong_to_lazy()))
{
wndlayout_type::paint(wd, redraw, false);
this->map(wd, forced);
}
else
{
if(redraw)
wndlayout_type::paint(wd, true, false);
if(wd->other.upd_state == core_window_t::update_state::lazy)
wd->other.upd_state = core_window_t::update_state::refresh;
if (!wd->flags.refreshing)
{
window_layer::paint(wd, redraw, false);
this->map(wd, forced, update_area);
return true;
}
}
else if (redraw)
window_layer::paint(wd, true, false);
if (wd->other.upd_state == core_window_t::update_state::lazy)
wd->other.upd_state = core_window_t::update_state::refresh;
}
return true;
}
@ -724,8 +711,8 @@ namespace detail
std::lock_guard<decltype(mutex_)> lock(mutex_);
//It's not worthy to redraw if visible is false
if (impl_->wd_register.available(wd) && wd->visible && wd->visible_parents())
wndlayout_type::paint(wd, true, true);
if (impl_->wd_register.available(wd) && wd->displayed())
window_layer::paint(wd, true, true);
}
//do_lazy_refresh
@ -746,18 +733,16 @@ namespace detail
{
if ((wd->other.upd_state == core_window_t::update_state::refresh) || force_copy_to_screen)
{
wndlayout_type::paint(wd, false, false);
window_layer::paint(wd, false, false);
this->map(wd, force_copy_to_screen);
}
else if (effects::edge_nimbus::none != wd->effect.edge_nimbus)
{
//Update the nimbus effect
using nimbus_renderer = detail::edge_nimbus_renderer<core_window_t>;
nimbus_renderer::instance().render(wd, force_copy_to_screen);
this->map(wd, true);
}
}
else
wndlayout_type::paint(wd, true, false); //only refreshing if it has an invisible parent
window_layer::paint(wd, true, false); //only refreshing if it has an invisible parent
}
wd->other.upd_state = core_window_t::update_state::none;
return true;
@ -777,7 +762,7 @@ namespace detail
result.make(wd->drawer.graphics.size());
result.bitblt(0, 0, wd->drawer.graphics);
wndlayout_type::paste_children_to_graphics(wd, result);
window_layer::paste_children_to_graphics(wd, result);
return true;
}
@ -786,14 +771,14 @@ namespace detail
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
return (impl_->wd_register.available(wd) ?
wndlayout_type::read_visual_rectangle(wd, r) :
window_layer::read_visual_rectangle(wd, r) :
false);
}
::nana::widget* window_manager::get_widget(core_window_t* wd) const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return (impl_->wd_register.available(wd) ? wd->widget_ptr : nullptr);
return (impl_->wd_register.available(wd) ? wd->widget_notifier->widget_ptr() : nullptr);
}
std::vector<window_manager::core_window_t*> window_manager::get_children(core_window_t* wd) const
@ -933,6 +918,9 @@ namespace detail
// the return value is NULL
window_manager::core_window_t* window_manager::capture_window(core_window_t* wd, bool value)
{
if (!this->available(wd))
return nullptr;
nana::point pos = native_interface::cursor_position();
auto & attr_cap = attr_.capture.history;
@ -1015,6 +1003,39 @@ namespace detail
}
}
// preconditions of get_tabstop: tabstop is not empty and at least one window is visible
window_manager::core_window_t* get_tabstop(window_manager::core_window_t* wd, bool forward)
{
auto & tabs = wd->root_widget->other.attribute.root->tabstop;
if (forward)
{
if (detail::tab_type::none == wd->flags.tab)
return (tabs.front());
else if (detail::tab_type::tabstop & wd->flags.tab)
{
auto end = tabs.cend();
auto i = std::find(tabs.cbegin(), end, wd);
if (i != end)
{
++i;
window_manager::core_window_t* ts = (i != end ? (*i) : tabs.front());
return (ts != wd ? ts : 0);
}
else
return tabs.front();
}
}
else if (tabs.size() > 1) //at least 2 elments in tabs are required when moving backward.
{
auto i = std::find(tabs.cbegin(), tabs.cend(), wd);
if (i != tabs.cend())
return (tabs.cbegin() == i ? tabs.back() : *(i - 1));
}
return nullptr;
}
auto window_manager::tabstop(core_window_t* wd, bool forward) const -> core_window_t*
{
//Thread-Safe Required!
@ -1023,33 +1044,32 @@ namespace detail
return nullptr;
auto & tabs = wd->root_widget->other.attribute.root->tabstop;
if (tabs.size())
if (tabs.empty())
return nullptr;
bool precondition = false;
for (auto & tab_wd : tabs)
{
if (forward) //
if (tab_wd->displayed())
{
if (detail::tab_type::none == wd->flags.tab)
return (tabs.front());
else if (detail::tab_type::tabstop & wd->flags.tab)
{
auto end = tabs.cend();
auto i = std::find(tabs.cbegin(), end, wd);
if (i != end)
{
++i;
core_window_t* ts = (i != end ? (*i) : tabs.front());
return (ts != wd ? ts : 0);
}
else
return tabs.front();
}
}
else if (tabs.size() > 1) //at least 2 elments in tabs is required when moving perviously.
{
auto i = std::find(tabs.cbegin(), tabs.cend(), wd);
if (i != tabs.cend())
return (tabs.cbegin() == i ? tabs.back() : *(i - 1));
precondition = true;
break;
}
}
if (precondition)
{
auto new_stop = get_tabstop(wd, forward);
while (new_stop && (wd != new_stop))
{
if (new_stop->flags.enabled && new_stop->displayed())
return new_stop;
new_stop = get_tabstop(new_stop, forward);
}
}
return nullptr;
}
@ -1063,7 +1083,7 @@ namespace detail
//Thread-Safe Required!
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd))
return wndlayout_type::enable_effects_bground(wd, enabled);
return window_layer::enable_effects_bground(wd, enabled);
return false;
}
@ -1161,11 +1181,6 @@ namespace detail
return nullptr;
}
void window_manager::_m_attach_signal(core_window_t* wd, signal_invoker_interface* si)
{
impl_->signal.make(wd, si);
}
bool check_tree(basic_window* wd, basic_window* const cond)
{
if (wd == cond) return true;
@ -1252,18 +1267,9 @@ namespace detail
if (!established)
{
if (effects::edge_nimbus::none != wd->effect.edge_nimbus)
{
auto & cont = root_attr->effects_edge_nimbus;
for (auto i = cont.begin(); i != cont.end(); ++i)
{
if (i->window == wd)
{
cont.erase(i);
break;
}
}
}
//remove the window from edge nimbus effect when it is destroying
using edge_nimbus = detail::edge_nimbus_renderer<core_window_t>;
edge_nimbus::instance().erase(wd);
}
else if (pa_root_attr != root_attr)
{
@ -1363,21 +1369,22 @@ namespace detail
delete wd->together.caret;
wd->together.caret = nullptr;
}
//Delete the children widgets.
for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end; ++i)
_m_destroy(*i);
wd->children.clear();
arg_destroy arg;
arg.window_handle = reinterpret_cast<window>(wd);
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
//Delete the children widgets.
for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end; ++i)
_m_destroy(*i);
wd->children.clear();
_m_disengage(wd, nullptr);
wndlayout_type::enable_effects_bground(wd, false);
window_layer::enable_effects_bground(wd, false);
wd->drawer.detached();
impl_->signal.call_signal(wd, signals::code::destroy, signals_);
impl_->signal.umake(wd);
wd->widget_notifier->destroy();
if(wd->other.category == category::frame_tag::value)
{
@ -1398,9 +1405,17 @@ namespace detail
if(wd->other.category != category::root_tag::value) //A root widget always starts at (0, 0) and its childs are not to be changed
{
wd->pos_root += delta;
if(wd->other.category == category::frame_tag::value)
if (category::flags::frame != wd->other.category)
{
if (wd->together.caret && wd->together.caret->visible())
wd->together.caret->update();
}
else
native_interface::move_window(wd->other.attribute.frame->container, wd->pos_root.x, wd->pos_root.y);
if (wd->displayed() && wd->effect.bground)
window_layer::make_bground(wd);
for (auto child : wd->children)
_m_move_core(child, delta);
}

View File

@ -26,7 +26,7 @@ namespace nana
{
if(fade_rate_ < 0.001)
return;
graph.blend(graph.size(), API::bgcolor(wd), fade_rate_);
graph.blend(::nana::rectangle{ graph.size() }, API::bgcolor(wd), fade_rate_);
}
private:
const double fade_rate_;
@ -42,7 +42,7 @@ namespace nana
void take_effect(window, graph_reference graph) const
{
graph.blur(graph.size(), radius_);
graph.blur(::nana::rectangle{ graph.size() }, radius_);
}
private:
const std::size_t radius_;

View File

@ -141,7 +141,7 @@ namespace nana
}
else
{
::nana::color highlighted(0x5e, 0xb6, 0xf7);
::nana::color highlighted(static_cast<color_rgb>(0x5eb6f7));
auto bld_bgcolor = bgcolor;
auto bld_fgcolor = fgcolor;
switch(es)
@ -156,7 +156,7 @@ namespace nana
bld_fgcolor = fgcolor.blend(highlighted, 0.4);
break;
case element_state::disabled:
bld_bgcolor = bld_fgcolor = nana::color(0xb2, 0xb7, 0xbc);
bld_bgcolor = bld_fgcolor.from_rgb(0xb2, 0xb7, 0xbc);
break;
default:
//Leave things as they are
@ -264,7 +264,7 @@ namespace nana
bool draw(graph_reference graph, const ::nana::color& bgcolor, const ::nana::color& fgcolor, const ::nana::rectangle& r, element_state estate, unsigned weight)
{
graph.rectangle(r, false, static_cast<color_rgb>((element_state::focus_hovered == estate || element_state::focus_normal == estate) ? 0x0595E2 : 0x999A9E));
graph.rectangle(::nana::rectangle{r}.pare_off(1), false, bgcolor);
graph.rectangle(::nana::rectangle(r).pare_off(1), false, bgcolor);
return true;
}
};
@ -580,9 +580,6 @@ namespace nana
class element_manager
: nana::noncopyable, nana::nonmovable
{
//VC2012 does not support alias declaration.
//template<typename E> using factory_interface = element::provider::factory_interface<E>;
template<typename ElementInterface>
struct item
{

View File

@ -163,7 +163,7 @@ namespace nana
btn_folder_.create(*this);
btn_folder_.caption(STR("&New Folder"));
btn_folder_.events().click.connect_unignorable([this](const arg_mouse&)
btn_folder_.events().click.connect_unignorable([this](const arg_click&)
{
form fm(this->handle(), API::make_center(*this, 300, 35));
fm.caption(STR("Name the new folder"));
@ -179,7 +179,7 @@ namespace nana
button btn_cancel(fm, nana::rectangle(235, 5, 60, 25));
btn_cancel.caption(STR("Cancel"));
btn_cancel.events().click.connect_unignorable([&fm](const arg_mouse&)
btn_cancel.events().click.connect_unignorable([&fm](const arg_click&)
{
fm.close();
});
@ -288,14 +288,14 @@ namespace nana
btn_ok_.create(*this);
btn_ok_.caption(STR("&OK"));
btn_ok_.events().click.connect_unignorable([this](const arg_mouse&)
btn_ok_.events().click.connect_unignorable([this](const arg_click&)
{
_m_ok();
});
btn_cancel_.create(*this);
btn_cancel_.caption(STR("&Cancel"));
btn_cancel_.events().click.connect_unignorable([this](const arg_mouse&)
btn_cancel_.events().click.connect_unignorable([this](const arg_click&)
{
API::close_window(handle());
});
@ -1021,6 +1021,7 @@ namespace nana
if (!impl_->open_or_save)
ofn.Flags = OFN_OVERWRITEPROMPT; //Overwrite prompt if it is save mode
ofn.Flags |= OFN_NOCHANGEDIR;
if(FALSE == (impl_->open_or_save ? ::GetOpenFileName(&ofn) : ::GetSaveFileName(&ofn)))
return false;

View File

@ -52,11 +52,13 @@ namespace nana
bool overlap(const rectangle& ir, const size& valid_input_area, const rectangle & dr, const size& valid_dst_area, rectangle& op_ir, rectangle& op_dr)
{
if(overlap(ir, valid_input_area, op_ir) == false)
rectangle valid_r{ valid_input_area };
if (overlap(ir, valid_r, op_ir) == false)
return false;
valid_r = valid_dst_area;
rectangle good_dr;
if(overlap(dr, valid_dst_area, good_dr) == false)
if (overlap(dr, valid_r, good_dr) == false)
return false;
zoom(ir, op_ir, dr, op_dr);

View File

@ -48,7 +48,7 @@ namespace nana
{
graph.rectangle(rectangle{0, 0, graph.width(), graph.height() - 50}, true, colors::white);
if(ico_.empty() == false)
ico_.stretch(ico_.size(), graph, rectangle{12, 25, 32, 32});
ico_.stretch(rectangle{ico_.size()}, graph, rectangle{12, 25, 32, 32});
});
unsigned width_pixel = 45;
@ -57,7 +57,7 @@ namespace nana
place_.bind(*this);
yes_.create(*this);
yes_.events().click.connect_unignorable([this](const arg_mouse& arg)
yes_.events().click.connect_unignorable([this](const arg_click& arg)
{
_m_click(arg);
});
@ -69,7 +69,7 @@ namespace nana
yes_.caption(STR("Yes"));
no_.create(*this);
no_.caption(STR("No"));
no_.events().click.connect_unignorable([this](const arg_mouse& arg)
no_.events().click.connect_unignorable([this](const arg_click& arg)
{
_m_click(arg);
});
@ -80,7 +80,7 @@ namespace nana
{
cancel_.create(*this);
cancel_.caption(STR("Cancel"));
cancel_.events().click.connect_unignorable([this](const arg_mouse& arg)
cancel_.events().click.connect_unignorable([this](const arg_click& arg)
{
_m_click(arg);
});
@ -303,11 +303,11 @@ namespace nana
nana::paint::pixel_buffer pxbuf(32, 32);
pxbuf.put(reinterpret_cast<const unsigned char*>(rawpx), 32, 32, 32, 4*32, true);
ico_.make({32, 32});
pxbuf.paste(ico_.handle(), 0, 0);
pxbuf.paste(ico_.handle(), {});
}
}
void _m_click(const arg_mouse& arg)
void _m_click(const arg_click& arg)
{
if(arg.window_handle == yes_)
pick_ = (no_.empty() ? msgbox::pick_ok : msgbox::pick_yes);

View File

@ -112,7 +112,7 @@ namespace API
iwd->effect.bground = new_effect_ptr;
iwd->effect.bground_fade_rate = fade_rate;
restrict::window_manager.enable_effects_bground(iwd, true);
if (fade_rate < 0.01)
iwd->flags.make_bground_declared = true;
@ -184,7 +184,7 @@ namespace API
}
}
nana::string window_caption(window wd)
nana::string window_caption(window wd) throw()
{
auto const iwd = reinterpret_cast<restrict::core_window_t*>(wd);
internal_scope_guard isg;
@ -354,14 +354,14 @@ namespace API
return r;
}
void window_icon_default(const paint::image& img)
void window_icon_default(const paint::image& small_icon, const paint::image& big_icon)
{
restrict::window_manager.default_icon(img);
restrict::window_manager.default_icon(small_icon, big_icon);
}
void window_icon(window wd, const paint::image& img)
void window_icon(window wd, const paint::image& small_icon, const paint::image& big_icon)
{
restrict::window_manager.icon(reinterpret_cast<restrict::core_window_t*>(wd), img);
restrict::window_manager.icon(reinterpret_cast<restrict::core_window_t*>(wd), small_icon, big_icon);
}
bool empty_window(window wd)
@ -374,6 +374,16 @@ namespace API
return restrict::window_manager.available(reinterpret_cast<restrict::core_window_t*>(wd));
}
bool is_destroying(window wd)
{
auto iwd = reinterpret_cast<restrict::core_window_t*>(wd);
internal_scope_guard lock;
if (!restrict::window_manager.available(iwd))
return false;
return iwd->flags.destroying;
}
void enable_dropfiles(window wd, bool enb)
{
internal_scope_guard lock;
@ -534,13 +544,19 @@ namespace API
internal_scope_guard lock;
if(restrict::window_manager.move(iwd, x, y, false))
{
if(category::flags::root != iwd->other.category)
restrict::core_window_t* update_wd = nullptr;
if (iwd->displayed() && iwd->effect.bground)
{
do{
iwd = iwd->parent;
} while (category::flags::lite_widget == iwd->other.category);
update_wd = iwd;
restrict::window_manager.update(iwd, true, false);
}
restrict::window_manager.update(iwd, false, false);
restrict::core_window_t* anc = iwd;
if (category::flags::root != iwd->other.category)
anc = iwd->seek_non_lite_widget_ancestor();
if (anc != update_wd)
restrict::window_manager.update(anc, false, false);
}
}
@ -551,11 +567,8 @@ namespace API
if(restrict::window_manager.move(iwd, r))
{
if (category::flags::root != iwd->other.category)
{
do{
iwd = iwd->parent;
} while (category::flags::lite_widget == iwd->other.category);
}
iwd = iwd->seek_non_lite_widget_ancestor();
restrict::window_manager.update(iwd, false, false);
}
}
@ -624,11 +637,8 @@ namespace API
if(restrict::window_manager.size(iwd, sz, false, false))
{
if (category::flags::root != iwd->other.category)
{
do{
iwd = iwd->parent;
} while (category::flags::lite_widget == iwd->other.category);
}
iwd = iwd->seek_non_lite_widget_ancestor();
restrict::window_manager.update(iwd, false, false);
}
}
@ -639,7 +649,7 @@ namespace API
internal_scope_guard lock;
if (!restrict::window_manager.available(iwd))
return{};
auto sz = window_size(wd);
sz.width += iwd->extra_width;
sz.height += iwd->extra_height;
@ -721,7 +731,7 @@ namespace API
if(restrict::window_manager.available(iwd) && (iwd->flags.enabled != enabled))
{
iwd->flags.enabled = enabled;
restrict::window_manager.update(iwd, true, false);
restrict::window_manager.update(iwd, true, true);
if(category::flags::root == iwd->other.category)
restrict::interface_type::enable_window(iwd->root, enabled);
}
@ -770,16 +780,16 @@ namespace API
{
auto const iwd = reinterpret_cast<restrict::core_window_t*>(wd);
internal_scope_guard lock;
if(restrict::window_manager.available(iwd))
restrict::window_manager.signal_fire_caption(iwd, title.c_str());
if (restrict::window_manager.available(iwd))
iwd->widget_notifier->caption(title);
}
nana::string window_caption(window wd)
{
auto const iwd = reinterpret_cast<restrict::core_window_t*>(wd);
internal_scope_guard lock;
if(restrict::window_manager.available(iwd))
return restrict::window_manager.signal_fire_caption(iwd);
if (restrict::window_manager.available(iwd))
return iwd->widget_notifier->caption();
return{};
}
@ -930,7 +940,7 @@ namespace API
if (prev != clr)
{
iwd->scheme->background = clr;
//If the bground mode of this window is basic, it should remake the background
if (iwd->effect.bground && iwd->effect.bground_fade_rate < 0.01) // fade rate < 0.01 means it is basic mode
iwd->flags.make_bground_declared = true;
@ -1284,5 +1294,25 @@ namespace API
}
return nana::element_state::normal;
}
bool ignore_mouse_focus(window wd, bool ignore)
{
auto iwd = reinterpret_cast<restrict::core_window_t*>(wd);
internal_scope_guard lock;
if (restrict::window_manager.available(iwd))
{
auto state = iwd->flags.ignore_mouse_focus;
iwd->flags.ignore_mouse_focus = ignore;
return state;
}
return false;
}
bool ignore_mouse_focus(window wd)
{
auto iwd = reinterpret_cast<restrict::core_window_t*>(wd);
internal_scope_guard lock;
return (restrict::window_manager.available(iwd) ? iwd->flags.ignore_mouse_focus : false);
}
}//end namespace API
}//end namespace nana

View File

@ -114,7 +114,7 @@ namespace nana
void load_monitors()
{
displays.clear();
displays.emplace_back(0, primary_monitor_size());
displays.emplace_back(0, rectangle{primary_monitor_size()});
}
#endif

View File

@ -17,6 +17,7 @@ namespace nana{ namespace drawerbase
{
namespace button
{
//trigger
//@brief: draw the button
trigger::trigger()
@ -97,14 +98,41 @@ namespace nana{ namespace drawerbase
void trigger::refresh(graph_reference graph)
{
_m_draw(graph);
bool eb = wdg_->enabled();;
attr_.bgcolor = wdg_->bgcolor();
attr_.fgcolor = wdg_->fgcolor();
element_state e_state = attr_.e_state;
if (eb)
{
if (attr_.focused)
{
if (element_state::normal == e_state)
e_state = element_state::focus_normal;
else if (element_state::hovered == e_state)
e_state = element_state::focus_hovered;
}
}
else
e_state = element_state::disabled;
if (false == cite_.draw(graph, attr_.bgcolor, attr_.fgcolor, ::nana::rectangle{ graph.size() }, e_state))
{
if (bground_mode::basic != API::effects_bground_mode(wdg_->handle()))
{
_m_draw_background(graph);
_m_draw_border(graph);
}
}
_m_draw_title(graph, eb);
}
void trigger::mouse_enter(graph_reference graph, const arg_mouse&)
{
attr_.e_state = (attr_.pushed || attr_.keep_pressed ? element_state::pressed : element_state::hovered);
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}
@ -114,49 +142,39 @@ namespace nana{ namespace drawerbase
return;
attr_.e_state = element_state::normal;
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}
void trigger::mouse_down(graph_reference graph, const arg_mouse&)
void trigger::mouse_down(graph_reference graph, const arg_mouse& arg)
{
attr_.e_state = element_state::pressed;
attr_.keep_pressed = true;
if (::nana::mouse::left_button != arg.button)
return;
_m_draw(graph);
API::capture_window(*wdg_, true);
API::lazy_refresh();
_m_press(graph, true);
}
void trigger::mouse_up(graph_reference graph, const arg_mouse&)
void trigger::mouse_up(graph_reference graph, const arg_mouse& arg)
{
API::capture_window(*wdg_, false);
attr_.keep_pressed = false;
if(attr_.enable_pushed && (false == attr_.pushed))
{
attr_.pushed = true;
}
else
{
if (element_state::pressed == attr_.e_state)
attr_.e_state = element_state::hovered;
else
attr_.e_state = element_state::normal;
if (::nana::mouse::left_button != arg.button)
return;
attr_.pushed = false;
_m_draw(graph);
API::lazy_refresh();
}
_m_press(graph, false);
}
void trigger::key_char(graph_reference, const arg_keyboard& arg)
{
if(arg.key == static_cast<char_t>(keyboard::enter))
if (static_cast<char_t>(keyboard::enter) == arg.key)
emit_click();
}
void trigger::key_press(graph_reference, const arg_keyboard& arg)
void trigger::key_press(graph_reference graph, const arg_keyboard& arg)
{
if (keyboard::space == static_cast<char_t>(arg.key))
{
_m_press(graph, true);
return;
}
bool ch_tabstop_next;
switch(arg.key)
{
@ -169,13 +187,26 @@ namespace nana{ namespace drawerbase
default:
return;
}
API::move_tabstop(*wdg_, ch_tabstop_next);
}
void trigger::key_release(graph_reference graph, const arg_keyboard& arg)
{
if (arg.key != static_cast<char_t>(keyboard::space))
return;
emit_click();
//Check the widget, because it may be deleted by click event
if (API::is_window(*wdg_))
_m_press(graph, false);
}
void trigger::focus(graph_reference graph, const arg_focus& arg)
{
attr_.focused = arg.getting;
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}
@ -217,12 +248,8 @@ namespace nana{ namespace drawerbase
++pos.x;
++pos.y;
}
//color_t fgcolor = (attr_.focus_color ? (attr_.focused ? 0xFF : attr_.fgcolor) : attr_.fgcolor);
auto fgcolor = attr_.fgcolor;
if (attr_.focus_color && attr_.focused)
fgcolor = ::nana::color(colors::blue);
graph.set_text_color(fgcolor);
graph.set_text_color(attr_.focus_color && attr_.focused ? ::nana::color(colors::blue) : attr_.fgcolor);
if (attr_.omitted)
tr.render(pos, txtptr, txtlen, omitted_pixels, true);
@ -258,39 +285,7 @@ namespace nana{ namespace drawerbase
}
if(attr_.icon)
attr_.icon->paste(graph, 3, (gsize.height - icon_sz.height) / 2);
}
void trigger::_m_draw(graph_reference graph)
{
bool eb = wdg_->enabled();;
attr_.bgcolor = wdg_->bgcolor();
attr_.fgcolor = wdg_->fgcolor();
element_state e_state = attr_.e_state;
if (eb)
{
if (attr_.focused)
{
if (element_state::normal == e_state)
e_state = element_state::focus_normal;
else if (element_state::hovered == e_state)
e_state = element_state::focus_hovered;
}
}
else
e_state = element_state::disabled;
if (false == cite_.draw(graph, attr_.bgcolor, attr_.fgcolor, graph.size(), e_state))
{
if (bground_mode::basic != API::effects_bground_mode(wdg_->handle()))
{
_m_draw_background(graph);
_m_draw_border(graph);
}
}
_m_draw_title(graph, eb);
attr_.icon->paste(graph, point{ 3, static_cast<int>(gsize.height - icon_sz.height) / 2 });
}
void trigger::_m_draw_background(graph_reference graph)
@ -309,40 +304,76 @@ namespace nana{ namespace drawerbase
graph.gradual_rectangle(r, from, to, true);
}
void draw_corner_point(::nana::paint::graphics& graph, const rectangle& r)
{
graph.set_pixel(r.x, r.y);
graph.set_pixel(r.right() - 1, r.y);
graph.set_pixel(r.right() - 1, r.bottom() - 1);
graph.set_pixel(r.x, r.bottom() - 1);
}
void trigger::_m_draw_border(graph_reference graph)
{
nana::rectangle r(graph.size());
int right = r.width - 1;
int bottom = r.height - 1;
::nana::color lt{0x7f,0x7f,0x7f}, rb{0x70,0x70,0x70};
::nana::color lt(static_cast<color_rgb>(0x7f7f7f)), rb(static_cast<color_rgb>(0x707070));
graph.frame_rectangle(r, lt, lt, rb, rb);
graph.set_color({0x91,0x91,0x91});
graph.set_pixel(1, 1);
graph.set_pixel(right - 1, 1);
graph.set_pixel(right - 1, bottom - 1);
graph.set_pixel(1, bottom - 1);
graph.set_color(colors::button_face);
graph.set_pixel(0, 0);
graph.set_pixel(right, 0);
graph.set_pixel(0, bottom);
graph.set_pixel(right, bottom);
draw_corner_point(graph, r);
graph.set_color(static_cast<color_rgb>(0x919191));
draw_corner_point(graph, r.pare_off(1));
if (element_state::pressed == attr_.e_state)
graph.rectangle(r.pare_off(1), false, {0xc3, 0xc3, 0xc3});
graph.rectangle(r, false, static_cast<color_rgb>(0xc3c3c3));
}
void trigger::_m_press(graph_reference graph, bool is_pressed)
{
bool draw = false;
if (is_pressed)
{
if (attr_.e_state != element_state::pressed)
{
attr_.e_state = element_state::pressed;
attr_.keep_pressed = true;
API::capture_window(*wdg_, true);
draw = true;
}
}
else
{
API::capture_window(*wdg_, false);
attr_.keep_pressed = false;
if (attr_.enable_pushed && (false == attr_.pushed))
{
attr_.pushed = true;
}
else
{
if (element_state::pressed == attr_.e_state)
attr_.e_state = element_state::hovered;
else
attr_.e_state = element_state::normal;
attr_.pushed = false;
draw = true;
}
}
if (draw)
{
refresh(graph);
API::lazy_refresh();
}
}
void trigger::emit_click()
{
arg_mouse arg;
arg.evt_code = event_code::click;
arg_click arg;
arg.window_handle = wdg_->handle();
arg.ctrl = arg.shift = false;
arg.mid_button = arg.right_button = false;
arg.left_button = true;
arg.pos.x = arg.pos.y = 1;
arg.by_mouse = false;
API::emit_event(event_code::click, arg.window_handle, arg);
}
@ -470,18 +501,11 @@ namespace nana{ namespace drawerbase
return *this;
}
void button::_m_shortkey()
{
get_drawer_trigger().emit_click();
}
void button::_m_complete_creation()
{
events().shortkey.connect_unignorable([this]
{
_m_shortkey();
get_drawer_trigger().emit_click();
});
}

View File

@ -156,10 +156,10 @@ namespace nana
{
rectangle r{ graph.size() };
graph.rectangle(r, false, { 0xf0, 0xf0, 0xf0 });
graph.rectangle(r, false, static_cast<color_rgb>(0xf0f0f0));
color lb(0x9d, 0xab, 0xb9);
color tr(0x48, 0x4e, 0x55);
color lb(static_cast<color_rgb>(0x9dabb9));
color tr(static_cast<color_rgb>(0x484e55));
graph.frame_rectangle(r.pare_off(1), lb, tr, tr, lb);
}
private:
@ -168,7 +168,7 @@ namespace nana
const unsigned half = (height - 2) / 2;
int left = x + 1;
int top = y + 1;
nana::color clr_top(0xea, 0xea, 0xea), clr_bottom(0xdc, 0xdc, 0xdc);
nana::color clr_top(static_cast<color_rgb>(0xEAEAEA)), clr_bottom(static_cast<color_rgb>(0xDCDCDC));
switch(state)
{
case mouse_action::over:
@ -192,7 +192,7 @@ namespace nana
int bottom = y + height - 1;
int right = x + width - 1;
graph.set_color(color(0x6e, 0x8d, 0x9f));
graph.set_color(static_cast<color_rgb>(0x6E8D9F));
graph.line(point{ x, y }, point{right, y});
graph.line(point{ x, y + 1 }, point{ x, bottom });
++x;
@ -207,8 +207,6 @@ namespace nana
ui_element ui_el_;
struct style_tag
{
//nana::color_t bgcolor;
//nana::color_t fgcolor;
color bgcolor;
color fgcolor;
}style_;
@ -217,8 +215,8 @@ namespace nana
class tree_wrapper
{
public:
typedef widgets::detail::tree_cont<item_tag> container;
typedef container::node_type * node_handle;
using container = widgets::detail::tree_cont<item_tag>;
using node_handle = container::node_type*;
tree_wrapper()
:splitstr_(STR("\\")), cur_(nullptr)
@ -495,12 +493,11 @@ namespace nana
bool erase_locate()
{
ui_el_.index = npos;
if(ui_el_.what != ui_el_.none)
{
ui_el_.what = ui_el_.none;
return true;
}
return false;
if(ui_el_.what == ui_el_.none)
return false;
ui_el_.what = ui_el_.none;
return true;
}
ui_element locate() const
@ -528,13 +525,8 @@ namespace nana
if(style_.mode != mode::floatlist)
{
style_.state = mouse_action::normal;
switch(ui_el_.what)
{
case ui_element::item_name:
if (ui_element::item_name == ui_el_.what)
_m_selected(treebase_.tail(ui_el_.index));
break;
default: break;
}
}
}
@ -882,9 +874,8 @@ namespace nana
void trigger::_m_event_agent_ready() const
{
auto & evt = scheme_->evt_holder();
auto evt_agent = event_agent_.get();
evt.selected = [evt_agent](::nana::any& val){
scheme_->evt_holder().selected = [evt_agent](::nana::any& val){
evt_agent->selected(val);
};
}

View File

@ -48,29 +48,35 @@ namespace checkbox
void drawer::refresh(graph_reference graph)
{
_m_draw(graph);
_m_draw_background(graph);
_m_draw_title(graph);
_m_draw_checkbox(graph, graph.text_extent_size(STR("jN"), 2).height + 2);
}
void drawer::mouse_down(graph_reference graph, const arg_mouse&)
{
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}
void drawer::mouse_up(graph_reference graph, const arg_mouse&)
{
if(impl_->react)
impl_->crook.reverse();
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}
void drawer::mouse_enter(graph_reference graph, const arg_mouse&)
{
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}
void drawer::mouse_leave(graph_reference graph, const arg_mouse&)
{
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}
drawer::implement * drawer::impl() const
@ -78,14 +84,6 @@ namespace checkbox
return impl_;
}
void drawer::_m_draw(graph_reference graph)
{
_m_draw_background(graph);
_m_draw_title(graph);
_m_draw_checkbox(graph, graph.text_extent_size(STR("jN"), 2).height + 2);
API::lazy_refresh();
}
void drawer::_m_draw_background(graph_reference graph)
{
if(bground_mode::basic != API::effects_bground_mode(*widget_))
@ -177,6 +175,7 @@ namespace checkbox
void checkbox::radio(bool is_radio)
{
get_drawer_trigger().impl()->crook.radio(is_radio);
API::refresh_window(handle());
}
void checkbox::transparent(bool enabled)
@ -185,6 +184,7 @@ namespace checkbox
API::effects_bground(*this, effects::bground_transparent(0), 0.0);
else
API::effects_bground_remove(*this);
API::refresh_window(handle());
}
bool checkbox::transparent() const
@ -196,10 +196,12 @@ namespace checkbox
//class radio_group
radio_group::~radio_group()
{
for(auto & i : ui_container_)
for(auto & e : ui_container_)
{
API::umake_event(i.eh_checked);
API::umake_event(i.eh_destroy);
e.uiobj->radio(false);
e.uiobj->react(true);
API::umake_event(e.eh_checked);
API::umake_event(e.eh_destroy);
}
}
@ -231,7 +233,7 @@ namespace checkbox
return ui_container_.size();
}
void radio_group::_m_checked(const arg_mouse& arg)
void radio_group::_m_checked(const arg_click& arg)
{
for (auto & i : ui_container_)
i.uiobj->check(arg.window_handle == i.uiobj->handle());

View File

@ -18,6 +18,8 @@
#include <nana/gui/widgets/skeletons/text_editor.hpp>
#include <nana/gui/widgets/skeletons/textbase_export_interface.hpp>
#include <iterator>
namespace nana
{
arg_combox::arg_combox(combox& wdg): widget(wdg)
@ -199,20 +201,16 @@ namespace nana
if (new_where == state_.pointer_where)
return false;
state_.pointer_where = new_where;
return true;
}
void set_mouse_over(bool mo)
void set_button_state(element_state state, bool reset_where)
{
state_.button_state = (mo ? element_state::hovered : element_state::normal);
state_.pointer_where = parts::none;
}
void set_mouse_press(bool mp)
{
state_.button_state = (mp ? element_state::pressed : element_state::hovered);
state_.button_state = state;
if (reset_where)
state_.pointer_where = parts::none;
}
void set_focused(bool f)
@ -263,7 +261,7 @@ namespace nana
state_.lister->move_items(upwards, circle);
return;
}
auto pos = module_.index;
if (upwards)
{
@ -414,7 +412,7 @@ namespace nana
{
if (image_pixels_ == px)
return false;
image_pixels_ = px;
return true;
}
@ -521,7 +519,7 @@ namespace nana
}
nana::point pos((image_pixels_ - imgsz.width) / 2 + 2, (vpix - imgsz.height) / 2 + 2);
img.stretch(img.size(), *graph_, nana::rectangle(pos, imgsz));
img.stretch(::nana::rectangle{ img.size() }, *graph_, nana::rectangle(pos, imgsz));
}
private:
std::vector<std::shared_ptr<item>> items_;
@ -598,7 +596,7 @@ namespace nana
void trigger::mouse_enter(graph_reference, const arg_mouse&)
{
drawer_->set_mouse_over(true);
drawer_->set_button_state(element_state::hovered, true);
if(drawer_->widget_ptr()->enabled())
{
drawer_->draw();
@ -608,7 +606,7 @@ namespace nana
void trigger::mouse_leave(graph_reference, const arg_mouse&)
{
drawer_->set_mouse_over(false);
drawer_->set_button_state(element_state::normal, true);
drawer_->editor()->mouse_enter(false);
if(drawer_->widget_ptr()->enabled())
{
@ -619,11 +617,12 @@ namespace nana
void trigger::mouse_down(graph_reference graph, const arg_mouse& arg)
{
drawer_->set_mouse_press(true);
//drawer_->set_mouse_press(true);
drawer_->set_button_state(element_state::pressed, false);
if(drawer_->widget_ptr()->enabled())
{
auto * editor = drawer_->editor();
if(false == editor->mouse_down(arg.left_button, arg.pos))
if(false == editor->mouse_down(arg.button, arg.pos))
drawer_->open_lister_if_push_button_positioned();
drawer_->draw();
@ -638,8 +637,8 @@ namespace nana
{
if (drawer_->widget_ptr()->enabled() && !drawer_->has_lister())
{
drawer_->editor()->mouse_up(arg.left_button, arg.pos);
drawer_->set_mouse_press(false);
drawer_->editor()->mouse_up(arg.button, arg.pos);
drawer_->set_button_state(element_state::hovered, false);
drawer_->draw();
API::lazy_refresh();
}
@ -685,7 +684,7 @@ namespace nana
{
case keyboard::os_arrow_left:
case keyboard::os_arrow_right:
drawer_->editor()->respond_key(arg.key);
drawer_->editor()->respond_key(arg);
drawer_->editor()->reset_caret();
break;
case keyboard::os_arrow_up:
@ -714,14 +713,14 @@ namespace nana
}
}
if (call_other_keys)
drawer_->editor()->respond_key(arg.key);
drawer_->editor()->respond_key(arg);
API::lazy_refresh();
}
void trigger::key_char(graph_reference graph, const arg_keyboard& arg)
{
if (drawer_->editor()->respond_char(arg.key))
if (drawer_->editor()->respond_char(arg))
API::lazy_refresh();
}
//end class trigger
@ -989,7 +988,7 @@ namespace nana
API::refresh_window(*this);
}
nana::string combox::_m_caption() const
nana::string combox::_m_caption() const throw()
{
internal_scope_guard lock;
auto editor = _m_impl().editor();

View File

@ -80,37 +80,6 @@ namespace nana
return where::none;
}
void trigger::_m_draw(graph_reference graph)
{
const unsigned width = graph.width() - 2;
graph.rectangle(false, {0xb0, 0xb0, 0xb0});
graph.rectangle({ 1, 1, width, static_cast<unsigned>(topbar_height) }, true, colors::white);
_m_draw_topbar(graph);
if(graph.height() > 2 + topbar_height)
{
nana::point refpos(1, static_cast<int>(topbar_height) + 1);
nana::paint::graphics gbuf({ width, graph.height() - 2 - topbar_height });
gbuf.rectangle(true, {0xf0, 0xf0, 0xf0});
switch(page_)
{
case page::date:
_m_draw_days(refpos, gbuf);
break;
case page::month:
_m_draw_months(refpos, gbuf);
break;
default: break;
}
graph.bitblt(refpos.x, refpos.y, gbuf);
}
}
void trigger::_m_draw_topbar(graph_reference graph)
{
::nana::color arrow_bgcolor;
@ -414,7 +383,7 @@ namespace nana
r.y = static_cast<int>(newbuf.height() - r.height) / 2;
newbuf.stretch(nzbuf, r);
nzbuf.blend(nzbuf.size(), dzbuf, nana::point(), fade * (count - i));
nzbuf.blend(::nana::rectangle{ nzbuf.size() }, dzbuf, nana::point(), fade * (count - i));
graph.bitblt(refpos.x, refpos.y, dzbuf);
API::update_window(*widget_);
@ -442,7 +411,7 @@ namespace nana
nzbuf.rectangle(true, colors::white);
newbuf.stretch(nzbuf, r);
nzbuf.blend(nzbuf.size(), dzbuf, nana::point(), fade * (count - i));
nzbuf.blend(::nana::rectangle{ nzbuf.size() }, dzbuf, nana::point(), fade * (count - i));
graph.bitblt(refpos.x, refpos.y, dzbuf);
API::update_window(*widget_);
@ -455,7 +424,33 @@ namespace nana
void trigger::refresh(graph_reference graph)
{
_m_draw(graph);
const unsigned width = graph.width() - 2;
graph.rectangle(false, { 0xb0, 0xb0, 0xb0 });
graph.rectangle({ 1, 1, width, static_cast<unsigned>(topbar_height) }, true, colors::white);
_m_draw_topbar(graph);
if (graph.height() > 2 + topbar_height)
{
nana::point refpos(1, static_cast<int>(topbar_height)+1);
nana::paint::graphics gbuf({ width, graph.height() - 2 - topbar_height });
gbuf.rectangle(true, { 0xf0, 0xf0, 0xf0 });
switch (page_)
{
case page::date:
_m_draw_days(refpos, gbuf);
break;
case page::month:
_m_draw_months(refpos, gbuf);
break;
default: break;
}
graph.bitblt(refpos.x, refpos.y, gbuf);
}
}
void trigger::attached(widget_reference widget, graph_reference)
@ -468,7 +463,7 @@ namespace nana
where pos = _m_pos_where(graph, arg.pos);
if(pos == pos_ && pos_ != where::textarea) return;
pos_ = pos;
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}
@ -476,7 +471,7 @@ namespace nana
{
if(where::none == pos_) return;
pos_ = where::none;
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}
@ -595,7 +590,7 @@ namespace nana
nana::paint::graphics dirtybuf({ r.width, r.height });
dirtybuf.bitblt(r, graph, refpos);
_m_draw(graph);
refresh(graph);
nana::paint::graphics gbuf({ r.width, r.height });
gbuf.bitblt(r, graph, refpos);
@ -603,7 +598,7 @@ namespace nana
_m_perf_transform(tfid, graph, dirtybuf, gbuf, refpos);
}
else
_m_draw(graph);
refresh(graph);
API::lazy_refresh();
}

View File

@ -34,7 +34,7 @@ namespace nana
{
if (state == StateHighlighted)
{
::nana::color clr{ 0xaf, 0xc7, 0xe3 };
::nana::color clr(static_cast<color_rgb>(0xafc7e3));
graph.rectangle(r, false, clr);
auto right = r.right() - 1;
@ -99,7 +99,7 @@ namespace nana
nana::point to_pos(x, r.y + 2);
to_pos.x += (image_pixels_ - imgsz.width) / 2;
to_pos.y += (vpix - imgsz.height) / 2;
item->image().stretch(item->image().size(), graph, nana::rectangle(to_pos, imgsz));
item->image().stretch(::nana::rectangle{ item->image().size() }, graph, nana::rectangle(to_pos, imgsz));
}
x += (image_pixels_ + 2);
}
@ -276,7 +276,7 @@ namespace nana
}
}
bool right_area(graph_reference graph, int x, int y) const
static bool right_area(graph_reference graph, int x, int y)
{
return ((1 < x && 1 < y) &&
x < static_cast<int>(graph.width()) - 2 &&
@ -325,7 +325,7 @@ namespace nana
_m_open_scrollbar(*widget_, pages);
}
else
graph_->string({ 4, 4 }, STR("Empty Listbox, No Module!"), {0x80, 0x80, 0x80});
graph_->string({ 4, 4 }, STR("Empty Listbox, No Module!"), static_cast<color_rgb>(0x808080));
//Draw border
graph_->rectangle(false, colors::black);
@ -361,7 +361,7 @@ namespace nana
auto fn = [this](const arg_mouse& arg)
{
if (arg.left_button && (scrollbar_.value() != state_.offset_y))
if (arg.is_left_button() && (scrollbar_.value() != state_.offset_y))
{
state_.offset_y = static_cast<unsigned>(scrollbar_.value());
draw();
@ -449,12 +449,16 @@ namespace nana
void trigger::mouse_up(graph_reference graph, const arg_mouse& arg)
{
if(drawer_->right_area(graph, arg.pos.x, arg.pos.y))
bool close_wdg = false;
if (drawer_->right_area(graph, arg.pos.x, arg.pos.y))
{
drawer_->set_result();
drawer_->widget_ptr()->close();
close_wdg = true;
}
else if(false == drawer_->ignore_emitting_mouseup())
else
close_wdg = (false == drawer_->ignore_emitting_mouseup());
if (close_wdg)
drawer_->widget_ptr()->close();
}
//end class trigger

View File

@ -18,9 +18,10 @@ namespace nana
namespace form
{
//class trigger
void trigger::attached(widget_reference widget, graph_reference graph)
void trigger::attached(widget_reference wdg, graph_reference graph)
{
wd_ = &widget;
wd_ = &wdg;
API::ignore_mouse_focus(wdg, true);
}
void trigger::refresh(graph_reference graph)

View File

@ -0,0 +1,249 @@
/**
* A group widget implementation
* Nana C++ Library(http://www.nanaro.org)
* Copyright(C) 2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/widgets/group.cpp
*
* @Author: Stefan Pfeifer(st-321), Ariel Vina-Rodriguez (qPCR4vir)
*
* @brief group is a widget used to visually group and layout other widgets.
*/
#include <nana/gui/widgets/group.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/drawing.hpp>
#include <nana/gui/widgets/checkbox.hpp>
#define _THROW_IF_EMPTY()\
if(empty()) \
throw std::logic_error("the group is invalid");
namespace nana{
static const char* field_title = "__nana_group_title__";
static const char* field_options = "__nana_group_options__";
struct group::implement
{
label caption;
place place_content;
unsigned gap{2};
std::string usr_div_str;
std::vector<std::unique_ptr<checkbox>> options;
radio_group * radio_logic{nullptr};
implement() = default;
implement(window grp_panel, ::nana::string titel, bool vsb, unsigned gap=2)
: caption (grp_panel, std::move(titel), vsb),
place_content{grp_panel},
gap{gap}
{
}
void create(window pnl)
{
caption.create(pnl);
caption.caption(STR(""));
place_content.bind(pnl);
if (!radio_logic)
radio_logic = new radio_group;
}
void update_div()
{
::nana::size sz = caption.measure(1000);
std::stringstream ss;
ss << "vert margin=[0," << gap << "," << gap + 5 << "," << gap << "]"
<< " <weight=" << sz.height << " <weight=5> <" << field_title << " weight=" << sz.width + 1 << "> >"
<< "<<vert margin=5 " << field_options << ">";
if (!usr_div_str.empty())
ss << "<" << usr_div_str << ">>";
else
ss << ">";
place_content.div(ss.str().c_str());
if (options.empty())
place_content.field_display(field_options, false);
}
};
group::group()
: impl_(new implement)
{
}
group::group(window parent, const rectangle& r, bool vsb)
: group()
{
create(parent, r, vsb);
}
group::group(window parent, ::nana::string titel, bool formatted, unsigned gap, const rectangle& r, bool vsb)
: panel(parent, r, vsb),
impl_(new implement(*this, std::move(titel), vsb, gap))
{
impl_->caption.format(formatted);
_m_init();
}
group::~group()
{
delete impl_->radio_logic;
}
group& group::add_option(::nana::string text)
{
_THROW_IF_EMPTY()
impl_->options.emplace_back(new checkbox(handle()));
auto & opt = impl_->options.back();
opt->transparent(true);
opt->caption(std::move(text));
impl_->place_content[field_options] << *opt;
impl_->place_content.field_display(field_options, true);
impl_->place_content.collocate();
if (impl_->radio_logic)
impl_->radio_logic->add(*opt);
return *this;
}
group& group::radio_mode(bool enable)
{
_THROW_IF_EMPTY()
if (enable)
{
//Create radio_group if it is null
if (!impl_->radio_logic)
impl_->radio_logic = new ::nana::radio_group;
//add all options into the radio_group
for (auto & opt : impl_->options)
impl_->radio_logic->add(*opt);
}
else
{
delete impl_->radio_logic;
impl_->radio_logic = nullptr;
}
return *this;
}
std::size_t group::option() const
{
_THROW_IF_EMPTY();
if (impl_->radio_logic)
return impl_->radio_logic->checked();
throw std::logic_error("the radio_mode of the group is disabled");
}
bool group::option_checked(std::size_t pos) const
{
_THROW_IF_EMPTY();
return impl_->options.at(pos)->checked();
}
group& group::enable_format_caption(bool format)
{
impl_->caption.format(format);
return *this;
}
group& group::collocate() throw ()
{
impl_->place_content.collocate();
return *this;
}
group& group::div(const char* div_str) throw ()
{
if (div_str)
impl_->usr_div_str = div_str;
else
impl_->usr_div_str.clear();
impl_->update_div();
return *this;
}
group::field_reference group::operator[](const char* field)
{
return impl_->place_content.field(field);
}
void group::_m_add_child(const char* field, widget* wdg)
{
impl_->place_content[field] << wdg->handle();
}
void group::_m_init()
{
this->div(nullptr);
auto & outter = impl_->place_content;
outter[field_title] << impl_->caption;
outter.collocate();
color pbg = API::bgcolor(this->parent());
impl_->caption.bgcolor(pbg.blend(colors::black, 0.975));
color bg = pbg.blend(colors::black, 0.950);
bgcolor(bg);
drawing dw(*this);
::nana::size sz = impl_->caption.measure(1000);
// This drawing function is owner by the onwer of dw (the outer panel of the group widget), not by dw !!
dw.draw([this, sz, bg, pbg](paint::graphics& graph)
{
auto gap_px = impl_->gap - 1;
graph.rectangle(true, pbg);
graph.round_rectangle(rectangle(point(gap_px, sz.height / 2),
nana::size(graph.width() - 2 * gap_px, graph.height() - sz.height / 2 - gap_px)
),
3, 3, colors::gray_border, true, bg);
});
}
void group::_m_complete_creation()
{
panel::_m_complete_creation();
impl_->create(handle());
_m_init();
}
::nana::string group::_m_caption() const throw()
{
return impl_->caption.caption();
}
void group::_m_caption(::nana::string&& str)
{
impl_->caption.caption(std::move(str));
impl_->update_div();
impl_->place_content.collocate();
}
}//end namespace nana

View File

@ -628,6 +628,8 @@ namespace nana
nana::string target; //It indicates which target is tracing.
nana::string url;
window for_associated_wd{ nullptr };
void add_listener(std::function<void(command, const nana::string&)>&& fn)
{
listener_.emplace_back(std::move(fn));
@ -730,7 +732,7 @@ namespace nana
}
}
void trigger::click(graph_reference, const arg_mouse&)
void trigger::click(graph_reference, const arg_click&)
{
//make a copy, because the listener may popup a window, and then
//user moves the mouse. it will reset the url when the mouse is moving out from the element.
@ -740,6 +742,8 @@ namespace nana
impl_->call_listener(command::click, impl_->target);
system::open_url(url);
API::focus_window(impl_->for_associated_wd);
}
void trigger::refresh(graph_reference graph)
@ -775,13 +779,6 @@ namespace nana
caption(text);
}
label::label(window wd, const nana::char_t* text, bool visible)
{
create(wd, rectangle(), visible);
bgcolor(API::bgcolor(wd));
caption(text);
}
label::label(window wd, const rectangle& r, bool visible)
{
create(wd, r, visible);
@ -797,7 +794,7 @@ namespace nana
return *this;
}
bool label::transparent() const
bool label::transparent() const throw()
{
return (bground_mode::basic == API::effects_bground_mode(*this));
}
@ -821,6 +818,12 @@ namespace nana
return *this;
}
label& label::click_for(window associated_window) throw()
{
get_drawer_trigger().impl()->for_associated_wd = associated_window;
return *this;
}
nana::size label::measure(unsigned limited) const
{
if(empty())

File diff suppressed because it is too large Load Diff

View File

@ -114,7 +114,7 @@ namespace nana
{
if(at.item_state == state::active)
{
graph.rectangle(r, false, {0xa8, 0xd8, 0xeb});
graph.rectangle(r, false, static_cast<color_rgb>(0xa8d8eb));
nana::point points[4] = {
nana::point(r.x, r.y),
nana::point(r.x + r.width - 1, r.y),
@ -144,9 +144,9 @@ namespace nana
}
}
void item_image(graph_reference graph, const nana::point& pos, const paint::image& img)
void item_image(graph_reference graph, const nana::point& pos, unsigned image_px, const paint::image& img)
{
img.paste(graph, pos.x, pos.y);
img.stretch(rectangle{ img.size() }, graph, rectangle{ pos, ::nana::size(image_px, image_px) });
}
void item_text(graph_reference graph, const nana::point& pos, const nana::string& text, unsigned text_pixels, const attr& at)
@ -200,35 +200,35 @@ namespace nana
void checked(std::size_t index, bool check)
{
if(root_.items.size() > index)
if (root_.items.size() <= index)
return;
item_type & m = root_.items[index];
if(check && (checks::option == m.style))
{
item_type & m = root_.items[index];
if(check && (checks::option == m.style))
if(index)
{
if(index)
std::size_t i = index;
do
{
std::size_t i = index;
do
{
item_type& el = root_.items[--i];
if(el.flags.splitter) break;
if(checks::option == el.style)
el.flags.checked = false;
}while(i);
}
for(std::size_t i = index + 1; i < root_.items.size(); ++i)
{
item_type & el = root_.items[i];
item_type& el = root_.items[--i];
if(el.flags.splitter) break;
if(checks::option == el.style)
el.flags.checked = false;
}
}while(i);
}
for(std::size_t i = index + 1; i < root_.items.size(); ++i)
{
item_type & el = root_.items[i];
if(el.flags.splitter) break;
if(checks::option == el.style)
el.flags.checked = false;
}
m.flags.checked = check;
}
m.flags.checked = check;
}
menu_type& data()
@ -304,7 +304,7 @@ namespace nana
: public drawer_trigger
{
public:
typedef menu_item_type::item_proxy item_proxy;
using item_proxy = menu_item_type::item_proxy;
renderer_interface * renderer;
@ -330,12 +330,12 @@ namespace nana
detail_.monitor_pos = API::cursor_position();
}
void mouse_move(graph_reference, const arg_mouse& arg)
void mouse_move(graph_reference graph, const arg_mouse& arg)
{
state_.nullify_mouse = false;
if(track_mouse(arg.pos.x, arg.pos.y))
if(track_mouse(arg.pos))
{
draw();
refresh(graph);
API::lazy_refresh();
}
}
@ -350,9 +350,70 @@ namespace nana
state_.nullify_mouse = false;
}
void refresh(graph_reference)
void refresh(graph_reference graph)
{
draw();
if (nullptr == menu_) return;
_m_adjust_window_size();
renderer->background(graph, *widget_);
const unsigned item_h_px = _m_item_height();
const unsigned image_px = item_h_px - 2;
nana::rectangle item_r(2, 2, graph_->width() - 4, item_h_px);
unsigned strpixels = item_r.width - 60;
int text_top_off = (item_h_px - graph.text_extent_size(STR("jh({[")).height) / 2;
std::size_t pos = 0;
for (auto & m : menu_->items)
{
if (m.flags.splitter)
{
graph_->set_color(colors::gray_border);
graph_->line({ item_r.x + 40, item_r.y }, { static_cast<int>(graph.width()) - 1, item_r.y });
item_r.y += 2;
++pos;
continue;
}
renderer_interface::attr attr = _m_make_renderer_attr(pos == state_.active, m);
//Draw item background
renderer->item(*graph_, item_r, attr);
//Draw text, the text is transformed from orignal for hotkey character
nana::char_t hotkey;
nana::string::size_type hotkey_pos;
nana::string text = API::transform_shortkey_text(m.text, hotkey, &hotkey_pos);
if (m.image.empty() == false)
renderer->item_image(graph, nana::point(item_r.x + 5, item_r.y + static_cast<int>(item_h_px - image_px) / 2 - 1), image_px, m.image);
renderer->item_text(graph, nana::point(item_r.x + 40, item_r.y + text_top_off), text, strpixels, attr);
if (hotkey)
{
m.hotkey = hotkey;
if (m.flags.enabled)
{
unsigned off_w = (hotkey_pos ? graph.text_extent_size(text, static_cast<unsigned>(hotkey_pos)).width : 0);
nana::size hotkey_size = graph.text_extent_size(text.c_str() + hotkey_pos, 1);
int x = item_r.x + 40 + off_w;
int y = item_r.y + text_top_off + hotkey_size.height;
graph_->set_color(colors::black);
graph_->line({ x, y }, { x + static_cast<int>(hotkey_size.width) - 1, y });
}
}
if (m.sub_menu)
renderer->sub_arrow(graph, nana::point(graph_->width() - 20, item_r.y), item_h_px, attr);
item_r.y += item_r.height + 1;
++pos;
}
}
std::size_t active() const
@ -411,21 +472,21 @@ namespace nana
state_.active = pos;
state_.sub_window = false;
draw();
refresh(*graph_);
return true;
}
return false;
}
bool track_mouse(int x, int y)
bool track_mouse(const ::nana::point& pos)
{
if(state_.nullify_mouse == false)
if (!state_.nullify_mouse)
{
std::size_t index = _m_get_index_by_pos(x, y);
if(index != state_.active)
std::size_t index = _m_get_index_by_pos(pos.x, pos.y);
if (index != state_.active)
{
if((index == npos) && menu_->items.at(state_.active).sub_menu && state_.sub_window)
if ((index == npos) && menu_->items.at(state_.active).sub_menu && state_.sub_window)
return false;
state_.active = (index != npos && menu_->items.at(index).flags.splitter) ? npos : index;
@ -433,6 +494,7 @@ namespace nana
return true;
}
}
return false;
}
@ -451,29 +513,35 @@ namespace nana
state_.sub_window = subw;
}
menu_type* retrive_sub_menu(nana::point& pos, std::size_t interval) const
menu_type* get_sub(nana::point& pos, unsigned long& tmstamp) const
{
if(state_.active != npos && (nana::system::timestamp() - state_.active_timestamp >= interval))
if (npos == state_.active)
return nullptr;
auto sub = menu_->items.at(state_.active).sub_menu;
if (sub)
{
pos.x = graph_->width() - 2;
pos.x = static_cast<int>(graph_->width()) - 2;
pos.y = 2;
std::size_t index = 0;
for(auto & m : menu_->items)
auto index = state_.active;
for (auto & m : menu_->items)
{
if(false == m.flags.splitter)
if (m.flags.splitter)
{
if(index == state_.active)
break;
pos.y += _m_item_height() + 1;
}
else
pos.y += 2;
continue;
}
++index;
if (0 == index)
break;
pos.y += _m_item_height() + 1;
--index;
}
return (menu_->items.at(state_.active).sub_menu);
tmstamp = state_.active_timestamp;
return sub;
}
return nullptr;
}
@ -498,8 +566,7 @@ namespace nana
state_.active = index;
state_.active_timestamp = nana::system::timestamp();
draw();
API::update_window(*widget_);
API::refresh_window(*widget_);
return 2;
}
else if(m.flags.enabled)
@ -514,71 +581,6 @@ namespace nana
}
return 0;
}
void draw() const
{
if(nullptr == menu_) return;
_m_adjust_window_size();
renderer->background(*graph_, *widget_);
const unsigned item_h_px = _m_item_height();
nana::rectangle item_r(2, 2, graph_->width() - 4, item_h_px);
unsigned strpixels = item_r.width - 60;
int text_top_off = (item_h_px - graph_->text_extent_size(STR("jh({[")).height) / 2;
std::size_t pos = 0;
for(auto & m : menu_->items)
{
if(m.flags.splitter)
{
graph_->set_color(colors::gray_border);
graph_->line({ item_r.x + 40, item_r.y }, { static_cast<int>(graph_->width()) - 1, item_r.y });
item_r.y += 2;
++pos;
continue;
}
renderer_interface::attr attr = _m_make_renderer_attr(pos == state_.active, m);
//Draw item background
renderer->item(*graph_, item_r, attr);
//Draw text, the text is transformed from orignal for hotkey character
nana::char_t hotkey;
nana::string::size_type hotkey_pos;
nana::string text = API::transform_shortkey_text(m.text, hotkey, &hotkey_pos);
if(m.image.empty() == false)
renderer->item_image(*graph_, nana::point(item_r.x + 5, item_r.y + (item_h_px - m.image.size().height) / 2), m.image);
renderer->item_text(*graph_, nana::point(item_r.x + 40, item_r.y + text_top_off), text, strpixels, attr);
if(hotkey)
{
m.hotkey = hotkey;
if(m.flags.enabled)
{
unsigned off_w = (hotkey_pos ? graph_->text_extent_size(text, static_cast<unsigned>(hotkey_pos)).width : 0);
nana::size hotkey_size = graph_->text_extent_size(text.c_str() + hotkey_pos, 1);
int x = item_r.x + 40 + off_w;
int y = item_r.y + text_top_off + hotkey_size.height;
graph_->set_color(colors::black);
graph_->line({ x, y }, { x + static_cast<int>(hotkey_size.width) - 1, y });
}
}
if(m.sub_menu)
renderer->sub_arrow(*graph_, nana::point(graph_->width() - 20, item_r.y), item_h_px, attr);
item_r.y += item_r.height + 1;
++pos;
}
}
private:
static renderer_interface::attr _m_make_renderer_attr(bool active, const menu_item_type & m)
{
@ -683,10 +685,10 @@ namespace nana
struct state
{
std::size_t active;
unsigned long active_timestamp;
unsigned long sub_window: 1;
unsigned long nullify_mouse: 1;
std::size_t active;
unsigned active_timestamp;
bool sub_window: 1;
bool nullify_mouse: 1;
}state_;
struct widget_detail
@ -699,15 +701,18 @@ namespace nana
class menu_window
: public widget_object<category::root_tag, menu_drawer>
{
typedef menu_drawer drawer_type;
typedef widget_object<category::root_tag, menu_drawer> base_type;
using drawer_type = menu_drawer;
using base_type = widget_object<category::root_tag, menu_drawer>;
public:
typedef menu_builder::item_type item_type;
using item_type = menu_builder::item_type;
menu_window(window wd, const point& pos, renderer_interface * rdptr)
menu_window(window wd, bool is_wd_parent_menu, const point& pos, renderer_interface * rdptr)
//add a is_wd_parent_menu to determine whether the menu wants the focus.
//if a submenu gets the focus, the program may cause a crash error when the submenu is being destroyed
: base_type(wd, false, rectangle(pos, nana::size(2, 2)), appear::bald<appear::floating>()),
want_focus_(nullptr == wd || (API::focus_window() != wd)),
event_focus_(nullptr)
want_focus_{ (!wd) || ((!is_wd_parent_menu) && (API::focus_window() != wd)) },
event_focus_{ nullptr }
{
caption(STR("nana menu window"));
get_drawer_trigger().close_menu_tree([this]{ this->_m_close_all(); });
@ -718,7 +723,19 @@ namespace nana
submenu_.child = submenu_.parent = nullptr;
submenu_.object = nullptr;
_m_make_mouse_event();
state_.mouse_pos = API::cursor_position();
events().mouse_move.connect_unignorable([this]{
nana::point pos = API::cursor_position();
if (pos != state_.mouse_pos)
{
menu_window * root = this;
while (root->submenu_.parent)
root = root->submenu_.parent;
root->state_.auto_popup_submenu = true;
state_.mouse_pos = pos;
}
});
}
void popup(menu_type& menu, bool owner_menubar)
@ -737,21 +754,30 @@ namespace nana
API::register_menu_window(this->handle(), !owner_menubar);
}
events().destroy.connect_unignorable([this]{
auto & events = this->events();
events.destroy.connect_unignorable([this]{
_m_destroy();
});
events().key_press.connect_unignorable([this](const arg_keyboard& arg){
events.key_press.connect_unignorable([this](const arg_keyboard& arg){
_m_key_down(arg);
});
events().mouse_up.connect_unignorable([this]{
pick();
});
auto fn = [this](const arg_mouse& arg)
{
if (event_code::mouse_down == arg.evt_code)
_m_open_sub(0); //Try to open submenu immediately
else if (event_code::mouse_up == arg.evt_code)
if (arg.button == ::nana::mouse::left_button)
pick();
};
events.mouse_down.connect_unignorable(fn);
events.mouse_up.connect_unignorable(fn);
timer_.interval(100);
timer_.elapse([this]{
this->_m_check_repeatly();
this->_m_open_sub(500); //Try to open submenu
});
timer_.start();
@ -759,7 +785,7 @@ namespace nana
if (want_focus_)
{
event_focus_ = events().focus.connect_unignorable([this](const arg_focus& arg)
event_focus_ = events.focus.connect_unignorable([this](const arg_focus& arg)
{
//when the focus of the menu window is losing, close the menu.
//But here is not every menu window may have focus event installed,
@ -797,29 +823,27 @@ namespace nana
bool submenu(bool enter)
{
menu_window * object = this;
while (object->submenu_.child)
object = object->submenu_.child;
menu_window * menu_wd = this;
while (menu_wd->submenu_.child)
menu_wd = menu_wd->submenu_.child;
state_.auto_popup_submenu = false;
if (enter)
if (!enter)
{
if (object->submenu_.parent)
if (menu_wd->submenu_.parent)
{
auto & sub = object->submenu_.parent->submenu_;
auto & sub = menu_wd->submenu_.parent->submenu_;
sub.child = nullptr;
sub.object = nullptr;
object->close();
menu_wd->close();
return true;
}
return false;
}
nana::point pos;
menu_type * sbm = object->get_drawer_trigger().retrive_sub_menu(pos, 0);
return object->_m_show_submenu(sbm, pos, true);
return menu_wd->_m_manipulate_sub(0, true);
}
int send_shortkey(nana::char_t key)
@ -965,63 +989,51 @@ namespace nana
}
}
void _m_make_mouse_event()
bool _m_manipulate_sub(unsigned long delay_ms, bool forced)
{
state_.mouse_pos = API::cursor_position();
events().mouse_move.connect_unignorable([this]{
_m_mouse_event();
});
}
auto & drawer = get_drawer_trigger();
::nana::point pos;
unsigned long tmstamp;
void _m_mouse_event()
{
nana::point pos = API::cursor_position();
if(pos != state_.mouse_pos)
auto menu_ptr = drawer.get_sub(pos, tmstamp);
if (menu_ptr == submenu_.object)
return false;
if (menu_ptr && (::nana::system::timestamp() - tmstamp < delay_ms))
return false;
if (submenu_.object && (menu_ptr != submenu_.object))
{
menu_window * root = this;
while(root->submenu_.parent)
root = root->submenu_.parent;
root->state_.auto_popup_submenu = true;
state_.mouse_pos = pos;
}
}
bool _m_show_submenu(menu_type* sbm, nana::point pos, bool forced)
{
auto & mdtrigger = get_drawer_trigger();
if(submenu_.object && (sbm != submenu_.object))
{
mdtrigger.set_sub_window(false);
drawer.set_sub_window(false);
submenu_.child->close();
submenu_.child = nullptr;
submenu_.object = nullptr;
}
if(sbm)
if (menu_ptr)
{
menu_window * root = this;
while(root->submenu_.parent)
while (root->submenu_.parent)
root = root->submenu_.parent;
if((submenu_.object == nullptr) && sbm && (forced || root->state_.auto_popup_submenu))
if ((submenu_.object == nullptr) && menu_ptr && (forced || root->state_.auto_popup_submenu))
{
sbm->item_pixels = mdtrigger.data()->item_pixels;
sbm->gaps = mdtrigger.data()->gaps;
pos.x += sbm->gaps.x;
pos.y += sbm->gaps.y;
menu_ptr->item_pixels = drawer.data()->item_pixels;
menu_ptr->gaps = drawer.data()->gaps;
pos += menu_ptr->gaps;
menu_window & mwnd = form_loader<menu_window, false>()(handle(), pos, mdtrigger.renderer);
menu_window & mwnd = form_loader<menu_window, false>()(handle(), true, pos, drawer.renderer);
mwnd.state_.self_submenu = true;
submenu_.child = & mwnd;
submenu_.child = &mwnd;
submenu_.child->submenu_.parent = this;
submenu_.object = sbm;
submenu_.object = menu_ptr;
API::set_window_z_order(handle(), mwnd.handle(), z_order_action::none);
mwnd.popup(*sbm, state_.owner_menubar);
mdtrigger.set_sub_window(true);
if(forced)
mwnd.popup(*menu_ptr, state_.owner_menubar);
drawer.set_sub_window(true);
if (forced)
mwnd.goto_next(true);
return true;
@ -1030,17 +1042,16 @@ namespace nana
return false;
}
void _m_check_repeatly()
void _m_open_sub(unsigned delay_ms) //check_repeatly
{
if(state_.auto_popup_submenu)
{
nana::point pos = API::cursor_position();
auto pos = API::cursor_position();
drawer_type& drawer = get_drawer_trigger();
API::calc_window_point(handle(), pos);
drawer.track_mouse(pos.x, pos.y);
menu_type* sbm = drawer.retrive_sub_menu(pos, 500);
_m_show_submenu(sbm, pos, false);
get_drawer_trigger().track_mouse(pos);
_m_manipulate_sub(delay_ms, false);
}
}
private:
@ -1293,7 +1304,7 @@ namespace nana
{
close();
impl_->uiobj = &(form_loader<drawerbase::menu::menu_window, false>()(wd, point(x, y), &(*impl_->mbuilder.renderer())));
impl_->uiobj = &(form_loader<drawerbase::menu::menu_window, false>()(wd, false, point(x, y), &(*impl_->mbuilder.renderer())));
impl_->uiobj->events().destroy.connect_unignorable([this]{
impl_->uiobj = nullptr;
if (impl_->destroy_answer)

View File

@ -148,7 +148,7 @@ namespace nana
auto pos = items_->cont().size();
items_->append(text, shkey);
_m_draw();
refresh(*graph_);
API::update_window(*widget_);
return at(pos);
@ -173,13 +173,65 @@ namespace nana
widget_ = &widget;
}
void trigger::refresh(graph_reference)
void trigger::refresh(graph_reference graph)
{
_m_draw();
API::lazy_refresh();
auto bgcolor = API::bgcolor(*widget_);
graph_->rectangle(true, bgcolor);
item_renderer ird(*widget_, graph);
nana::point item_pos(2, 2);
nana::size item_s(0, 23);
unsigned long index = 0;
for (auto i : items_->cont())
{
//Transform the text if it contains the hotkey character
::nana::char_t hotkey;
::nana::string::size_type hotkey_pos;
auto text = API::transform_shortkey_text(i->text, hotkey, &hotkey_pos);
nana::size text_s = graph.text_extent_size(text);
item_s.width = text_s.width + 16;
i->pos = item_pos;
i->size = item_s;
using state = item_renderer::state;
state item_state = (index != state_.active ? state::normal : (state_.menu_active ? state::selected : state::highlighted));
ird.background(item_pos, item_s, item_state);
if (state::selected == item_state)
{
int x = item_pos.x + item_s.width;
int y1 = item_pos.y + 2, y2 = item_pos.y + item_s.height - 1;
graph.line({ x, y1 }, { x, y2 }, bgcolor.blend(colors::gray_border, 0.4));
graph.line({ x + 1, y1 }, { x + 1, y2 }, bgcolor.blend(colors::button_face_shadow_end, 0.5));
}
//Draw text, the text is transformed from orignal for hotkey character
int text_top_off = (item_s.height - text_s.height) / 2;
ird.caption({ item_pos.x + 8, item_pos.y + text_top_off }, text);
if (hotkey)
{
unsigned off_w = (hotkey_pos ? graph.text_extent_size(text, static_cast<unsigned>(hotkey_pos)).width : 0);
nana::size hotkey_size = graph.text_extent_size(text.c_str() + hotkey_pos, 1);
unsigned ascent, descent, inleading;
graph.text_metrics(ascent, descent, inleading);
int x = item_pos.x + 8 + off_w;
int y = item_pos.y + text_top_off + ascent + 1;
graph.line({ x, y }, { x + static_cast<int>(hotkey_size.width) - 1, y }, ::nana::colors::black);
}
item_pos.x += i->size.width;
++index;
}
}
void trigger::mouse_move(graph_reference, const arg_mouse& arg)
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
{
if (arg.pos != state_.mouse_pos)
state_.nullify_mouse = false;
@ -200,7 +252,7 @@ namespace nana
if(popup)
{
_m_popup_menu();
_m_draw();
refresh(graph);
API::lazy_refresh();
}
@ -228,7 +280,7 @@ namespace nana
else
_m_total_close();
_m_draw();
refresh(graph);
API::lazy_refresh();
}
@ -245,12 +297,12 @@ namespace nana
{
state_.behavior = state_.behavior_none;
_m_total_close();
_m_draw();
refresh(graph);
API::lazy_refresh();
}
}
void trigger::focus(graph_reference, const arg_focus& arg)
void trigger::focus(graph_reference graph, const arg_focus& arg)
{
if((arg.getting == false) && (state_.active != npos))
{
@ -259,12 +311,12 @@ namespace nana
state_.menu_active = false;
_m_close_menu();
state_.active = npos;
_m_draw();
refresh(graph);
API::lazy_refresh();
}
}
void trigger::key_press(graph_reference, const arg_keyboard& arg)
void trigger::key_press(graph_reference graph, const arg_keyboard& arg)
{
state_.nullify_mouse = true;
if(state_.menu)
@ -354,11 +406,11 @@ namespace nana
}
}
_m_draw();
refresh(graph);
API::lazy_refresh();
}
void trigger::key_release(graph_reference, const arg_keyboard& arg)
void trigger::key_release(graph_reference graph, const arg_keyboard& arg)
{
if(arg.key == 18)
{
@ -376,7 +428,7 @@ namespace nana
}
state_.menu_active = false;
_m_draw();
refresh(graph);
API::lazy_refresh();
}
}
@ -396,7 +448,7 @@ namespace nana
if(_m_popup_menu())
state_.menu->goto_next(true);
_m_draw();
refresh(graph);
API::lazy_refresh();
state_.behavior = state_.behavior_menu;
}
@ -424,7 +476,7 @@ namespace nana
if(index != state_.active)
{
state_.active = index;
_m_draw();
refresh(*graph_);
API::lazy_refresh();
if(_m_popup_menu())
@ -456,7 +508,7 @@ namespace nana
{
_m_total_close();
_m_draw();
refresh(*graph_);
API::update_window(widget_->handle());
}
});
@ -526,6 +578,7 @@ namespace nana
return false;
}
/*
void trigger::_m_draw()
{
auto bgcolor = API::bgcolor(*widget_);
@ -583,6 +636,7 @@ namespace nana
++index;
}
}
*/
//struct state_type
trigger::state_type::state_type()

View File

@ -20,10 +20,13 @@ namespace nana
namespace panel
{
//class drawer
void drawer::attached(widget_reference widget, graph_reference)
void drawer::attached(widget_reference wdg, graph_reference)
{
widget.caption(STR("Nana Panel"));
window_ = widget.handle();
wdg.caption(STR("panel widget"));
window_ = wdg.handle();
API::ignore_mouse_focus(wdg, true);
}
void drawer::refresh(graph_reference graph)

View File

@ -13,6 +13,7 @@
*/
#include <nana/gui/widgets/picture.hpp>
#include <nana/gui/layout_utility.hpp>
#include <nana/paint/image.hpp>
#include <nana/gui/element.hpp>
@ -111,7 +112,7 @@ namespace nana
_m_draw_background(fit_size.width, fit_size.height);
backimg.image.stretch(valid_area, graph, { pos, fit_size });
backimg.image.stretch(valid_area, graph, ::nana::rectangle{ pos, fit_size });
}
else
{
@ -150,7 +151,7 @@ namespace nana
_m_draw_background(graphsize.width, graphsize.height);
color invalid_clr_for_call;
backimg.bground->draw(graph, invalid_clr_for_call, invalid_clr_for_call, graphsize, element_state::normal);
backimg.bground->draw(graph, invalid_clr_for_call, invalid_clr_for_call, rectangle{ graphsize }, element_state::normal);
}
graph.setsta();
@ -170,7 +171,7 @@ namespace nana
else if (bground.gradual_from == bground.gradual_to)
graph->rectangle(true, bground.gradual_from);
else
graph->gradual_rectangle(graph->size(), bground.gradual_from, bground.gradual_to, !bground.horizontal);
graph->gradual_rectangle(::nana::rectangle{ graph->size() }, bground.gradual_from, bground.gradual_to, !bground.horizontal);
}
}
}

View File

@ -42,7 +42,7 @@ namespace nana
if(_m_check_changing(value_))
{
_m_draw();
refresh(*graph_);
API::update_window(widget_->handle());
}
return v;
@ -89,24 +89,28 @@ namespace nana
{
return unknown_;
}
void trigger::refresh(graph_reference)
bool trigger::stopped() const
{
_m_draw();
return stop_;
}
bool trigger::stop(bool s)
{
std::swap(s,stop_);
return s;
}
void trigger::_m_draw()
void trigger::refresh(graph_reference graph)
{
if(false == unknown_)
draw_width_ = static_cast<unsigned>((graph_->width() - border * 2) * (double(value_) / max_));
if (false == unknown_)
draw_width_ = static_cast<unsigned>((graph.width() - border * 2) * (double(value_) / max_));
_m_draw_box(*graph_);
_m_draw_progress(*graph_);
_m_draw_box(graph);
_m_draw_progress(graph);
}
void trigger::_m_draw_box(graph_reference graph)
{
rectangle r = graph.size();
rectangle r{ graph.size() };
graph.gradual_rectangle(r, colors::button_face_shadow_end, colors::button_face_shadow_start, true);
::nana::color lt{ colors::gray }, rb{colors::white};
graph.frame_rectangle(r, lt, lt, rb, rb);
@ -197,5 +201,13 @@ namespace nana
{
return get_drawer_trigger().unknown();
}
bool progress::stop(bool s)
{
return get_drawer_trigger().stop(s);
}
bool progress::stopped() const
{
return get_drawer_trigger().stopped();
}
//end class progress
}//end namespace nana

View File

@ -132,7 +132,7 @@ namespace nana
_m_background(graph);
rectangle_rotator r(vertical_, graph.size());
rectangle_rotator r(vertical_, ::nana::rectangle{ graph.size() });
r.x_ref() = static_cast<int>(r.w() - fixedsize);
r.w_ref() = fixedsize;
@ -159,7 +159,7 @@ namespace nana
if (!metrics_.pressed || !_m_check())
return;
nana::rectangle_rotator r(vertical_, graph.size());
nana::rectangle_rotator r(vertical_, ::nana::rectangle{ graph.size() });
if(metrics_.what == buttons::forward)
{
r.x_ref() = static_cast<int>(fixedsize);
@ -253,7 +253,7 @@ namespace nana
{
if(_m_check())
{
rectangle_rotator r(vertical_, graph.size());
rectangle_rotator r(vertical_, rectangle{ graph.size() });
r.x_ref() = static_cast<int>(fixedsize + metrics_.scroll_pos);
r.w_ref() = static_cast<unsigned>(metrics_.scroll_length);

View File

@ -17,6 +17,7 @@
#include <nana/unicode_bidi.hpp>
#include <numeric>
#include <cwctype>
#include <cstring>
#include <set>
#include <algorithm>
@ -54,7 +55,6 @@ namespace nana{ namespace widgets
virtual bool merge(const undoable_command_interface<EnumCommand>& rhs) override
{
//Implement later
return false;
}
protected:
@ -324,9 +324,8 @@ namespace nana{ namespace widgets
pos.x = editor_._m_pixels_by_char(lnstr, pos.x) + editor_.text_area_.area.x;
int pos_y = static_cast<int>((pos.y - editor_.points_.offset.y) * editor_.line_height() + editor_._m_text_top_base());
int pos_x = static_cast<int>(pos.x - editor_.points_.offset.x);
return{ pos_x, pos_y };
return{ static_cast<int>(pos.x - editor_.points_.offset.x), pos_y };
}
nana::upoint screen_to_caret(point scrpos) override
@ -461,6 +460,7 @@ namespace nana{ namespace widgets
editor_._m_scrollbar();
return (adjusted_cond || adjusted_cond2);
}
private:
std::size_t _m_textline_from_screen(int y) const
{
@ -1285,7 +1285,7 @@ namespace nana{ namespace widgets
if (!API::widget_borderless(this->window_))
{
::nana::facade<element::border> facade;
facade.draw(graph, bgcolor, API::fgcolor(this->window_), API::window_size(this->window_), API::element_state(this->window_));
facade.draw(graph, bgcolor, API::fgcolor(this->window_), ::nana::rectangle{ API::window_size(this->window_) }, API::element_state(this->window_));
}
};
}
@ -1349,8 +1349,9 @@ namespace nana{ namespace widgets
attributes_.acceptive = acceptive;
}
bool text_editor::respond_char(char_type key) //key is a character of ASCII code
bool text_editor::respond_char(const arg_keyboard& arg) //key is a character of ASCII code
{
char_type key = arg.key;
switch (key)
{
case keyboard::end_of_text:
@ -1400,14 +1401,28 @@ namespace nana{ namespace widgets
return false;
}
bool text_editor::respond_key(char_type key)
bool text_editor::respond_key(const arg_keyboard& arg)
{
char_type key = arg.key;
switch (key)
{
#if 0
case keyboard::os_arrow_left: move_left(); break;
case keyboard::os_arrow_right: move_right(); break;
case keyboard::os_arrow_up: move_ns(true); break;
case keyboard::os_arrow_down: move_ns(false); break;
#else
case keyboard::os_arrow_left:
case keyboard::os_arrow_right:
case keyboard::os_arrow_up:
case keyboard::os_arrow_down:
case keyboard::os_home:
case keyboard::os_end:
case keyboard::os_pageup:
case keyboard::os_pagedown:
_handle_move_key(arg);
break;
#endif
case keyboard::os_del:
if (this->attr().editable)
del();
@ -1482,6 +1497,8 @@ namespace nana{ namespace widgets
behavior_->pre_calc_lines(width_pixels());
_m_scrollbar();
move_caret(points_.caret);
return true;
}
@ -1591,29 +1608,24 @@ namespace nana{ namespace widgets
return true;
}
bool text_editor::mouse_down(bool left_button, const point& scrpos)
bool text_editor::mouse_down(::nana::mouse button, const point& scrpos)
{
if (!hit_text_area(scrpos))
return false;
if(left_button)
if(::nana::mouse::left_button == button)
{
API::capture_window(window_, true);
text_area_.captured = true;
//Set caret pos by screen point and get the caret pos.
auto pos = mouse_caret(scrpos);
if(!hit_select_area(pos))
mouse_caret(scrpos);
if(!select(false))
{
if(!select(false))
{
select_.a = points_.caret; //Set begin caret
set_end_caret();
}
select_.mode_selection = selection::mode_mouse_selected;
select_.a = points_.caret; //Set begin caret
set_end_caret();
}
else
select_.mode_selection = selection::mode_no_selected;
select_.mode_selection = selection::mode_mouse_selected;
}
text_area_.border_renderer(graph_, _m_bgcolor());
@ -1644,7 +1656,7 @@ namespace nana{ namespace widgets
return false;
}
bool text_editor::mouse_up(bool left_button, const point& scrpos)
bool text_editor::mouse_up(::nana::mouse button, const point& scrpos)
{
auto is_prev_no_selected = (select_.mode_selection == selection::mode_no_selected);
@ -2217,7 +2229,137 @@ namespace nana{ namespace widgets
points_.xpos = points_.caret.x;
}
nana::upoint text_editor::mouse_caret(const point& scrpos) //From screen position
void text_editor::_handle_move_key(const arg_keyboard& arg)
{
bool changed = false;
nana::upoint caret = points_.caret;
char_t key = arg.key;
size_t nlines = textbase_.lines();
if (arg.ctrl) {
switch (key) {
case keyboard::os_arrow_left:
case keyboard::os_arrow_right:
// TODO: move the caret word by word
break;
case keyboard::os_home:
if (caret.y != 0) {
caret.y = 0;
points_.offset.y = 0;
changed = true;
}
break;
case keyboard::os_end:
if (caret.y != nlines - 1) {
caret.y = nlines - 1;
changed = true;
}
break;
}
}
size_t lnsz = textbase_.getline(caret.y).size();
switch (key) {
case keyboard::os_arrow_left:
if (caret.x != 0) {
--caret.x;
changed = true;
}else {
if (caret.y != 0) {
--caret.y;
caret.x = textbase_.getline(caret.y).size();
changed = true;
}
}
break;
case keyboard::os_arrow_right:
if (caret.x < lnsz) {
++caret.x;
changed = true;
}else {
if (caret.y != nlines - 1) {
++caret.y;
caret.x = 0;
changed = true;
}
}
break;
case keyboard::os_arrow_up:
case keyboard::os_arrow_down:
{
auto screen_pt = behavior_->caret_to_screen(caret);
int offset = line_height();
if (key == keyboard::os_arrow_up) {
offset = -offset;
}
screen_pt.y += offset;
auto new_caret = behavior_->screen_to_caret(screen_pt);
if (new_caret != caret) {
caret = new_caret;
if (screen_pt.y < 0) {
scroll(true, true);
}
changed = true;
}
}
break;
case keyboard::os_home:
if (caret.x != 0) {
caret.x = 0;
changed = true;
}
break;
case keyboard::os_end:
if (caret.x < lnsz) {
caret.x = lnsz;
changed = true;
}
break;
case keyboard::os_pageup:
if (caret.y >= screen_lines() && points_.offset.y >= static_cast<int>(screen_lines())) {
points_.offset.y -= screen_lines();
caret.y -= screen_lines();
changed = true;
}
break;
case keyboard::os_pagedown:
if (caret.y + screen_lines() <= behavior_->take_lines()) {
points_.offset.y += screen_lines();
caret.y += screen_lines();
changed = true;
}
break;
}
if (select_.a != caret || select_.b != caret) {
changed = true;
}
if (changed) {
if (arg.shift) {
switch (key) {
case keyboard::os_arrow_left:
case keyboard::os_arrow_up:
case keyboard::os_home:
case keyboard::os_pageup:
select_.b = caret;
break;
case keyboard::os_arrow_right:
case keyboard::os_arrow_down:
case keyboard::os_end:
case keyboard::os_pagedown:
select_.b = caret;
break;
}
}else {
select_.b = caret;
select_.a = caret;
}
points_.caret = caret;
behavior_->adjust_caret_into_screen();
render(true);
_m_scrollbar();
points_.xpos = points_.caret.x;
}
}
upoint text_editor::mouse_caret(const point& scrpos) //From screen position
{
points_.caret = behavior_->screen_to_caret(scrpos);
@ -2228,11 +2370,16 @@ namespace nana{ namespace widgets
return points_.caret;
}
nana::upoint text_editor::caret() const
upoint text_editor::caret() const
{
return points_.caret;
}
point text_editor::caret_screen_pos() const
{
return behavior_->caret_to_screen(points_.caret);
}
bool text_editor::scroll(bool upwards, bool vert)
{
if(vert && attributes_.vscroll)
@ -2532,8 +2679,34 @@ namespace nana{ namespace widgets
return true;
}
std::size_t eat_endl(const wchar_t* str, std::size_t pos)
{
auto ch = str[pos];
if (0 == ch)
return pos;
const wchar_t * endlstr;
switch (ch)
{
case L'\n':
endlstr = L"\n\r";
break;
case L'\r':
endlstr = L"\r\n";
break;
default:
return pos;
}
if (std::memcmp(str + pos, endlstr, sizeof(wchar_t) * 2) == 0)
return pos + 2;
return pos + 1;
}
bool text_editor::_m_resolve_text(const nana::string& text, std::vector<std::pair<std::size_t, std::size_t>> & lines)
{
auto const text_str = text.data();
std::size_t begin = 0;
while (true)
{
@ -2546,13 +2719,23 @@ namespace nana{ namespace widgets
}
lines.emplace_back(begin, pos);
begin = text.find_first_not_of(STR("\r\n"), pos + 1);
pos = eat_endl(text_str, pos);
begin = text.find_first_not_of(STR("\r\n"), pos);
//The number of new lines minus one
const auto chp_end = text.data() + (begin == text.npos ? text.size() : begin);
for (auto chp = text.data() + (pos + 1); chp != chp_end; ++chp)
if (*chp == '\n')
const auto chp_end = text_str + (begin == text.npos ? text.size() : begin);
for (auto chp = text_str + pos; chp != chp_end; ++chp)
{
auto eats = eat_endl(chp, 0);
if (eats)
{
lines.emplace_back(0, 0);
chp += (eats - 1);
}
}
if (text.npos == begin)
{
@ -2740,50 +2923,43 @@ namespace nana{ namespace widgets
const auto str_end = str + len;
auto & entities = parser.entities();
for (auto & ent : entities)
for (auto & ent : entities)
{
const ::nana::char_t* ent_begin = nullptr;
int ent_off = 0;
if (str <= ent.begin && ent.begin < str_end)
{
const ::nana::char_t* ent_begin = nullptr;
ent_begin = ent.begin;
ent_off = std::accumulate(glyphs, glyphs + (ent.begin - str), 0);
}
else if (ent.begin <= str && str < ent.end)
ent_begin = str;
int ent_off = 0;
if (str <= ent.begin && ent.begin < str_end)
if (ent_begin)
{
auto ent_end = (ent.end < str_end ? ent.end : str_end);
auto ent_pixels = std::accumulate(glyphs + (ent_begin - str), glyphs + (ent_end - str), unsigned{});
canvas.set_color(ent.scheme->bgcolor.invisible() ? _m_bgcolor() : ent.scheme->bgcolor);
canvas.set_text_color(ent.scheme->fgcolor.invisible() ? fgcolor : ent.scheme->fgcolor);
canvas.rectangle(true);
ent_pos.x += ent_off;
if (rtl)
{
ent_begin = ent.begin;
ent_off = std::accumulate(glyphs, glyphs + (ent.begin - str), 0);
//draw the whole text if it is a RTL text, because Arbic language is transformable.
canvas.string({}, str, len);
graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas, ::nana::point{ ent_off, 0 });
}
else if (ent.begin <= str && str < ent.end)
ent_begin = str;
if (ent_begin)
else
{
auto ent_end = (ent.end < str_end ? ent.end : str_end);
auto ent_pixels = std::accumulate(glyphs + (ent_begin - str), glyphs + (ent_end - str), unsigned{});
if (ent.scheme->bgcolor.invisible())
canvas.set_color(_m_bgcolor());
else
canvas.set_color(ent.scheme->bgcolor);
canvas.rectangle(true);
if (ent.scheme->fgcolor.invisible())
canvas.set_text_color(fgcolor);
else
canvas.set_text_color(ent.scheme->fgcolor);
ent_pos.x += ent_off;
if (rtl)
{
//draw the whole text if it is a RTL text, because Arbic language is transformable.
canvas.string({}, str, len);
graph_.bitblt({ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas, ::nana::point{ ent_off, 0 });
}
else
{
canvas.string({}, ent_begin, ent_end - ent_begin);
graph_.bitblt({ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas);
}
canvas.string({}, ent_begin, ent_end - ent_begin);
graph_.bitblt(::nana::rectangle{ ent_pos, ::nana::size{ ent_pixels, canvas.height() } }, canvas);
}
}
}
}
void text_editor::_m_draw_string(int top, const ::nana::color& clr, const nana::upoint& str_pos, const nana::string& str, bool if_mask) const
@ -2795,6 +2971,7 @@ namespace nana{ namespace widgets
if (if_mask && mask_char_)
mask_str.reset(new nana::string(str.size(), mask_char_));
bool focused = API::is_focus_ready(window_);
auto & linestr = (if_mask && mask_char_ ? *mask_str : str);
@ -2817,7 +2994,7 @@ namespace nana{ namespace widgets
graph_.set_color(scheme_->selection.get_color());
//The text is not selected or the whole line text is selected
if ((!_m_get_sort_select_points(a, b)) || (select_.a.y != str_pos.y && select_.b.y != str_pos.y))
if (!focused || (!_m_get_sort_select_points(a, b)) || (select_.a.y != str_pos.y && select_.b.y != str_pos.y))
{
bool selected = (a.y < str_pos.y && str_pos.y < b.y);
for (auto & ent : reordered)
@ -2827,10 +3004,10 @@ namespace nana{ namespace widgets
if ((text_pos.x + static_cast<int>(str_w) > text_area_.area.x) && (text_pos.x < xend))
{
if (selected)
if (selected && focused)
{
graph_.set_text_color(scheme_->selection_text.get_color());
graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true);
graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true);
graph_.string(text_pos, ent.begin, len);
}
else
@ -2839,7 +3016,7 @@ namespace nana{ namespace widgets
text_pos.x += static_cast<int>(str_w);
}
if (selected)
graph_.rectangle({ text_pos, { whitespace_w, line_h_pixels } }, true);
graph_.rectangle(::nana::rectangle{ text_pos, { whitespace_w, line_h_pixels } }, true);
}
else
{
@ -2876,7 +3053,7 @@ namespace nana{ namespace widgets
//selected all
if (a.x <= pos && str_end <= b.x)
{
graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true);
graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true);
graph_.set_text_color(scheme_->selection_text.get_color());
graph_.string(text_pos, ent.begin, len);
}
@ -2906,7 +3083,7 @@ namespace nana{ namespace widgets
part_pos.x += static_cast<int>(head_w);
//Draw selected part
graph_.rectangle({ part_pos, { sel_w, line_h_pixels } }, true);
graph_.rectangle(::nana::rectangle{ part_pos, { sel_w, line_h_pixels } }, true);
graph_.set_text_color(scheme_->selection_text.get_color());
graph_.string(part_pos, ent.begin + (a.x - pos), endpos - a.x);
@ -2931,7 +3108,7 @@ namespace nana{ namespace widgets
else
{ //LTR
//Draw selected part
graph_.rectangle({ text_pos, { sel_w, line_h_pixels } }, true);
graph_.rectangle(::nana::rectangle{ text_pos, { sel_w, line_h_pixels } }, true);
graph_.set_text_color(scheme_->selection_text.get_color());
graph_.string(text_pos, ent.begin, endpos - pos);
@ -2957,7 +3134,7 @@ namespace nana{ namespace widgets
if (a.x < pos)
{
//Draw selected all
graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true, { 0x33, 0x99, 0xFF });
graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true, static_cast<color_rgb>(0x3399FF));
graph_.set_text_color(scheme_->selection_text.get_color());
graph_.string(text_pos, ent.begin, len);
}
@ -2978,7 +3155,7 @@ namespace nana{ namespace widgets
::nana::point part_pos{ text_pos.x + static_cast<int>(head_w), text_pos.y };
//Draw selected part
graph_.rectangle({ part_pos, {str_w - head_w, line_h_pixels } }, true);
graph_.rectangle(::nana::rectangle{ part_pos, {str_w - head_w, line_h_pixels } }, true);
graph_.set_text_color(scheme_->selection_text.get_color());
graph_.string(part_pos, ent.begin + a.x - pos, len - (a.x - pos));
}
@ -2991,7 +3168,7 @@ namespace nana{ namespace widgets
if (str_pos.y < b.y)
{
if (a.y < str_pos.y || ((a.y == str_pos.y) && (a.x <= str_pos.x )))
graph_.rectangle({ text_pos, { whitespace_w, line_h_pixels } }, true);
graph_.rectangle(::nana::rectangle{ text_pos, { whitespace_w, line_h_pixels } }, true);
}
}
else if (b.y == str_pos.y)
@ -3007,7 +3184,7 @@ namespace nana{ namespace widgets
if (pos + len <= b.x)
{
//Draw selected part
graph_.rectangle({ text_pos, { str_w, line_h_pixels } }, true);
graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true);
graph_.set_text_color(scheme_->selection_text.get_color());
graph_.string(text_pos, ent.begin, len);
}
@ -3021,7 +3198,7 @@ namespace nana{ namespace widgets
else
{
//draw selected part
graph_.rectangle({ text_pos, { sel_w, line_h_pixels } }, true);
graph_.rectangle(::nana::rectangle{ text_pos, { sel_w, line_h_pixels } }, true);
graph_.set_text_color(scheme_->selection_text.get_color());
graph_.string(text_pos, ent.begin, b.x - pos);

View File

@ -55,7 +55,7 @@ namespace nana
virtual void slider(window, graph_reference graph, const slider_t& s)
{
nana::rectangle r = graph.size();
nana::rectangle r{ graph.size() };
if(s.horizontal)
{
r.x = s.pos;
@ -66,7 +66,7 @@ namespace nana
r.y = s.pos;
r.height = s.scale;
}
graph.round_rectangle(r, 3, 3, colors::black, true, {0xf0,0xf0,0xf0});
graph.round_rectangle(r, 3, 3, colors::black, true, static_cast<color_rgb>(0xf0f0f0));
}
};
@ -390,7 +390,7 @@ namespace nana
nana::rectangle _m_bar_area() const
{
auto sz = other_.graph->size();
nana::rectangle r = sz;
nana::rectangle r{ sz };
if(style::horizontal == attr_.dir)
{
r.x = attr_.slider_scale / 2 - attr_.border;

View File

@ -86,7 +86,7 @@ namespace nana
ss >> v;
if (v < begin_ || last_ < v)
return false;
diff = (value_ != v);
value_ = v;
return true;
@ -297,7 +297,7 @@ namespace nana
bool diff;
if (!range_->value(value_str, diff))
return false;
if (diff)
reset_text();
return true;
@ -371,9 +371,9 @@ namespace nana
bool refreshed = false;
if (pressed)
refreshed = editor_->mouse_down(arg.left_button, arg.pos);
refreshed = editor_->mouse_down(arg.button, arg.pos);
else
refreshed = editor_->mouse_up(arg.left_button, arg.pos);
refreshed = editor_->mouse_up(arg.button, arg.pos);
if (refreshed)
_m_draw_spins(buttons::none);
@ -403,7 +403,7 @@ namespace nana
_m_draw_spins(buttons::none);
return true;
}
return false;
}
@ -435,7 +435,7 @@ namespace nana
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 };
}
@ -513,7 +513,7 @@ namespace nana
{
impl_->attach(wdg, graph);
}
void drawer::refresh(graph_reference)
{
impl_->render();
@ -526,7 +526,7 @@ namespace nana
impl_->editor()->reset_caret();
API::lazy_refresh();
}
void drawer::mouse_wheel(graph_reference, const arg_wheel& arg)
{
impl_->mouse_wheel(arg.upwards);
@ -557,10 +557,10 @@ namespace nana
impl_->render();
API::lazy_refresh();
}
void drawer::key_press(graph_reference, const arg_keyboard& arg)
{
if (impl_->editor()->respond_key(arg.key))
if (impl_->editor()->respond_key(arg))
{
impl_->editor()->reset_caret();
impl_->draw_spins();
@ -570,7 +570,7 @@ namespace nana
void drawer::key_char(graph_reference, const arg_keyboard& arg)
{
if (impl_->editor()->respond_char(arg.key))
if (impl_->editor()->respond_char(arg))
{
if (!impl_->value(impl_->editor()->text()))
impl_->draw_spins();
@ -682,7 +682,7 @@ namespace nana
modifier(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
::nana::string spinbox::_m_caption() const throw()
{
internal_scope_guard lock;
auto editor = get_drawer_trigger().impl()->editor();

View File

@ -947,7 +947,7 @@ namespace nana
auto bgcolor = API::bgcolor(basis_.wd);
auto fgcolor = API::fgcolor(basis_.wd);
item_renderer::item_t m = { basis_.graph->size() };
item_renderer::item_t m{ ::nana::rectangle{ basis_.graph->size() } };
basis_.renderer->background(*basis_.graph, m.r, bgcolor);
@ -985,7 +985,7 @@ namespace nana
}
if(false == item.img.empty())
item.img.stretch(item.img.size(), *basis_.graph, nana::rectangle(m.r.x + 4, (m.r.height - 16) / 2, 16, 16));
item.img.stretch(::nana::rectangle{ item.img.size() }, *basis_.graph, nana::rectangle(m.r.x + 4, (m.r.height - 16) / 2, 16, 16));
if(item.text.size())
{

View File

@ -15,6 +15,9 @@
#include <stdexcept>
#include <sstream>
#include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/inner_fwd_implement.hpp>
namespace nana
{
arg_textbox::arg_textbox(textbox& wdg)
@ -89,7 +92,11 @@ namespace drawerbase {
void drawer::focus(graph_reference graph, const arg_focus& arg)
{
refresh(graph);
if (!editor_->attr().multi_lines && arg.getting)
{
editor_->select(true);
editor_->move_caret_end();
}
editor_->show_caret(arg.getting);
editor_->reset_caret();
API::lazy_refresh();
@ -97,7 +104,7 @@ namespace drawerbase {
void drawer::mouse_down(graph_reference, const arg_mouse& arg)
{
if(editor_->mouse_down(arg.left_button, arg.pos))
if(editor_->mouse_down(arg.button, arg.pos))
API::lazy_refresh();
}
@ -109,7 +116,7 @@ namespace drawerbase {
void drawer::mouse_up(graph_reference graph, const arg_mouse& arg)
{
if(editor_->mouse_up(arg.left_button, arg.pos))
if(editor_->mouse_up(arg.button, arg.pos))
API::lazy_refresh();
}
@ -136,7 +143,7 @@ namespace drawerbase {
void drawer::key_press(graph_reference, const arg_keyboard& arg)
{
if(editor_->respond_key(arg.key))
if(editor_->respond_key(arg))
{
editor_->reset_caret();
API::lazy_refresh();
@ -145,7 +152,7 @@ namespace drawerbase {
void drawer::key_char(graph_reference, const arg_keyboard& arg)
{
if (editor_->respond_char(arg.key))
if (editor_->respond_char(arg))
API::lazy_refresh();
}
@ -287,6 +294,26 @@ namespace drawerbase {
return (editor ? editor->getline(line_index, text) : false);
}
/// Gets the caret position
bool textbox::caret_pos(point& pos, bool text_coordinate) const
{
internal_scope_guard lock;
auto editor = get_drawer_trigger().editor();
auto scr_pos = editor->caret_screen_pos();
if (text_coordinate)
{
auto upos = editor->caret();
pos.x = static_cast<int>(upos.x);
pos.y = static_cast<int>(upos.y);
}
else
pos = scr_pos;
return editor->hit_text_area(scr_pos);
}
textbox& textbox::append(const nana::string& text, bool at_caret)
{
internal_scope_guard lock;
@ -508,7 +535,7 @@ namespace drawerbase {
}
//Override _m_caption for caption()
nana::string textbox::_m_caption() const
nana::string textbox::_m_caption() const throw()
{
internal_scope_guard lock;
auto editor = get_drawer_trigger().editor();

View File

@ -11,10 +11,10 @@
*/
#include <nana/gui/widgets/toolbar.hpp>
#include <vector>
#include <stdexcept>
#include <nana/gui/tooltip.hpp>
#include <vector>
namespace nana
{
arg_toolbar::arg_toolbar(toolbar& tbar, std::size_t btn)
@ -25,13 +25,6 @@ namespace nana
{
namespace toolbar
{
struct listitem
{
nana::string text;
nana::paint::image image;
bool enable;
};
struct item_type
{
enum kind{ button, container};
@ -43,28 +36,23 @@ namespace nana
unsigned pixels{0};
nana::size textsize;
bool enable{true};
window other{nullptr};
kind type;
std::function<void(size_type, size_type)> answer;
std::vector<listitem> children;
item_type(const nana::string& text, const nana::paint::image& img, kind type)
:text(text), image(img), type(type)
{}
};
class container
{
container(const container&) = delete;
container& operator=(const container&) = delete;
public:
typedef std::vector<item_type*>::size_type size_type;
typedef std::vector<item_type*>::iterator iterator;
typedef std::vector<item_type*>::const_iterator const_iterator;
container() = default;
~container()
class item_container
{
public:
using container_type = std::vector<item_type*>;
using size_type = container_type::size_type;
~item_container()
{
for(auto ptr : cont_)
delete ptr;
@ -98,7 +86,7 @@ namespace nana
cont_.push_back(nullptr);
}
void push_back()
void separate()
{
cont_.push_back(nullptr);
}
@ -108,35 +96,17 @@ namespace nana
return cont_.size();
}
item_type* at(size_type n)
container_type& container()
{
if(n < cont_.size())
return cont_[n];
throw std::out_of_range("toolbar: bad index!");
return cont_;
}
iterator begin()
item_type * at(size_type pos)
{
return cont_.begin();
}
iterator end()
{
return cont_.end();
}
const_iterator begin() const
{
return cont_.cbegin();
}
const_iterator end() const
{
return cont_.cend();
return cont_.at(pos);
}
private:
std::vector<item_type*> cont_;
container_type cont_;
};
class item_renderer
@ -152,38 +122,36 @@ namespace nana
void operator()(int x, int y, unsigned width, unsigned height, item_type& item, state_t state)
{
//draw background
if(state != state_t::normal)
graph.rectangle({ x, y, width, height }, false, { 0x33, 0x99, 0xFF });
switch(state)
if (state != state_t::normal)
{
case state_t::highlighted:
graph.gradual_rectangle({ x + 1, y + 1, width - 2, height - 2 }, bgcolor, { 0xC0, 0xDD, 0xFC }, true);
break;
case state_t::selected:
graph.gradual_rectangle({ x + 1, y + 1, width - 2, height - 2 }, bgcolor, { 0x99, 0xCC, 0xFF }, true);
default: break;
nana::rectangle background_r(x, y, width, height);
graph.rectangle(background_r, false, static_cast<color_rgb>(0x3399FF));
if (state_t::highlighted == state || state_t::selected == state)
graph.gradual_rectangle(background_r.pare_off(1), bgcolor, static_cast<color_rgb>(state_t::selected == state ? 0x99CCFF : 0xC0DDFC), true);
}
if(item.image.empty() == false)
if(!item.image.empty())
{
nana::size size = item.image.size();
if(size.width > scale) size.width = scale;
if(size.height > scale) size.height = scale;
auto imgsize = item.image.size();
if (imgsize.width > scale) imgsize.width = scale;
if (imgsize.height > scale) imgsize.height = scale;
nana::point pos(x, y);
pos.x += static_cast<int>(scale + extra_size - size.width) / 2;
pos.y += static_cast<int>(height - size.height) / 2;
pos.x += static_cast<int>(scale + extra_size - imgsize.width) / 2;
pos.y += static_cast<int>(height - imgsize.height) / 2;
item.image.paste(size, graph, pos);
item.image.paste(::nana::rectangle{ imgsize }, graph, pos);
if(item.enable == false)
{
nana::paint::graphics gh(size);
gh.bitblt(size, graph, pos);
nana::paint::graphics gh(imgsize);
gh.bitblt(::nana::rectangle{ imgsize }, graph, pos);
gh.rgb_to_wb();
gh.paste(graph, pos.x, pos.y);
}
else if(state == state_t::normal)
graph.blend(nana::rectangle(pos, size), ::nana::color(0xc0, 0xdd, 0xfc).blend(bgcolor, 0.5), 0.25);
graph.blend(nana::rectangle(pos, imgsize), ::nana::color(0xc0, 0xdd, 0xfc).blend(bgcolor, 0.5), 0.25);
x += scale;
width -= scale;
@ -204,13 +172,15 @@ namespace nana
struct drawer::drawer_impl_type
{
event_handle event_size{nullptr};
event_handle event_size{ nullptr };
paint::graphics* graph_ptr{ nullptr };
unsigned scale{16};
bool textout{false};
size_type which{npos};
item_renderer::state_t state{item_renderer::state_t::normal};
container cont;
item_container items;
::nana::tooltip tooltip;
};
@ -225,116 +195,118 @@ namespace nana
delete impl_;
}
void drawer::append(const nana::string& text, const nana::paint::image& img)
item_container& drawer::items() const
{
impl_->cont.push_back(text, img);
}
void drawer::append()
{
impl_->cont.push_back();
}
bool drawer::enable(drawer::size_type n) const
{
if(impl_->cont.size() > n)
{
auto item = impl_->cont.at(n);
return (item && item->enable);
}
return false;
}
bool drawer::enable(size_type n, bool eb)
{
if(impl_->cont.size() > n)
{
item_type * item = impl_->cont.at(n);
if(item && (item->enable != eb))
{
item->enable = eb;
return true;
}
}
return false;
return impl_->items;
}
void drawer::scale(unsigned s)
{
impl_->scale = s;
for(auto m : impl_->cont)
_m_fill_pixels(m, true);
for(auto m : impl_->items.container())
_m_calc_pixels(m, true);
}
void drawer::refresh(graph_reference)
void drawer::refresh(graph_reference graph)
{
_m_draw();
int x = 2, y = 2;
auto bgcolor = API::bgcolor(widget_->handle());
graph.set_text_color(bgcolor);
graph.gradual_rectangle(rectangle{ graph.size() }, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.95), true);
item_renderer ir(graph, impl_->textout, impl_->scale, bgcolor);
size_type index = 0;
for (auto item : impl_->items.container())
{
if (item)
{
_m_calc_pixels(item, false);
ir(x, y, item->pixels, impl_->scale + ir.extra_size, *item, (index == impl_->which ? impl_->state : item_renderer::state_t::normal));
x += item->pixels;
}
else
{
x += 2;
graph.line({ x, y + 2 }, { x, y + static_cast<int>(impl_->scale + ir.extra_size) - 4 }, static_cast<color_rgb>(0x808080));
x += 4;
}
++index;
}
}
void drawer::attached(widget_reference widget, graph_reference graph)
{
graph_ = &graph;
impl_->graph_ptr = &graph;
widget_ = static_cast< ::nana::toolbar*>(&widget);
widget.caption(STR("Nana Toolbar"));
impl_->event_size = widget.events().resized.connect_unignorable(std::bind(&drawer::_m_owner_sized, this, std::placeholders::_1));
widget.caption(L"Nana Toolbar");
impl_->event_size = API::events(widget.parent()).resized.connect_unignorable([this](const arg_resized& arg)
{
auto wd = widget_->handle();
API::window_size(wd, nana::size(arg.width, widget_->size().height));
API::update_window(wd);
});
}
void drawer::detached()
{
API::umake_event(impl_->event_size);
impl_->event_size = nullptr;
impl_->graph_ptr = nullptr;
}
void drawer::mouse_move(graph_reference graph, const arg_mouse& arg)
{
if(arg.left_button == false)
if (arg.left_button)
return;
size_type which = _m_which(arg.pos, true);
if(impl_->which != which)
{
size_type which = _m_which(arg.pos.x, arg.pos.y, true);
if(impl_->which != which)
auto & container = impl_->items.container();
if (impl_->which != npos && container.at(impl_->which)->enable)
{
if (impl_->which != npos && impl_->cont.at(impl_->which)->enable)
{
::nana::arg_toolbar arg{ *widget_, impl_->which };
widget_->events().leave.emit(arg);
}
impl_->which = which;
if(which == npos || impl_->cont.at(which)->enable)
{
impl_->state = (arg.left_button ? item_renderer::state_t::selected : item_renderer::state_t::highlighted);
_m_draw();
API::lazy_refresh();
if (impl_->state == item_renderer::state_t::highlighted)
{
::nana::arg_toolbar arg{ *widget_, which };
widget_->events().enter.emit(arg);
}
}
if(which != npos)
impl_->tooltip.show(widget_->handle(), nana::point(arg.pos.x, arg.pos.y + 20), (*(impl_->cont.begin() + which))->text, 0);
else
impl_->tooltip.close();
::nana::arg_toolbar arg{ *widget_, impl_->which };
widget_->events().leave.emit(arg);
}
impl_->which = which;
if (which == npos || container.at(which)->enable)
{
impl_->state = item_renderer::state_t::highlighted;
refresh(graph);
API::lazy_refresh();
if (impl_->state == item_renderer::state_t::highlighted)
{
::nana::arg_toolbar arg{ *widget_, which };
widget_->events().enter.emit(arg);
}
}
if(which != npos)
impl_->tooltip.show(widget_->handle(), nana::point(arg.pos.x, arg.pos.y + 20), (*(container.begin() + which))->text, 0);
else
impl_->tooltip.close();
}
}
void drawer::mouse_leave(graph_reference, const arg_mouse&)
void drawer::mouse_leave(graph_reference graph, const arg_mouse&)
{
if(impl_->which != npos)
{
size_type which = impl_->which;
impl_->which = npos;
_m_draw();
refresh(graph);
API::lazy_refresh();
if (which != npos && impl_->cont.at(which)->enable)
if (which != npos && impl_->items.at(which)->enable)
{
::nana::arg_toolbar arg{ *widget_, which };
widget_->events().leave.emit(arg);
@ -343,22 +315,22 @@ namespace nana
impl_->tooltip.close();
}
void drawer::mouse_down(graph_reference, const arg_mouse&)
void drawer::mouse_down(graph_reference graph, const arg_mouse&)
{
impl_->tooltip.close();
if(impl_->which != npos && (impl_->cont.at(impl_->which)->enable))
if(impl_->which != npos && (impl_->items.at(impl_->which)->enable))
{
impl_->state = item_renderer::state_t::selected;
_m_draw();
refresh(graph);
API::lazy_refresh();
}
}
void drawer::mouse_up(graph_reference, const arg_mouse& arg)
void drawer::mouse_up(graph_reference graph, const arg_mouse& arg)
{
if(impl_->which != npos)
{
size_type which = _m_which(arg.pos.x, arg.pos.y, false);
size_type which = _m_which(arg.pos, false);
if(impl_->which == which)
{
::nana::arg_toolbar arg{ *widget_, which };
@ -372,89 +344,47 @@ namespace nana
impl_->state = (which == npos ? item_renderer::state_t::normal : item_renderer::state_t::highlighted);
}
_m_draw();
refresh(graph);
API::lazy_refresh();
}
}
drawer::size_type drawer::_m_which(int x, int y, bool want_if_disabled) const
drawer::size_type drawer::_m_which(point pos, bool want_if_disabled) const
{
if(x < 2 || y < 2 || y >= static_cast<int>(impl_->scale + item_renderer::extra_size + 2)) return npos;
if (pos.x < 2 || pos.y < 2 || pos.y >= static_cast<int>(impl_->scale + item_renderer::extra_size + 2)) return npos;
x -= 2;
pos.x -= 2;
size_type pos = 0;
for(auto m: impl_->cont)
std::size_t index = 0;
for(auto m: impl_->items.container())
{
bool compart = (nullptr == m);
auto px = static_cast<const int>(m ? m->pixels : 3);
if(x < static_cast<int>(compart ? 3 : m->pixels))
return ((compart || (m->enable == false && want_if_disabled == false)) ? npos : pos);
if(pos.x < px)
return (((!m) || (!m->enable && !want_if_disabled)) ? npos : index);
x -= (compart ? 3 : m->pixels);
pos.x -= px;
++pos;
++index;
}
return npos;
}
void drawer::_m_draw_background(const ::nana::color& clr)
void drawer::_m_calc_pixels(item_type* item, bool force)
{
graph_->gradual_rectangle(graph_->size(), clr.blend(colors::white, 0.9), clr.blend(colors::black, 0.95), true);
}
void drawer::_m_draw()
{
int x = 2, y = 2;
auto bgcolor = API::bgcolor(widget_->handle());
graph_->set_text_color(bgcolor);
_m_draw_background(bgcolor);
item_renderer ir(*graph_, impl_->textout, impl_->scale, bgcolor);
size_type index = 0;
for(auto item : impl_->cont)
if (item && (force || (0 == item->pixels)))
{
if(item)
{
_m_fill_pixels(item, false);
ir(x, y, item->pixels, impl_->scale + ir.extra_size, *item, (index == impl_->which ? impl_->state : item_renderer::state_t::normal));
x += item->pixels;
}
else
{
graph_->line({ x + 2, y + 2 }, { x + 2, y + static_cast<int>(impl_->scale + ir.extra_size) - 4 }, { 0x80, 0x80, 0x80 });
x += 6;
}
++index;
}
}
if (item->text.size())
item->textsize = impl_->graph_ptr->text_extent_size(item->text);
void drawer::_m_owner_sized(const arg_resized& arg)
{
auto wd = widget_->handle();
API::window_size(wd, nana::size(arg.width, widget_->size().height));
_m_draw();
API::update_window(wd);
}
void drawer::_m_fill_pixels(item_type* item, bool force)
{
if(item && (force || (0 == item->pixels)))
{
if(item->text.size())
item->textsize = graph_->text_extent_size(item->text);
if(item->image.empty() == false)
if (item->image.empty() == false)
item->pixels = impl_->scale + item_renderer::extra_size;
if(item->textsize.width && impl_->textout)
if (item->textsize.width && impl_->textout)
item->pixels += item->textsize.width + 8;
}
}
//};//class drawer
//class drawer
}//end namespace toolbar
}//end namespace drawerbase
@ -469,33 +399,48 @@ namespace nana
create(wd, r, visible);
}
void toolbar::append()
void toolbar::separate()
{
get_drawer_trigger().append();
get_drawer_trigger().items().separate();
API::refresh_window(handle());
}
void toolbar::append(const nana::string& text, const nana::paint::image& img)
{
get_drawer_trigger().append(text, img);
get_drawer_trigger().items().push_back(text, img);
API::refresh_window(handle());
}
void toolbar::append(const nana::string& text)
{
get_drawer_trigger().append(text, nana::paint::image());
get_drawer_trigger().items().push_back(text, {});
API::refresh_window(this->handle());
}
bool toolbar::enable(size_type n) const
bool toolbar::enable(size_type pos) const
{
return get_drawer_trigger().enable(n);
auto & items = get_drawer_trigger().items();
if (items.size() <= pos)
return false;
auto m = items.at(pos);
return (m && m->enable);
}
void toolbar::enable(size_type n, bool eb)
void toolbar::enable(size_type pos, bool eb)
{
if(get_drawer_trigger().enable(n, eb))
API::refresh_window(this->handle());
auto & items = get_drawer_trigger().items();
if (items.size() > pos)
{
auto m = items.at(pos);
if (m && (m->enable != eb))
{
m->enable = eb;
API::refresh_window(this->handle());
}
}
}
void toolbar::scale(unsigned s)
@ -503,5 +448,5 @@ namespace nana
get_drawer_trigger().scale(s);
API::refresh_window(handle());
}
//}; class toolbar
//end class toolbar
}//end namespace nana

View File

@ -27,7 +27,7 @@ namespace nana
//Here defines some function objects
namespace treebox
{
typedef trigger::node_type node_type;
using node_type = trigger::node_type;
bool no_sensitive_compare(const nana::string& text, const nana::char_t *pattern, std::size_t len)
{
@ -56,7 +56,7 @@ namespace nana
node = node->child;
while(node)
{
if(no_sensitive_compare(node->value.second.text, pattern, len)) return node;
if(no_sensitive_compare(node->value.second.text, pattern, len)) return node;
if(node == end) break;
@ -78,7 +78,7 @@ namespace nana
: public drawer_trigger, public compset_interface
{
public:
typedef drawer_trigger::graph_reference graph_reference;
using graph_reference = drawer_trigger::graph_reference;
void assign(const item_attribute_t & item_attr, const pat::cloneable<renderer_interface>* renderer, const pat::cloneable<compset_placer_interface> * compset_placer)
{
@ -583,7 +583,7 @@ namespace nana
void event_scrollbar(const arg_mouse& arg)
{
if((event_code::mouse_wheel == arg.evt_code) || arg.left_button)
if((event_code::mouse_wheel == arg.evt_code) || arg.is_left_button())
{
if(shape.prev_first_value != shape.scroll.value())
{
@ -719,17 +719,29 @@ namespace nana
node_state.tooltip->impl().assign(node_attr, &data.renderer, &data.comp_placer);
node_state.tooltip->show();
auto & events = node_state.tooltip->events();
events.mouse_leave.connect([this](const arg_mouse&){
this->close_tooltip_window();
});
events.mouse_move.connect([this](const arg_mouse&){
this->mouse_move_tooltip_window();
});
auto fn = [this](const arg_mouse& arg){
this->click_tooltip_window(arg);
auto fn = [this](const arg_mouse& arg)
{
switch (arg.evt_code)
{
case event_code::mouse_leave:
close_tooltip_window();
break;
case event_code::mouse_move:
mouse_move_tooltip_window();
break;
case event_code::mouse_down:
case event_code::mouse_up:
case event_code::dbl_click:
click_tooltip_window(arg);
break;
default: //ignore other events
break;
}
};
auto & events = node_state.tooltip->events();
events.mouse_leave(fn);
events.mouse_move(fn);
events.mouse_down.connect(fn);
events.mouse_up.connect(fn);
events.dbl_click.connect(fn);
@ -1241,13 +1253,14 @@ namespace nana
if(compset->comp_attribute(component::icon, attr))
{
const nana::paint::image * img = nullptr;
if(compset->item_attribute().mouse_pointed)
img = &(compset->item_attribute().icon_hover);
else if(compset->item_attribute().expended)
img = &(compset->item_attribute().icon_expanded);
auto & item_attr = compset->item_attribute();
if (item_attr.mouse_pointed)
img = &(item_attr.icon_hover);
else if (item_attr.expended)
img = &(item_attr.icon_expanded);
if((nullptr == img) || img->empty())
img = &(compset->item_attribute().icon_normal);
img = &(item_attr.icon_normal);
if(! img->empty())
{
@ -1260,10 +1273,10 @@ namespace nana
attr.area.x += (attr.area.width - fit_size.width) / 2;
attr.area.y += (attr.area.height - fit_size.height) / 2;
attr.area = fit_size;
img->stretch(size, graph, attr.area);
img->stretch(::nana::rectangle{ size }, graph, attr.area);
}
else
img->paste(graph, attr.area.x + static_cast<int>(attr.area.width - size.width) / 2, attr.area.y + static_cast<int>(attr.area.height - size.height) / 2);
img->paste(graph, point{ attr.area.x + static_cast<int>(attr.area.width - size.width) / 2, attr.area.y + static_cast<int>(attr.area.height - size.height) / 2 });
}
}
}
@ -1272,12 +1285,8 @@ namespace nana
{
comp_attribute_t attr;
if (compset->comp_attribute(component::text, attr))
{
graph.set_text_color(fgcolor_);
graph.string(point{ attr.area.x, attr.area.y + 3 }, compset->item_attribute().text);
}
graph.string(point{ attr.area.x, attr.area.y + 3 }, compset->item_attribute().text, fgcolor_);
}
private:
mutable facade<element::crook> crook_;
};

View File

@ -1,9 +1,9 @@
/*
* The fundamental widget class implementation
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
* 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
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/widgets/widget.cpp
@ -11,6 +11,7 @@
#include <nana/gui/widgets/widget.hpp>
#include <nana/gui/tooltip.hpp>
#include <nana/gui/detail/widget_notifier_interface.hpp>
namespace nana
{
@ -18,9 +19,42 @@ namespace nana
{
void set_eval(window, i18n_eval&&);
}
//class widget
//@brief:The definition of class widget
nana::string widget::caption() const
class widget::notifier: public detail::widget_notifier_interface
{
public:
notifier(widget& wdg)
: wdg_(wdg)
{}
private:
//implementation of widget_notifier_interface
widget* widget_ptr() const override
{
return &wdg_;
}
void destroy() override
{
wdg_._m_notify_destroy();
}
std::wstring caption() override
{
return wdg_._m_caption();
}
virtual void caption(std::wstring text)
{
wdg_._m_caption(std::move(text));
}
private:
widget& wdg_;
};
nana::string widget::caption() const throw()
{
return this->_m_caption();
}
@ -30,7 +64,7 @@ namespace nana
_m_caption(std::wstring(::nana::charset(utf8, ::nana::unicode::utf8)));
}
void widget::caption(nana::string str)
void widget::caption(std::wstring str)
{
_m_caption(std::move(str));
}
@ -91,7 +125,7 @@ namespace nana
bool widget::empty() const
{
return (nullptr == handle());
return (nullptr == handle());
}
void widget::focus()
@ -139,6 +173,11 @@ namespace nana
_m_move(x, y);
}
void widget::move(const point& pos)
{
_m_move(pos.x, pos.y);
}
void widget::move(const rectangle& r)
{
_m_move(r);
@ -205,10 +244,15 @@ namespace nana
return handle();
}
std::unique_ptr<::nana::detail::widget_notifier_interface> widget::_m_wdg_notifier()
{
return std::unique_ptr<::nana::detail::widget_notifier_interface>(new notifier(*this));
}
void widget::_m_complete_creation()
{}
nana::string widget::_m_caption() const
nana::string widget::_m_caption() const throw()
{
return API::dev::window_caption(handle());
}
@ -298,7 +342,14 @@ namespace nana
{
return API::bgcolor(handle());
}
//end class widget
namespace detail
{
std::unique_ptr<widget_notifier_interface> widget_notifier_interface::get_notifier(widget* wdg)
{
return std::unique_ptr<widget_notifier_interface>(new widget::notifier(*wdg));
}
}
}//end namespace nana

View File

@ -13,7 +13,7 @@
#ifndef NANA_PAINT_DETAIL_IMAGE_BMP_HPP
#define NANA_PAINT_DETAIL_IMAGE_BMP_HPP
#include "image_impl_interface.hpp"
#include <nana/paint/detail/image_impl_interface.hpp>
#include <memory>
namespace nana{ namespace paint
@ -25,24 +25,24 @@ namespace nana{ namespace paint
struct bitmap_file_header
{
unsigned short bfType;
unsigned long bfSize;
unsigned bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned long bfOffBits;
unsigned bfOffBits;
} __attribute__((packed));
struct bitmap_info_header {
unsigned long biSize;
long biWidth;
long biHeight;
unsigned biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
unsigned biCompression;
unsigned biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned biClrUsed;
unsigned biClrImportant;
}__attribute__((packed));
struct rgb_quad
@ -75,7 +75,13 @@ namespace nana{ namespace paint
this->close();
}
bool open(const nana::char_t* filename)
bool open(const void* data, std::size_t bytes) override
{
// TODO: read a BMP file from memory
return false;
}
bool open(const nana::char_t* filename) override
{
if(nullptr == filename) return false;
std::ifstream ifs;
@ -330,33 +336,33 @@ namespace nana{ namespace paint
return (false == pixbuf_.empty());
}
bool alpha_channel() const
bool alpha_channel() const override
{
return false;
}
bool empty() const
bool empty() const override
{
return pixbuf_.empty();
}
void close()
void close() override
{
pixbuf_.close();
}
nana::size size() const
nana::size size() const override
{
return pixbuf_.size();
}
void paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const
void paste(const nana::rectangle& src_r, graph_reference graph, const point& p_dst) const override
{
if(graph && pixbuf_)
pixbuf_.paste(src_r, graph.handle(), x, y);
pixbuf_.paste(src_r, graph.handle(), p_dst);
}
void stretch(const nana::rectangle& src_r, graph_reference graph, const nana::rectangle& r) const
void stretch(const nana::rectangle& src_r, graph_reference graph, const nana::rectangle& r) const override
{
if(graph && pixbuf_)
pixbuf_.stretch(src_r, graph.handle(), r);

View File

@ -1,7 +1,7 @@
#ifndef NANA_PAINT_DETAIL_IMAGE_ICO_HPP
#define NANA_PAINT_DETAIL_IMAGE_ICO_HPP
#include "image_impl_interface.hpp"
#include <nana/paint/detail/image_impl_interface.hpp>
namespace nana{ namespace paint
{
@ -22,14 +22,15 @@ namespace nana{ namespace paint
public:
image_ico(bool is_ico);
bool open(const nana::char_t* filename);
bool alpha_channel() const;
bool empty() const;
void close();
nana::size size() const;
virtual void paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const;
virtual void stretch(const nana::rectangle&, graph_reference graph, const nana::rectangle& r) const;
bool open(const nana::char_t* filename) override;
bool open(const void* data, std::size_t bytes) override;
bool alpha_channel() const override;
bool empty() const override;
void close() override;
nana::size size() const override;
virtual void paste(const nana::rectangle& src_r, graph_reference graph, const point& p_dst) const override;
virtual void stretch(const nana::rectangle&, graph_reference graph, const nana::rectangle& r) const override;
const ptr_t & ptr() const;
private:
const bool is_ico_;

Some files were not shown because too many files have changed in this diff Show More