case sensitive
This commit is contained in:
parent
544ea05dd7
commit
ec512490dd
|
|
@ -1,162 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.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="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{5D45F66B-BECD-4909-BCFC-C0F3CED9D0A2}</ProjectGuid>
|
||||
<Keyword>Easy2D-Audio</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</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 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 Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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|x64'">
|
||||
<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'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>../Easy2D</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>../Easy2D</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>../Easy2D</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>../Easy2D</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="audio-modules.cpp" />
|
||||
<ClCompile Include="audio.cpp" />
|
||||
<ClCompile Include="Music.cpp" />
|
||||
<ClCompile Include="Player.cpp" />
|
||||
<ClCompile Include="Transcoder.cpp" />
|
||||
<ClCompile Include="Voice.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="easy2d-audio.h" />
|
||||
<ClInclude Include="audio-modules.h" />
|
||||
<ClInclude Include="audio.h" />
|
||||
<ClInclude Include="Music.h" />
|
||||
<ClInclude Include="Player.h" />
|
||||
<ClInclude Include="Transcoder.h" />
|
||||
<ClInclude Include="Voice.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="audio.cpp" />
|
||||
<ClCompile Include="audio-modules.cpp" />
|
||||
<ClCompile Include="Music.cpp" />
|
||||
<ClCompile Include="Player.cpp" />
|
||||
<ClCompile Include="Transcoder.cpp" />
|
||||
<ClCompile Include="Voice.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="audio.h" />
|
||||
<ClInclude Include="audio-modules.h" />
|
||||
<ClInclude Include="Music.h" />
|
||||
<ClInclude Include="Player.h" />
|
||||
<ClInclude Include="Transcoder.h" />
|
||||
<ClInclude Include="Voice.h" />
|
||||
<ClInclude Include="easy2d-audio.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "easy2d-audio.h"
|
||||
#include "Music.h"
|
||||
#include "Transcoder.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Music::Music()
|
||||
: opened_(false)
|
||||
, playing_(false)
|
||||
, wave_data_(nullptr)
|
||||
, size_(0)
|
||||
, voice_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Music::Music(Resource const& res)
|
||||
: Music()
|
||||
{
|
||||
Load(res);
|
||||
}
|
||||
|
||||
Music::~Music()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool Music::Load(Resource const& res)
|
||||
{
|
||||
if (opened_)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
Transcoder transcoder;
|
||||
|
||||
if (res.IsFileType())
|
||||
{
|
||||
if (!modules::Shlwapi::Get().PathFileExistsW(res.GetFileName().c_str()))
|
||||
{
|
||||
E2D_WARNING_LOG(L"Media file '%s' not found", res.GetFileName().c_str());
|
||||
return false;
|
||||
}
|
||||
hr = transcoder.LoadMediaFile(res.GetFileName(), &wave_data_, &size_);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = transcoder.LoadMediaResource(res, &wave_data_, &size_);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
E2D_ERROR_LOG(L"Load media file failed with HRESULT of %08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = Audio::Instance().CreateVoice(voice_, transcoder.GetWaveFormatEx());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (wave_data_)
|
||||
{
|
||||
delete[] wave_data_;
|
||||
wave_data_ = nullptr;
|
||||
}
|
||||
E2D_ERROR_LOG(L"Create source voice failed with HRESULT of %08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
opened_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Music::Play(int loop_count)
|
||||
{
|
||||
if (!opened_)
|
||||
{
|
||||
E2D_ERROR_LOG(L"Music must be opened first!");
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 buffers_queued = 0;
|
||||
voice_.GetBuffersQueued(&buffers_queued);
|
||||
if (buffers_queued)
|
||||
Stop();
|
||||
|
||||
if (loop_count < 0)
|
||||
loop_count = XAUDIO2_LOOP_INFINITE;
|
||||
else
|
||||
loop_count = std::min(loop_count, XAUDIO2_LOOP_INFINITE - 1);
|
||||
|
||||
HRESULT hr = voice_.Play(wave_data_, size_, static_cast<UINT32>(loop_count));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
E2D_ERROR_LOG(L"Submitting source buffer failed with HRESULT of %08X", hr);
|
||||
}
|
||||
|
||||
playing_ = SUCCEEDED(hr);
|
||||
|
||||
return playing_;
|
||||
}
|
||||
|
||||
void Music::Pause()
|
||||
{
|
||||
if (SUCCEEDED(voice_.Pause()))
|
||||
playing_ = false;
|
||||
}
|
||||
|
||||
void Music::Resume()
|
||||
{
|
||||
if (SUCCEEDED(voice_.Resume()))
|
||||
playing_ = true;
|
||||
}
|
||||
|
||||
void Music::Stop()
|
||||
{
|
||||
if (SUCCEEDED(voice_.Stop()))
|
||||
playing_ = false;
|
||||
}
|
||||
|
||||
void Music::Close()
|
||||
{
|
||||
voice_.Destroy();
|
||||
|
||||
if (wave_data_)
|
||||
{
|
||||
delete[] wave_data_;
|
||||
wave_data_ = nullptr;
|
||||
}
|
||||
|
||||
opened_ = false;
|
||||
playing_ = false;
|
||||
}
|
||||
|
||||
bool Music::IsPlaying() const
|
||||
{
|
||||
if (opened_)
|
||||
{
|
||||
UINT32 buffers_queued = 0;
|
||||
voice_.GetBuffersQueued(&buffers_queued);
|
||||
if (buffers_queued && playing_)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float Music::GetVolume() const
|
||||
{
|
||||
float volume = 0.f;
|
||||
voice_.GetVolume(&volume);
|
||||
return volume;
|
||||
}
|
||||
|
||||
bool Music::SetVolume(float volume)
|
||||
{
|
||||
return SUCCEEDED(voice_.SetVolume(volume));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Voice.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
E2D_DECLARE_SMART_PTR(Music);
|
||||
|
||||
// 音乐对象
|
||||
class E2D_API Music
|
||||
: public virtual Object
|
||||
{
|
||||
public:
|
||||
Music();
|
||||
|
||||
Music(
|
||||
Resource const& res /* 音乐资源 */
|
||||
);
|
||||
|
||||
virtual ~Music();
|
||||
|
||||
// 打开音乐资源
|
||||
bool Load(
|
||||
Resource const& res /* 音乐资源 */
|
||||
);
|
||||
|
||||
// 播放
|
||||
bool Play(
|
||||
int loop_count = 0 /* 播放循环次数 (-1 为循环播放) */
|
||||
);
|
||||
|
||||
// 暂停
|
||||
void Pause();
|
||||
|
||||
// 继续
|
||||
void Resume();
|
||||
|
||||
// 停止
|
||||
void Stop();
|
||||
|
||||
// 关闭并回收资源
|
||||
void Close();
|
||||
|
||||
// 是否正在播放
|
||||
bool IsPlaying() const;
|
||||
|
||||
// 获取音量
|
||||
float GetVolume() const;
|
||||
|
||||
// 设置音量
|
||||
bool SetVolume(
|
||||
float volume /* 1 为原始音量, 大于 1 为放大音量, 0 为最小音量 */
|
||||
);
|
||||
|
||||
protected:
|
||||
bool opened_;
|
||||
bool playing_;
|
||||
UINT32 size_;
|
||||
BYTE* wave_data_;
|
||||
Voice voice_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "easy2d-audio.h"
|
||||
#include "Player.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Player::Player()
|
||||
: volume_(1.f)
|
||||
{
|
||||
}
|
||||
|
||||
Player::~Player()
|
||||
{
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
bool Player::Load(Resource const& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
return true;
|
||||
|
||||
MusicPtr music = new (std::nothrow) Music();
|
||||
|
||||
if (music)
|
||||
{
|
||||
if (music->Load(res))
|
||||
{
|
||||
music->SetVolume(volume_);
|
||||
musics_cache_.insert(std::make_pair(hash_code, music));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Player::Play(Resource const& res, int loop_count)
|
||||
{
|
||||
if (Load(res))
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
auto music = musics_cache_[hash_code];
|
||||
if (music->Play(loop_count))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Player::Pause(Resource const& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
musics_cache_[hash_code]->Pause();
|
||||
}
|
||||
|
||||
void Player::Resume(Resource const& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
musics_cache_[hash_code]->Resume();
|
||||
}
|
||||
|
||||
void Player::Stop(Resource const& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
musics_cache_[hash_code]->Stop();
|
||||
}
|
||||
|
||||
bool Player::IsPlaying(Resource const& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
return musics_cache_[hash_code]->IsPlaying();
|
||||
return false;
|
||||
}
|
||||
|
||||
float Player::GetVolume() const
|
||||
{
|
||||
return volume_;
|
||||
}
|
||||
|
||||
void Player::SetVolume(float volume)
|
||||
{
|
||||
volume_ = std::min(std::max(volume, -224.f), 224.f);
|
||||
for (const auto& pair : musics_cache_)
|
||||
{
|
||||
pair.second->SetVolume(volume_);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::PauseAll()
|
||||
{
|
||||
for (const auto& pair : musics_cache_)
|
||||
{
|
||||
pair.second->Pause();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::ResumeAll()
|
||||
{
|
||||
for (const auto& pair : musics_cache_)
|
||||
{
|
||||
pair.second->Resume();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::StopAll()
|
||||
{
|
||||
for (const auto& pair : musics_cache_)
|
||||
{
|
||||
pair.second->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::ClearCache()
|
||||
{
|
||||
musics_cache_.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
E2D_DECLARE_SMART_PTR(Player);
|
||||
|
||||
// 稜있꺄렴포
|
||||
class E2D_API Player
|
||||
: protected Object
|
||||
{
|
||||
using MusicMap = Map<size_t, MusicPtr>;
|
||||
|
||||
public:
|
||||
Player();
|
||||
|
||||
~Player();
|
||||
|
||||
// 渡속潼稜있栗都
|
||||
bool Load(
|
||||
Resource const& res /* 稜있栗都 */
|
||||
);
|
||||
|
||||
// 꺄렴稜있
|
||||
bool Play(
|
||||
Resource const& res, /* 稜있栗都 */
|
||||
int loop_count = 0 /* 꺄렴琦뻔늴鑒 (-1 槨琦뻔꺄렴) */
|
||||
);
|
||||
|
||||
// 董界稜있
|
||||
void Pause(
|
||||
Resource const& res /* 稜있栗都 */
|
||||
);
|
||||
|
||||
// 셨崎꺄렴稜있
|
||||
void Resume(
|
||||
Resource const& res /* 稜있栗都 */
|
||||
);
|
||||
|
||||
// 界岺稜있
|
||||
void Stop(
|
||||
Resource const& res /* 稜있栗都 */
|
||||
);
|
||||
|
||||
// 삿혤稜있꺄렴榴檄
|
||||
bool IsPlaying(
|
||||
Resource const& res /* 稜있栗都 */
|
||||
);
|
||||
|
||||
// 삿혤稜좆
|
||||
float GetVolume() const;
|
||||
|
||||
// <20>零稜좆
|
||||
void SetVolume(
|
||||
float volume /* 1.0 槨覩迦稜좆 */
|
||||
);
|
||||
|
||||
// 董界杰唐稜있
|
||||
void PauseAll();
|
||||
|
||||
// 셨崎꺄렴杰唐稜있
|
||||
void ResumeAll();
|
||||
|
||||
// 界岺杰唐稜있
|
||||
void StopAll();
|
||||
|
||||
// 헌뇜뻠닸
|
||||
void ClearCache();
|
||||
|
||||
protected:
|
||||
float volume_;
|
||||
MusicMap musics_cache_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,267 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef INITGUID
|
||||
# define INITGUID // MFAudioFormat_PCM, MF_MT_MAJOR_TYPE, MF_MT_SUBTYPE, MFMediaType_Audio
|
||||
#endif
|
||||
|
||||
#include "easy2d-audio.h"
|
||||
#include "Transcoder.h"
|
||||
#include "audio-modules.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Transcoder::Transcoder()
|
||||
: wave_format_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Transcoder::~Transcoder()
|
||||
{
|
||||
if (wave_format_)
|
||||
{
|
||||
::CoTaskMemFree(wave_format_);
|
||||
wave_format_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const WAVEFORMATEX* Transcoder::GetWaveFormatEx() const
|
||||
{
|
||||
return wave_format_;
|
||||
}
|
||||
|
||||
HRESULT Transcoder::LoadMediaFile(String const& file_path, BYTE** wave_data, UINT32* wave_data_size)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
ComPtr<IMFSourceReader> reader;
|
||||
|
||||
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromURL(
|
||||
file_path.c_str(),
|
||||
nullptr,
|
||||
&reader
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = ReadSource(reader.Get(), wave_data, wave_data_size);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Transcoder::LoadMediaResource(Resource const& res, BYTE** wave_data, UINT32* wave_data_size)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
ComPtr<IStream> stream;
|
||||
ComPtr<IMFByteStream> byte_stream;
|
||||
ComPtr<IMFSourceReader> reader;
|
||||
|
||||
LPVOID buffer;
|
||||
DWORD buffer_size;
|
||||
if (!res.Load(buffer, buffer_size)) { return false; }
|
||||
|
||||
stream = modules::Shlwapi::Get().SHCreateMemStream(
|
||||
static_cast<const BYTE*>(buffer),
|
||||
static_cast<UINT>(buffer_size)
|
||||
);
|
||||
|
||||
if (stream == nullptr)
|
||||
{
|
||||
E2D_ERROR_LOG(L"SHCreateMemStream failed");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = modules::MediaFoundation::Get().MFCreateMFByteStreamOnStream(stream.Get(), &byte_stream);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromByteStream(
|
||||
byte_stream.Get(),
|
||||
nullptr,
|
||||
&reader
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = ReadSource(reader.Get(), wave_data, wave_data_size);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Transcoder::ReadSource(IMFSourceReader* reader, BYTE** wave_data, UINT32* wave_data_size)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
DWORD max_stream_size = 0;
|
||||
|
||||
ComPtr<IMFMediaType> partial_type;
|
||||
ComPtr<IMFMediaType> uncompressed_type;
|
||||
|
||||
hr = modules::MediaFoundation::Get().MFCreateMediaType(&partial_type);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = partial_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = partial_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
|
||||
}
|
||||
|
||||
// 设置 source reader 的媒体类型,它将使用合适的解码器去解码这个音频
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = reader->SetCurrentMediaType(
|
||||
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
|
||||
0,
|
||||
partial_type.Get()
|
||||
);
|
||||
}
|
||||
|
||||
// 从 IMFMediaType 中获取 WAVEFORMAT 结构
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = reader->GetCurrentMediaType(
|
||||
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
|
||||
&uncompressed_type
|
||||
);
|
||||
}
|
||||
|
||||
// 指定音频流
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = reader->SetStreamSelection(
|
||||
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// 获取 WAVEFORMAT 数据
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
UINT32 size = 0;
|
||||
hr = modules::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType(
|
||||
uncompressed_type.Get(),
|
||||
&wave_format_,
|
||||
&size,
|
||||
(DWORD)MFWaveFormatExConvertFlag_Normal
|
||||
);
|
||||
}
|
||||
|
||||
// 估算音频流大小
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
PROPVARIANT prop;
|
||||
PropVariantInit(&prop);
|
||||
|
||||
hr = reader->GetPresentationAttribute(
|
||||
(DWORD)MF_SOURCE_READER_MEDIASOURCE,
|
||||
MF_PD_DURATION,
|
||||
&prop
|
||||
);
|
||||
|
||||
LONGLONG duration = prop.uhVal.QuadPart;
|
||||
max_stream_size = static_cast<DWORD>(
|
||||
(duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1
|
||||
);
|
||||
PropVariantClear(&prop);
|
||||
}
|
||||
|
||||
// 读取音频数据
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
DWORD flags = 0;
|
||||
DWORD position = 0;
|
||||
BYTE* data = new (std::nothrow) BYTE[max_stream_size];
|
||||
|
||||
ComPtr<IMFSample> sample;
|
||||
ComPtr<IMFMediaBuffer> buffer;
|
||||
|
||||
if (data == nullptr)
|
||||
{
|
||||
E2D_ERROR_LOG(L"Low memory");
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
hr = reader->ReadSample(
|
||||
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
|
||||
0,
|
||||
nullptr,
|
||||
&flags,
|
||||
nullptr,
|
||||
&sample
|
||||
);
|
||||
|
||||
if (flags & MF_SOURCE_READERF_ENDOFSTREAM) { break; }
|
||||
|
||||
if (sample == nullptr) { continue; }
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = sample->ConvertToContiguousBuffer(&buffer);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
BYTE *audio_data = nullptr;
|
||||
DWORD sample_buffer_length = 0;
|
||||
|
||||
hr = buffer->Lock(
|
||||
&audio_data,
|
||||
nullptr,
|
||||
&sample_buffer_length
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
for (DWORD i = 0; i < sample_buffer_length; i++)
|
||||
{
|
||||
data[position++] = audio_data[i];
|
||||
}
|
||||
hr = buffer->Unlock();
|
||||
}
|
||||
}
|
||||
buffer = nullptr;
|
||||
}
|
||||
sample = nullptr;
|
||||
|
||||
if (FAILED(hr)) { break; }
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*wave_data = data;
|
||||
*wave_data_size = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
#include <mfreadwrite.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API Transcoder
|
||||
{
|
||||
WAVEFORMATEX* wave_format_;
|
||||
|
||||
public:
|
||||
Transcoder();
|
||||
|
||||
~Transcoder();
|
||||
|
||||
const WAVEFORMATEX* GetWaveFormatEx() const;
|
||||
|
||||
HRESULT LoadMediaFile(
|
||||
String const& file_path,
|
||||
BYTE** wave_data,
|
||||
UINT32* wave_data_size
|
||||
);
|
||||
|
||||
HRESULT LoadMediaResource(
|
||||
Resource const& res,
|
||||
BYTE** wave_data,
|
||||
UINT32* wave_data_size
|
||||
);
|
||||
|
||||
HRESULT ReadSource(
|
||||
IMFSourceReader* reader,
|
||||
BYTE** wave_data,
|
||||
UINT32* wave_data_size
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "easy2d-audio.h"
|
||||
#include "Voice.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Voice::Voice()
|
||||
: source_voice_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Voice::Voice(IXAudio2SourceVoice * source_voice)
|
||||
: source_voice_(source_voice)
|
||||
{
|
||||
}
|
||||
|
||||
Voice::~Voice()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
Audio::Instance().DeleteVoice(this);
|
||||
}
|
||||
|
||||
HRESULT Voice::Play(const BYTE * wave_data, UINT32 data_size, UINT32 loop_count)
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
XAUDIO2_BUFFER buffer = { 0 };
|
||||
buffer.pAudioData = wave_data;
|
||||
buffer.Flags = XAUDIO2_END_OF_STREAM;
|
||||
buffer.AudioBytes = data_size;
|
||||
buffer.LoopCount = loop_count;
|
||||
|
||||
HRESULT hr = source_voice_->SubmitSourceBuffer(&buffer);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = source_voice_->Start();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Voice::Pause()
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return source_voice_->Stop();
|
||||
}
|
||||
|
||||
HRESULT Voice::Resume()
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return source_voice_->Start();
|
||||
}
|
||||
|
||||
HRESULT Voice::Stop()
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
HRESULT hr = source_voice_->Stop();
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = source_voice_->ExitLoop();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = source_voice_->FlushSourceBuffers();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Voice::GetVolume(float * volume) const
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (volume == nullptr)
|
||||
return E_POINTER;
|
||||
|
||||
source_voice_->GetVolume(volume);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Voice::SetVolume(float volume)
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
volume = std::min(std::max(volume, -224.f), 224.f);
|
||||
return source_voice_->SetVolume(volume);
|
||||
}
|
||||
|
||||
HRESULT Voice::GetBuffersQueued(UINT32 * queued) const
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (queued == nullptr)
|
||||
return E_POINTER;
|
||||
|
||||
XAUDIO2_VOICE_STATE state;
|
||||
source_voice_->GetState(&state);
|
||||
*queued = state.BuffersQueued;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void Voice::Destroy()
|
||||
{
|
||||
if (source_voice_)
|
||||
{
|
||||
source_voice_->Stop();
|
||||
source_voice_->FlushSourceBuffers();
|
||||
source_voice_->DestroyVoice();
|
||||
source_voice_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Voice::SetSourceVoice(IXAudio2SourceVoice * source_voice)
|
||||
{
|
||||
Destroy();
|
||||
source_voice_ = source_voice;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <xaudio2.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API Voice
|
||||
: protected Noncopyable
|
||||
{
|
||||
public:
|
||||
Voice();
|
||||
|
||||
Voice(
|
||||
IXAudio2SourceVoice* source_voice
|
||||
);
|
||||
|
||||
~Voice();
|
||||
|
||||
HRESULT Play(
|
||||
const BYTE* wave_data,
|
||||
UINT32 data_size,
|
||||
UINT32 loop_count
|
||||
);
|
||||
|
||||
HRESULT Pause();
|
||||
|
||||
HRESULT Resume();
|
||||
|
||||
HRESULT Stop();
|
||||
|
||||
HRESULT GetVolume(
|
||||
float* volume
|
||||
) const;
|
||||
|
||||
HRESULT SetVolume(
|
||||
float volume
|
||||
);
|
||||
|
||||
HRESULT GetBuffersQueued(
|
||||
UINT32* queued
|
||||
) const;
|
||||
|
||||
void Destroy();
|
||||
|
||||
void SetSourceVoice(
|
||||
IXAudio2SourceVoice* source_voice
|
||||
);
|
||||
|
||||
protected:
|
||||
IXAudio2SourceVoice* source_voice_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "easy2d-audio.h"
|
||||
#include "audio-modules.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace modules
|
||||
{
|
||||
XAudio2::XAudio2()
|
||||
{
|
||||
const auto xaudio2_dll_names =
|
||||
{
|
||||
L"xaudio2_9.dll", // for Windows 10
|
||||
L"xaudio2_8.dll", // for Windows 8
|
||||
L"xaudio2_7.dll" // for DirectX SDK
|
||||
};
|
||||
|
||||
for (const auto& name : xaudio2_dll_names)
|
||||
{
|
||||
xaudio2 = LoadLibraryW(name);
|
||||
if (xaudio2)
|
||||
{
|
||||
XAudio2Create = (PFN_XAudio2Create)
|
||||
GetProcAddress(xaudio2, "XAudio2Create");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!xaudio2)
|
||||
{
|
||||
E2D_ERROR_LOG(L"Load xaudio2.dll failed");
|
||||
throw std::runtime_error("Load xaudio2.dll failed");
|
||||
}
|
||||
}
|
||||
|
||||
MediaFoundation::MediaFoundation()
|
||||
{
|
||||
mfplat = LoadLibraryW(L"Mfplat.dll");
|
||||
if (mfplat)
|
||||
{
|
||||
MFStartup = (PFN_MFStartup)
|
||||
GetProcAddress(mfplat, "MFStartup");
|
||||
|
||||
MFShutdown = (PFN_MFShutdown)
|
||||
GetProcAddress(mfplat, "MFShutdown");
|
||||
|
||||
MFCreateMediaType = (PFN_MFCreateMediaType)
|
||||
GetProcAddress(mfplat, "MFCreateMediaType");
|
||||
|
||||
MFCreateWaveFormatExFromMFMediaType = (PFN_MFCreateWaveFormatExFromMFMediaType)
|
||||
GetProcAddress(mfplat, "MFCreateWaveFormatExFromMFMediaType");
|
||||
|
||||
MFCreateMFByteStreamOnStream = (PFN_MFCreateMFByteStreamOnStream)
|
||||
GetProcAddress(mfplat, "MFCreateMFByteStreamOnStream");
|
||||
}
|
||||
else
|
||||
{
|
||||
E2D_LOG(L"Load Mfplat.dll failed");
|
||||
throw std::runtime_error("Load Mfplat.dll failed");
|
||||
}
|
||||
|
||||
mfreadwrite = LoadLibraryW(L"Mfreadwrite.dll");
|
||||
if (mfreadwrite)
|
||||
{
|
||||
MFCreateSourceReaderFromURL = (PFN_MFCreateSourceReaderFromURL)
|
||||
GetProcAddress(mfreadwrite, "MFCreateSourceReaderFromURL");
|
||||
|
||||
MFCreateSourceReaderFromByteStream = (PFN_MFCreateSourceReaderFromByteStream)
|
||||
GetProcAddress(mfreadwrite, "MFCreateSourceReaderFromByteStream");
|
||||
}
|
||||
else
|
||||
{
|
||||
E2D_LOG(L"Load Mfreadwrite.dll failed");
|
||||
throw std::runtime_error("Load Mfreadwrite.dll failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <xaudio2.h>
|
||||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
#include <mfreadwrite.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace modules
|
||||
{
|
||||
class E2D_API XAudio2
|
||||
{
|
||||
XAudio2();
|
||||
|
||||
HMODULE xaudio2;
|
||||
|
||||
// XAudio2 functions
|
||||
typedef HRESULT(WINAPI *PFN_XAudio2Create)(IXAudio2**, UINT32, XAUDIO2_PROCESSOR);
|
||||
|
||||
public:
|
||||
static inline XAudio2& Get()
|
||||
{
|
||||
static XAudio2 instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
PFN_XAudio2Create XAudio2Create;
|
||||
};
|
||||
|
||||
|
||||
class E2D_API MediaFoundation
|
||||
{
|
||||
MediaFoundation();
|
||||
|
||||
HMODULE mfplat;
|
||||
HMODULE mfreadwrite;
|
||||
|
||||
// MediaFoundation functions
|
||||
typedef HRESULT(WINAPI *PFN_MFStartup)(ULONG, DWORD);
|
||||
typedef HRESULT(WINAPI *PFN_MFShutdown)();
|
||||
typedef HRESULT(WINAPI *PFN_MFCreateMediaType)(IMFMediaType**);
|
||||
typedef HRESULT(WINAPI *PFN_MFCreateWaveFormatExFromMFMediaType)(IMFMediaType*, WAVEFORMATEX**, UINT32*, UINT32);
|
||||
typedef HRESULT(WINAPI *PFN_MFCreateSourceReaderFromURL)(LPCWSTR, IMFAttributes*, IMFSourceReader**);
|
||||
typedef HRESULT(WINAPI *PFN_MFCreateSourceReaderFromByteStream)(IMFByteStream*, IMFAttributes*, IMFSourceReader**);
|
||||
typedef HRESULT(WINAPI *PFN_MFCreateMFByteStreamOnStream)(IStream*, IMFByteStream**);
|
||||
|
||||
public:
|
||||
static inline MediaFoundation& Get()
|
||||
{
|
||||
static MediaFoundation instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
PFN_MFStartup MFStartup;
|
||||
PFN_MFShutdown MFShutdown;
|
||||
PFN_MFCreateMediaType MFCreateMediaType;
|
||||
PFN_MFCreateWaveFormatExFromMFMediaType MFCreateWaveFormatExFromMFMediaType;
|
||||
PFN_MFCreateSourceReaderFromURL MFCreateSourceReaderFromURL;
|
||||
PFN_MFCreateSourceReaderFromByteStream MFCreateSourceReaderFromByteStream;
|
||||
PFN_MFCreateMFByteStreamOnStream MFCreateMFByteStreamOnStream;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "easy2d-audio.h"
|
||||
#include "audio.h"
|
||||
#include "audio-modules.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Audio::Audio()
|
||||
: x_audio2_(nullptr)
|
||||
, mastering_voice_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Audio::~Audio()
|
||||
{
|
||||
}
|
||||
|
||||
void Audio::SetupComponent(Application*)
|
||||
{
|
||||
E2D_LOG(L"Creating audio resources");
|
||||
|
||||
HRESULT hr = modules::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = modules::XAudio2::Get().XAudio2Create(&x_audio2_, 0, XAUDIO2_DEFAULT_PROCESSOR);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = x_audio2_->CreateMasteringVoice(&mastering_voice_);
|
||||
}
|
||||
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Audio::DestroyComponent()
|
||||
{
|
||||
E2D_LOG(L"Destroying audio resources");
|
||||
|
||||
ClearVoiceCache();
|
||||
|
||||
if (mastering_voice_)
|
||||
{
|
||||
mastering_voice_->DestroyVoice();
|
||||
mastering_voice_ = nullptr;
|
||||
}
|
||||
|
||||
if (x_audio2_)
|
||||
{
|
||||
x_audio2_->Release();
|
||||
x_audio2_ = nullptr;
|
||||
}
|
||||
|
||||
modules::MediaFoundation::Get().MFShutdown();
|
||||
}
|
||||
|
||||
HRESULT Audio::CreateVoice(Voice& voice, const WAVEFORMATEX* wfx)
|
||||
{
|
||||
HRESULT hr;
|
||||
IXAudio2SourceVoice* source_voice;
|
||||
|
||||
hr = x_audio2_->CreateSourceVoice(&source_voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
voice.SetSourceVoice(source_voice);
|
||||
voice_cache_.insert(&voice);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void Audio::DeleteVoice(Voice* voice)
|
||||
{
|
||||
voice_cache_.erase(voice);
|
||||
}
|
||||
|
||||
void Audio::ClearVoiceCache()
|
||||
{
|
||||
for (auto voice : voice_cache_)
|
||||
{
|
||||
voice->Destroy();
|
||||
}
|
||||
voice_cache_.clear();
|
||||
}
|
||||
|
||||
void Audio::Open()
|
||||
{
|
||||
x_audio2_->StartEngine();
|
||||
}
|
||||
|
||||
void Audio::Close()
|
||||
{
|
||||
x_audio2_->StopEngine();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Voice.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API Audio
|
||||
: public Singleton<Audio>
|
||||
, public Component
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(Audio);
|
||||
|
||||
using VoiceMap = UnorderedSet<Voice*>;
|
||||
|
||||
public:
|
||||
void SetupComponent(Application*) override;
|
||||
|
||||
void DestroyComponent() override;
|
||||
|
||||
// ¿ªÆôÉ豸
|
||||
void Open();
|
||||
|
||||
// ¹Ø±ÕÉ豸
|
||||
void Close();
|
||||
|
||||
HRESULT CreateVoice(
|
||||
Voice& voice,
|
||||
const WAVEFORMATEX* wfx
|
||||
);
|
||||
|
||||
void DeleteVoice(
|
||||
Voice* voice
|
||||
);
|
||||
|
||||
void ClearVoiceCache();
|
||||
|
||||
protected:
|
||||
Audio();
|
||||
|
||||
~Audio();
|
||||
|
||||
protected:
|
||||
VoiceMap voice_cache_;
|
||||
IXAudio2* x_audio2_;
|
||||
IXAudio2MasteringVoice* mastering_voice_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "easy2d.h"
|
||||
|
||||
#include "audio.h"
|
||||
#include "Music.h"
|
||||
#include "Player.h"
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.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="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{23AFF03B-A670-4C33-B790-18EEC82C61AE}</ProjectGuid>
|
||||
<Keyword>Easy2D-ImGui</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</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 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 Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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|x64'">
|
||||
<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'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>../Easy2D</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>../Easy2D</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>../Easy2D</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>../Easy2D</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="easy2d-imgui.h" />
|
||||
<ClInclude Include="libs\ImGui\imconfig.h" />
|
||||
<ClInclude Include="libs\ImGui\imgui.h" />
|
||||
<ClInclude Include="libs\ImGui\imgui_internal.h" />
|
||||
<ClInclude Include="libs\ImGui\imstb_rectpack.h" />
|
||||
<ClInclude Include="libs\ImGui\imstb_textedit.h" />
|
||||
<ClInclude Include="libs\ImGui\imstb_truetype.h" />
|
||||
<ClInclude Include="ImGuiLayer.h" />
|
||||
<ClInclude Include="ImGuiView.h" />
|
||||
<ClInclude Include="imgui_impl_dx11.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="libs\ImGui\imgui.cpp" />
|
||||
<ClCompile Include="libs\ImGui\imgui_demo.cpp" />
|
||||
<ClCompile Include="libs\ImGui\imgui_draw.cpp" />
|
||||
<ClCompile Include="libs\ImGui\imgui_widgets.cpp" />
|
||||
<ClCompile Include="ImGuiLayer.cpp" />
|
||||
<ClCompile Include="ImGuiView.cpp" />
|
||||
<ClCompile Include="imgui_impl_dx11.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClInclude Include="imgui_impl_dx11.h" />
|
||||
<ClInclude Include="ImGuiLayer.h" />
|
||||
<ClInclude Include="ImGuiView.h" />
|
||||
<ClInclude Include="libs\ImGui\imconfig.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="libs\ImGui\imgui.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="libs\ImGui\imgui_internal.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="libs\ImGui\imstb_rectpack.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="libs\ImGui\imstb_textedit.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="libs\ImGui\imstb_truetype.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="easy2d-imgui.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="imgui_impl_dx11.cpp" />
|
||||
<ClCompile Include="ImGuiLayer.cpp" />
|
||||
<ClCompile Include="ImGuiView.cpp" />
|
||||
<ClCompile Include="libs\ImGui\imgui.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libs\ImGui\imgui_demo.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libs\ImGui\imgui_draw.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libs\ImGui\imgui_widgets.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="imgui">
|
||||
<UniqueIdentifier>{d0ea3700-326c-4dc2-a674-fcb657039e87}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "easy2d-imgui.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace
|
||||
{
|
||||
Map<int, int> mouse_buttons =
|
||||
{
|
||||
{ MouseButton::Left, 0 },
|
||||
{ MouseButton::Right, 1 },
|
||||
{ MouseButton::Middle, 2 }
|
||||
};
|
||||
}
|
||||
|
||||
ImGuiLayer::ImGuiLayer()
|
||||
{
|
||||
target_window_ = Renderer::Instance().GetTargetWindow();
|
||||
}
|
||||
|
||||
ImGuiLayer::~ImGuiLayer()
|
||||
{
|
||||
}
|
||||
|
||||
void ImGuiLayer::OnMouseButtonDown(int btn, Point const & p)
|
||||
{
|
||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == nullptr)
|
||||
::SetCapture(target_window_);
|
||||
|
||||
E2D_ASSERT(mouse_buttons.find(btn) != mouse_buttons.end());
|
||||
ImGui::GetIO().MouseDown[mouse_buttons[btn]] = true;
|
||||
}
|
||||
|
||||
void ImGuiLayer::OnMouseButtonUp(int btn, Point const & p)
|
||||
{
|
||||
E2D_ASSERT(mouse_buttons.find(btn) != mouse_buttons.end());
|
||||
ImGui::GetIO().MouseDown[mouse_buttons[btn]] = false;
|
||||
|
||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == target_window_)
|
||||
::ReleaseCapture();
|
||||
}
|
||||
|
||||
void ImGuiLayer::OnMouseWheel(float wheel)
|
||||
{
|
||||
ImGui::GetIO().MouseWheel += wheel;
|
||||
}
|
||||
|
||||
void ImGuiLayer::OnKeyDown(int key)
|
||||
{
|
||||
E2D_ASSERT(key < 256);
|
||||
ImGui::GetIO().KeysDown[key] = 1;
|
||||
}
|
||||
|
||||
void ImGuiLayer::OnKeyUp(int key)
|
||||
{
|
||||
E2D_ASSERT(key < 256);
|
||||
ImGui::GetIO().KeysDown[key] = 0;
|
||||
}
|
||||
|
||||
void ImGuiLayer::OnChar(char c)
|
||||
{
|
||||
ImGui::GetIO().AddInputCharacter(c);
|
||||
}
|
||||
|
||||
void ImGuiLayer::OnUpdate(Duration dt)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup time step
|
||||
io.DeltaTime = dt.Seconds();
|
||||
|
||||
// Read keyboard modifiers inputs
|
||||
io.KeyCtrl = Input::Instance().IsDown(KeyCode::Ctrl);
|
||||
io.KeyShift = Input::Instance().IsDown(KeyCode::Shift);
|
||||
io.KeyAlt = Input::Instance().IsDown(KeyCode::Alt);
|
||||
io.KeySuper = false;
|
||||
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
|
||||
|
||||
// Update OS mouse position
|
||||
UpdateMousePos();
|
||||
|
||||
// Update OS mouse cursor with the cursor requested by imgui
|
||||
UpdateMouseCursor();
|
||||
}
|
||||
|
||||
void ImGuiLayer::OnRender()
|
||||
{
|
||||
ImGuiView::Instance().NewFrame();
|
||||
|
||||
for (const auto& pipeline : pipelines_)
|
||||
{
|
||||
pipeline.second();
|
||||
}
|
||||
|
||||
ImGuiView::Instance().Render();
|
||||
}
|
||||
|
||||
void ImGuiLayer::UpdateMousePos()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
{
|
||||
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
||||
HWND hwnd = target_window_;
|
||||
::ClientToScreen(hwnd, &pos);
|
||||
::SetCursorPos(pos.x, pos.y);
|
||||
}
|
||||
|
||||
Point pos = Input::Instance().GetMousePos();
|
||||
io.MousePos = ImVec2(pos.x, pos.y);
|
||||
}
|
||||
|
||||
void ImGuiLayer::UpdateMouseCursor()
|
||||
{
|
||||
static ImGuiMouseCursor last_mouse_cursor = ImGuiMouseCursor_COUNT;
|
||||
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
|
||||
if (last_mouse_cursor != imgui_cursor)
|
||||
{
|
||||
last_mouse_cursor = imgui_cursor;
|
||||
|
||||
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||
return;
|
||||
|
||||
MouseCursor cursor = MouseCursor::Arrow;
|
||||
switch (imgui_cursor)
|
||||
{
|
||||
case ImGuiMouseCursor_Arrow: cursor = MouseCursor::Arrow; break;
|
||||
case ImGuiMouseCursor_TextInput: cursor = MouseCursor::TextInput; break;
|
||||
case ImGuiMouseCursor_ResizeAll: cursor = MouseCursor::SizeAll; break;
|
||||
case ImGuiMouseCursor_ResizeEW: cursor = MouseCursor::SizeWE; break;
|
||||
case ImGuiMouseCursor_ResizeNS: cursor = MouseCursor::SizeNS; break;
|
||||
case ImGuiMouseCursor_ResizeNESW: cursor = MouseCursor::SizeNESW; break;
|
||||
case ImGuiMouseCursor_ResizeNWSE: cursor = MouseCursor::SizeNWSE; break;
|
||||
case ImGuiMouseCursor_Hand: cursor = MouseCursor::Hand; break;
|
||||
}
|
||||
|
||||
GetScene()->SetMouseCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiLayer::AddItem(ImGuiPipeline const & item, String const & name)
|
||||
{
|
||||
pipelines_.insert(std::make_pair(name, item));
|
||||
}
|
||||
|
||||
void ImGuiLayer::RemoveItem(String const & name)
|
||||
{
|
||||
auto iter = pipelines_.find(name);
|
||||
if (iter != pipelines_.end())
|
||||
{
|
||||
pipelines_.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiLayer::RemoveAllItems()
|
||||
{
|
||||
pipelines_.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
E2D_DECLARE_SMART_PTR(ImGuiLayer);
|
||||
|
||||
using ImGuiPipeline = std::function<void()>;
|
||||
|
||||
class ImGuiLayer
|
||||
: public Layer
|
||||
{
|
||||
public:
|
||||
ImGuiLayer();
|
||||
|
||||
virtual ~ImGuiLayer();
|
||||
|
||||
// Ìí¼Ó ImGui ÔªËØ
|
||||
void AddItem(
|
||||
ImGuiPipeline const& item,
|
||||
String const& name
|
||||
);
|
||||
|
||||
// ÒÆ³ý ImGui ÔªËØ
|
||||
void RemoveItem(
|
||||
String const& name
|
||||
);
|
||||
|
||||
// ÒÆ³ýËùÓÐÔªËØ
|
||||
void RemoveAllItems();
|
||||
|
||||
public:
|
||||
void OnMouseButtonDown(int btn, Point const& p) override;
|
||||
void OnMouseButtonUp(int btn, Point const& p) override;
|
||||
void OnMouseWheel(float wheel) override;
|
||||
|
||||
void OnKeyDown(int key) override;
|
||||
void OnKeyUp(int key) override;
|
||||
void OnChar(char c) override;
|
||||
|
||||
public:
|
||||
void OnUpdate(Duration dt) override;
|
||||
void OnRender() override;
|
||||
|
||||
void UpdateMousePos();
|
||||
void UpdateMouseCursor();
|
||||
|
||||
protected:
|
||||
HWND target_window_;
|
||||
Map<String, ImGuiPipeline> pipelines_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright (C) 2019 Nomango
|
||||
|
||||
#include "easy2d-imgui.h"
|
||||
#include "imgui_impl_dx11.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
void ImGuiView::SetupComponent(Application* app)
|
||||
{
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// Setup Platform/Renderer bindings
|
||||
Init(app->GetWindow()->GetHandle());
|
||||
}
|
||||
|
||||
void ImGuiView::DestroyComponent()
|
||||
{
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
void ImGuiView::Init(HWND hwnd)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
io.BackendPlatformName = "imgui_impl_win32";
|
||||
io.ImeWindowHandle = hwnd;
|
||||
|
||||
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
|
||||
io.KeyMap[ImGuiKey_Tab] = KeyCode::Tab;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = KeyCode::Left;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = KeyCode::Right;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = KeyCode::Up;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = KeyCode::Down;
|
||||
io.KeyMap[ImGuiKey_Delete] = KeyCode::Delete;
|
||||
io.KeyMap[ImGuiKey_Backspace] = KeyCode::Back;
|
||||
io.KeyMap[ImGuiKey_Space] = KeyCode::Space;
|
||||
io.KeyMap[ImGuiKey_Enter] = KeyCode::Enter;
|
||||
io.KeyMap[ImGuiKey_Escape] = KeyCode::Esc;
|
||||
io.KeyMap[ImGuiKey_A] = KeyCode::A;
|
||||
io.KeyMap[ImGuiKey_C] = KeyCode::C;
|
||||
io.KeyMap[ImGuiKey_V] = KeyCode::V;
|
||||
io.KeyMap[ImGuiKey_X] = KeyCode::X;
|
||||
io.KeyMap[ImGuiKey_Y] = KeyCode::Y;
|
||||
io.KeyMap[ImGuiKey_Z] = KeyCode::Z;
|
||||
|
||||
ImGui_ImplDX11_Init(
|
||||
Renderer::Instance().GetDeviceResources()->GetD3DDevice(),
|
||||
Renderer::Instance().GetDeviceResources()->GetD3DDeviceContext()
|
||||
);
|
||||
}
|
||||
|
||||
void ImGuiView::NewFrame()
|
||||
{
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
E2D_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
Size display_size = Renderer::Instance().GetOutputSize();
|
||||
io.DisplaySize = ImVec2(display_size.x, display_size.y);
|
||||
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void ImGuiView::Render()
|
||||
{
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class ImGuiView
|
||||
: public Singleton<ImGuiView>
|
||||
, public Component
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(ImGuiView);
|
||||
|
||||
public:
|
||||
void SetupComponent(Application* app) override;
|
||||
|
||||
void DestroyComponent() override;
|
||||
|
||||
public:
|
||||
void Init(HWND hwnd);
|
||||
|
||||
void NewFrame();
|
||||
|
||||
void Render();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "easy2d.h"
|
||||
#include "ImGuiView.h"
|
||||
#include "ImGuiLayer.h"
|
||||
|
||||
// ImGui
|
||||
#include "libs/ImGui/imgui.h"
|
||||
|
|
@ -1,493 +0,0 @@
|
|||
// dear imgui: Renderer for Easy2D (DirectX11)
|
||||
|
||||
#include "libs/ImGui/imgui.h"
|
||||
#include "imgui_impl_dx11.h"
|
||||
|
||||
// DirectX
|
||||
#include <stdio.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||
#endif
|
||||
|
||||
// DirectX data
|
||||
static ID3D11Device* g_pd3dDevice = NULL;
|
||||
static ID3D11DeviceContext* g_pd3dDeviceContext = NULL;
|
||||
static IDXGIFactory* g_pFactory = NULL;
|
||||
static ID3D11Buffer* g_pVB = NULL;
|
||||
static ID3D11Buffer* g_pIB = NULL;
|
||||
static ID3D10Blob* g_pVertexShaderBlob = NULL;
|
||||
static ID3D11VertexShader* g_pVertexShader = NULL;
|
||||
static ID3D11InputLayout* g_pInputLayout = NULL;
|
||||
static ID3D11Buffer* g_pVertexConstantBuffer = NULL;
|
||||
static ID3D10Blob* g_pPixelShaderBlob = NULL;
|
||||
static ID3D11PixelShader* g_pPixelShader = NULL;
|
||||
static ID3D11SamplerState* g_pFontSampler = NULL;
|
||||
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
|
||||
static ID3D11RasterizerState* g_pRasterizerState = NULL;
|
||||
static ID3D11BlendState* g_pBlendState = NULL;
|
||||
static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
|
||||
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER
|
||||
{
|
||||
float mvp[4][4];
|
||||
};
|
||||
|
||||
// Render function
|
||||
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
|
||||
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
|
||||
g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = g_VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0)
|
||||
return;
|
||||
}
|
||||
if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
|
||||
g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy and convert all vertices into a single contiguous buffer
|
||||
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
|
||||
if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||
return;
|
||||
if (ctx->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
}
|
||||
ctx->Unmap(g_pVB, 0);
|
||||
ctx->Unmap(g_pIB, 0);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||
if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||
return;
|
||||
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData;
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
float mvp[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||
};
|
||||
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||
ctx->Unmap(g_pVertexConstantBuffer, 0);
|
||||
}
|
||||
|
||||
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||
struct BACKUP_DX11_STATE
|
||||
{
|
||||
UINT ScissorRectsCount, ViewportsCount;
|
||||
D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||
D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||
ID3D11RasterizerState* RS;
|
||||
ID3D11BlendState* BlendState;
|
||||
FLOAT BlendFactor[4];
|
||||
UINT SampleMask;
|
||||
UINT StencilRef;
|
||||
ID3D11DepthStencilState* DepthStencilState;
|
||||
ID3D11ShaderResourceView* PSShaderResource;
|
||||
ID3D11SamplerState* PSSampler;
|
||||
ID3D11PixelShader* PS;
|
||||
ID3D11VertexShader* VS;
|
||||
UINT PSInstancesCount, VSInstancesCount;
|
||||
ID3D11ClassInstance* PSInstances[256], *VSInstances[256]; // 256 is max according to PSSetShader documentation
|
||||
D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;
|
||||
ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
|
||||
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
|
||||
DXGI_FORMAT IndexBufferFormat;
|
||||
ID3D11InputLayout* InputLayout;
|
||||
};
|
||||
BACKUP_DX11_STATE old;
|
||||
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
ctx->RSGetState(&old.RS);
|
||||
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
old.PSInstancesCount = old.VSInstancesCount = 256;
|
||||
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
||||
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
||||
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
ctx->IAGetInputLayout(&old.InputLayout);
|
||||
|
||||
// Setup viewport
|
||||
D3D11_VIEWPORT vp;
|
||||
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
|
||||
vp.Width = draw_data->DisplaySize.x;
|
||||
vp.Height = draw_data->DisplaySize.y;
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0;
|
||||
ctx->RSSetViewports(1, &vp);
|
||||
|
||||
// Bind shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
ctx->IASetInputLayout(g_pInputLayout);
|
||||
ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
|
||||
ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->VSSetShader(g_pVertexShader, NULL, 0);
|
||||
ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
|
||||
ctx->PSSetShader(g_pPixelShader, NULL, 0);
|
||||
ctx->PSSetSamplers(0, 1, &g_pFontSampler);
|
||||
|
||||
// Setup render state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
|
||||
ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
|
||||
ctx->RSSetState(g_pRasterizerState);
|
||||
|
||||
// Render command lists
|
||||
int vtx_offset = 0;
|
||||
int idx_offset = 0;
|
||||
ImVec2 pos = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback (registered via ImDrawList::AddCallback)
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y) };
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
|
||||
// Bind texture, Draw
|
||||
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->TextureId;
|
||||
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
||||
ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset);
|
||||
}
|
||||
idx_offset += pcmd->ElemCount;
|
||||
}
|
||||
vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// Restore modified DX state
|
||||
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
||||
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
|
||||
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
||||
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
|
||||
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
|
||||
// Upload texture to graphics system
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
ID3D11Texture2D *pTexture = NULL;
|
||||
D3D11_SUBRESOURCE_DATA subResource;
|
||||
subResource.pSysMem = pixels;
|
||||
subResource.SysMemPitch = desc.Width * 4;
|
||||
subResource.SysMemSlicePitch = 0;
|
||||
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||
|
||||
// Create texture view
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView);
|
||||
pTexture->Release();
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->TexID = (ImTextureID)g_pFontTextureView;
|
||||
|
||||
// Create texture sampler
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
{
|
||||
if (!g_pd3dDevice)
|
||||
return false;
|
||||
if (g_pFontSampler)
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
|
||||
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||
// If you would like to use this DX11 sample code but remove this dependency you can:
|
||||
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
|
||||
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||
|
||||
// Create the vertex shader
|
||||
{
|
||||
static const char* vertexShader =
|
||||
"cbuffer vertexBuffer : register(b0) \
|
||||
{\
|
||||
float4x4 ProjectionMatrix; \
|
||||
};\
|
||||
struct VS_INPUT\
|
||||
{\
|
||||
float2 pos : POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
\
|
||||
struct PS_INPUT\
|
||||
{\
|
||||
float4 pos : SV_POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
\
|
||||
PS_INPUT main(VS_INPUT input)\
|
||||
{\
|
||||
PS_INPUT output;\
|
||||
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
|
||||
output.col = input.col;\
|
||||
output.uv = input.uv;\
|
||||
return output;\
|
||||
}";
|
||||
|
||||
D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, NULL);
|
||||
if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
return false;
|
||||
if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK)
|
||||
return false;
|
||||
|
||||
// Create the input layout
|
||||
D3D11_INPUT_ELEMENT_DESC local_layout[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
|
||||
return false;
|
||||
|
||||
// Create the constant buffer
|
||||
{
|
||||
D3D11_BUFFER_DESC desc;
|
||||
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the pixel shader
|
||||
{
|
||||
static const char* pixelShader =
|
||||
"struct PS_INPUT\
|
||||
{\
|
||||
float4 pos : SV_POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
sampler sampler0;\
|
||||
Texture2D texture0;\
|
||||
\
|
||||
float4 main(PS_INPUT input) : SV_Target\
|
||||
{\
|
||||
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
|
||||
return out_col; \
|
||||
}";
|
||||
|
||||
D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, NULL);
|
||||
if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
return false;
|
||||
if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the blending setup
|
||||
{
|
||||
D3D11_BLEND_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.AlphaToCoverageEnable = false;
|
||||
desc.RenderTarget[0].BlendEnable = true;
|
||||
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||
g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState);
|
||||
}
|
||||
|
||||
// Create the rasterizer state
|
||||
{
|
||||
D3D11_RASTERIZER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.FillMode = D3D11_FILL_SOLID;
|
||||
desc.CullMode = D3D11_CULL_NONE;
|
||||
desc.ScissorEnable = true;
|
||||
desc.DepthClipEnable = true;
|
||||
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
|
||||
}
|
||||
|
||||
// Create depth-stencil State
|
||||
{
|
||||
D3D11_DEPTH_STENCIL_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.DepthEnable = false;
|
||||
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.StencilEnable = false;
|
||||
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.BackFace = desc.FrontFace;
|
||||
g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_CreateFontsTexture();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_InvalidateDeviceObjects()
|
||||
{
|
||||
if (!g_pd3dDevice)
|
||||
return;
|
||||
|
||||
if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; }
|
||||
if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
|
||||
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
|
||||
|
||||
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
|
||||
if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
|
||||
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
|
||||
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
|
||||
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
|
||||
if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; }
|
||||
if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; }
|
||||
if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; }
|
||||
if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; }
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendRendererName = "imgui_impl_dx11";
|
||||
|
||||
// Get factory from device
|
||||
IDXGIDevice* pDXGIDevice = NULL;
|
||||
IDXGIAdapter* pDXGIAdapter = NULL;
|
||||
IDXGIFactory* pFactory = NULL;
|
||||
|
||||
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
|
||||
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
|
||||
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
|
||||
{
|
||||
g_pd3dDevice = device;
|
||||
g_pd3dDeviceContext = device_context;
|
||||
g_pFactory = pFactory;
|
||||
}
|
||||
if (pDXGIDevice) pDXGIDevice->Release();
|
||||
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; }
|
||||
g_pd3dDevice = NULL;
|
||||
g_pd3dDeviceContext = NULL;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_NewFrame()
|
||||
{
|
||||
if (!g_pFontSampler)
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// dear imgui: Renderer for Easy2D (DirectX11)
|
||||
|
||||
#pragma once
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Use if you want to reset your rendering device without losing ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2019 Omar Cornut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating imgui, or maintain a patch/branch with your modifications to imconfig.h)
|
||||
// B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h"
|
||||
// If you do so you need to make sure that configuration settings are defined consistently _everywhere_ dear imgui is used, which include
|
||||
// the imgui*.cpp files but also _any_ of your code that uses imgui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows.
|
||||
//#define IMGUI_API __declspec( dllexport )
|
||||
//#define IMGUI_API __declspec( dllimport )
|
||||
|
||||
//---- Don't define obsolete functions/enums names. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
|
||||
//---- It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function.
|
||||
//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf.
|
||||
//#define IMGUI_DISABLE_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 wrapper so you can implement them yourself. Declare your prototypes in imconfig.h.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of imgui cpp files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) to allow meshes with more than 64K vertices. Render function needs to support it.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,623 +0,0 @@
|
|||
// stb_rect_pack.h - v0.11 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
typedef int stbrp_coord;
|
||||
#else
|
||||
typedef unsigned short stbrp_coord;
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
//
|
||||
// The function returns 1 if all of the rectangles were successfully
|
||||
// packed and 0 otherwise.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
||||
#endif
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
context->extra[1].y = (1<<30);
|
||||
#else
|
||||
context->extra[1].y = 65535;
|
||||
#endif
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height < c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
STBRP_ASSERT(y <= best_y);
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
#define STBRP__MAXVAL 0xffffffff
|
||||
#else
|
||||
#define STBRP__MAXVAL 0xffff
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
|
||||
#endif
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags and all_rects_packed status
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
// return the all_rects_packed status
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,102 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Action.h"
|
||||
#include "Node.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Action::Action()
|
||||
: running_(true)
|
||||
, detach_target_(false)
|
||||
, loops_done_(0)
|
||||
, loops_(0)
|
||||
, status_(Status::NotStarted)
|
||||
{
|
||||
}
|
||||
|
||||
Action::~Action()
|
||||
{
|
||||
}
|
||||
|
||||
void Action::UpdateStep(NodePtr const& target, Duration dt)
|
||||
{
|
||||
elapsed_ += dt;
|
||||
|
||||
if (status_ == Status::NotStarted)
|
||||
{
|
||||
Init(target);
|
||||
status_ = delay_.IsZero() ? Status::Started : Status::Delayed;
|
||||
}
|
||||
|
||||
switch (status_)
|
||||
{
|
||||
case Status::Delayed:
|
||||
if (elapsed_ >= delay_)
|
||||
{
|
||||
status_ = Status::Started;
|
||||
}
|
||||
break;
|
||||
|
||||
case Status::Started:
|
||||
Update(target, dt);
|
||||
break;
|
||||
}
|
||||
|
||||
if (status_ == Status::Done)
|
||||
{
|
||||
if (cb_done_)
|
||||
cb_done_();
|
||||
|
||||
if (detach_target_)
|
||||
target->RemoveFromParent();
|
||||
|
||||
status_ = Status::Removeable;
|
||||
}
|
||||
}
|
||||
|
||||
void Action::Complete(NodePtr const& target)
|
||||
{
|
||||
if (cb_loop_done_)
|
||||
cb_loop_done_();
|
||||
|
||||
if (loops_ >= 0
|
||||
&& loops_done_ >= loops_)
|
||||
{
|
||||
Done();
|
||||
}
|
||||
else
|
||||
{
|
||||
Init(target); // reinit when a loop is done
|
||||
}
|
||||
|
||||
++loops_done_;
|
||||
}
|
||||
|
||||
void Action::Restart(NodePtr const & target)
|
||||
{
|
||||
status_ = Status::NotStarted;
|
||||
elapsed_ = 0;
|
||||
loops_done_ = 0;
|
||||
|
||||
Init(target);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "include-forwards.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
using ActionCallback = std::function<void()>;
|
||||
|
||||
class ActionManager;
|
||||
|
||||
class Action
|
||||
: public virtual Object
|
||||
, protected IntrusiveListItem<ActionPtr>
|
||||
{
|
||||
friend class ActionManager;
|
||||
friend class ActionGroup;
|
||||
friend class IntrusiveList<ActionPtr>;
|
||||
|
||||
public:
|
||||
enum class Status
|
||||
{
|
||||
NotStarted,
|
||||
Delayed,
|
||||
Started,
|
||||
Done,
|
||||
Removeable
|
||||
};
|
||||
|
||||
Action();
|
||||
|
||||
virtual ~Action();
|
||||
|
||||
// 继续动作
|
||||
inline void Resume() { running_ = true; }
|
||||
|
||||
// 暂停动作
|
||||
inline void Pause() { running_ = false; }
|
||||
|
||||
// 停止动作
|
||||
inline void Stop() { status_ = Status::Removeable; }
|
||||
|
||||
// 设置动作延时
|
||||
inline void SetDelay(Duration delay) { delay_ = delay; }
|
||||
|
||||
// 设置循环次数 (-1 为永久循环)
|
||||
inline void SetLoops(int loops) { loops_ = loops; }
|
||||
|
||||
// 动作结束时移除目标节点
|
||||
inline void RemoveTargetWhenDone() { detach_target_ = true; }
|
||||
|
||||
// 设置动作结束时的回调函数
|
||||
inline void SetDoneCallback(ActionCallback const& cb) { cb_done_ = cb; }
|
||||
|
||||
// 设置动作循环结束时的回调函数
|
||||
inline void SetLoopDoneCallback(ActionCallback const& cb) { cb_loop_done_ = cb; }
|
||||
|
||||
// 获取动作的拷贝
|
||||
virtual ActionPtr Clone() const = 0;
|
||||
|
||||
// 获取动作的倒转
|
||||
virtual ActionPtr Reverse() const = 0;
|
||||
|
||||
inline void Done() { status_ = Status::Done; }
|
||||
|
||||
inline Status GetStatus() const { return status_; }
|
||||
|
||||
inline bool IsRunning() const { return running_; }
|
||||
|
||||
inline bool IsDone() const { return status_ == Status::Done || status_ == Status::Removeable; }
|
||||
|
||||
inline bool IsRemoveable() const { return status_ == Status::Removeable; }
|
||||
|
||||
inline int GetLoops() const { return loops_; }
|
||||
|
||||
inline Duration GetDelay() const { return delay_; }
|
||||
|
||||
inline Duration GetElapsed() const { return elapsed_; }
|
||||
|
||||
inline ActionCallback const& GetDoneCallback() const { return cb_done_; }
|
||||
|
||||
inline ActionCallback const& GetLoopDoneCallback() const { return cb_loop_done_; }
|
||||
|
||||
protected:
|
||||
virtual void Init(NodePtr const& target) {}
|
||||
|
||||
virtual void Update(NodePtr const& target, Duration dt) {}
|
||||
|
||||
void UpdateStep(NodePtr const& target, Duration dt);
|
||||
|
||||
void Complete(NodePtr const& target);
|
||||
|
||||
void Restart(NodePtr const& target);
|
||||
|
||||
protected:
|
||||
Status status_;
|
||||
bool running_;
|
||||
bool detach_target_;
|
||||
int loops_;
|
||||
int loops_done_;
|
||||
Duration delay_;
|
||||
Duration elapsed_;
|
||||
ActionCallback cb_done_;
|
||||
ActionCallback cb_loop_done_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "ActionGroup.h"
|
||||
#include "../base/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
//-------------------------------------------------------
|
||||
// ActionGroup
|
||||
//-------------------------------------------------------
|
||||
|
||||
ActionGroup::ActionGroup()
|
||||
: sequence_(true)
|
||||
{
|
||||
}
|
||||
|
||||
ActionGroup::ActionGroup(Array<ActionPtr> const& actions, bool sequence)
|
||||
: sequence_(sequence)
|
||||
{
|
||||
this->Add(actions);
|
||||
}
|
||||
|
||||
ActionGroup::~ActionGroup()
|
||||
{
|
||||
}
|
||||
|
||||
void ActionGroup::Init(NodePtr const& target)
|
||||
{
|
||||
if (actions_.IsEmpty())
|
||||
{
|
||||
Done();
|
||||
return;
|
||||
}
|
||||
|
||||
current_ = actions_.First();
|
||||
current_->Restart(target); // init first action
|
||||
|
||||
if (!sequence_)
|
||||
{
|
||||
// init all actions
|
||||
for (; current_; current_ = current_->NextItem())
|
||||
{
|
||||
current_->Restart(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionGroup::Update(NodePtr const& target, Duration dt)
|
||||
{
|
||||
if (sequence_)
|
||||
{
|
||||
if (current_)
|
||||
{
|
||||
current_->UpdateStep(target, dt);
|
||||
|
||||
if (current_->IsDone())
|
||||
{
|
||||
current_ = current_->NextItem();
|
||||
|
||||
if (current_)
|
||||
current_->Restart(target); // init next action
|
||||
else
|
||||
Complete(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool done = true;
|
||||
for (current_ = actions_.First(); current_; current_ = current_->NextItem())
|
||||
{
|
||||
if (!current_->IsDone())
|
||||
{
|
||||
done = false;
|
||||
current_->UpdateStep(target, dt);
|
||||
}
|
||||
}
|
||||
|
||||
if (done)
|
||||
{
|
||||
Complete(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionGroup::Add(ActionPtr const& action)
|
||||
{
|
||||
if (action)
|
||||
{
|
||||
actions_.PushBack(action);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionGroup::Add(Array<ActionPtr> const& actions)
|
||||
{
|
||||
for (const auto& action : actions)
|
||||
Add(action);
|
||||
}
|
||||
|
||||
ActionPtr ActionGroup::Clone() const
|
||||
{
|
||||
auto group = new (std::nothrow) ActionGroup();
|
||||
if (group)
|
||||
{
|
||||
for (auto action = actions_.First(); action; action = action->NextItem())
|
||||
{
|
||||
if (action)
|
||||
{
|
||||
group->Add(action->Clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
ActionPtr ActionGroup::Reverse() const
|
||||
{
|
||||
auto group = new (std::nothrow) ActionGroup();
|
||||
if (group && !actions_.IsEmpty())
|
||||
{
|
||||
for (auto action = actions_.Last(); action; action = action->PrevItem())
|
||||
{
|
||||
group->Add(action->Reverse());
|
||||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Action.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 动作组
|
||||
class E2D_API ActionGroup
|
||||
: public Action
|
||||
{
|
||||
public:
|
||||
using ActionList = IntrusiveList<ActionPtr>;
|
||||
|
||||
ActionGroup();
|
||||
|
||||
explicit ActionGroup(
|
||||
Array<ActionPtr> const& actions,
|
||||
bool sequence = true // 按顺序执行或同时执行
|
||||
);
|
||||
|
||||
virtual ~ActionGroup();
|
||||
|
||||
// 添加动作
|
||||
void Add(
|
||||
ActionPtr const& action
|
||||
);
|
||||
|
||||
// 添加多个动作
|
||||
void Add(
|
||||
Array<ActionPtr> const& actions
|
||||
);
|
||||
|
||||
// 获取所有动作
|
||||
inline ActionList const& GetActions() { return actions_; }
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
ActionPtr Reverse() const override;
|
||||
|
||||
protected:
|
||||
// 初始化动作
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
// 更新动作
|
||||
void Update(NodePtr const& target, Duration dt) override;
|
||||
|
||||
protected:
|
||||
bool sequence_;
|
||||
ActionPtr current_;
|
||||
ActionList actions_;
|
||||
};
|
||||
|
||||
|
||||
// 顺序动作
|
||||
class E2D_API ActionSequence
|
||||
: public ActionGroup
|
||||
{
|
||||
public:
|
||||
E2D_DEPRECATED("ActionSequence is deprecated, use ActionGroup instead")
|
||||
inline ActionSequence() : ActionGroup() {}
|
||||
|
||||
E2D_DEPRECATED("ActionSequence is deprecated, use ActionGroup instead")
|
||||
inline explicit ActionSequence(Array<ActionPtr> const& actions) : ActionGroup(actions, true) {}
|
||||
|
||||
virtual ~ActionSequence() {}
|
||||
};
|
||||
|
||||
|
||||
// 同步动作
|
||||
class E2D_API ActionSpawn
|
||||
: public ActionGroup
|
||||
{
|
||||
public:
|
||||
E2D_DEPRECATED("ActionSpawn is deprecated, use ActionGroup instead")
|
||||
inline ActionSpawn() : ActionGroup() { sequence_ = false; }
|
||||
|
||||
E2D_DEPRECATED("ActionSpawn is deprecated, use ActionGroup instead")
|
||||
inline explicit ActionSpawn(Array<ActionPtr> const& actions) : ActionGroup(actions, false) {}
|
||||
|
||||
virtual ~ActionSpawn() {}
|
||||
};
|
||||
}
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "ActionGroup.h"
|
||||
#include "ActionTween.h"
|
||||
#include "Animation.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
struct ActionHelper
|
||||
{
|
||||
// 设置循环次数
|
||||
inline ActionHelper& SetLoops(int loops) { base->SetLoops(loops); return (*this); }
|
||||
|
||||
// 设置动作延迟
|
||||
inline ActionHelper& SetDelay(Duration delay) { base->SetDelay(delay); return (*this); }
|
||||
|
||||
// 设置动作结束回调函数
|
||||
inline ActionHelper& SetDoneCallback(ActionCallback const& cb) { base->SetDoneCallback(cb); return (*this); }
|
||||
|
||||
// 设置动作循环结束时的回调函数
|
||||
inline ActionHelper& SetLoopDoneCallback(ActionCallback const& cb) { base->SetLoopDoneCallback(cb); return (*this); }
|
||||
|
||||
// 动作结束时移除目标节点
|
||||
inline ActionHelper& RemoveTargetWhenDone() { base->RemoveTargetWhenDone(); return (*this); }
|
||||
|
||||
// 设置名称
|
||||
inline ActionHelper& SetName(String const& name) { base->SetName(name); return (*this); }
|
||||
|
||||
// 获取指针
|
||||
inline ActionPtr const& Get() const { return base; }
|
||||
|
||||
inline ActionHelper(ActionPtr const& base) : base(base) {}
|
||||
|
||||
inline operator ActionPtr() const { return base; }
|
||||
|
||||
protected:
|
||||
ActionPtr base;
|
||||
};
|
||||
|
||||
struct TweenHelper
|
||||
{
|
||||
// 设置动画持续时长
|
||||
inline TweenHelper& SetDuration(Duration dur) { base->SetDuration(dur); return (*this); }
|
||||
|
||||
// 设置循环次数
|
||||
inline TweenHelper& SetLoops(int loops) { base->SetLoops(loops); return (*this); }
|
||||
|
||||
// 设置缓动函数
|
||||
inline TweenHelper& SetEaseFunc(EaseFunc ease) { base->SetEaseFunc(ease); return (*this); }
|
||||
|
||||
// 设置动作延迟
|
||||
inline TweenHelper& SetDelay(Duration delay) { base->SetDelay(delay); return (*this); }
|
||||
|
||||
// 设置动作结束回调函数
|
||||
inline TweenHelper& SetDoneCallback(ActionCallback const& cb) { base->SetDoneCallback(cb); return (*this); }
|
||||
|
||||
// 设置动作循环结束时的回调函数
|
||||
inline TweenHelper& SetLoopDoneCallback(ActionCallback const& cb) { base->SetLoopDoneCallback(cb); return (*this); }
|
||||
|
||||
// 动作结束时移除目标节点
|
||||
inline TweenHelper& RemoveTargetWhenDone() { base->RemoveTargetWhenDone(); return (*this); }
|
||||
|
||||
// 设置名称
|
||||
inline TweenHelper& SetName(String const& name) { base->SetName(name); return (*this); }
|
||||
|
||||
// 获取指针
|
||||
inline ActionTweenPtr const& Get() const { return base; }
|
||||
|
||||
inline TweenHelper(ActionTweenPtr const& base) : base(base) {}
|
||||
|
||||
inline operator ActionPtr() const { return base; }
|
||||
|
||||
protected:
|
||||
ActionTweenPtr base;
|
||||
};
|
||||
|
||||
// Tween actions helper
|
||||
struct Tween
|
||||
{
|
||||
public:
|
||||
static inline TweenHelper
|
||||
MoveBy(Point const& vector)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionMoveBy(0, vector));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
MoveTo(Point const& pos)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionMoveTo(0, pos));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
JumpBy(
|
||||
Point const& pos, /* 目的坐标 */
|
||||
float height, /* 跳跃高度 */
|
||||
int jumps = 1) /* 跳跃次数 */
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionJumpBy(0, pos, height, jumps));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
JumpTo(
|
||||
Point const& pos, /* 目的坐标 */
|
||||
float height, /* 跳跃高度 */
|
||||
int jumps = 1) /* 跳跃次数 */
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionJumpTo(0, pos, height, jumps));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
ScaleBy(float scale)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionScaleBy(0, scale));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
ScaleBy(float scale_x, float scale_y)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionScaleBy(0, scale_x, scale_y));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
ScaleTo(float scale)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionScaleTo(0, scale));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
ScaleTo(float scale_x, float scale_y)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionScaleTo(0, scale_x, scale_y));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
OpacityBy(float opacity)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionOpacityBy(0, opacity));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
OpacityTo(float opacity)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionOpacityTo(0, opacity));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
FadeIn(Duration dur)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionFadeIn(dur));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
FadeOut(Duration dur)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionFadeOut(dur));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
RotateBy(float rotation)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionRotateBy(0, rotation));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
RotateTo(float rotation)
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionRotateTo(0, rotation));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
Path(
|
||||
GeometryPtr const& geo, /* 几何图形 */
|
||||
bool rotating = false, /* 沿路径切线方向旋转 */
|
||||
float start = 0.f, /* 起点 */
|
||||
float end = 1.f) /* 终点 */
|
||||
{
|
||||
return TweenHelper(new easy2d::ActionPath(0, geo, rotating, start, end));
|
||||
}
|
||||
|
||||
static inline TweenHelper
|
||||
Animation(FramesPtr const& frames)
|
||||
{
|
||||
return TweenHelper(new easy2d::Animation(0, frames));
|
||||
}
|
||||
|
||||
static inline ActionHelper
|
||||
Group(Array<ActionPtr> const& actions, bool sequence = true)
|
||||
{
|
||||
return ActionHelper(new easy2d::ActionGroup(actions, sequence));
|
||||
}
|
||||
|
||||
static inline ActionHelper
|
||||
Multiple(Array<ActionPtr> const& actions)
|
||||
{
|
||||
return ActionHelper(new easy2d::ActionGroup(actions, false));
|
||||
}
|
||||
|
||||
E2D_DEPRECATED("Tween::Sequence is deprecated, use Tween::Group instead")
|
||||
static inline ActionHelper
|
||||
Sequence(Array<ActionPtr> const& actions)
|
||||
{
|
||||
return ActionHelper(new easy2d::ActionGroup(actions, true));
|
||||
}
|
||||
|
||||
E2D_DEPRECATED("Tween::Spawn is deprecated, use Tween::Multiple instead")
|
||||
static inline ActionHelper
|
||||
Spawn(Array<ActionPtr> const& actions)
|
||||
{
|
||||
return ActionHelper(new easy2d::ActionGroup(actions, false));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "ActionManager.h"
|
||||
#include "../base/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
void ActionManager::UpdateActions(NodePtr const& target, Duration dt)
|
||||
{
|
||||
if (actions_.IsEmpty() || !target)
|
||||
return;
|
||||
|
||||
ActionPtr next;
|
||||
for (auto action = actions_.First(); action; action = next)
|
||||
{
|
||||
next = action->NextItem();
|
||||
|
||||
if (action->IsRunning())
|
||||
action->UpdateStep(target, dt);
|
||||
|
||||
if (action->IsRemoveable())
|
||||
actions_.Remove(action);
|
||||
}
|
||||
}
|
||||
|
||||
ActionPtr ActionManager::AddAction(ActionPtr const& action)
|
||||
{
|
||||
E2D_ASSERT(action && "AddAction failed, NULL pointer exception");
|
||||
|
||||
if (action)
|
||||
{
|
||||
actions_.PushBack(action);
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
ActionPtr ActionManager::GetAction(String const & name)
|
||||
{
|
||||
if (actions_.IsEmpty())
|
||||
return nullptr;
|
||||
|
||||
for (auto action = actions_.First().Get(); action; action = action->NextItem().Get())
|
||||
if (action->IsName(name))
|
||||
return action;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ActionManager::ResumeAllActions()
|
||||
{
|
||||
if (actions_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (auto action = actions_.First().Get(); action; action = action->NextItem().Get())
|
||||
{
|
||||
action->Resume();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionManager::PauseAllActions()
|
||||
{
|
||||
if (actions_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (auto action = actions_.First().Get(); action; action = action->NextItem().Get())
|
||||
{
|
||||
action->Pause();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionManager::StopAllActions()
|
||||
{
|
||||
if (actions_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (auto action = actions_.First().Get(); action; action = action->NextItem().Get())
|
||||
{
|
||||
action->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
const ActionManager::Actions& ActionManager::GetAllActions() const
|
||||
{
|
||||
return actions_;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Action.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API ActionManager
|
||||
{
|
||||
using Actions = IntrusiveList<ActionPtr>;
|
||||
|
||||
public:
|
||||
// 添加动作
|
||||
ActionPtr AddAction(
|
||||
ActionPtr const& action
|
||||
);
|
||||
|
||||
// 获取动作
|
||||
ActionPtr GetAction(
|
||||
String const& name
|
||||
);
|
||||
|
||||
// 继续所有暂停动作
|
||||
void ResumeAllActions();
|
||||
|
||||
// 暂停所有动作
|
||||
void PauseAllActions();
|
||||
|
||||
// 停止所有动作
|
||||
void StopAllActions();
|
||||
|
||||
// 获取所有动作
|
||||
Actions const& GetAllActions() const;
|
||||
|
||||
protected:
|
||||
void UpdateActions(NodePtr const& target, Duration dt);
|
||||
|
||||
protected:
|
||||
Actions actions_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,480 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "ActionTween.h"
|
||||
#include "include-forwards.h"
|
||||
#include "Node.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
//-------------------------------------------------------
|
||||
// Ease Functions
|
||||
//-------------------------------------------------------
|
||||
|
||||
EaseFunc Ease::Linear = math::Linear;
|
||||
EaseFunc Ease::EaseIn = MakeEaseIn(2.f);
|
||||
EaseFunc Ease::EaseOut = MakeEaseOut(2.f);
|
||||
EaseFunc Ease::EaseInOut = MakeEaseInOut(2.f);
|
||||
EaseFunc Ease::ExpoIn = math::EaseExponentialIn;
|
||||
EaseFunc Ease::ExpoOut = math::EaseExponentialOut;
|
||||
EaseFunc Ease::ExpoInOut = math::EaseExponentialInOut;
|
||||
EaseFunc Ease::BounceIn = math::EaseBounceIn;
|
||||
EaseFunc Ease::BounceOut = math::EaseBounceOut;
|
||||
EaseFunc Ease::BounceInOut = math::EaseBounceInOut;
|
||||
EaseFunc Ease::ElasticIn = MakeEaseElasticIn(0.3f);
|
||||
EaseFunc Ease::ElasticOut = MakeEaseElasticOut(0.3f);
|
||||
EaseFunc Ease::ElasticInOut = MakeEaseElasticInOut(0.3f);
|
||||
EaseFunc Ease::SineIn = math::EaseSineIn;
|
||||
EaseFunc Ease::SineOut = math::EaseSineOut;
|
||||
EaseFunc Ease::SineInOut = math::EaseSineInOut;
|
||||
EaseFunc Ease::BackIn = math::EaseBackIn;
|
||||
EaseFunc Ease::BackOut = math::EaseBackOut;
|
||||
EaseFunc Ease::BackInOut = math::EaseBackInOut;
|
||||
EaseFunc Ease::QuadIn = math::EaseQuadIn;
|
||||
EaseFunc Ease::QuadOut = math::EaseQuadOut;
|
||||
EaseFunc Ease::QuadInOut = math::EaseQuadInOut;
|
||||
EaseFunc Ease::CubicIn = math::EaseCubicIn;
|
||||
EaseFunc Ease::CubicOut = math::EaseCubicOut;
|
||||
EaseFunc Ease::CubicInOut = math::EaseCubicInOut;
|
||||
EaseFunc Ease::QuartIn = math::EaseQuartIn;
|
||||
EaseFunc Ease::QuartOut = math::EaseQuartOut;
|
||||
EaseFunc Ease::QuartInOut = math::EaseQuartInOut;
|
||||
EaseFunc Ease::QuintIn = math::EaseQuintIn;
|
||||
EaseFunc Ease::QuintOut = math::EaseQuintOut;
|
||||
EaseFunc Ease::QuintInOut = math::EaseQuintInOut;
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ActionTween
|
||||
//-------------------------------------------------------
|
||||
|
||||
ActionTween::ActionTween()
|
||||
: dur_()
|
||||
, ease_func_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ActionTween::ActionTween(Duration duration, EaseFunc func)
|
||||
{
|
||||
SetDuration(duration);
|
||||
SetEaseFunc(func);
|
||||
}
|
||||
|
||||
void ActionTween::SetEaseFunc(EaseFunc const& func)
|
||||
{
|
||||
ease_func_ = func;
|
||||
}
|
||||
|
||||
EaseFunc const & ActionTween::GetEaseFunc() const
|
||||
{
|
||||
return ease_func_;
|
||||
}
|
||||
|
||||
Duration ActionTween::GetDuration() const
|
||||
{
|
||||
return dur_;
|
||||
}
|
||||
|
||||
void ActionTween::Update(NodePtr const& target, Duration dt)
|
||||
{
|
||||
float percent;
|
||||
|
||||
if (dur_.IsZero())
|
||||
{
|
||||
percent = 1.f;
|
||||
Complete(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
Duration elapsed = elapsed_ - delay_;
|
||||
float loops_done = elapsed / dur_;
|
||||
|
||||
while (loops_done_ < static_cast<int>(loops_done))
|
||||
{
|
||||
Complete(target); // loops_done_++
|
||||
}
|
||||
|
||||
percent = (status_ == Status::Done) ? 1.f : (loops_done - static_cast<float>(loops_done_));
|
||||
}
|
||||
|
||||
if (ease_func_)
|
||||
percent = ease_func_(percent);
|
||||
|
||||
UpdateTween(target, percent);
|
||||
}
|
||||
|
||||
void ActionTween::SetDuration(Duration duration)
|
||||
{
|
||||
dur_ = duration;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Move Action
|
||||
//-------------------------------------------------------
|
||||
|
||||
ActionMoveBy::ActionMoveBy(Duration duration, Point const& vector, EaseFunc func)
|
||||
: ActionTween(duration, func)
|
||||
{
|
||||
delta_pos_ = vector;
|
||||
}
|
||||
|
||||
void ActionMoveBy::Init(NodePtr const& target)
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
prev_pos_ = start_pos_ = target->GetPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMoveBy::UpdateTween(NodePtr const& target, float percent)
|
||||
{
|
||||
Point diff = target->GetPosition() - prev_pos_;
|
||||
start_pos_ = start_pos_ + diff;
|
||||
|
||||
Point new_pos = start_pos_ + (delta_pos_ * percent);
|
||||
target->SetPosition(new_pos);
|
||||
|
||||
prev_pos_ = new_pos;
|
||||
}
|
||||
|
||||
ActionPtr ActionMoveBy::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionMoveBy(dur_, delta_pos_, ease_func_);
|
||||
}
|
||||
|
||||
ActionPtr ActionMoveBy::Reverse() const
|
||||
{
|
||||
return new (std::nothrow) ActionMoveBy(dur_, -delta_pos_, ease_func_);
|
||||
}
|
||||
|
||||
ActionMoveTo::ActionMoveTo(Duration duration, Point const& pos, EaseFunc func)
|
||||
: ActionMoveBy(duration, Point(), func)
|
||||
{
|
||||
end_pos_ = pos;
|
||||
}
|
||||
|
||||
ActionPtr ActionMoveTo::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionMoveTo(dur_, end_pos_, ease_func_);
|
||||
}
|
||||
|
||||
void ActionMoveTo::Init(NodePtr const& target)
|
||||
{
|
||||
ActionMoveBy::Init(target);
|
||||
delta_pos_ = end_pos_ - start_pos_;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Jump Action
|
||||
//-------------------------------------------------------
|
||||
|
||||
ActionJumpBy::ActionJumpBy(Duration duration, Point const& vec, float height, int jumps, EaseFunc func)
|
||||
: ActionTween(duration, func)
|
||||
, delta_pos_(vec)
|
||||
, height_(height)
|
||||
, jumps_(jumps)
|
||||
{
|
||||
}
|
||||
|
||||
ActionPtr ActionJumpBy::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionJumpBy(dur_, delta_pos_, height_, jumps_, ease_func_);
|
||||
}
|
||||
|
||||
ActionPtr ActionJumpBy::Reverse() const
|
||||
{
|
||||
return new (std::nothrow) ActionJumpBy(dur_, -delta_pos_, height_, jumps_, ease_func_);
|
||||
}
|
||||
|
||||
void ActionJumpBy::Init(NodePtr const& target)
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
prev_pos_ = start_pos_ = target->GetPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionJumpBy::UpdateTween(NodePtr const& target, float percent)
|
||||
{
|
||||
float frac = fmod(percent * jumps_, 1.f);
|
||||
float x = delta_pos_.x * percent;
|
||||
float y = height_ * 4 * frac * (1 - frac);
|
||||
y += delta_pos_.y * percent;
|
||||
|
||||
Point diff = target->GetPosition() - prev_pos_;
|
||||
start_pos_ = diff + start_pos_;
|
||||
|
||||
Point new_pos = start_pos_ + Point(x, y);
|
||||
target->SetPosition(new_pos);
|
||||
|
||||
prev_pos_ = new_pos;
|
||||
}
|
||||
|
||||
ActionJumpTo::ActionJumpTo(Duration duration, Point const& pos, float height, int jumps, EaseFunc func)
|
||||
: ActionJumpBy(duration, Point(), height, jumps, func)
|
||||
, end_pos_(pos)
|
||||
{
|
||||
}
|
||||
|
||||
ActionPtr ActionJumpTo::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionJumpTo(dur_, end_pos_, height_, jumps_, ease_func_);
|
||||
}
|
||||
|
||||
void ActionJumpTo::Init(NodePtr const& target)
|
||||
{
|
||||
ActionJumpBy::Init(target);
|
||||
delta_pos_ = end_pos_ - start_pos_;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Scale Action
|
||||
//-------------------------------------------------------
|
||||
|
||||
ActionScaleBy::ActionScaleBy(Duration duration, float scale, EaseFunc func)
|
||||
: ActionTween(duration, func)
|
||||
{
|
||||
delta_x_ = scale;
|
||||
delta_y_ = scale;
|
||||
}
|
||||
|
||||
ActionScaleBy::ActionScaleBy(Duration duration, float scale_x, float scale_y, EaseFunc func)
|
||||
: ActionTween(duration, func)
|
||||
{
|
||||
delta_x_ = scale_x;
|
||||
delta_y_ = scale_y;
|
||||
}
|
||||
|
||||
void ActionScaleBy::Init(NodePtr const& target)
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
start_scale_x_ = target->GetScaleX();
|
||||
start_scale_y_ = target->GetScaleY();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionScaleBy::UpdateTween(NodePtr const& target, float percent)
|
||||
{
|
||||
target->SetScale(start_scale_x_ + delta_x_ * percent, start_scale_y_ + delta_y_ * percent);
|
||||
}
|
||||
|
||||
ActionPtr ActionScaleBy::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionScaleBy(dur_, delta_x_, delta_y_, ease_func_);
|
||||
}
|
||||
|
||||
ActionPtr ActionScaleBy::Reverse() const
|
||||
{
|
||||
return new (std::nothrow) ActionScaleBy(dur_, -delta_x_, -delta_y_, ease_func_);
|
||||
}
|
||||
|
||||
ActionScaleTo::ActionScaleTo(Duration duration, float scale, EaseFunc func)
|
||||
: ActionScaleBy(duration, 0, 0, func)
|
||||
{
|
||||
end_scale_x_ = scale;
|
||||
end_scale_y_ = scale;
|
||||
}
|
||||
|
||||
ActionScaleTo::ActionScaleTo(Duration duration, float scale_x, float scale_y, EaseFunc func)
|
||||
: ActionScaleBy(duration, 0, 0, func)
|
||||
{
|
||||
end_scale_x_ = scale_x;
|
||||
end_scale_y_ = scale_y;
|
||||
}
|
||||
|
||||
ActionPtr ActionScaleTo::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionScaleTo(dur_, end_scale_x_, end_scale_y_, ease_func_);
|
||||
}
|
||||
|
||||
void ActionScaleTo::Init(NodePtr const& target)
|
||||
{
|
||||
ActionScaleBy::Init(target);
|
||||
delta_x_ = end_scale_x_ - start_scale_x_;
|
||||
delta_y_ = end_scale_y_ - start_scale_y_;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Opacity Action
|
||||
//-------------------------------------------------------
|
||||
|
||||
ActionOpacityBy::ActionOpacityBy(Duration duration, float opacity, EaseFunc func)
|
||||
: ActionTween(duration, func)
|
||||
{
|
||||
delta_val_ = opacity;
|
||||
}
|
||||
|
||||
void ActionOpacityBy::Init(NodePtr const& target)
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
start_val_ = target->GetOpacity();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionOpacityBy::UpdateTween(NodePtr const& target, float percent)
|
||||
{
|
||||
target->SetOpacity(start_val_ + delta_val_ * percent);
|
||||
}
|
||||
|
||||
ActionPtr ActionOpacityBy::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionOpacityBy(dur_, delta_val_, ease_func_);
|
||||
}
|
||||
|
||||
ActionPtr ActionOpacityBy::Reverse() const
|
||||
{
|
||||
return new (std::nothrow) ActionOpacityBy(dur_, -delta_val_, ease_func_);
|
||||
}
|
||||
|
||||
ActionOpacityTo::ActionOpacityTo(Duration duration, float opacity, EaseFunc func)
|
||||
: ActionOpacityBy(duration, 0, func)
|
||||
{
|
||||
end_val_ = opacity;
|
||||
}
|
||||
|
||||
ActionPtr ActionOpacityTo::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionOpacityTo(dur_, end_val_, ease_func_);
|
||||
}
|
||||
|
||||
void ActionOpacityTo::Init(NodePtr const& target)
|
||||
{
|
||||
ActionOpacityBy::Init(target);
|
||||
delta_val_ = end_val_ - start_val_;
|
||||
}
|
||||
|
||||
ActionFadeIn::ActionFadeIn(Duration duration, EaseFunc func)
|
||||
: ActionOpacityTo(duration, 1, func)
|
||||
{
|
||||
}
|
||||
|
||||
ActionFadeOut::ActionFadeOut(Duration duration, EaseFunc func)
|
||||
: ActionOpacityTo(duration, 0, func)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Rotate Action
|
||||
//-------------------------------------------------------
|
||||
|
||||
ActionRotateBy::ActionRotateBy(Duration duration, float rotation, EaseFunc func)
|
||||
: ActionTween(duration, func)
|
||||
, delta_val_(rotation)
|
||||
{
|
||||
}
|
||||
|
||||
void ActionRotateBy::Init(NodePtr const& target)
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
start_val_ = target->GetRotation();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionRotateBy::UpdateTween(NodePtr const& target, float percent)
|
||||
{
|
||||
float rotation = start_val_ + delta_val_ * percent;
|
||||
if (rotation > 360.f)
|
||||
rotation -= 360.f;
|
||||
|
||||
target->SetRotation(rotation);
|
||||
}
|
||||
|
||||
ActionPtr ActionRotateBy::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionRotateBy(dur_, delta_val_, ease_func_);
|
||||
}
|
||||
|
||||
ActionPtr ActionRotateBy::Reverse() const
|
||||
{
|
||||
return new (std::nothrow) ActionRotateBy(dur_, -delta_val_, ease_func_);
|
||||
}
|
||||
|
||||
ActionRotateTo::ActionRotateTo(Duration duration, float rotation, EaseFunc func)
|
||||
: ActionRotateBy(duration, 0, func)
|
||||
{
|
||||
end_val_ = rotation;
|
||||
}
|
||||
|
||||
ActionPtr ActionRotateTo::Clone() const
|
||||
{
|
||||
return new (std::nothrow) ActionRotateTo(dur_, end_val_, ease_func_);
|
||||
}
|
||||
|
||||
void ActionRotateTo::Init(NodePtr const& target)
|
||||
{
|
||||
ActionRotateBy::Init(target);
|
||||
delta_val_ = end_val_ - start_val_;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ActionPath
|
||||
//-------------------------------------------------------
|
||||
|
||||
ActionPath::ActionPath(Duration duration, GeometryPtr const& geo, bool rotating, float start, float end, EaseFunc func)
|
||||
: ActionTween(duration, func)
|
||||
, start_(start)
|
||||
, end_(end)
|
||||
, geo_(geo)
|
||||
, rotating_(rotating)
|
||||
{
|
||||
}
|
||||
|
||||
ActionPtr ActionPath::Clone() const
|
||||
{
|
||||
return new ActionPath(dur_, geo_, rotating_, start_, end_, ease_func_);
|
||||
}
|
||||
|
||||
ActionPtr ActionPath::Reverse() const
|
||||
{
|
||||
return new ActionPath(dur_, geo_, rotating_, end_, start_, ease_func_);
|
||||
}
|
||||
|
||||
void ActionPath::Init(NodePtr const& target)
|
||||
{
|
||||
start_pos_ = target->GetPosition();
|
||||
}
|
||||
|
||||
void ActionPath::UpdateTween(NodePtr const& target, float percent)
|
||||
{
|
||||
float length = geo_->GetLength() * std::min(std::max((end_ - start_) * percent + start_, 0.f), 1.f);
|
||||
|
||||
Point point, tangent;
|
||||
if (geo_->ComputePointAt(length, &point, &tangent))
|
||||
{
|
||||
target->SetPosition(start_pos_ + point);
|
||||
|
||||
if (rotating_)
|
||||
{
|
||||
float ac = math::Acos(tangent.x);
|
||||
float rotation = (tangent.y < 0.f) ? 360.f - ac : ac;
|
||||
target->SetRotation(rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,478 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Action.h"
|
||||
#include "Geometry.h" // ActionPath
|
||||
#include "../base/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 缓动函数
|
||||
using EaseFunc = std::function<float(float)>;
|
||||
|
||||
// 缓动函数枚举
|
||||
// See https://easings.net for more information
|
||||
struct Ease
|
||||
{
|
||||
static E2D_API EaseFunc Linear; // 线性
|
||||
static E2D_API EaseFunc EaseIn; // 由慢变快
|
||||
static E2D_API EaseFunc EaseOut; // 由快变慢
|
||||
static E2D_API EaseFunc EaseInOut; // 由慢变快, 再由快变慢
|
||||
static E2D_API EaseFunc ExpoIn; // 由慢变极快
|
||||
static E2D_API EaseFunc ExpoOut; // 由极快变慢
|
||||
static E2D_API EaseFunc ExpoInOut; // 由慢至极快, 再由极快边慢
|
||||
static E2D_API EaseFunc ElasticIn; // 自起点赋予弹性
|
||||
static E2D_API EaseFunc ElasticOut; // 自终点赋予弹性
|
||||
static E2D_API EaseFunc ElasticInOut; // 再起点和终点赋予弹性
|
||||
static E2D_API EaseFunc BounceIn; // 自起点赋予反弹力
|
||||
static E2D_API EaseFunc BounceOut; // 自终点赋予反弹力
|
||||
static E2D_API EaseFunc BounceInOut; // 在起点和终点赋予反弹力
|
||||
static E2D_API EaseFunc BackIn;
|
||||
static E2D_API EaseFunc BackOut;
|
||||
static E2D_API EaseFunc BackInOut;
|
||||
static E2D_API EaseFunc QuadIn;
|
||||
static E2D_API EaseFunc QuadOut;
|
||||
static E2D_API EaseFunc QuadInOut;
|
||||
static E2D_API EaseFunc CubicIn;
|
||||
static E2D_API EaseFunc CubicOut;
|
||||
static E2D_API EaseFunc CubicInOut;
|
||||
static E2D_API EaseFunc QuartIn;
|
||||
static E2D_API EaseFunc QuartOut;
|
||||
static E2D_API EaseFunc QuartInOut;
|
||||
static E2D_API EaseFunc QuintIn;
|
||||
static E2D_API EaseFunc QuintOut;
|
||||
static E2D_API EaseFunc QuintInOut;
|
||||
static E2D_API EaseFunc SineIn;
|
||||
static E2D_API EaseFunc SineOut;
|
||||
static E2D_API EaseFunc SineInOut;
|
||||
};
|
||||
|
||||
inline EaseFunc MakeEaseIn(float rate) { return std::bind(math::EaseIn, std::placeholders::_1, rate); }
|
||||
inline EaseFunc MakeEaseOut(float rate) { return std::bind(math::EaseOut, std::placeholders::_1, rate); }
|
||||
inline EaseFunc MakeEaseInOut(float rate) { return std::bind(math::EaseInOut, std::placeholders::_1, rate); }
|
||||
inline EaseFunc MakeEaseElasticIn(float period) { return std::bind(math::EaseElasticIn, std::placeholders::_1, period); }
|
||||
inline EaseFunc MakeEaseElasticOut(float period) { return std::bind(math::EaseElasticOut, std::placeholders::_1, period); }
|
||||
inline EaseFunc MakeEaseElasticInOut(float period) { return std::bind(math::EaseElasticInOut, std::placeholders::_1, period); }
|
||||
|
||||
|
||||
// 补间动画
|
||||
class E2D_API ActionTween
|
||||
: public Action
|
||||
{
|
||||
public:
|
||||
ActionTween();
|
||||
|
||||
ActionTween(
|
||||
Duration duration,
|
||||
EaseFunc func
|
||||
);
|
||||
|
||||
// 自定义缓动函数
|
||||
void SetEaseFunc(
|
||||
EaseFunc const& func
|
||||
);
|
||||
|
||||
EaseFunc const& GetEaseFunc() const;
|
||||
|
||||
Duration GetDuration() const;
|
||||
|
||||
void SetDuration(Duration duration);
|
||||
|
||||
protected:
|
||||
void Update(NodePtr const& target, Duration dt) override;
|
||||
|
||||
virtual void UpdateTween(NodePtr const& target, float percent) = 0;
|
||||
|
||||
protected:
|
||||
Duration dur_;
|
||||
EaseFunc ease_func_;
|
||||
};
|
||||
|
||||
|
||||
// 相对位移动作
|
||||
class E2D_API ActionMoveBy
|
||||
: public ActionTween
|
||||
{
|
||||
public:
|
||||
ActionMoveBy(
|
||||
Duration duration, /* 持续时长 */
|
||||
Point const& vector, /* 移动距离 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
ActionPtr Reverse() const override;
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
void UpdateTween(NodePtr const& target, float percent) override;
|
||||
|
||||
protected:
|
||||
Point start_pos_;
|
||||
Point prev_pos_;
|
||||
Point delta_pos_;
|
||||
};
|
||||
|
||||
|
||||
// 位移动作
|
||||
class E2D_API ActionMoveTo
|
||||
: public ActionMoveBy
|
||||
{
|
||||
public:
|
||||
ActionMoveTo(
|
||||
Duration duration, /* 持续时长 */
|
||||
Point const& pos, /* 目的坐标 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
virtual ActionPtr Reverse() const override
|
||||
{
|
||||
E2D_ERROR_LOG(L"Reverse() not supported in ActionMoveTo");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
protected:
|
||||
Point end_pos_;
|
||||
};
|
||||
|
||||
|
||||
// 相对跳跃动作
|
||||
class E2D_API ActionJumpBy
|
||||
: public ActionTween
|
||||
{
|
||||
public:
|
||||
ActionJumpBy(
|
||||
Duration duration, /* 持续时长 */
|
||||
Point const& vec, /* 跳跃距离 */
|
||||
float height, /* 跳跃高度 */
|
||||
int jumps = 1, /* 跳跃次数 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
ActionPtr Reverse() const override;
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
void UpdateTween(NodePtr const& target, float percent) override;
|
||||
|
||||
protected:
|
||||
Point start_pos_;
|
||||
Point delta_pos_;
|
||||
float height_;
|
||||
int jumps_;
|
||||
Point prev_pos_;
|
||||
};
|
||||
|
||||
|
||||
// 跳跃动作
|
||||
class E2D_API ActionJumpTo
|
||||
: public ActionJumpBy
|
||||
{
|
||||
public:
|
||||
ActionJumpTo(
|
||||
Duration duration, /* 持续时长 */
|
||||
Point const& pos, /* 目的坐标 */
|
||||
float height, /* 跳跃高度 */
|
||||
int jumps = 1, /* 跳跃次数 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
virtual ActionPtr Reverse() const override
|
||||
{
|
||||
E2D_ERROR_LOG(L"Reverse() not supported in ActionJumpTo");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
protected:
|
||||
Point end_pos_;
|
||||
};
|
||||
|
||||
|
||||
// 相对缩放动作
|
||||
class E2D_API ActionScaleBy
|
||||
: public ActionTween
|
||||
{
|
||||
public:
|
||||
ActionScaleBy(
|
||||
Duration duration, /* 持续时长 */
|
||||
float scale, /* 相对变化值 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
ActionScaleBy(
|
||||
Duration duration, /* 持续时长 */
|
||||
float scale_x, /* 横向缩放相对变化值 */
|
||||
float scale_y, /* 纵向缩放相对变化值 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
ActionPtr Reverse() const override;
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
void UpdateTween(NodePtr const& target, float percent) override;
|
||||
|
||||
protected:
|
||||
float start_scale_x_;
|
||||
float start_scale_y_;
|
||||
float delta_x_;
|
||||
float delta_y_;
|
||||
};
|
||||
|
||||
|
||||
// 缩放动作
|
||||
class E2D_API ActionScaleTo
|
||||
: public ActionScaleBy
|
||||
{
|
||||
public:
|
||||
ActionScaleTo(
|
||||
Duration duration, /* 持续时长 */
|
||||
float scale, /* 目标值 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
ActionScaleTo(
|
||||
Duration duration, /* 持续时长 */
|
||||
float scale_x, /* 横向缩放目标值 */
|
||||
float scale_y, /* 纵向缩放目标值 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
virtual ActionPtr Reverse() const override
|
||||
{
|
||||
E2D_ERROR_LOG(L"Reverse() not supported in ActionScaleTo");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
protected:
|
||||
float end_scale_x_;
|
||||
float end_scale_y_;
|
||||
};
|
||||
|
||||
|
||||
// 透明度相对渐变动作
|
||||
class E2D_API ActionOpacityBy
|
||||
: public ActionTween
|
||||
{
|
||||
public:
|
||||
ActionOpacityBy(
|
||||
Duration duration, /* 持续时长 */
|
||||
float opacity, /* 相对变化值 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
ActionPtr Reverse() const override;
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
void UpdateTween(NodePtr const& target, float percent) override;
|
||||
|
||||
protected:
|
||||
float start_val_;
|
||||
float delta_val_;
|
||||
};
|
||||
|
||||
|
||||
// 透明度渐变动作
|
||||
class E2D_API ActionOpacityTo
|
||||
: public ActionOpacityBy
|
||||
{
|
||||
public:
|
||||
ActionOpacityTo(
|
||||
Duration duration, /* 持续时长 */
|
||||
float opacity, /* 目标值 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
virtual ActionPtr Reverse() const override
|
||||
{
|
||||
E2D_ERROR_LOG(L"Reverse() not supported in ActionOpacityTo");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
protected:
|
||||
float end_val_;
|
||||
};
|
||||
|
||||
|
||||
// 淡入动作
|
||||
class E2D_API ActionFadeIn
|
||||
: public ActionOpacityTo
|
||||
{
|
||||
public:
|
||||
// 创建淡入动作
|
||||
explicit ActionFadeIn(
|
||||
Duration duration, /* 持续时长 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// 淡出动作
|
||||
class E2D_API ActionFadeOut
|
||||
: public ActionOpacityTo
|
||||
{
|
||||
public:
|
||||
// 创建淡出动作
|
||||
explicit ActionFadeOut(
|
||||
Duration duration, /* 持续时长 */
|
||||
EaseFunc func = Ease::Linear /* 速度变化 */
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// 相对旋转动作
|
||||
class E2D_API ActionRotateBy
|
||||
: public ActionTween
|
||||
{
|
||||
public:
|
||||
ActionRotateBy(
|
||||
Duration duration, /* 持续时长 */
|
||||
float rotation, /* 相对变化值 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
ActionPtr Reverse() const override;
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
void UpdateTween(NodePtr const& target, float percent) override;
|
||||
|
||||
protected:
|
||||
float start_val_;
|
||||
float delta_val_;
|
||||
};
|
||||
|
||||
|
||||
// 旋转动作
|
||||
class E2D_API ActionRotateTo
|
||||
: public ActionRotateBy
|
||||
{
|
||||
public:
|
||||
ActionRotateTo(
|
||||
Duration duration, /* 持续时长 */
|
||||
float rotation, /* 目标值 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
virtual ActionPtr Reverse() const override
|
||||
{
|
||||
E2D_ERROR_LOG(L"Reverse() not supported in ActionRotateTo");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
protected:
|
||||
float end_val_;
|
||||
};
|
||||
|
||||
|
||||
// 路径动作
|
||||
class E2D_API ActionPath
|
||||
: public ActionTween
|
||||
{
|
||||
public:
|
||||
ActionPath(
|
||||
Duration duration, /* 持续时长 */
|
||||
GeometryPtr const& geo, /* 几何图形 */
|
||||
bool rotating = false, /* 沿路径切线方向旋转 */
|
||||
float start = 0.f, /* 起点 */
|
||||
float end = 1.f, /* 终点 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
ActionPtr Reverse() const override;
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
void UpdateTween(NodePtr const& target, float percent) override;
|
||||
|
||||
protected:
|
||||
bool rotating_;
|
||||
float start_;
|
||||
float end_;
|
||||
Point start_pos_;
|
||||
GeometryPtr geo_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Animation.h"
|
||||
#include "Frames.h"
|
||||
#include "Image.h"
|
||||
#include "Sprite.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Animation::Animation()
|
||||
: frames_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(Duration duration, FramesPtr const& animation, EaseFunc func)
|
||||
: ActionTween(duration, func)
|
||||
, frames_(nullptr)
|
||||
{
|
||||
this->SetFrames(animation);
|
||||
}
|
||||
|
||||
Animation::~Animation()
|
||||
{
|
||||
}
|
||||
|
||||
FramesPtr Animation::GetFrames() const
|
||||
{
|
||||
return frames_;
|
||||
}
|
||||
|
||||
void Animation::SetFrames(FramesPtr const& frames)
|
||||
{
|
||||
frames_ = frames;
|
||||
}
|
||||
|
||||
void Animation::Init(NodePtr const& target)
|
||||
{
|
||||
if (!frames_ || frames_->GetFrames().empty())
|
||||
{
|
||||
Done();
|
||||
return;
|
||||
}
|
||||
|
||||
auto sprite_target = dynamic_cast<Sprite*>(target.Get());
|
||||
if (sprite_target && frames_)
|
||||
{
|
||||
sprite_target->Load(frames_->GetFrames()[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::UpdateTween(NodePtr const& target, float percent)
|
||||
{
|
||||
auto sprite_target = dynamic_cast<Sprite*>(target.Get());
|
||||
|
||||
E2D_ASSERT(sprite_target && "Animation only supports Sprites");
|
||||
|
||||
const auto& frames = frames_->GetFrames();
|
||||
int size = frames.size();
|
||||
int index = std::min(static_cast<int>(math::Floor(size * percent)), size - 1);
|
||||
|
||||
sprite_target->Load(frames[index]);
|
||||
}
|
||||
|
||||
ActionPtr Animation::Clone() const
|
||||
{
|
||||
if (frames_)
|
||||
{
|
||||
return new (std::nothrow) Animation(dur_, frames_, ease_func_);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ActionPtr Animation::Reverse() const
|
||||
{
|
||||
if (frames_)
|
||||
{
|
||||
FramesPtr frames = frames_->Reverse();
|
||||
if (frames)
|
||||
{
|
||||
return new (std::nothrow) Animation(dur_, frames, ease_func_);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "ActionTween.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 帧动画
|
||||
class E2D_API Animation
|
||||
: public ActionTween
|
||||
{
|
||||
public:
|
||||
Animation();
|
||||
|
||||
Animation(
|
||||
Duration duration, /* 动画时长 */
|
||||
FramesPtr const& frames, /* 序列帧 */
|
||||
EaseFunc func = nullptr /* 速度变化 */
|
||||
);
|
||||
|
||||
virtual ~Animation();
|
||||
|
||||
// 获取动画
|
||||
FramesPtr GetFrames() const;
|
||||
|
||||
// 设置动画
|
||||
void SetFrames(
|
||||
FramesPtr const& frames
|
||||
);
|
||||
|
||||
// 获取该动作的拷贝对象
|
||||
ActionPtr Clone() const override;
|
||||
|
||||
// 获取该动作的倒转
|
||||
ActionPtr Reverse() const override;
|
||||
|
||||
protected:
|
||||
void Init(NodePtr const& target) override;
|
||||
|
||||
void UpdateTween(NodePtr const& target, float percent) override;
|
||||
|
||||
protected:
|
||||
FramesPtr frames_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,505 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Canvas.h"
|
||||
#include "Image.h"
|
||||
#include "Geometry.h"
|
||||
#include "../base/logs.h"
|
||||
#include "../renderer/render.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Canvas::Canvas()
|
||||
: cache_expired_(false)
|
||||
, stroke_width_(1.0f)
|
||||
{
|
||||
auto ctx = Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext();
|
||||
|
||||
ThrowIfFailed(
|
||||
ctx->CreateCompatibleRenderTarget(&render_target_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
render_target_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(0, 0, 0, 0),
|
||||
D2D1::BrushProperties(),
|
||||
&fill_brush_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
render_target_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(Color::White),
|
||||
D2D1::BrushProperties(),
|
||||
&stroke_brush_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
ITextRenderer::Create(
|
||||
&text_renderer_,
|
||||
render_target_.Get()
|
||||
)
|
||||
);
|
||||
|
||||
SetTextStyle(Font{}, TextStyle{});
|
||||
}
|
||||
|
||||
Canvas::Canvas(float width, float height)
|
||||
: Canvas()
|
||||
{
|
||||
this->SetSize(width, height);
|
||||
}
|
||||
|
||||
Canvas::Canvas(Size const & size)
|
||||
: Canvas(size.x, size.y)
|
||||
{
|
||||
}
|
||||
|
||||
Canvas::~Canvas()
|
||||
{
|
||||
}
|
||||
|
||||
void Canvas::BeginDraw()
|
||||
{
|
||||
render_target_->BeginDraw();
|
||||
}
|
||||
|
||||
void Canvas::EndDraw()
|
||||
{
|
||||
ThrowIfFailed(
|
||||
render_target_->EndDraw()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::OnRender()
|
||||
{
|
||||
if (cache_expired_)
|
||||
{
|
||||
GetBitmap();
|
||||
}
|
||||
|
||||
if (bitmap_cached_)
|
||||
{
|
||||
Renderer::Instance().DrawBitmap(bitmap_cached_);
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::SetStrokeColor(Color const& color)
|
||||
{
|
||||
stroke_brush_->SetColor(DX::ConvertToColorF(color));
|
||||
}
|
||||
|
||||
void Canvas::SetFillColor(Color const& color)
|
||||
{
|
||||
fill_brush_->SetColor(DX::ConvertToColorF(color));
|
||||
}
|
||||
|
||||
void Canvas::SetStrokeWidth(float width)
|
||||
{
|
||||
stroke_width_ = std::max(width, 0.f);
|
||||
}
|
||||
|
||||
void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join)
|
||||
{
|
||||
outline_join_style_ = Renderer::Instance().GetDeviceResources()->GetStrokeStyle(outline_join);
|
||||
}
|
||||
|
||||
void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style)
|
||||
{
|
||||
text_font_ = font;
|
||||
text_style_ = text_style;
|
||||
|
||||
text_renderer_->SetTextStyle(
|
||||
DX::ConvertToColorF(text_style_.color),
|
||||
text_style_.outline,
|
||||
DX::ConvertToColorF(text_style_.outline_color),
|
||||
text_style_.outline_width,
|
||||
Renderer::Instance().GetDeviceResources()->GetStrokeStyle(text_style_.outline_stroke)
|
||||
);
|
||||
|
||||
// clear text format
|
||||
text_format_ = nullptr;
|
||||
}
|
||||
|
||||
Color Canvas::GetStrokeColor() const
|
||||
{
|
||||
auto color_f = stroke_brush_->GetColor();
|
||||
return Color{ color_f.r, color_f.g, color_f.b, color_f.a };
|
||||
}
|
||||
|
||||
Color Canvas::GetFillColor() const
|
||||
{
|
||||
auto color_f = fill_brush_->GetColor();
|
||||
return Color{ color_f.r, color_f.g, color_f.b, color_f.a };
|
||||
}
|
||||
|
||||
float Canvas::GetStrokeWidth() const
|
||||
{
|
||||
return stroke_width_;
|
||||
}
|
||||
|
||||
void Canvas::SetBrushTransform(Matrix const & transform)
|
||||
{
|
||||
render_target_->SetTransform(DX::ConvertToMatrix3x2F(transform));
|
||||
}
|
||||
|
||||
void Canvas::DrawLine(const Point & begin, const Point & end)
|
||||
{
|
||||
render_target_->DrawLine(
|
||||
D2D1::Point2F(begin.x, begin.y),
|
||||
D2D1::Point2F(end.x, end.y),
|
||||
stroke_brush_.Get(),
|
||||
stroke_width_,
|
||||
outline_join_style_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::DrawCircle(const Point & center, float radius)
|
||||
{
|
||||
render_target_->DrawEllipse(
|
||||
D2D1::Ellipse(
|
||||
D2D1::Point2F(
|
||||
center.x,
|
||||
center.y
|
||||
),
|
||||
radius,
|
||||
radius
|
||||
),
|
||||
stroke_brush_.Get(),
|
||||
stroke_width_,
|
||||
outline_join_style_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::DrawEllipse(const Point & center, float radius_x, float radius_y)
|
||||
{
|
||||
render_target_->DrawEllipse(
|
||||
D2D1::Ellipse(
|
||||
D2D1::Point2F(
|
||||
center.x,
|
||||
center.y
|
||||
),
|
||||
radius_x,
|
||||
radius_y
|
||||
),
|
||||
stroke_brush_.Get(),
|
||||
stroke_width_,
|
||||
outline_join_style_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::DrawRect(const Rect & rect)
|
||||
{
|
||||
render_target_->DrawRectangle(
|
||||
D2D1::RectF(
|
||||
rect.origin.x,
|
||||
rect.origin.y,
|
||||
rect.origin.x + rect.size.x,
|
||||
rect.origin.y + rect.size.y
|
||||
),
|
||||
stroke_brush_.Get(),
|
||||
stroke_width_,
|
||||
outline_join_style_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::DrawRoundedRect(const Rect & rect, float radius_x, float radius_y)
|
||||
{
|
||||
render_target_->DrawRoundedRectangle(
|
||||
D2D1::RoundedRect(
|
||||
D2D1::RectF(
|
||||
rect.origin.x,
|
||||
rect.origin.y,
|
||||
rect.origin.x + rect.size.x,
|
||||
rect.origin.y + rect.size.y
|
||||
),
|
||||
radius_x,
|
||||
radius_y
|
||||
),
|
||||
stroke_brush_.Get(),
|
||||
stroke_width_,
|
||||
outline_join_style_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::DrawImage(ImagePtr const & image, float opacity)
|
||||
{
|
||||
if (image && image->GetBitmap())
|
||||
{
|
||||
render_target_->DrawBitmap(
|
||||
image->GetBitmap().Get(),
|
||||
D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()),
|
||||
opacity,
|
||||
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
|
||||
DX::ConvertToRectF(image->GetCropRect())
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::DrawText(String const & text, Point const & point)
|
||||
{
|
||||
if (text.empty())
|
||||
return;
|
||||
|
||||
if (!text_format_)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
Renderer::Instance().GetDeviceResources()->CreateTextFormat(
|
||||
text_format_,
|
||||
text_font_,
|
||||
text_style_
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
ComPtr<IDWriteTextLayout> text_layout;
|
||||
Size layout_size;
|
||||
ThrowIfFailed(
|
||||
Renderer::Instance().GetDeviceResources()->CreateTextLayout(
|
||||
text_layout,
|
||||
layout_size,
|
||||
text,
|
||||
text_format_,
|
||||
text_style_
|
||||
)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
text_layout->Draw(nullptr, text_renderer_.Get(), point.x, point.y)
|
||||
);
|
||||
}
|
||||
|
||||
void Canvas::DrawGeometry(GeometryPtr const & geo)
|
||||
{
|
||||
if (geo && geo->geo_)
|
||||
{
|
||||
render_target_->DrawGeometry(
|
||||
geo->geo_.Get(),
|
||||
stroke_brush_.Get(),
|
||||
stroke_width_,
|
||||
outline_join_style_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::FillCircle(const Point & center, float radius)
|
||||
{
|
||||
render_target_->FillEllipse(
|
||||
D2D1::Ellipse(
|
||||
D2D1::Point2F(
|
||||
center.x,
|
||||
center.y
|
||||
),
|
||||
radius,
|
||||
radius
|
||||
),
|
||||
fill_brush_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::FillEllipse(const Point & center, float radius_x, float radius_y)
|
||||
{
|
||||
render_target_->FillEllipse(
|
||||
D2D1::Ellipse(
|
||||
D2D1::Point2F(
|
||||
center.x,
|
||||
center.y
|
||||
),
|
||||
radius_x,
|
||||
radius_y
|
||||
),
|
||||
fill_brush_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::FillRect(const Rect & rect)
|
||||
{
|
||||
render_target_->FillRectangle(
|
||||
D2D1::RectF(
|
||||
rect.origin.x,
|
||||
rect.origin.y,
|
||||
rect.origin.x + rect.size.x,
|
||||
rect.origin.y + rect.size.y
|
||||
),
|
||||
fill_brush_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::FillRoundedRect(const Rect & rect, float radius_x, float radius_y)
|
||||
{
|
||||
render_target_->FillRoundedRectangle(
|
||||
D2D1::RoundedRect(
|
||||
D2D1::RectF(
|
||||
rect.origin.x,
|
||||
rect.origin.y,
|
||||
rect.origin.x + rect.size.x,
|
||||
rect.origin.y + rect.size.y
|
||||
),
|
||||
radius_x,
|
||||
radius_y
|
||||
),
|
||||
fill_brush_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::FillGeometry(GeometryPtr const & geo)
|
||||
{
|
||||
if (geo && geo->geo_)
|
||||
{
|
||||
render_target_->FillGeometry(
|
||||
geo->geo_.Get(),
|
||||
fill_brush_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::BeginPath(Point const& begin_pos)
|
||||
{
|
||||
current_geometry_ = nullptr;
|
||||
|
||||
ThrowIfFailed(
|
||||
Renderer::Instance().GetDeviceResources()->GetD2DFactory()->CreatePathGeometry(¤t_geometry_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
current_geometry_->Open(¤t_sink_)
|
||||
);
|
||||
|
||||
current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED);
|
||||
}
|
||||
|
||||
void Canvas::EndPath(bool closed)
|
||||
{
|
||||
if (current_sink_)
|
||||
{
|
||||
current_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN);
|
||||
ThrowIfFailed(
|
||||
current_sink_->Close()
|
||||
);
|
||||
current_sink_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::AddLine(Point const & point)
|
||||
{
|
||||
if (current_sink_)
|
||||
current_sink_->AddLine(DX::ConvertToPoint2F(point));
|
||||
}
|
||||
|
||||
void Canvas::AddLines(Array<Point> const& points)
|
||||
{
|
||||
if (current_sink_ && !points.empty())
|
||||
{
|
||||
current_sink_->AddLines(
|
||||
reinterpret_cast<const D2D_POINT_2F*>(&points[0]),
|
||||
static_cast<UINT32>(points.size())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::AddBezier(Point const & point1, Point const & point2, Point const & point3)
|
||||
{
|
||||
if (current_sink_)
|
||||
{
|
||||
current_sink_->AddBezier(
|
||||
D2D1::BezierSegment(
|
||||
DX::ConvertToPoint2F(point1),
|
||||
DX::ConvertToPoint2F(point2),
|
||||
DX::ConvertToPoint2F(point3)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::AddArc(Point const & point, Point const & radius, float rotation, bool clockwise, bool is_small)
|
||||
{
|
||||
if (current_sink_)
|
||||
{
|
||||
current_sink_->AddArc(
|
||||
D2D1::ArcSegment(
|
||||
DX::ConvertToPoint2F(point),
|
||||
DX::ConvertToSizeF(radius),
|
||||
rotation,
|
||||
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
|
||||
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::StrokePath()
|
||||
{
|
||||
render_target_->DrawGeometry(
|
||||
current_geometry_.Get(),
|
||||
stroke_brush_.Get(),
|
||||
stroke_width_,
|
||||
outline_join_style_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::FillPath()
|
||||
{
|
||||
render_target_->FillGeometry(
|
||||
current_geometry_.Get(),
|
||||
fill_brush_.Get()
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::Clear()
|
||||
{
|
||||
render_target_->Clear();
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
ImagePtr Canvas::ExportToImage() const
|
||||
{
|
||||
auto image = new Image(GetBitmap());
|
||||
image->Crop(Rect(Point{}, this->GetSize()));
|
||||
return image;
|
||||
}
|
||||
|
||||
ComPtr<ID2D1Bitmap> const& easy2d::Canvas::GetBitmap() const
|
||||
{
|
||||
if (cache_expired_)
|
||||
{
|
||||
bitmap_cached_ = nullptr;
|
||||
ThrowIfFailed(
|
||||
render_target_->GetBitmap(&bitmap_cached_)
|
||||
);
|
||||
cache_expired_ = false;
|
||||
}
|
||||
return bitmap_cached_;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,243 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
#include "Font.hpp"
|
||||
#include "TextStyle.hpp"
|
||||
#include "../renderer/TextRenderer.h"
|
||||
|
||||
#undef DrawText
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 画布
|
||||
class E2D_API Canvas
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
Canvas();
|
||||
|
||||
Canvas(
|
||||
Size const& size
|
||||
);
|
||||
|
||||
Canvas(
|
||||
float width,
|
||||
float height
|
||||
);
|
||||
|
||||
virtual ~Canvas();
|
||||
|
||||
// 开始绘图
|
||||
void BeginDraw();
|
||||
|
||||
// 结束绘图
|
||||
void EndDraw();
|
||||
|
||||
// 画直线
|
||||
void DrawLine(
|
||||
const Point& begin,
|
||||
const Point& end
|
||||
);
|
||||
|
||||
// 画圆形边框
|
||||
void DrawCircle(
|
||||
const Point& center,
|
||||
float radius
|
||||
);
|
||||
|
||||
// 画椭圆形边框
|
||||
void DrawEllipse(
|
||||
const Point& center,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
// 画矩形边框
|
||||
void DrawRect(
|
||||
const Rect& rect
|
||||
);
|
||||
|
||||
// 画圆角矩形边框
|
||||
void DrawRoundedRect(
|
||||
const Rect& rect,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
// 画图片
|
||||
void DrawImage(
|
||||
ImagePtr const& image,
|
||||
float opacity = 1.f
|
||||
);
|
||||
|
||||
// 画文字
|
||||
void DrawText(
|
||||
String const& text, /* 文字 */
|
||||
Point const& point /* 文字位置 */
|
||||
);
|
||||
|
||||
// 画几何图形边框
|
||||
void DrawGeometry(
|
||||
GeometryPtr const& geo
|
||||
);
|
||||
|
||||
// 填充圆形
|
||||
void FillCircle(
|
||||
const Point& center,
|
||||
float radius
|
||||
);
|
||||
|
||||
// 填充椭圆形
|
||||
void FillEllipse(
|
||||
const Point& center,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
// 填充矩形
|
||||
void FillRect(
|
||||
const Rect& rect
|
||||
);
|
||||
|
||||
// 填充圆角矩形
|
||||
void FillRoundedRect(
|
||||
const Rect& rect,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
// 填充几何图形
|
||||
void FillGeometry(
|
||||
GeometryPtr const& geo
|
||||
);
|
||||
|
||||
// 开始绘制路径
|
||||
void BeginPath(
|
||||
Point const& begin_pos /* 路径起始点 */
|
||||
);
|
||||
|
||||
// 结束路径
|
||||
void EndPath(
|
||||
bool closed = true /* 路径是否闭合 */
|
||||
);
|
||||
|
||||
// 添加一条线段
|
||||
void AddLine(
|
||||
Point const& point /* 端点 */
|
||||
);
|
||||
|
||||
// 添加多条线段
|
||||
void AddLines(
|
||||
Array<Point> const& points
|
||||
);
|
||||
|
||||
// 添加一条三次方贝塞尔曲线
|
||||
void AddBezier(
|
||||
Point const& point1, /* 贝塞尔曲线的第一个控制点 */
|
||||
Point const& point2, /* 贝塞尔曲线的第二个控制点 */
|
||||
Point const& point3 /* 贝塞尔曲线的终点 */
|
||||
);
|
||||
|
||||
// 添加弧线
|
||||
void AddArc(
|
||||
Point const& point, /* 终点 */
|
||||
Point const& radius, /* 椭圆半径 */
|
||||
float rotation, /* 椭圆旋转角度 */
|
||||
bool clockwise = true, /* 顺时针 or 逆时针 */
|
||||
bool is_small = true /* 是否取小于 180° 的弧 */
|
||||
);
|
||||
|
||||
// 路径描边
|
||||
void StrokePath();
|
||||
|
||||
// 路径填充
|
||||
void FillPath();
|
||||
|
||||
// 清空画布
|
||||
void Clear();
|
||||
|
||||
// 设置填充颜色
|
||||
void SetFillColor(
|
||||
const Color& color
|
||||
);
|
||||
|
||||
// 设置线条颜色
|
||||
void SetStrokeColor(
|
||||
const Color& color
|
||||
);
|
||||
|
||||
// 设置线条宽度
|
||||
void SetStrokeWidth(
|
||||
float width
|
||||
);
|
||||
|
||||
// 设置线条相交样式
|
||||
void SetOutlineJoinStyle(
|
||||
StrokeStyle outline_join
|
||||
);
|
||||
|
||||
// 设置文字画刷样式
|
||||
void SetTextStyle(
|
||||
Font const& font,
|
||||
TextStyle const& text_style
|
||||
);
|
||||
|
||||
// 获取填充颜色
|
||||
Color GetFillColor() const;
|
||||
|
||||
// 获取线条颜色
|
||||
Color GetStrokeColor() const;
|
||||
|
||||
// 获取线条宽度
|
||||
float GetStrokeWidth() const;
|
||||
|
||||
// 变换画笔
|
||||
void SetBrushTransform(
|
||||
Matrix const& transform
|
||||
);
|
||||
|
||||
// 导出为图片
|
||||
ImagePtr ExportToImage() const;
|
||||
|
||||
void OnRender() override;
|
||||
|
||||
protected:
|
||||
ComPtr<ID2D1Bitmap> const& GetBitmap() const;
|
||||
|
||||
protected:
|
||||
float stroke_width_;
|
||||
Font text_font_;
|
||||
TextStyle text_style_;
|
||||
|
||||
ComPtr<ID2D1PathGeometry> current_geometry_;
|
||||
ComPtr<ID2D1GeometrySink> current_sink_;
|
||||
ComPtr<ID2D1StrokeStyle> outline_join_style_;
|
||||
ComPtr<ID2D1SolidColorBrush> fill_brush_;
|
||||
ComPtr<ID2D1SolidColorBrush> stroke_brush_;
|
||||
ComPtr<IDWriteTextFormat> text_format_;
|
||||
ComPtr<ITextRenderer> text_renderer_;
|
||||
ComPtr<ID2D1BitmapRenderTarget> render_target_;
|
||||
|
||||
mutable bool cache_expired_;
|
||||
mutable ComPtr<ID2D1Bitmap> bitmap_cached_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Color.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const unsigned int RED_SHIFT = 16;
|
||||
const unsigned int GREEN_SHIFT = 8;
|
||||
const unsigned int BLUE_SHIFT = 0;
|
||||
|
||||
const unsigned int RED_MASK = 0xff << RED_SHIFT;
|
||||
const unsigned int GREEN_MASK = 0xff << GREEN_SHIFT;
|
||||
const unsigned int BLUE_MASK = 0xff << BLUE_SHIFT;
|
||||
}
|
||||
|
||||
Color::Color()
|
||||
: r(0)
|
||||
, g(0)
|
||||
, b(0)
|
||||
, a(1.f)
|
||||
{
|
||||
}
|
||||
|
||||
Color::Color(float r, float g, float b)
|
||||
: r(r)
|
||||
, g(g)
|
||||
, b(b)
|
||||
, a(1.f)
|
||||
{
|
||||
}
|
||||
|
||||
Color::Color(float r, float g, float b, float alpha)
|
||||
: r(r)
|
||||
, g(g)
|
||||
, b(b)
|
||||
, a(alpha)
|
||||
{
|
||||
}
|
||||
|
||||
Color::Color(unsigned int rgb)
|
||||
: r(((rgb & RED_MASK) >> RED_SHIFT) / 255.f)
|
||||
, g(((rgb & GREEN_MASK) >> GREEN_SHIFT) / 255.f)
|
||||
, b(((rgb & BLUE_MASK) >> BLUE_SHIFT) / 255.f)
|
||||
, a(1.f)
|
||||
{
|
||||
}
|
||||
|
||||
Color::Color(unsigned int rgb, float alpha)
|
||||
: r(((rgb & RED_MASK) >> RED_SHIFT) / 255.f)
|
||||
, g(((rgb & GREEN_MASK) >> GREEN_SHIFT) / 255.f)
|
||||
, b(((rgb & BLUE_MASK) >> BLUE_SHIFT) / 255.f)
|
||||
, a(alpha)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../macros.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 颜色
|
||||
//
|
||||
// 使用枚举表示颜色: Color blue = Color::Blue;
|
||||
// 使用 RGB 表示一个颜色: Color red(1.0f, 0.0f, 0.0f);
|
||||
// 使用 RGBA 表示一个带透明度的颜色: Color not_black(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
// 使用一个 unsigned int 类型的值表示 RGB: Color black(0x000000);
|
||||
//
|
||||
class E2D_API Color
|
||||
{
|
||||
public:
|
||||
Color();
|
||||
|
||||
Color(
|
||||
float r,
|
||||
float g,
|
||||
float b
|
||||
);
|
||||
|
||||
Color(
|
||||
float r,
|
||||
float g,
|
||||
float b,
|
||||
float alpha
|
||||
);
|
||||
|
||||
Color(
|
||||
unsigned int rgb
|
||||
);
|
||||
|
||||
Color(
|
||||
unsigned int rgb,
|
||||
float alpha
|
||||
);
|
||||
|
||||
public:
|
||||
enum Value : unsigned int
|
||||
{
|
||||
Black = 0x000000,
|
||||
Blue = 0x0000FF,
|
||||
BlueViolet = 0x8A2BE2,
|
||||
Brown = 0xA52A2A,
|
||||
Chocolate = 0xD2691E,
|
||||
DarkBlue = 0x00008B,
|
||||
DarkGray = 0xA9A9A9,
|
||||
DarkGreen = 0x006400,
|
||||
DarkOrange = 0xFF8C00,
|
||||
DarkRed = 0x8B0000,
|
||||
DarkViolet = 0x9400D3,
|
||||
ForestGreen = 0x228B22,
|
||||
Gold = 0xFFD700,
|
||||
Gray = 0x808080,
|
||||
Green = 0x008000,
|
||||
GreenYellow = 0xADFF2F,
|
||||
LightBlue = 0xADD8E6,
|
||||
LightCyan = 0xE0FFFF,
|
||||
LightGreen = 0x90EE90,
|
||||
LightGray = 0xD3D3D3,
|
||||
LightPink = 0xFFB6C1,
|
||||
LightSeaGreen = 0x20B2AA,
|
||||
LightSkyBlue = 0x87CEFA,
|
||||
LightYellow = 0xFFFFE0,
|
||||
Orange = 0xFFA500,
|
||||
OrangeRed = 0xFF4500,
|
||||
Pink = 0xFFC0CB,
|
||||
Purple = 0x800080,
|
||||
Red = 0xFF0000,
|
||||
Silver = 0xC0C0C0,
|
||||
SkyBlue = 0x87CEEB,
|
||||
Snow = 0xFFFAFA,
|
||||
Violet = 0xEE82EE,
|
||||
Wheat = 0xF5DEB3,
|
||||
White = 0xFFFFFF,
|
||||
WhiteSmoke = 0xF5F5F5,
|
||||
Wood = 0xDEB887,
|
||||
Yellow = 0xFFFF00,
|
||||
YellowGreen = 0x9ACD32
|
||||
};
|
||||
|
||||
public:
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "DebugNode.h"
|
||||
#include "Text.h"
|
||||
#include "../renderer/render.h"
|
||||
#include <sstream>
|
||||
#include <psapi.h>
|
||||
|
||||
#pragma comment(lib, "psapi.lib")
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
DebugNode::DebugNode()
|
||||
{
|
||||
debug_text_ = new Text();
|
||||
debug_text_->SetPosition(20, 20);
|
||||
this->AddChild(debug_text_);
|
||||
|
||||
Font font;
|
||||
font.size = 16.f;
|
||||
font.weight = FontWeight::Normal;
|
||||
debug_text_->SetFont(font);
|
||||
|
||||
TextStyle style;
|
||||
style.wrap = false;
|
||||
style.line_spacing = 20.f;
|
||||
debug_text_->SetStyle(style);
|
||||
}
|
||||
|
||||
DebugNode::~DebugNode()
|
||||
{
|
||||
}
|
||||
|
||||
void DebugNode::OnRender()
|
||||
{
|
||||
Renderer::Instance().GetSolidColorBrush()->SetColor(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.5f));
|
||||
|
||||
Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext()->FillRectangle(
|
||||
D2D1_RECT_F{ 10, 10, 30 + debug_text_->GetWidth(), 30 + debug_text_->GetHeight() },
|
||||
Renderer::Instance().GetSolidColorBrush()
|
||||
);
|
||||
}
|
||||
|
||||
void DebugNode::OnUpdate(Duration dt)
|
||||
{
|
||||
E2D_NOT_USED(dt);
|
||||
|
||||
frame_time_.push_back(time::Now());
|
||||
while (frame_time_.back() - frame_time_.front() >= time::Second)
|
||||
{
|
||||
frame_time_.erase(frame_time_.begin());
|
||||
}
|
||||
|
||||
std::wstringstream ss;
|
||||
ss << "Fps: " << frame_time_.size() << std::endl;
|
||||
|
||||
#ifdef E2D_DEBUG
|
||||
ss << "Objects: " << Object::__GetTracingObjects().size() << std::endl;
|
||||
#endif
|
||||
|
||||
ss << "Render: " << Renderer::Instance().GetStatus().duration.Milliseconds() << "ms" << std::endl;
|
||||
|
||||
ss << "Primitives / sec: " << Renderer::Instance().GetStatus().primitives * frame_time_.size() << std::endl;
|
||||
|
||||
PROCESS_MEMORY_COUNTERS_EX pmc;
|
||||
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
|
||||
ss << "Memory: " << pmc.PrivateUsage / 1024 << "kb";
|
||||
|
||||
debug_text_->SetText(ss.str());
|
||||
|
||||
debug_text_->SetSize(debug_text_->GetLayoutSize());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API DebugNode
|
||||
: public Node
|
||||
{
|
||||
public:
|
||||
DebugNode();
|
||||
|
||||
virtual ~DebugNode();
|
||||
|
||||
void OnRender() override;
|
||||
|
||||
void OnUpdate(Duration dt) override;
|
||||
|
||||
protected:
|
||||
TextPtr debug_text_;
|
||||
Array<TimePoint> frame_time_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// ×ÖÌå´Öϸֵ
|
||||
enum FontWeight : unsigned int
|
||||
{
|
||||
Thin = 100,
|
||||
ExtraLight = 200,
|
||||
Light = 300,
|
||||
Normal = 400,
|
||||
Medium = 500,
|
||||
Bold = 700,
|
||||
ExtraBold = 800,
|
||||
Black = 900,
|
||||
ExtraBlack = 950
|
||||
};
|
||||
|
||||
// ×ÖÌå
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
String family; // ×ÖÌå×å
|
||||
float size; // ×ÖºÅ
|
||||
unsigned int weight; // ´Öϸֵ
|
||||
bool italic; // ÊÇ·ñбÌå
|
||||
|
||||
public:
|
||||
Font(
|
||||
const String& family = L"",
|
||||
float size = 18,
|
||||
unsigned int weight = FontWeight::Normal,
|
||||
bool italic = false
|
||||
)
|
||||
: family(family)
|
||||
, size(size)
|
||||
, weight(weight)
|
||||
, italic(italic)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Frames.h"
|
||||
#include "Image.h"
|
||||
#include "../base/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Frames::Frames()
|
||||
{
|
||||
}
|
||||
|
||||
Frames::Frames(Array<ImagePtr> const& frames)
|
||||
{
|
||||
this->Add(frames);
|
||||
}
|
||||
|
||||
Frames::~Frames()
|
||||
{
|
||||
}
|
||||
|
||||
void Frames::Add(ImagePtr const& frame)
|
||||
{
|
||||
E2D_ASSERT(frame && "Frames::Add failed, NULL pointer exception");
|
||||
|
||||
if (frame)
|
||||
{
|
||||
frames_.push_back(frame);
|
||||
}
|
||||
}
|
||||
|
||||
void Frames::Add(Array<ImagePtr> const& frames)
|
||||
{
|
||||
if (frames_.empty())
|
||||
frames_ = frames;
|
||||
else
|
||||
{
|
||||
frames_.reserve(frames_.size() + frames.size());
|
||||
for (const auto& image : frames)
|
||||
Add(image);
|
||||
}
|
||||
}
|
||||
|
||||
Array<ImagePtr> const& Frames::GetFrames() const
|
||||
{
|
||||
return frames_;
|
||||
}
|
||||
|
||||
FramesPtr Frames::Clone() const
|
||||
{
|
||||
auto animation = new (std::nothrow) Frames;
|
||||
if (animation)
|
||||
{
|
||||
for (const auto& frame : frames_)
|
||||
{
|
||||
animation->Add(frame);
|
||||
}
|
||||
}
|
||||
return animation;
|
||||
}
|
||||
|
||||
FramesPtr Frames::Reverse() const
|
||||
{
|
||||
auto animation = new (std::nothrow) Frames;
|
||||
if (!frames_.empty())
|
||||
{
|
||||
for (auto iter = frames_.crbegin(), crend = frames_.crend(); iter != crend; ++iter)
|
||||
{
|
||||
if (*iter)
|
||||
animation->Add(*iter);
|
||||
}
|
||||
}
|
||||
return animation;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "include-forwards.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 序列帧
|
||||
class E2D_API Frames
|
||||
: public virtual Object
|
||||
{
|
||||
public:
|
||||
Frames();
|
||||
|
||||
explicit Frames(
|
||||
Array<ImagePtr> const& frames /* 序列帧 */
|
||||
);
|
||||
|
||||
virtual ~Frames();
|
||||
|
||||
// 添加关键帧
|
||||
void Add(
|
||||
ImagePtr const& frame
|
||||
);
|
||||
|
||||
// 添加多个关键帧
|
||||
void Add(
|
||||
Array<ImagePtr> const& frames
|
||||
);
|
||||
|
||||
// 获取关键帧
|
||||
Array<ImagePtr> const& GetFrames() const;
|
||||
|
||||
// 获取帧动画的拷贝对象
|
||||
FramesPtr Clone() const;
|
||||
|
||||
// 获取帧动画的倒转
|
||||
FramesPtr Reverse() const;
|
||||
|
||||
protected:
|
||||
Array<ImagePtr> frames_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,442 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Geometry.h"
|
||||
#include "../renderer/render.h"
|
||||
#include "../base/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
//-------------------------------------------------------
|
||||
// Geometry
|
||||
//-------------------------------------------------------
|
||||
|
||||
Geometry::Geometry()
|
||||
{
|
||||
}
|
||||
|
||||
Geometry::~Geometry()
|
||||
{
|
||||
}
|
||||
|
||||
Rect Geometry::GetBoundingBox()
|
||||
{
|
||||
if (!geo_)
|
||||
return Rect{};
|
||||
|
||||
D2D1_RECT_F rect;
|
||||
// no matter it failed or not
|
||||
geo_->GetBounds(D2D1::Matrix3x2F::Identity(), &rect);
|
||||
return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top };
|
||||
}
|
||||
|
||||
float Geometry::GetLength()
|
||||
{
|
||||
float length = 0.f;
|
||||
if (geo_)
|
||||
{
|
||||
// no matter it failed or not
|
||||
geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
bool Geometry::ComputePointAt(float length, Point* point, Point* tangent)
|
||||
{
|
||||
if (geo_)
|
||||
{
|
||||
D2D1_POINT_2F point_tmp, tangent_tmp;
|
||||
if (SUCCEEDED(geo_->ComputePointAtLength(
|
||||
length,
|
||||
D2D1::Matrix3x2F::Identity(),
|
||||
&point_tmp,
|
||||
&tangent_tmp)))
|
||||
{
|
||||
(*point).x = point_tmp.x;
|
||||
(*point).y = point_tmp.y;
|
||||
(*tangent).x = tangent_tmp.x;
|
||||
(*tangent).y = tangent_tmp.y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float Geometry::ComputeArea()
|
||||
{
|
||||
if (!geo_)
|
||||
return 0.f;
|
||||
|
||||
float area = 0.f;
|
||||
// no matter it failed or not
|
||||
geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area);
|
||||
return area;
|
||||
}
|
||||
|
||||
bool Geometry::ContainsPoint(Point const & point)
|
||||
{
|
||||
if (!geo_)
|
||||
return false;
|
||||
|
||||
BOOL ret = 0;
|
||||
// no matter it failed or not
|
||||
geo_->FillContainsPoint(
|
||||
DX::ConvertToPoint2F(point),
|
||||
D2D1::Matrix3x2F::Identity(),
|
||||
&ret
|
||||
);
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// LineGeometry
|
||||
//-------------------------------------------------------
|
||||
|
||||
LineGeometry::LineGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
LineGeometry::LineGeometry(Point const & begin, Point const & end)
|
||||
{
|
||||
SetLine(begin, end);
|
||||
}
|
||||
|
||||
LineGeometry::~LineGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
void LineGeometry::SetLine(Point const & begin, Point const & end)
|
||||
{
|
||||
ComPtr<ID2D1PathGeometry> path_geo;
|
||||
ComPtr<ID2D1GeometrySink> path_sink;
|
||||
|
||||
HRESULT hr = Renderer::Instance().GetDeviceResources()->GetD2DFactory()->CreatePathGeometry(&path_geo);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = path_geo->Open(&path_sink);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
path_sink->BeginFigure(DX::ConvertToPoint2F(begin), D2D1_FIGURE_BEGIN_FILLED);
|
||||
path_sink->AddLine(DX::ConvertToPoint2F(end));
|
||||
path_sink->EndFigure(D2D1_FIGURE_END_OPEN);
|
||||
hr = path_sink->Close();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
geo_ = path_geo;
|
||||
}
|
||||
}
|
||||
|
||||
void LineGeometry::SetBegin(Point const & begin)
|
||||
{
|
||||
SetLine(begin, end_);
|
||||
}
|
||||
|
||||
void LineGeometry::SetEnd(Point const & end)
|
||||
{
|
||||
SetLine(begin_, end);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// RectangleGeometry
|
||||
//-------------------------------------------------------
|
||||
|
||||
RectangleGeometry::RectangleGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
RectangleGeometry::RectangleGeometry(Rect const & rect)
|
||||
{
|
||||
SetRect(rect);
|
||||
}
|
||||
|
||||
RectangleGeometry::RectangleGeometry(Point const & left_top, Size const & size)
|
||||
{
|
||||
SetRect(Rect{ left_top, size });
|
||||
}
|
||||
|
||||
RectangleGeometry::~RectangleGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
void RectangleGeometry::SetRect(Rect const & rect)
|
||||
{
|
||||
ComPtr<ID2D1RectangleGeometry> geo;
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo)))
|
||||
{
|
||||
geo_ = geo;
|
||||
rect_ = rect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// CircleGeometry
|
||||
//-------------------------------------------------------
|
||||
|
||||
CircleGeometry::CircleGeometry()
|
||||
: radius_(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
CircleGeometry::CircleGeometry(Point const & center, float radius)
|
||||
{
|
||||
SetCircle(center, radius);
|
||||
}
|
||||
|
||||
CircleGeometry::~CircleGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
void CircleGeometry::SetRadius(float radius)
|
||||
{
|
||||
SetCircle(center_, radius);
|
||||
}
|
||||
|
||||
void CircleGeometry::SetCenter(Point const & center)
|
||||
{
|
||||
SetCircle(center, radius_);
|
||||
}
|
||||
|
||||
void CircleGeometry::SetCircle(Point const & center, float radius)
|
||||
{
|
||||
ComPtr<ID2D1EllipseGeometry> geo;
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
if (SUCCEEDED(factory->CreateEllipseGeometry(
|
||||
D2D1::Ellipse(
|
||||
DX::ConvertToPoint2F(center),
|
||||
radius,
|
||||
radius),
|
||||
&geo)))
|
||||
{
|
||||
geo_ = geo;
|
||||
center_ = center;
|
||||
radius_ = radius;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// EllipseGeometry
|
||||
//-------------------------------------------------------
|
||||
|
||||
EllipseGeometry::EllipseGeometry()
|
||||
: radius_x_(0.f)
|
||||
, radius_y_(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
EllipseGeometry::EllipseGeometry(Point const & center, float radius_x, float radius_y)
|
||||
{
|
||||
SetEllipse(center, radius_x, radius_y);
|
||||
}
|
||||
|
||||
EllipseGeometry::~EllipseGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
void EllipseGeometry::SetRadius(float radius_x, float radius_y)
|
||||
{
|
||||
SetEllipse(center_, radius_x, radius_y);
|
||||
}
|
||||
|
||||
void EllipseGeometry::SetCenter(Point const & center)
|
||||
{
|
||||
SetEllipse(center, radius_x_, radius_y_);
|
||||
}
|
||||
|
||||
void EllipseGeometry::SetEllipse(Point const & center, float radius_x, float radius_y)
|
||||
{
|
||||
ComPtr<ID2D1EllipseGeometry> geo;
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
if (SUCCEEDED(factory->CreateEllipseGeometry(
|
||||
D2D1::Ellipse(
|
||||
DX::ConvertToPoint2F(center),
|
||||
radius_x,
|
||||
radius_y),
|
||||
&geo)))
|
||||
{
|
||||
geo_ = geo;
|
||||
radius_x_ = radius_x;
|
||||
radius_y_ = radius_y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// PathGeometry
|
||||
//-------------------------------------------------------
|
||||
|
||||
PathGeometry::PathGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
PathGeometry::~PathGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
void PathGeometry::BeginPath(Point const& begin_pos)
|
||||
{
|
||||
current_geometry_ = nullptr;
|
||||
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
ThrowIfFailed(
|
||||
factory->CreatePathGeometry(¤t_geometry_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
current_geometry_->Open(¤t_sink_)
|
||||
);
|
||||
|
||||
current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED);
|
||||
}
|
||||
|
||||
void PathGeometry::EndPath(bool closed)
|
||||
{
|
||||
if (current_sink_)
|
||||
{
|
||||
current_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN);
|
||||
ThrowIfFailed(
|
||||
current_sink_->Close()
|
||||
);
|
||||
|
||||
geo_ = current_geometry_;
|
||||
|
||||
current_sink_ = nullptr;
|
||||
current_geometry_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PathGeometry::AddLine(Point const & point)
|
||||
{
|
||||
if (current_sink_)
|
||||
current_sink_->AddLine(DX::ConvertToPoint2F(point));
|
||||
}
|
||||
|
||||
void PathGeometry::AddLines(Array<Point> const& points)
|
||||
{
|
||||
if (current_sink_ && !points.empty())
|
||||
{
|
||||
current_sink_->AddLines(
|
||||
reinterpret_cast<const D2D_POINT_2F*>(&points[0]),
|
||||
static_cast<UINT32>(points.size())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void PathGeometry::AddBezier(Point const & point1, Point const & point2, Point const & point3)
|
||||
{
|
||||
if (current_sink_)
|
||||
{
|
||||
current_sink_->AddBezier(
|
||||
D2D1::BezierSegment(
|
||||
DX::ConvertToPoint2F(point1),
|
||||
DX::ConvertToPoint2F(point2),
|
||||
DX::ConvertToPoint2F(point3)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void PathGeometry::AddArc(Point const & point, Size const & radius, float rotation, bool clockwise, bool is_small)
|
||||
{
|
||||
if (current_sink_)
|
||||
{
|
||||
current_sink_->AddArc(
|
||||
D2D1::ArcSegment(
|
||||
DX::ConvertToPoint2F(point),
|
||||
DX::ConvertToSizeF(radius),
|
||||
rotation,
|
||||
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
|
||||
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void PathGeometry::ClearPath()
|
||||
{
|
||||
geo_ = nullptr;
|
||||
current_sink_ = nullptr;
|
||||
current_geometry_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// RoundedRectGeometry
|
||||
//-------------------------------------------------------
|
||||
|
||||
RoundedRectGeometry::RoundedRectGeometry()
|
||||
: radius_x_(0.f)
|
||||
, radius_y_(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
RoundedRectGeometry::RoundedRectGeometry(Rect const & rect, float radius_x, float radius_y)
|
||||
{
|
||||
SetRoundedRect(rect, radius_x, radius_y);
|
||||
}
|
||||
|
||||
RoundedRectGeometry::~RoundedRectGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
void RoundedRectGeometry::SetRadius(float radius_x, float radius_y)
|
||||
{
|
||||
SetRoundedRect(rect_, radius_x, radius_y);
|
||||
}
|
||||
|
||||
void RoundedRectGeometry::SetRect(Rect const & rect)
|
||||
{
|
||||
SetRoundedRect(rect, radius_x_, radius_y_);
|
||||
}
|
||||
|
||||
void RoundedRectGeometry::SetRoundedRect(Rect const & rect, float radius_x, float radius_y)
|
||||
{
|
||||
ComPtr<ID2D1RoundedRectangleGeometry> geo;
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
if (SUCCEEDED(factory->CreateRoundedRectangleGeometry(
|
||||
D2D1::RoundedRect(
|
||||
DX::ConvertToRectF(rect),
|
||||
radius_x,
|
||||
radius_y
|
||||
),
|
||||
&geo)))
|
||||
{
|
||||
geo_ = geo;
|
||||
rect_ = rect;
|
||||
radius_x_ = radius_x;
|
||||
radius_y_ = radius_y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,304 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "include-forwards.h"
|
||||
#include <d2d1.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 几何抽象
|
||||
class E2D_API Geometry
|
||||
: public virtual Object
|
||||
{
|
||||
friend class Canvas;
|
||||
friend class GeometryNode;
|
||||
|
||||
public:
|
||||
Geometry();
|
||||
|
||||
virtual ~Geometry();
|
||||
|
||||
// 获取外切包围盒
|
||||
Rect GetBoundingBox();
|
||||
|
||||
// 判断图形是否包含点
|
||||
bool ContainsPoint(
|
||||
Point const& point
|
||||
);
|
||||
|
||||
// 获取图形展开成一条直线的长度
|
||||
float GetLength();
|
||||
|
||||
// 计算图形路径上点的位置和切线向量
|
||||
bool ComputePointAt(
|
||||
float length,
|
||||
Point* point,
|
||||
Point* tangent
|
||||
);
|
||||
|
||||
// 计算面积
|
||||
float ComputeArea();
|
||||
|
||||
protected:
|
||||
ComPtr<ID2D1Geometry> geo_;
|
||||
};
|
||||
|
||||
|
||||
// 直线
|
||||
class E2D_API LineGeometry
|
||||
: public Geometry
|
||||
{
|
||||
public:
|
||||
LineGeometry();
|
||||
|
||||
LineGeometry(
|
||||
Point const& begin,
|
||||
Point const& end
|
||||
);
|
||||
|
||||
virtual ~LineGeometry();
|
||||
|
||||
Point const& GetBegin() const { return begin_; }
|
||||
|
||||
Point const& GetEnd() const { return end_; }
|
||||
|
||||
void SetLine(
|
||||
Point const& begin,
|
||||
Point const& end
|
||||
);
|
||||
|
||||
void SetBegin(
|
||||
Point const& begin
|
||||
);
|
||||
|
||||
void SetEnd(
|
||||
Point const& end
|
||||
);
|
||||
|
||||
protected:
|
||||
Point begin_;
|
||||
Point end_;
|
||||
};
|
||||
|
||||
|
||||
// 几何矩形
|
||||
class E2D_API RectangleGeometry
|
||||
: public Geometry
|
||||
{
|
||||
public:
|
||||
RectangleGeometry();
|
||||
|
||||
RectangleGeometry(
|
||||
Rect const& rect
|
||||
);
|
||||
|
||||
RectangleGeometry(
|
||||
Point const& left_top,
|
||||
Size const& size
|
||||
);
|
||||
|
||||
virtual ~RectangleGeometry();
|
||||
|
||||
Rect const& GetRect() const { return rect_; }
|
||||
|
||||
void SetRect(Rect const& rect);
|
||||
|
||||
protected:
|
||||
Rect rect_;
|
||||
};
|
||||
|
||||
|
||||
// 几何圆形
|
||||
class E2D_API CircleGeometry
|
||||
: public Geometry
|
||||
{
|
||||
public:
|
||||
CircleGeometry();
|
||||
|
||||
CircleGeometry(
|
||||
Point const& center,
|
||||
float radius
|
||||
);
|
||||
|
||||
virtual ~CircleGeometry();
|
||||
|
||||
float GetRadius() const { return radius_; }
|
||||
|
||||
void SetRadius(
|
||||
float radius
|
||||
);
|
||||
|
||||
Point const& GetCenter() const { return center_; }
|
||||
|
||||
void SetCenter(
|
||||
Point const& center
|
||||
);
|
||||
|
||||
void SetCircle(
|
||||
Point const& center,
|
||||
float radius
|
||||
);
|
||||
|
||||
protected:
|
||||
Point center_;
|
||||
float radius_;
|
||||
};
|
||||
|
||||
|
||||
// 几何椭圆
|
||||
class E2D_API EllipseGeometry
|
||||
: public Geometry
|
||||
{
|
||||
public:
|
||||
EllipseGeometry();
|
||||
|
||||
EllipseGeometry(
|
||||
Point const& center,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
virtual ~EllipseGeometry();
|
||||
|
||||
float GetRadiusX() const { return radius_x_; }
|
||||
|
||||
float GetRadiusY() const { return radius_y_; }
|
||||
|
||||
void SetRadius(
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
Point const& GetCenter() const { return center_; }
|
||||
|
||||
void SetCenter(
|
||||
Point const& center
|
||||
);
|
||||
|
||||
void SetEllipse(
|
||||
Point const& center,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
protected:
|
||||
Point center_;
|
||||
float radius_x_;
|
||||
float radius_y_;
|
||||
};
|
||||
|
||||
|
||||
// 几何路径
|
||||
class E2D_API PathGeometry
|
||||
: public Geometry
|
||||
{
|
||||
public:
|
||||
PathGeometry();
|
||||
|
||||
virtual ~PathGeometry();
|
||||
|
||||
// 开始添加路径
|
||||
void BeginPath(
|
||||
Point const& begin_pos = Point{} /* 起始点 */
|
||||
);
|
||||
|
||||
// 结束路径
|
||||
void EndPath(
|
||||
bool closed = true /* 路径是否闭合 */
|
||||
);
|
||||
|
||||
// 添加一条线段
|
||||
void AddLine(
|
||||
Point const& point /* 端点 */
|
||||
);
|
||||
|
||||
// 添加多条线段
|
||||
void AddLines(
|
||||
Array<Point> const& points
|
||||
);
|
||||
|
||||
// 添加一条三次方贝塞尔曲线
|
||||
void AddBezier(
|
||||
Point const& point1, /* 贝塞尔曲线的第一个控制点 */
|
||||
Point const& point2, /* 贝塞尔曲线的第二个控制点 */
|
||||
Point const& point3 /* 贝塞尔曲线的终点 */
|
||||
);
|
||||
|
||||
// 添加弧线
|
||||
void AddArc(
|
||||
Point const& point, /* 终点 */
|
||||
Size const& radius, /* 椭圆半径 */
|
||||
float rotation, /* 椭圆旋转角度 */
|
||||
bool clockwise = true, /* 顺时针 or 逆时针 */
|
||||
bool is_small = true /* 是否取小于 180° 的弧 */
|
||||
);
|
||||
|
||||
// 清除路径
|
||||
void ClearPath();
|
||||
|
||||
protected:
|
||||
ComPtr<ID2D1PathGeometry> current_geometry_;
|
||||
ComPtr<ID2D1GeometrySink> current_sink_;
|
||||
};
|
||||
|
||||
|
||||
// 几何圆角矩形
|
||||
class E2D_API RoundedRectGeometry
|
||||
: public Geometry
|
||||
{
|
||||
public:
|
||||
RoundedRectGeometry();
|
||||
|
||||
RoundedRectGeometry(
|
||||
Rect const& rect,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
virtual ~RoundedRectGeometry();
|
||||
|
||||
float GetRadiusX() const { return radius_x_; }
|
||||
|
||||
float GetRadiusY() const { return radius_y_; }
|
||||
|
||||
void SetRadius(
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
Rect const& GetRect() const { return rect_; }
|
||||
|
||||
void SetRect(
|
||||
Rect const& rect
|
||||
);
|
||||
|
||||
void SetRoundedRect(
|
||||
Rect const& rect,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
);
|
||||
|
||||
protected:
|
||||
Rect rect_;
|
||||
float radius_x_;
|
||||
float radius_y_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "GeometryNode.h"
|
||||
#include "../renderer/render.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
GeometryNode::GeometryNode()
|
||||
: fill_color_(Color::White)
|
||||
, stroke_color_(Color(Color::Black, 0))
|
||||
, stroke_width_(1.f)
|
||||
, outline_join_(StrokeStyle::Miter)
|
||||
{
|
||||
}
|
||||
|
||||
GeometryNode::GeometryNode(GeometryPtr const& geometry)
|
||||
: GeometryNode()
|
||||
{
|
||||
SetGeometry(geometry);
|
||||
}
|
||||
|
||||
GeometryNode::~GeometryNode()
|
||||
{
|
||||
}
|
||||
|
||||
void GeometryNode::SetGeometry(GeometryPtr const& geometry)
|
||||
{
|
||||
geometry_ = geometry;
|
||||
}
|
||||
|
||||
void GeometryNode::SetFillColor(const Color & color)
|
||||
{
|
||||
fill_color_ = color;
|
||||
}
|
||||
|
||||
void GeometryNode::SetStrokeColor(const Color & color)
|
||||
{
|
||||
stroke_color_ = color;
|
||||
}
|
||||
|
||||
void GeometryNode::SetStrokeWidth(float width)
|
||||
{
|
||||
stroke_width_ = std::max(width, 0.f);
|
||||
}
|
||||
|
||||
void GeometryNode::SetOutlineJoinStyle(StrokeStyle outline_join)
|
||||
{
|
||||
outline_join_ = outline_join;
|
||||
}
|
||||
|
||||
void GeometryNode::OnRender()
|
||||
{
|
||||
if (geometry_ && geometry_->geo_)
|
||||
{
|
||||
Renderer::Instance().FillGeometry(
|
||||
geometry_->geo_.Get(),
|
||||
fill_color_
|
||||
);
|
||||
|
||||
Renderer::Instance().DrawGeometry(
|
||||
geometry_->geo_,
|
||||
stroke_color_,
|
||||
stroke_width_,
|
||||
outline_join_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Geometry.h"
|
||||
#include "Node.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// ¼¸ºÎͼÐÎ
|
||||
class E2D_API GeometryNode
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
GeometryNode();
|
||||
|
||||
GeometryNode(
|
||||
GeometryPtr const& geometry
|
||||
);
|
||||
|
||||
virtual ~GeometryNode();
|
||||
|
||||
// ÉèÖÃÐÎ×´
|
||||
void SetGeometry(
|
||||
GeometryPtr const& geometry
|
||||
);
|
||||
|
||||
// ÉèÖÃÌî³äÑÕÉ«
|
||||
void SetFillColor(
|
||||
const Color& color
|
||||
);
|
||||
|
||||
// ÉèÖÃÏßÌõÑÕÉ«
|
||||
void SetStrokeColor(
|
||||
const Color& color
|
||||
);
|
||||
|
||||
// ÉèÖÃÏßÌõ¿í¶È
|
||||
void SetStrokeWidth(
|
||||
float width
|
||||
);
|
||||
|
||||
// ÉèÖÃÏßÌõÏཻÑùʽ
|
||||
void SetOutlineJoinStyle(
|
||||
StrokeStyle outline_join
|
||||
);
|
||||
|
||||
// »ñÈ¡ÐÎ×´
|
||||
GeometryPtr const& GetGeometry() const { return geometry_; }
|
||||
|
||||
// »ñÈ¡Ìî³äÑÕÉ«
|
||||
Color GetFillColor() const { return fill_color_; }
|
||||
|
||||
// »ñÈ¡ÏßÌõÑÕÉ«
|
||||
Color GetStrokeColor() const { return stroke_color_; }
|
||||
|
||||
// »ñÈ¡ÏßÌõ¿í¶È
|
||||
float GetStrokeWidth() const { return stroke_width_; }
|
||||
|
||||
// »ñÈ¡ÏßÌõÏཻÑùʽ
|
||||
StrokeStyle SetOutlineJoinStyle() const { return outline_join_; }
|
||||
|
||||
void OnRender() override;
|
||||
|
||||
protected:
|
||||
Color fill_color_;
|
||||
Color stroke_color_;
|
||||
float stroke_width_;
|
||||
StrokeStyle outline_join_;
|
||||
GeometryPtr geometry_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Image.h"
|
||||
#include "../base/logs.h"
|
||||
#include "../renderer/render.h"
|
||||
#include "../platform/modules.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Image::Image()
|
||||
: bitmap_(nullptr)
|
||||
, crop_rect_()
|
||||
{
|
||||
}
|
||||
|
||||
Image::Image(Resource const& res)
|
||||
: Image()
|
||||
{
|
||||
this->Load(res);
|
||||
}
|
||||
|
||||
Image::Image(Resource const& res, Rect const& crop_rect)
|
||||
: Image()
|
||||
{
|
||||
this->Load(res);
|
||||
this->Crop(crop_rect);
|
||||
}
|
||||
|
||||
Image::Image(ComPtr<ID2D1Bitmap> const & bitmap)
|
||||
: Image()
|
||||
{
|
||||
SetBitmap(bitmap);
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
}
|
||||
|
||||
bool Image::Load(Resource const& res)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
ComPtr<ID2D1Bitmap> bitmap;
|
||||
|
||||
if (res.IsFileType())
|
||||
{
|
||||
if (!modules::Shlwapi::Get().PathFileExistsW(res.GetFileName().c_str()))
|
||||
{
|
||||
E2D_WARNING_LOG(L"Image file '%s' not found!", res.GetFileName().c_str());
|
||||
return false;
|
||||
}
|
||||
hr = Renderer::Instance().GetDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName());
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = Renderer::Instance().GetDeviceResources()->CreateBitmapFromResource(bitmap, res);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
E2D_ERROR_LOG(L"Load image file failed with HRESULT of %08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
SetBitmap(bitmap);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Image::IsValid() const
|
||||
{
|
||||
return !!bitmap_;
|
||||
}
|
||||
|
||||
void Image::Crop(Rect const& crop_rect)
|
||||
{
|
||||
if (bitmap_)
|
||||
{
|
||||
auto bitmap_size = bitmap_->GetSize();
|
||||
crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.width);
|
||||
crop_rect_.origin.y = std::min(std::max(crop_rect.origin.y, 0.f), bitmap_size.height);
|
||||
crop_rect_.size.x = std::min(std::max(crop_rect.size.x, 0.f), bitmap_size.width - crop_rect.origin.x);
|
||||
crop_rect_.size.y = std::min(std::max(crop_rect.size.y, 0.f), bitmap_size.height - crop_rect.origin.y);
|
||||
}
|
||||
}
|
||||
|
||||
float Image::GetWidth() const
|
||||
{
|
||||
return crop_rect_.size.x;
|
||||
}
|
||||
|
||||
float Image::GetHeight() const
|
||||
{
|
||||
return crop_rect_.size.y;
|
||||
}
|
||||
|
||||
Size Image::GetSize() const
|
||||
{
|
||||
return crop_rect_.size;
|
||||
}
|
||||
|
||||
float Image::GetSourceWidth() const
|
||||
{
|
||||
if (bitmap_)
|
||||
{
|
||||
return bitmap_->GetSize().width;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
float Image::GetSourceHeight() const
|
||||
{
|
||||
if (bitmap_)
|
||||
{
|
||||
return bitmap_->GetSize().height;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Size Image::GetSourceSize() const
|
||||
{
|
||||
if (bitmap_)
|
||||
{
|
||||
auto bitmap_size = bitmap_->GetSize();
|
||||
return Size{ bitmap_size.width, bitmap_size.height };
|
||||
}
|
||||
return Size{};
|
||||
}
|
||||
|
||||
float Image::GetCropX() const
|
||||
{
|
||||
return crop_rect_.origin.x;
|
||||
}
|
||||
|
||||
float Image::GetCropY() const
|
||||
{
|
||||
return crop_rect_.origin.y;
|
||||
}
|
||||
|
||||
Point Image::GetCropPos() const
|
||||
{
|
||||
return crop_rect_.origin;
|
||||
}
|
||||
|
||||
Rect const& Image::GetCropRect() const
|
||||
{
|
||||
return crop_rect_;
|
||||
}
|
||||
|
||||
ComPtr<ID2D1Bitmap> const& Image::GetBitmap() const
|
||||
{
|
||||
return bitmap_;
|
||||
}
|
||||
|
||||
void Image::SetBitmap(ComPtr<ID2D1Bitmap> const & bitmap)
|
||||
{
|
||||
if (bitmap)
|
||||
{
|
||||
bitmap_ = bitmap;
|
||||
crop_rect_.origin.x = crop_rect_.origin.y = 0;
|
||||
crop_rect_.size.x = bitmap_->GetSize().width;
|
||||
crop_rect_.size.y = bitmap_->GetSize().height;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "include-forwards.h"
|
||||
#include "../base/Resource.h"
|
||||
#include <d2d1.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 图片
|
||||
class E2D_API Image
|
||||
: public virtual Object
|
||||
{
|
||||
public:
|
||||
Image();
|
||||
|
||||
explicit Image(
|
||||
Resource const& res
|
||||
);
|
||||
|
||||
explicit Image(
|
||||
Resource const& res,
|
||||
Rect const& crop_rect /* 裁剪矩形 */
|
||||
);
|
||||
|
||||
explicit Image(
|
||||
ComPtr<ID2D1Bitmap> const& bitmap
|
||||
);
|
||||
|
||||
virtual ~Image();
|
||||
|
||||
// 加载图片资源
|
||||
bool Load(
|
||||
Resource const& res
|
||||
);
|
||||
|
||||
// 资源是否有效
|
||||
bool IsValid() const;
|
||||
|
||||
// 将图片裁剪为矩形
|
||||
void Crop(
|
||||
Rect const& crop_rect /* 裁剪矩形 */
|
||||
);
|
||||
|
||||
// 获取宽度
|
||||
float GetWidth() const;
|
||||
|
||||
// 获取高度
|
||||
float GetHeight() const;
|
||||
|
||||
// 获取大小
|
||||
Size GetSize() const;
|
||||
|
||||
// 获取源图片宽度
|
||||
float GetSourceWidth() const;
|
||||
|
||||
// 获取源图片高度
|
||||
float GetSourceHeight() const;
|
||||
|
||||
// 获取源图片大小
|
||||
Size GetSourceSize() const;
|
||||
|
||||
// 获取裁剪位置 X 坐标
|
||||
float GetCropX() const;
|
||||
|
||||
// 获取裁剪位置 Y 坐标
|
||||
float GetCropY() const;
|
||||
|
||||
// 获取裁剪位置
|
||||
Point GetCropPos() const;
|
||||
|
||||
// 获取裁剪矩形
|
||||
Rect const& GetCropRect() const;
|
||||
|
||||
ComPtr<ID2D1Bitmap> const& GetBitmap() const;
|
||||
|
||||
protected:
|
||||
void SetBitmap(
|
||||
ComPtr<ID2D1Bitmap> const& bitmap
|
||||
);
|
||||
|
||||
protected:
|
||||
Rect crop_rect_;
|
||||
ComPtr<ID2D1Bitmap> bitmap_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Layer.h"
|
||||
#include "../renderer/render.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Layer::Layer()
|
||||
{
|
||||
SetSize(Renderer::Instance().GetOutputSize());
|
||||
|
||||
AddListener(Event::MouseBtnDown, Closure(this, &Layer::HandleMessages));
|
||||
AddListener(Event::MouseBtnUp, Closure(this, &Layer::HandleMessages));
|
||||
AddListener(Event::MouseMove, Closure(this, &Layer::HandleMessages));
|
||||
AddListener(Event::MouseWheel, Closure(this, &Layer::HandleMessages));
|
||||
|
||||
AddListener(Event::KeyDown, Closure(this, &Layer::HandleMessages));
|
||||
AddListener(Event::KeyUp, Closure(this, &Layer::HandleMessages));
|
||||
AddListener(Event::Char, Closure(this, &Layer::HandleMessages));
|
||||
}
|
||||
|
||||
Layer::~Layer()
|
||||
{
|
||||
}
|
||||
|
||||
void Layer::Dispatch(Event& evt)
|
||||
{
|
||||
if (!IsVisible())
|
||||
return;
|
||||
|
||||
NodePtr prev;
|
||||
for (auto child = children_.Last(); child; child = prev)
|
||||
{
|
||||
prev = child->PrevItem();
|
||||
child->Dispatch(evt);
|
||||
}
|
||||
|
||||
EventDispatcher::Dispatch(evt);
|
||||
}
|
||||
|
||||
void Layer::HandleMessages(Event const & evt)
|
||||
{
|
||||
switch (evt.type)
|
||||
{
|
||||
case Event::MouseBtnDown:
|
||||
OnMouseButtonDown(evt.mouse.button, Point{ evt.mouse.x, evt.mouse.y });
|
||||
break;
|
||||
case Event::MouseBtnUp:
|
||||
OnMouseButtonUp(evt.mouse.button, Point{ evt.mouse.x, evt.mouse.y });
|
||||
break;
|
||||
case Event::MouseMove:
|
||||
OnMouseMoved(Point{ evt.mouse.x, evt.mouse.y });
|
||||
break;
|
||||
case Event::MouseWheel:
|
||||
OnMouseWheel(evt.mouse.wheel);
|
||||
break;
|
||||
case Event::KeyDown:
|
||||
OnKeyDown(evt.key.code);
|
||||
break;
|
||||
case Event::KeyUp:
|
||||
OnKeyUp(evt.key.code);
|
||||
break;
|
||||
case Event::Char:
|
||||
OnChar(evt.key.c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API Layer
|
||||
: public Node
|
||||
{
|
||||
public:
|
||||
Layer();
|
||||
|
||||
virtual ~Layer();
|
||||
|
||||
virtual void OnMouseButtonDown(int btn, Point const& p) {}
|
||||
virtual void OnMouseButtonUp(int btn, Point const& p) {}
|
||||
virtual void OnMouseMoved(Point const& p) {}
|
||||
virtual void OnMouseWheel(float wheel) {}
|
||||
|
||||
virtual void OnKeyDown(int key) {}
|
||||
virtual void OnKeyUp(int key) {}
|
||||
virtual void OnChar(char c) {}
|
||||
|
||||
public:
|
||||
void Dispatch(Event& evt) override;
|
||||
|
||||
protected:
|
||||
void HandleMessages(Event const& evt);
|
||||
};
|
||||
}
|
||||
|
|
@ -1,594 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Node.h"
|
||||
#include "Action.h"
|
||||
#include "Scene.h"
|
||||
#include "../base/logs.h"
|
||||
#include "../renderer/render.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace
|
||||
{
|
||||
float default_anchor_x = 0.f;
|
||||
float default_anchor_y = 0.f;
|
||||
}
|
||||
|
||||
void Node::SetDefaultAnchor(float anchor_x, float anchor_y)
|
||||
{
|
||||
default_anchor_x = anchor_x;
|
||||
default_anchor_y = anchor_y;
|
||||
}
|
||||
|
||||
Node::Node()
|
||||
: visible_(true)
|
||||
, update_pausing_(false)
|
||||
, hover_(false)
|
||||
, pressed_(false)
|
||||
, responsible_(false)
|
||||
, dirty_transform_(false)
|
||||
, dirty_transform_inverse_(false)
|
||||
, parent_(nullptr)
|
||||
, scene_(nullptr)
|
||||
, hash_name_(0)
|
||||
, z_order_(0)
|
||||
, opacity_(1.f)
|
||||
, display_opacity_(1.f)
|
||||
, anchor_(default_anchor_x, default_anchor_y)
|
||||
{
|
||||
}
|
||||
|
||||
void Node::Update(Duration dt)
|
||||
{
|
||||
if (update_pausing_)
|
||||
return;
|
||||
|
||||
UpdateActions(this, dt);
|
||||
UpdateTimers(dt);
|
||||
|
||||
if (cb_update_)
|
||||
cb_update_(dt);
|
||||
|
||||
OnUpdate(dt);
|
||||
|
||||
if (!children_.IsEmpty())
|
||||
{
|
||||
NodePtr next;
|
||||
for (auto child = children_.First(); child; child = next)
|
||||
{
|
||||
next = child->NextItem();
|
||||
child->Update(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::Render()
|
||||
{
|
||||
if (!visible_)
|
||||
return;
|
||||
|
||||
UpdateTransform();
|
||||
|
||||
if (children_.IsEmpty())
|
||||
{
|
||||
PrepareRender();
|
||||
OnRender();
|
||||
}
|
||||
else
|
||||
{
|
||||
// render children those are less than 0 in Z-Order
|
||||
Node* child = children_.First().Get();
|
||||
while (child)
|
||||
{
|
||||
if (child->GetZOrder() >= 0)
|
||||
break;
|
||||
|
||||
child->Render();
|
||||
child = child->NextItem().Get();
|
||||
}
|
||||
|
||||
PrepareRender();
|
||||
OnRender();
|
||||
|
||||
while (child)
|
||||
{
|
||||
child->Render();
|
||||
child = child->NextItem().Get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::Dispatch(Event& evt)
|
||||
{
|
||||
if (!visible_)
|
||||
return;
|
||||
|
||||
NodePtr prev;
|
||||
for (auto child = children_.Last(); child; child = prev)
|
||||
{
|
||||
prev = child->PrevItem();
|
||||
child->Dispatch(evt);
|
||||
}
|
||||
|
||||
if (responsible_ && MouseEvent::Check(evt.type))
|
||||
{
|
||||
if (evt.type == Event::MouseMove)
|
||||
{
|
||||
if (!evt.target && ContainsPoint(Point{ evt.mouse.x, evt.mouse.y }))
|
||||
{
|
||||
evt.target = this;
|
||||
|
||||
if (!hover_)
|
||||
{
|
||||
hover_ = true;
|
||||
|
||||
Event hover = evt;
|
||||
hover.type = Event::MouseHover;
|
||||
EventDispatcher::Dispatch(hover);
|
||||
}
|
||||
}
|
||||
else if (hover_)
|
||||
{
|
||||
hover_ = false;
|
||||
pressed_ = false;
|
||||
|
||||
Event out = evt;
|
||||
out.target = this;
|
||||
out.type = Event::MouseOut;
|
||||
EventDispatcher::Dispatch(out);
|
||||
}
|
||||
}
|
||||
|
||||
if (evt.type == Event::MouseBtnDown && hover_)
|
||||
{
|
||||
pressed_ = true;
|
||||
evt.target = this;
|
||||
}
|
||||
|
||||
if (evt.type == Event::MouseBtnUp && pressed_)
|
||||
{
|
||||
pressed_ = false;
|
||||
evt.target = this;
|
||||
|
||||
Event click = evt;
|
||||
click.type = Event::Click;
|
||||
EventDispatcher::Dispatch(click);
|
||||
}
|
||||
}
|
||||
|
||||
EventDispatcher::Dispatch(evt);
|
||||
}
|
||||
|
||||
Matrix const & Node::GetTransformMatrix() const
|
||||
{
|
||||
UpdateTransform();
|
||||
return transform_matrix_;
|
||||
}
|
||||
|
||||
Matrix const & Node::GetTransformInverseMatrix() const
|
||||
{
|
||||
UpdateTransform();
|
||||
if (dirty_transform_inverse_)
|
||||
{
|
||||
transform_matrix_inverse_ = Matrix::Invert(transform_matrix_);
|
||||
dirty_transform_inverse_ = false;
|
||||
}
|
||||
return transform_matrix_inverse_;
|
||||
}
|
||||
|
||||
void Node::UpdateTransform() const
|
||||
{
|
||||
if (!dirty_transform_)
|
||||
return;
|
||||
|
||||
dirty_transform_ = false;
|
||||
dirty_transform_inverse_ = true;
|
||||
|
||||
transform_matrix_ = transform_.ToMatrix();
|
||||
|
||||
Point offset{ -size_.x * anchor_.x, -size_.y * anchor_.y };
|
||||
transform_matrix_.Translate(offset);
|
||||
|
||||
if (parent_)
|
||||
transform_matrix_ = transform_matrix_ * parent_->transform_matrix_;
|
||||
|
||||
// update children's transform
|
||||
for (Node* child = children_.First().Get(); child; child = child->NextItem().Get())
|
||||
child->dirty_transform_ = true;
|
||||
}
|
||||
|
||||
void Node::UpdateOpacity()
|
||||
{
|
||||
if (parent_)
|
||||
{
|
||||
display_opacity_ = opacity_ * parent_->display_opacity_;
|
||||
}
|
||||
for (Node* child = children_.First().Get(); child; child = child->NextItem().Get())
|
||||
{
|
||||
child->UpdateOpacity();
|
||||
}
|
||||
}
|
||||
|
||||
void Node::SetScene(Scene* scene)
|
||||
{
|
||||
if (scene && scene_ != scene)
|
||||
{
|
||||
scene_ = scene;
|
||||
for (Node* child = children_.First().Get(); child; child = child->NextItem().Get())
|
||||
{
|
||||
child->scene_ = scene;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::SetZOrder(int zorder)
|
||||
{
|
||||
z_order_ = zorder;
|
||||
|
||||
if (parent_)
|
||||
{
|
||||
NodePtr me = this;
|
||||
|
||||
parent_->children_.Remove(me);
|
||||
|
||||
Node* sibling = parent_->children_.Last().Get();
|
||||
|
||||
if (sibling && sibling->GetZOrder() > zorder)
|
||||
{
|
||||
sibling = sibling->PrevItem().Get();
|
||||
while (sibling)
|
||||
{
|
||||
if (sibling->GetZOrder() <= zorder)
|
||||
break;
|
||||
sibling = sibling->PrevItem().Get();
|
||||
}
|
||||
}
|
||||
|
||||
if (sibling)
|
||||
{
|
||||
parent_->children_.InsertAfter(me, sibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent_->children_.PushFront(me);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::SetOpacity(float opacity)
|
||||
{
|
||||
if (opacity_ == opacity)
|
||||
return;
|
||||
|
||||
display_opacity_ = opacity_ = std::min(std::max(opacity, 0.f), 1.f);
|
||||
UpdateOpacity();
|
||||
}
|
||||
|
||||
void Node::SetAnchorX(float anchor_x)
|
||||
{
|
||||
this->SetAnchor(anchor_x, anchor_.y);
|
||||
}
|
||||
|
||||
void Node::SetAnchorY(float anchor_y)
|
||||
{
|
||||
this->SetAnchor(anchor_.x, anchor_y);
|
||||
}
|
||||
|
||||
void Node::SetAnchor(float anchor_x, float anchor_y)
|
||||
{
|
||||
if (anchor_.x == anchor_x && anchor_.y == anchor_y)
|
||||
return;
|
||||
|
||||
anchor_.x = anchor_x;
|
||||
anchor_.y = anchor_y;
|
||||
dirty_transform_ = true;
|
||||
}
|
||||
|
||||
void Node::SetWidth(float width)
|
||||
{
|
||||
this->SetSize(width, size_.y);
|
||||
}
|
||||
|
||||
void Node::SetHeight(float height)
|
||||
{
|
||||
this->SetSize(size_.x, height);
|
||||
}
|
||||
|
||||
void Node::SetSize(const Size& size)
|
||||
{
|
||||
this->SetSize(size.x, size.y);
|
||||
}
|
||||
|
||||
void Node::SetSize(float width, float height)
|
||||
{
|
||||
if (size_.x == width && size_.y == height)
|
||||
return;
|
||||
|
||||
size_.x = width;
|
||||
size_.y = height;
|
||||
dirty_transform_ = true;
|
||||
}
|
||||
|
||||
void Node::SetTransform(Transform const& transform)
|
||||
{
|
||||
transform_ = transform;
|
||||
dirty_transform_ = true;
|
||||
}
|
||||
|
||||
void Node::SetVisible(bool val)
|
||||
{
|
||||
visible_ = val;
|
||||
}
|
||||
|
||||
void Node::SetName(String const& name)
|
||||
{
|
||||
if (!IsName(name))
|
||||
{
|
||||
Object::SetName(name);
|
||||
hash_name_ = std::hash<String>{}(name);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::SetPositionX(float x)
|
||||
{
|
||||
this->SetPosition(x, transform_.position.y);
|
||||
}
|
||||
|
||||
void Node::SetPositionY(float y)
|
||||
{
|
||||
this->SetPosition(transform_.position.x, y);
|
||||
}
|
||||
|
||||
void Node::SetPosition(const Point & p)
|
||||
{
|
||||
this->SetPosition(p.x, p.y);
|
||||
}
|
||||
|
||||
void Node::SetPosition(float x, float y)
|
||||
{
|
||||
if (transform_.position.x == x && transform_.position.y == y)
|
||||
return;
|
||||
|
||||
transform_.position.x = x;
|
||||
transform_.position.y = y;
|
||||
dirty_transform_ = true;
|
||||
}
|
||||
|
||||
void Node::Move(float x, float y)
|
||||
{
|
||||
this->SetPosition(transform_.position.x + x, transform_.position.y + y);
|
||||
}
|
||||
|
||||
void Node::Move(const Point & v)
|
||||
{
|
||||
this->Move(v.x, v.y);
|
||||
}
|
||||
|
||||
void Node::SetScaleX(float scale_x)
|
||||
{
|
||||
this->SetScale(scale_x, transform_.scale.y);
|
||||
}
|
||||
|
||||
void Node::SetScaleY(float scale_y)
|
||||
{
|
||||
this->SetScale(transform_.scale.x, scale_y);
|
||||
}
|
||||
|
||||
void Node::SetScale(float scale)
|
||||
{
|
||||
this->SetScale(scale, scale);
|
||||
}
|
||||
|
||||
void Node::SetScale(float scale_x, float scale_y)
|
||||
{
|
||||
if (transform_.scale.x == scale_x && transform_.scale.y == scale_y)
|
||||
return;
|
||||
|
||||
transform_.scale.x = scale_x;
|
||||
transform_.scale.y = scale_y;
|
||||
dirty_transform_ = true;
|
||||
}
|
||||
|
||||
void Node::SetSkewX(float skew_x)
|
||||
{
|
||||
this->SetSkew(skew_x, transform_.skew.y);
|
||||
}
|
||||
|
||||
void Node::SetSkewY(float skew_y)
|
||||
{
|
||||
this->SetSkew(transform_.skew.x, skew_y);
|
||||
}
|
||||
|
||||
void Node::SetSkew(float skew_x, float skew_y)
|
||||
{
|
||||
if (transform_.skew.x == skew_x && transform_.skew.y == skew_y)
|
||||
return;
|
||||
|
||||
transform_.skew.x = skew_x;
|
||||
transform_.skew.y = skew_y;
|
||||
dirty_transform_ = true;
|
||||
}
|
||||
|
||||
void Node::SetRotation(float angle)
|
||||
{
|
||||
if (transform_.rotation == angle)
|
||||
return;
|
||||
|
||||
transform_.rotation = angle;
|
||||
dirty_transform_ = true;
|
||||
}
|
||||
|
||||
void Node::AddChild(NodePtr const& child)
|
||||
{
|
||||
E2D_ASSERT(child && "Node::AddChild failed, NULL pointer exception");
|
||||
|
||||
if (child)
|
||||
{
|
||||
#ifdef E2D_DEBUG
|
||||
|
||||
if (child->parent_)
|
||||
E2D_ERROR_LOG(L"The node to be added already has a parent");
|
||||
|
||||
for (Node* parent = parent_; parent; parent = parent->parent_)
|
||||
if (parent == child)
|
||||
E2D_ERROR_LOG(L"A node cannot be its own parent");
|
||||
|
||||
#endif // E2D_DEBUG
|
||||
|
||||
children_.PushBack(child);
|
||||
child->parent_ = this;
|
||||
child->SetScene(this->scene_);
|
||||
child->dirty_transform_ = true;
|
||||
child->UpdateOpacity();
|
||||
child->SetZOrder(child->GetZOrder());
|
||||
}
|
||||
}
|
||||
|
||||
void Node::AddChildren(Array<NodePtr> const& children)
|
||||
{
|
||||
for (const auto& node : children)
|
||||
{
|
||||
this->AddChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
Rect Node::GetBounds() const
|
||||
{
|
||||
return Rect(Point{}, size_);
|
||||
}
|
||||
|
||||
Rect Node::GetBoundingBox() const
|
||||
{
|
||||
return GetTransformMatrix().Transform(GetBounds());
|
||||
}
|
||||
|
||||
Array<NodePtr> Node::GetChildren(String const& name) const
|
||||
{
|
||||
Array<NodePtr> children;
|
||||
size_t hash_code = std::hash<String>{}(name);
|
||||
|
||||
for (Node* child = children_.First().Get(); child; child = child->NextItem().Get())
|
||||
{
|
||||
if (child->hash_name_ == hash_code && child->IsName(name))
|
||||
{
|
||||
children.push_back(child);
|
||||
}
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
NodePtr Node::GetChild(String const& name) const
|
||||
{
|
||||
size_t hash_code = std::hash<String>{}(name);
|
||||
|
||||
for (Node* child = children_.First().Get(); child; child = child->NextItem().Get())
|
||||
{
|
||||
if (child->hash_name_ == hash_code && child->IsName(name))
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node::Children const & Node::GetChildren() const
|
||||
{
|
||||
return children_;
|
||||
}
|
||||
|
||||
void Node::RemoveFromParent()
|
||||
{
|
||||
if (parent_)
|
||||
{
|
||||
parent_->RemoveChild(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool Node::RemoveChild(NodePtr const& child)
|
||||
{
|
||||
return RemoveChild(child.Get());
|
||||
}
|
||||
|
||||
bool Node::RemoveChild(Node * child)
|
||||
{
|
||||
E2D_ASSERT(child && "Node::RemoveChild failed, NULL pointer exception");
|
||||
|
||||
if (children_.IsEmpty())
|
||||
return false;
|
||||
|
||||
if (child)
|
||||
{
|
||||
child->parent_ = nullptr;
|
||||
if (child->scene_) child->SetScene(nullptr);
|
||||
children_.Remove(NodePtr(child));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Node::RemoveChildren(String const& child_name)
|
||||
{
|
||||
if (children_.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
size_t hash_code = std::hash<String>{}(child_name);
|
||||
|
||||
Node* next;
|
||||
for (Node* child = children_.First().Get(); child; child = next)
|
||||
{
|
||||
next = child->NextItem().Get();
|
||||
|
||||
if (child->hash_name_ == hash_code && child->IsName(child_name))
|
||||
{
|
||||
RemoveChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::RemoveAllChildren()
|
||||
{
|
||||
children_.Clear();
|
||||
}
|
||||
|
||||
void Node::SetResponsible(bool enable)
|
||||
{
|
||||
responsible_ = enable;
|
||||
}
|
||||
|
||||
bool Node::ContainsPoint(const Point& point) const
|
||||
{
|
||||
if (size_.x == 0.f || size_.y == 0.f)
|
||||
return false;
|
||||
|
||||
Point local = GetTransformInverseMatrix().Transform(point);
|
||||
return GetBounds().ContainsPoint(local);
|
||||
}
|
||||
|
||||
|
||||
void VisualNode::PrepareRender()
|
||||
{
|
||||
Renderer::Instance().SetTransform(transform_matrix_);
|
||||
Renderer::Instance().SetOpacity(display_opacity_);
|
||||
}
|
||||
|
||||
}
|
||||
411
easy2d/2d/Node.h
411
easy2d/2d/Node.h
|
|
@ -1,411 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "include-forwards.h"
|
||||
#include "Transform.hpp"
|
||||
#include "ActionManager.h"
|
||||
#include "../base/TimerManager.h"
|
||||
#include "../base/EventDispatcher.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class Application;
|
||||
|
||||
// 节点
|
||||
class E2D_API Node
|
||||
: public virtual Object
|
||||
, public TimerManager
|
||||
, public ActionManager
|
||||
, public EventDispatcher
|
||||
, public IntrusiveListItem<NodePtr>
|
||||
{
|
||||
friend class Application;
|
||||
friend class Transition;
|
||||
friend class IntrusiveList<NodePtr>;
|
||||
|
||||
using Children = IntrusiveList<NodePtr>;
|
||||
using UpdateCallback = std::function<void(Duration)>;
|
||||
|
||||
public:
|
||||
Node();
|
||||
|
||||
// 更新节点
|
||||
virtual void OnUpdate(Duration dt) { E2D_NOT_USED(dt); }
|
||||
|
||||
// 渲染节点
|
||||
virtual void OnRender() {}
|
||||
|
||||
// 获取显示状态
|
||||
bool IsVisible() const { return visible_; }
|
||||
|
||||
// 获取名称的 Hash 值
|
||||
size_t GetHashName() const { return hash_name_; }
|
||||
|
||||
// 获取 Z 轴顺序
|
||||
int GetZOrder() const { return z_order_; }
|
||||
|
||||
// 获取坐标
|
||||
Point const& GetPosition() const { return transform_.position; }
|
||||
|
||||
// 获取 x 坐标
|
||||
float GetPositionX() const { return transform_.position.x; }
|
||||
|
||||
// 获取 y 坐标
|
||||
float GetPositionY() const { return transform_.position.y; }
|
||||
|
||||
// 获取横向缩放比例
|
||||
float GetScaleX() const { return transform_.scale.x; }
|
||||
|
||||
// 获取纵向缩放比例
|
||||
float GetScaleY() const { return transform_.scale.y; }
|
||||
|
||||
// 获取横向错切角度
|
||||
float GetSkewX() const { return transform_.skew.x; }
|
||||
|
||||
// 获取纵向错切角度
|
||||
float GetSkewY() const { return transform_.skew.y; }
|
||||
|
||||
// 获取旋转角度
|
||||
float GetRotation() const { return transform_.rotation; }
|
||||
|
||||
// 获取宽度
|
||||
float GetWidth() const { return size_.x; }
|
||||
|
||||
// 获取高度
|
||||
float GetHeight() const { return size_.y; }
|
||||
|
||||
// 获取大小
|
||||
Size const& GetSize() const { return size_; }
|
||||
|
||||
// 获取缩放后的宽度
|
||||
float GetScaledWidth() const { return size_.x * transform_.scale.x; }
|
||||
|
||||
// 获取缩放后的高度
|
||||
float GetScaledHeight() const { return size_.y * transform_.scale.y; }
|
||||
|
||||
// 获取缩放后的大小
|
||||
Size GetScaledSize() const { return Size{ GetScaledWidth(), GetScaledHeight() }; }
|
||||
|
||||
// 获取 x 方向锚点
|
||||
float GetAnchorX() const { return anchor_.x; }
|
||||
|
||||
// 获取 y 方向锚点
|
||||
float GetAnchorY() const { return anchor_.y; }
|
||||
|
||||
// 获取透明度
|
||||
float GetOpacity() const { return opacity_; }
|
||||
|
||||
// 获取变换
|
||||
Transform const& GetTransform() const { return transform_; }
|
||||
|
||||
// 获取边框
|
||||
Rect GetBounds() const;
|
||||
|
||||
// 获取外切包围盒
|
||||
Rect GetBoundingBox() const;
|
||||
|
||||
// 获取二维变换矩阵
|
||||
Matrix const& GetTransformMatrix() const;
|
||||
|
||||
// 获取二维变换的逆矩阵
|
||||
Matrix const& GetTransformInverseMatrix() const;
|
||||
|
||||
// 获取父节点
|
||||
inline Node* GetParent() const { return parent_; }
|
||||
|
||||
// 获取所在场景
|
||||
inline Scene* GetScene() const { return scene_; }
|
||||
|
||||
// 设置是否显示
|
||||
void SetVisible(
|
||||
bool val
|
||||
);
|
||||
|
||||
// 设置名称
|
||||
void SetName(
|
||||
String const& name
|
||||
);
|
||||
|
||||
// 设置横坐标
|
||||
void SetPositionX(
|
||||
float x
|
||||
);
|
||||
|
||||
// 设置纵坐标
|
||||
void SetPositionY(
|
||||
float y
|
||||
);
|
||||
|
||||
// 设置坐标
|
||||
void SetPosition(
|
||||
const Point & point
|
||||
);
|
||||
|
||||
// 设置坐标
|
||||
void SetPosition(
|
||||
float x,
|
||||
float y
|
||||
);
|
||||
|
||||
// 移动
|
||||
void Move(
|
||||
float x,
|
||||
float y
|
||||
);
|
||||
|
||||
// 移动
|
||||
void Move(
|
||||
const Point & vector
|
||||
);
|
||||
|
||||
// 设置横向缩放比例
|
||||
// 默认为 1.0
|
||||
void SetScaleX(
|
||||
float scale_x
|
||||
);
|
||||
|
||||
// 设置纵向缩放比例
|
||||
// 默认为 1.0
|
||||
void SetScaleY(
|
||||
float scale_y
|
||||
);
|
||||
|
||||
// 设置缩放比例
|
||||
// 默认为 (1.0, 1.0)
|
||||
void SetScale(
|
||||
float scale_x,
|
||||
float scale_y
|
||||
);
|
||||
|
||||
// 设置缩放比例
|
||||
// 默认为 1.0
|
||||
void SetScale(
|
||||
float scale
|
||||
);
|
||||
|
||||
// 设置横向错切角度
|
||||
// 默认为 0
|
||||
void SetSkewX(
|
||||
float skew_x
|
||||
);
|
||||
|
||||
// 设置纵向错切角度
|
||||
// 默认为 0
|
||||
void SetSkewY(
|
||||
float skew_y
|
||||
);
|
||||
|
||||
// 设置错切角度
|
||||
// 默认为 (0, 0)
|
||||
void SetSkew(
|
||||
float skew_x,
|
||||
float skew_y
|
||||
);
|
||||
|
||||
// 设置旋转角度
|
||||
// 默认为 0
|
||||
void SetRotation(
|
||||
float rotation
|
||||
);
|
||||
|
||||
// 设置锚点的横向位置
|
||||
// 默认为 0, 范围 [0, 1]
|
||||
void SetAnchorX(
|
||||
float anchor_x
|
||||
);
|
||||
|
||||
// 设置锚点的纵向位置
|
||||
// 默认为 0, 范围 [0, 1]
|
||||
void SetAnchorY(
|
||||
float anchor_y
|
||||
);
|
||||
|
||||
// 设置锚点位置
|
||||
// 默认为 (0, 0), 范围 [0, 1]
|
||||
void SetAnchor(
|
||||
float anchor_x,
|
||||
float anchor_y
|
||||
);
|
||||
|
||||
// 修改宽度
|
||||
void SetWidth(
|
||||
float width
|
||||
);
|
||||
|
||||
// 修改高度
|
||||
void SetHeight(
|
||||
float height
|
||||
);
|
||||
|
||||
// 修改大小
|
||||
void SetSize(
|
||||
float width,
|
||||
float height
|
||||
);
|
||||
|
||||
// 修改大小
|
||||
void SetSize(
|
||||
const Size & size
|
||||
);
|
||||
|
||||
void SetTransform(
|
||||
Transform const& transform
|
||||
);
|
||||
|
||||
// 设置透明度
|
||||
// 默认为 1.0, 范围 [0, 1]
|
||||
void SetOpacity(
|
||||
float opacity
|
||||
);
|
||||
|
||||
// 设置 Z 轴顺序
|
||||
// 默认为 0
|
||||
void SetZOrder(
|
||||
int zorder
|
||||
);
|
||||
|
||||
// 是否可响应 (鼠标 Hover | Out | Click 消息)
|
||||
// 默认为 false
|
||||
void SetResponsible(
|
||||
bool enable
|
||||
);
|
||||
|
||||
// 判断点是否在节点内
|
||||
bool ContainsPoint(
|
||||
const Point& point
|
||||
) const;
|
||||
|
||||
// 添加子节点
|
||||
void AddChild(
|
||||
NodePtr const& child
|
||||
);
|
||||
|
||||
// 添加多个子节点
|
||||
void AddChildren(
|
||||
Array<NodePtr> const& children
|
||||
);
|
||||
|
||||
// 获取所有名称相同的子节点
|
||||
Array<NodePtr> GetChildren(
|
||||
String const& name
|
||||
) const;
|
||||
|
||||
// 获取名称相同的子节点
|
||||
NodePtr GetChild(
|
||||
String const& name
|
||||
) const;
|
||||
|
||||
// 获取全部子节点
|
||||
Children const& GetChildren() const;
|
||||
|
||||
// 移除子节点
|
||||
bool RemoveChild(
|
||||
NodePtr const& child
|
||||
);
|
||||
|
||||
// 移除子节点
|
||||
bool RemoveChild(
|
||||
Node* child
|
||||
);
|
||||
|
||||
// 移除所有名称相同的子节点
|
||||
void RemoveChildren(
|
||||
String const& child_name
|
||||
);
|
||||
|
||||
// 移除所有节点
|
||||
void RemoveAllChildren();
|
||||
|
||||
// 从父节点移除
|
||||
void RemoveFromParent();
|
||||
|
||||
// 暂停节点更新
|
||||
inline void PauseUpdating() { update_pausing_ = true; }
|
||||
|
||||
// 继续节点更新
|
||||
inline void ResumeUpdating() { update_pausing_ = false; }
|
||||
|
||||
// 节点更新是否暂停
|
||||
inline bool IsUpdatePausing() const { return update_pausing_; }
|
||||
|
||||
// 设置更新时的回调函数
|
||||
inline void SetCallbackOnUpdate(UpdateCallback const& cb) { cb_update_ = cb; }
|
||||
|
||||
// 获取更新时的回调函数
|
||||
inline UpdateCallback const& GetCallbackOnUpdate() { return cb_update_; }
|
||||
|
||||
// 设置默认锚点
|
||||
static void SetDefaultAnchor(
|
||||
float anchor_x,
|
||||
float anchor_y
|
||||
);
|
||||
|
||||
public:
|
||||
// 事件分发
|
||||
void Dispatch(Event& evt) override;
|
||||
|
||||
protected:
|
||||
virtual void PrepareRender() {}
|
||||
|
||||
void Update(Duration dt);
|
||||
|
||||
void Render();
|
||||
|
||||
void UpdateTransform() const;
|
||||
|
||||
void UpdateOpacity();
|
||||
|
||||
void SetScene(Scene* scene);
|
||||
|
||||
protected:
|
||||
bool visible_;
|
||||
bool hover_;
|
||||
bool pressed_;
|
||||
bool responsible_;
|
||||
bool update_pausing_;
|
||||
int z_order_;
|
||||
float opacity_;
|
||||
float display_opacity_;
|
||||
size_t hash_name_;
|
||||
Transform transform_;
|
||||
Point anchor_;
|
||||
Size size_;
|
||||
Node* parent_;
|
||||
Scene* scene_;
|
||||
Children children_;
|
||||
UpdateCallback cb_update_;
|
||||
|
||||
mutable bool dirty_transform_;
|
||||
mutable bool dirty_transform_inverse_;
|
||||
mutable Matrix transform_matrix_;
|
||||
mutable Matrix transform_matrix_inverse_;
|
||||
};
|
||||
|
||||
|
||||
// 可视化节点
|
||||
class E2D_API VisualNode
|
||||
: public Node
|
||||
{
|
||||
public:
|
||||
virtual void PrepareRender() override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Scene.h"
|
||||
#include "../base/logs.h"
|
||||
#include "../renderer/render.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Scene::Scene()
|
||||
: mouse_cursor_(MouseCursor::Arrow)
|
||||
, last_mouse_cursor(MouseCursor(-1))
|
||||
{
|
||||
scene_ = this;
|
||||
|
||||
SetSize(Renderer::Instance().GetOutputSize());
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
}
|
||||
|
||||
void Scene::OnEnter()
|
||||
{
|
||||
E2D_LOG(L"Scene entered");
|
||||
}
|
||||
|
||||
void Scene::OnExit()
|
||||
{
|
||||
E2D_LOG(L"Scene exited");
|
||||
}
|
||||
|
||||
void Scene::Update(Duration dt)
|
||||
{
|
||||
Node::Update(dt);
|
||||
|
||||
if (last_mouse_cursor != mouse_cursor_)
|
||||
{
|
||||
last_mouse_cursor = mouse_cursor_;
|
||||
|
||||
LPTSTR win32_cursor = IDC_ARROW;
|
||||
switch (mouse_cursor_)
|
||||
{
|
||||
case MouseCursor::Arrow: win32_cursor = IDC_ARROW; break;
|
||||
case MouseCursor::TextInput: win32_cursor = IDC_IBEAM; break;
|
||||
case MouseCursor::SizeAll: win32_cursor = IDC_SIZEALL; break;
|
||||
case MouseCursor::SizeWE: win32_cursor = IDC_SIZEWE; break;
|
||||
case MouseCursor::SizeNS: win32_cursor = IDC_SIZENS; break;
|
||||
case MouseCursor::SizeNESW: win32_cursor = IDC_SIZENESW; break;
|
||||
case MouseCursor::SizeNWSE: win32_cursor = IDC_SIZENWSE; break;
|
||||
case MouseCursor::Hand: win32_cursor = IDC_HAND; break;
|
||||
}
|
||||
::SetCursor(::LoadCursorW(nullptr, win32_cursor));
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::SetMouseCursor(MouseCursor cursor)
|
||||
{
|
||||
mouse_cursor_ = cursor;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// ³¡¾°
|
||||
class E2D_API Scene
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
Scene();
|
||||
|
||||
virtual ~Scene();
|
||||
|
||||
// ½øÈ볡¾°
|
||||
virtual void OnEnter();
|
||||
|
||||
// Í˳ö³¡¾°
|
||||
virtual void OnExit();
|
||||
|
||||
public:
|
||||
void Update(Duration dt);
|
||||
|
||||
void SetMouseCursor(
|
||||
MouseCursor cursor
|
||||
);
|
||||
|
||||
protected:
|
||||
MouseCursor mouse_cursor_;
|
||||
MouseCursor last_mouse_cursor;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Sprite.h"
|
||||
#include "../renderer/render.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Sprite::Sprite()
|
||||
: image_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Sprite::Sprite(ImagePtr const& image)
|
||||
: image_(nullptr)
|
||||
{
|
||||
Load(image);
|
||||
}
|
||||
|
||||
Sprite::Sprite(Resource const& res)
|
||||
: image_(nullptr)
|
||||
{
|
||||
Load(res);
|
||||
}
|
||||
|
||||
Sprite::Sprite(Resource const& res, const Rect& crop_rect)
|
||||
: image_(nullptr)
|
||||
{
|
||||
Load(res);
|
||||
Crop(crop_rect);
|
||||
}
|
||||
|
||||
Sprite::~Sprite()
|
||||
{
|
||||
}
|
||||
|
||||
bool Sprite::Load(ImagePtr const& image)
|
||||
{
|
||||
if (image)
|
||||
{
|
||||
image_ = image;
|
||||
|
||||
Node::SetSize(image_->GetWidth(), image_->GetHeight());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sprite::Load(Resource const& res)
|
||||
{
|
||||
if (!image_)
|
||||
{
|
||||
image_ = new (std::nothrow) Image;
|
||||
}
|
||||
|
||||
if (image_)
|
||||
{
|
||||
if (image_->Load(res))
|
||||
{
|
||||
Node::SetSize(image_->GetWidth(), image_->GetHeight());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Sprite::Crop(const Rect& crop_rect)
|
||||
{
|
||||
image_->Crop(crop_rect);
|
||||
Node::SetSize(
|
||||
std::min(std::max(crop_rect.size.x, 0.f), image_->GetSourceWidth() - image_->GetCropX()),
|
||||
std::min(std::max(crop_rect.size.y, 0.f), image_->GetSourceHeight() - image_->GetCropY())
|
||||
);
|
||||
}
|
||||
|
||||
ImagePtr const& Sprite::GetImage() const
|
||||
{
|
||||
return image_;
|
||||
}
|
||||
|
||||
void Sprite::OnRender()
|
||||
{
|
||||
if (image_)
|
||||
{
|
||||
Renderer::Instance().DrawImage(image_, GetBounds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
#include "Image.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 精灵
|
||||
class E2D_API Sprite
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
Sprite();
|
||||
|
||||
explicit Sprite(
|
||||
ImagePtr const& image
|
||||
);
|
||||
|
||||
explicit Sprite(
|
||||
Resource const& res
|
||||
);
|
||||
|
||||
explicit Sprite(
|
||||
Resource const& res,
|
||||
const Rect& crop_rect /* 裁剪矩形 */
|
||||
);
|
||||
|
||||
virtual ~Sprite();
|
||||
|
||||
// 加载图片文件
|
||||
bool Load(
|
||||
Resource const& res
|
||||
);
|
||||
|
||||
// 加载图片
|
||||
bool Load(
|
||||
ImagePtr const& image
|
||||
);
|
||||
|
||||
// 将图片裁剪为矩形
|
||||
void Crop(
|
||||
const Rect& crop_rect /* 裁剪矩形 */
|
||||
);
|
||||
|
||||
// 获取 Image 对象
|
||||
ImagePtr const& GetImage() const;
|
||||
|
||||
// 渲染精灵
|
||||
void OnRender() override;
|
||||
|
||||
protected:
|
||||
ImagePtr image_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,347 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Text.h"
|
||||
#include "../base/logs.h"
|
||||
#include "../renderer/render.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace
|
||||
{
|
||||
Font text_default_font;
|
||||
TextStyle text_default_style;
|
||||
}
|
||||
|
||||
void easy2d::Text::SetDefaultFont(Font const & font)
|
||||
{
|
||||
text_default_font = font;
|
||||
}
|
||||
|
||||
void easy2d::Text::SetDefaultStyle(TextStyle const & style)
|
||||
{
|
||||
text_default_style = style;
|
||||
}
|
||||
|
||||
Text::Text()
|
||||
: font_(text_default_font)
|
||||
, style_(text_default_style)
|
||||
, layout_dirty_(false)
|
||||
{
|
||||
}
|
||||
|
||||
Text::Text(String const& text)
|
||||
: Text(text, text_default_font, text_default_style)
|
||||
{
|
||||
}
|
||||
|
||||
Text::Text(String const& text, const Font & font)
|
||||
: Text(text, font, text_default_style)
|
||||
{
|
||||
}
|
||||
|
||||
Text::Text(String const& text, const TextStyle & style)
|
||||
: Text(text, text_default_font, style)
|
||||
{
|
||||
}
|
||||
|
||||
Text::Text(String const& text, const Font & font, const TextStyle & style)
|
||||
: font_(font)
|
||||
, style_(style)
|
||||
, text_(text)
|
||||
, layout_dirty_(true)
|
||||
{
|
||||
}
|
||||
|
||||
Text::~Text()
|
||||
{
|
||||
}
|
||||
|
||||
String const& Text::GetText() const
|
||||
{
|
||||
return text_;
|
||||
}
|
||||
|
||||
const Font& Text::GetFont() const
|
||||
{
|
||||
return font_;
|
||||
}
|
||||
|
||||
const TextStyle& Text::GetStyle() const
|
||||
{
|
||||
return style_;
|
||||
}
|
||||
|
||||
String const& Text::GetFontFamily() const
|
||||
{
|
||||
return font_.family;
|
||||
}
|
||||
|
||||
float Text::GetFontSize() const
|
||||
{
|
||||
return font_.size;
|
||||
}
|
||||
|
||||
unsigned int Text::GetFontWeight() const
|
||||
{
|
||||
return font_.weight;
|
||||
}
|
||||
|
||||
const Color& Text::GetColor() const
|
||||
{
|
||||
return style_.color;
|
||||
}
|
||||
|
||||
const Color& Text::GetOutlineColor() const
|
||||
{
|
||||
return style_.outline_color;
|
||||
}
|
||||
|
||||
float Text::GetOutlineWidth() const
|
||||
{
|
||||
return style_.outline_width;
|
||||
}
|
||||
|
||||
StrokeStyle Text::GetOutlineStroke() const
|
||||
{
|
||||
return style_.outline_stroke;
|
||||
}
|
||||
|
||||
int Text::GetLineCount()
|
||||
{
|
||||
UpdateLayout();
|
||||
if (text_layout_)
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
if (SUCCEEDED(text_layout_->GetMetrics(&metrics)))
|
||||
{
|
||||
return static_cast<int>(metrics.lineCount);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Size const& Text::GetLayoutSize() const
|
||||
{
|
||||
UpdateLayout();
|
||||
return layout_size_;
|
||||
}
|
||||
|
||||
bool Text::IsItalic() const
|
||||
{
|
||||
return font_.italic;
|
||||
}
|
||||
|
||||
bool Text::HasStrikethrough() const
|
||||
{
|
||||
return style_.strikethrough;
|
||||
}
|
||||
|
||||
bool Text::HasUnderline() const
|
||||
{
|
||||
return style_.underline;
|
||||
}
|
||||
|
||||
bool Text::HasOutline() const
|
||||
{
|
||||
return style_.outline;
|
||||
}
|
||||
|
||||
void Text::SetText(String const& text)
|
||||
{
|
||||
text_ = text;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
|
||||
void Text::SetStyle(const TextStyle& style)
|
||||
{
|
||||
style_ = style;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
|
||||
void Text::SetFont(const Font & font)
|
||||
{
|
||||
font_ = font;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
|
||||
void Text::SetFontFamily(String const& family)
|
||||
{
|
||||
if (font_.family != family)
|
||||
{
|
||||
font_.family = family;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetFontSize(float size)
|
||||
{
|
||||
if (font_.size != size)
|
||||
{
|
||||
font_.size = size;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetFontWeight(unsigned int weight)
|
||||
{
|
||||
if (font_.weight != weight)
|
||||
{
|
||||
font_.weight = weight;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetColor(Color const& color)
|
||||
{
|
||||
style_.color = color;
|
||||
}
|
||||
|
||||
void Text::SetItalic(bool val)
|
||||
{
|
||||
if (font_.italic != val)
|
||||
{
|
||||
font_.italic = val;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetWrapEnabled(bool wrap)
|
||||
{
|
||||
if (style_.wrap != wrap)
|
||||
{
|
||||
style_.wrap = wrap;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetWrapWidth(float wrap_width)
|
||||
{
|
||||
if (style_.wrap_width != wrap_width)
|
||||
{
|
||||
style_.wrap_width = std::max(wrap_width, 0.f);
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetLineacingPtr(float line_spacing)
|
||||
{
|
||||
if (style_.line_spacing != line_spacing)
|
||||
{
|
||||
style_.line_spacing = line_spacing;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetAlignment(TextAlign align)
|
||||
{
|
||||
if (style_.alignment != align)
|
||||
{
|
||||
style_.alignment = align;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetUnderline(bool underline)
|
||||
{
|
||||
if (style_.underline != underline)
|
||||
{
|
||||
style_.underline = underline;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetStrikethrough(bool strikethrough)
|
||||
{
|
||||
if (style_.strikethrough != strikethrough)
|
||||
{
|
||||
style_.strikethrough = strikethrough;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetOutline(bool outline)
|
||||
{
|
||||
style_.outline = outline;
|
||||
}
|
||||
|
||||
void Text::SetOutlineColor(Color const&outline_color)
|
||||
{
|
||||
style_.outline_color = outline_color;
|
||||
}
|
||||
|
||||
void Text::SetOutlineWidth(float outline_width)
|
||||
{
|
||||
style_.outline_width = outline_width;
|
||||
}
|
||||
|
||||
void Text::SetOutlineStroke(StrokeStyle outline_stroke)
|
||||
{
|
||||
style_.outline_stroke = outline_stroke;
|
||||
}
|
||||
|
||||
void Text::OnRender()
|
||||
{
|
||||
UpdateLayout();
|
||||
|
||||
if (text_layout_)
|
||||
{
|
||||
Renderer::Instance().SetTextStyle(
|
||||
style_.color,
|
||||
style_.outline,
|
||||
style_.outline_color,
|
||||
style_.outline_width,
|
||||
style_.outline_stroke
|
||||
);
|
||||
Renderer::Instance().DrawTextLayout(text_layout_);
|
||||
}
|
||||
}
|
||||
|
||||
void Text::UpdateLayout() const
|
||||
{
|
||||
if (!layout_dirty_)
|
||||
return;
|
||||
|
||||
layout_dirty_ = false;
|
||||
text_format_ = nullptr;
|
||||
text_layout_ = nullptr;
|
||||
|
||||
if (text_.empty())
|
||||
return;
|
||||
|
||||
ThrowIfFailed(
|
||||
Renderer::Instance().GetDeviceResources()->CreateTextFormat(
|
||||
text_format_,
|
||||
font_,
|
||||
style_
|
||||
)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
Renderer::Instance().GetDeviceResources()->CreateTextLayout(
|
||||
text_layout_,
|
||||
layout_size_,
|
||||
text_,
|
||||
text_format_,
|
||||
style_
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
221
easy2d/2d/Text.h
221
easy2d/2d/Text.h
|
|
@ -1,221 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
#include "Font.hpp"
|
||||
#include "TextStyle.hpp"
|
||||
#include <dwrite.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 文本
|
||||
class E2D_API Text
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
Text();
|
||||
|
||||
explicit Text(
|
||||
String const& text /* 文字内容 */
|
||||
);
|
||||
|
||||
explicit Text(
|
||||
String const& text, /* 文字内容 */
|
||||
const Font& font /* 字体 */
|
||||
);
|
||||
|
||||
explicit Text(
|
||||
String const& text, /* 文字内容 */
|
||||
const TextStyle& style /* 文本样式 */
|
||||
);
|
||||
|
||||
explicit Text(
|
||||
String const& text, /* 文字内容 */
|
||||
const Font& font, /* 字体 */
|
||||
const TextStyle& style /* 文本样式 */
|
||||
);
|
||||
|
||||
virtual ~Text();
|
||||
|
||||
// 获取文本
|
||||
String const& GetText() const;
|
||||
|
||||
// 获取字体
|
||||
const Font& GetFont() const;
|
||||
|
||||
// 获取文本样式
|
||||
const TextStyle& GetStyle() const;
|
||||
|
||||
// 获取字体族
|
||||
String const& GetFontFamily() const;
|
||||
|
||||
// 获取当前字号
|
||||
float GetFontSize() const;
|
||||
|
||||
// 获取当前字体粗细值
|
||||
unsigned int GetFontWeight() const;
|
||||
|
||||
// 获取文字颜色
|
||||
const Color& GetColor() const;
|
||||
|
||||
// 获取描边颜色
|
||||
const Color& GetOutlineColor() const;
|
||||
|
||||
// 获取描边线宽
|
||||
float GetOutlineWidth() const;
|
||||
|
||||
// 获取描边线相交样式
|
||||
StrokeStyle GetOutlineStroke() const;
|
||||
|
||||
// 获取文本显示行数
|
||||
int GetLineCount();
|
||||
|
||||
// 获取文字布局大小
|
||||
Size const& GetLayoutSize() const;
|
||||
|
||||
// 是否是斜体
|
||||
bool IsItalic() const;
|
||||
|
||||
// 是否显示删除线
|
||||
bool HasStrikethrough() const;
|
||||
|
||||
// 是否显示下划线
|
||||
bool HasUnderline() const;
|
||||
|
||||
// 是否显示描边
|
||||
bool HasOutline() const;
|
||||
|
||||
// 设置文本
|
||||
void SetText(
|
||||
String const& text
|
||||
);
|
||||
|
||||
// 设置文本样式
|
||||
void SetStyle(
|
||||
const TextStyle& style
|
||||
);
|
||||
|
||||
// 设置字体
|
||||
void SetFont(
|
||||
const Font& font
|
||||
);
|
||||
|
||||
// 设置字体族
|
||||
void SetFontFamily(
|
||||
String const& family
|
||||
);
|
||||
|
||||
// 设置字号(默认值为 18)
|
||||
void SetFontSize(
|
||||
float size
|
||||
);
|
||||
|
||||
// 设置字体粗细值(默认值为 FontWeight::Normal)
|
||||
void SetFontWeight(
|
||||
unsigned int weight
|
||||
);
|
||||
|
||||
// 设置文字颜色(默认值为 Color::White)
|
||||
void SetColor(
|
||||
Color const& color
|
||||
);
|
||||
|
||||
// 设置文字斜体(默认值为 false)
|
||||
void SetItalic(
|
||||
bool val
|
||||
);
|
||||
|
||||
// 打开或关闭文本自动换行(默认为关闭)
|
||||
void SetWrapEnabled(
|
||||
bool wrap
|
||||
);
|
||||
|
||||
// 设置文本自动换行的宽度(默认为 0)
|
||||
void SetWrapWidth(
|
||||
float wrap_width
|
||||
);
|
||||
|
||||
// 设置行间距(默认为 0)
|
||||
void SetLineacingPtr(
|
||||
float line_spacing
|
||||
);
|
||||
|
||||
// 设置对齐方式(默认为 TextAlign::Left)
|
||||
void SetAlignment(
|
||||
TextAlign align
|
||||
);
|
||||
|
||||
// 设置下划线(默认值为 false)
|
||||
void SetUnderline(
|
||||
bool underline
|
||||
);
|
||||
|
||||
// 设置删除线(默认值为 false)
|
||||
void SetStrikethrough(
|
||||
bool strikethrough
|
||||
);
|
||||
|
||||
// 设置是否显示描边
|
||||
void SetOutline(
|
||||
bool outline
|
||||
);
|
||||
|
||||
// 设置描边颜色
|
||||
void SetOutlineColor(
|
||||
Color const& outline_color
|
||||
);
|
||||
|
||||
// 设置描边线宽
|
||||
void SetOutlineWidth(
|
||||
float outline_width
|
||||
);
|
||||
|
||||
// 设置描边线相交样式
|
||||
void SetOutlineStroke(
|
||||
StrokeStyle outline_stroke
|
||||
);
|
||||
|
||||
// 设置默认字体
|
||||
static void SetDefaultFont(
|
||||
Font const& font
|
||||
);
|
||||
|
||||
// 设置默认文字样式
|
||||
static void SetDefaultStyle(
|
||||
TextStyle const& style
|
||||
);
|
||||
|
||||
void OnRender() override;
|
||||
|
||||
protected:
|
||||
void UpdateLayout() const;
|
||||
|
||||
protected:
|
||||
String text_;
|
||||
Font font_;
|
||||
TextStyle style_;
|
||||
|
||||
mutable bool layout_dirty_;
|
||||
mutable Size layout_size_;
|
||||
mutable ComPtr<IDWriteTextFormat> text_format_;
|
||||
mutable ComPtr<IDWriteTextLayout> text_layout_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "include-forwards.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 文本对齐方式
|
||||
enum class TextAlign
|
||||
{
|
||||
Left, /* 左对齐 */
|
||||
Right, /* 右对齐 */
|
||||
Center /* 居中对齐 */
|
||||
};
|
||||
|
||||
// 文本样式
|
||||
class E2D_API TextStyle
|
||||
{
|
||||
public:
|
||||
Color color; // 颜色
|
||||
TextAlign alignment; // 对齐方式
|
||||
bool wrap; // 打开自动换行
|
||||
float wrap_width; // 自动换行宽度
|
||||
float line_spacing; // 行间距
|
||||
bool underline; // 下划线
|
||||
bool strikethrough; // 删除线
|
||||
bool outline; // 显示描边
|
||||
Color outline_color; // 描边颜色
|
||||
float outline_width; // 描边线宽
|
||||
StrokeStyle outline_stroke; // 描边线相交样式
|
||||
|
||||
public:
|
||||
TextStyle()
|
||||
: color(Color::White)
|
||||
, alignment(TextAlign::Left)
|
||||
, wrap(false)
|
||||
, wrap_width(0.f)
|
||||
, line_spacing(0.f)
|
||||
, underline(false)
|
||||
, strikethrough(false)
|
||||
, outline(true)
|
||||
, outline_color(Color(Color::Black, 0.5))
|
||||
, outline_width(1.f)
|
||||
, outline_stroke(StrokeStyle::Round)
|
||||
{}
|
||||
|
||||
TextStyle(
|
||||
Color color,
|
||||
TextAlign alignment = TextAlign::Left,
|
||||
bool wrap = false,
|
||||
float wrap_width = 0.f,
|
||||
float line_spacing = 0.f,
|
||||
bool underline = false,
|
||||
bool strikethrough = false,
|
||||
bool outline = true,
|
||||
Color outline_color = Color(Color::Black, 0.5),
|
||||
float outline_width = 1.f,
|
||||
StrokeStyle outline_stroke = StrokeStyle::Round
|
||||
)
|
||||
: color(color)
|
||||
, alignment(alignment)
|
||||
, wrap(wrap)
|
||||
, wrap_width(wrap_width)
|
||||
, line_spacing(line_spacing)
|
||||
, underline(underline)
|
||||
, strikethrough(strikethrough)
|
||||
, outline(outline)
|
||||
, outline_color(outline_color)
|
||||
, outline_width(outline_width)
|
||||
, outline_stroke(outline_stroke)
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../math/Matrix.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class Transform
|
||||
{
|
||||
public:
|
||||
float rotation; // Ðýת
|
||||
Point position; // ×ø±ê
|
||||
Point scale; // Ëõ·Å
|
||||
Point skew; // ´íÇнǶÈ
|
||||
|
||||
public:
|
||||
Transform()
|
||||
: position()
|
||||
, rotation(0)
|
||||
, scale(1.f, 1.f)
|
||||
, skew(0.f, 0.f)
|
||||
{}
|
||||
|
||||
bool operator== (const Transform& other) const
|
||||
{
|
||||
return position == other.position &&
|
||||
scale == other.scale &&
|
||||
skew == other.skew &&
|
||||
rotation == other.rotation;
|
||||
}
|
||||
|
||||
inline math::Matrix ToMatrix() const
|
||||
{
|
||||
// matrix multiplication is optimized by expression template
|
||||
return Matrix::Scaling(scale)
|
||||
* Matrix::Skewing(skew.x, skew.y)
|
||||
* Matrix::Rotation(rotation)
|
||||
* Matrix::Translation(position);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -1,396 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Transition.h"
|
||||
#include "Node.h"
|
||||
#include "Scene.h"
|
||||
#include "../base/window.h"
|
||||
#include "../base/logs.h"
|
||||
#include "../renderer/render.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
//-------------------------------------------------------
|
||||
// Transition
|
||||
//-------------------------------------------------------
|
||||
|
||||
Transition::Transition(Duration duration)
|
||||
: done_(false)
|
||||
, duration_(duration)
|
||||
, delta_()
|
||||
, process_(0)
|
||||
, window_size_()
|
||||
, out_scene_(nullptr)
|
||||
, in_scene_(nullptr)
|
||||
, out_layer_(nullptr)
|
||||
, in_layer_(nullptr)
|
||||
, out_layer_prop_()
|
||||
, in_layer_prop_()
|
||||
{
|
||||
}
|
||||
|
||||
Transition::~Transition()
|
||||
{
|
||||
}
|
||||
|
||||
bool Transition::IsDone()
|
||||
{
|
||||
return done_;
|
||||
}
|
||||
|
||||
void Transition::Init(ScenePtr const& prev, ScenePtr const& next)
|
||||
{
|
||||
process_ = 0;
|
||||
delta_ = Duration{};
|
||||
|
||||
out_scene_ = prev;
|
||||
in_scene_ = next;
|
||||
|
||||
if (in_scene_)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
Renderer::Instance().CreateLayer(in_layer_)
|
||||
);
|
||||
}
|
||||
|
||||
if (out_scene_)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
Renderer::Instance().CreateLayer(out_layer_)
|
||||
);
|
||||
}
|
||||
|
||||
window_size_ = Renderer::Instance().GetOutputSize();
|
||||
out_layer_prop_ = in_layer_prop_ = LayerProperties{ Rect(Point(), window_size_),1.f };
|
||||
}
|
||||
|
||||
void Transition::Update(Duration dt)
|
||||
{
|
||||
if (duration_.IsZero())
|
||||
{
|
||||
process_ = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta_ += dt;
|
||||
process_ = std::min(delta_ / duration_, 1.f);
|
||||
}
|
||||
|
||||
if (process_ >= 1)
|
||||
{
|
||||
this->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Transition::Render()
|
||||
{
|
||||
auto& renderer = Renderer::Instance();
|
||||
|
||||
if (out_scene_)
|
||||
{
|
||||
renderer.PushClip(
|
||||
out_scene_->GetTransformMatrix(),
|
||||
window_size_
|
||||
);
|
||||
renderer.PushLayer(out_layer_, out_layer_prop_);
|
||||
|
||||
out_scene_->Render();
|
||||
|
||||
renderer.PopLayer();
|
||||
renderer.PopClip();
|
||||
}
|
||||
|
||||
if (in_scene_)
|
||||
{
|
||||
renderer.PushClip(
|
||||
in_scene_->GetTransformMatrix(),
|
||||
window_size_
|
||||
);
|
||||
renderer.PushLayer(in_layer_, in_layer_prop_);
|
||||
|
||||
in_scene_->Render();
|
||||
|
||||
renderer.PopLayer();
|
||||
renderer.PopClip();
|
||||
}
|
||||
}
|
||||
|
||||
void Transition::Stop()
|
||||
{
|
||||
done_ = true;
|
||||
Reset();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// BoxTransition
|
||||
//-------------------------------------------------------
|
||||
|
||||
BoxTransition::BoxTransition(Duration duration)
|
||||
: Transition(duration)
|
||||
{
|
||||
}
|
||||
|
||||
void BoxTransition::Init(ScenePtr const& prev, ScenePtr const& next)
|
||||
{
|
||||
Transition::Init(prev, next);
|
||||
|
||||
in_layer_prop_.opacity = 0;
|
||||
}
|
||||
|
||||
void BoxTransition::Update(Duration dt)
|
||||
{
|
||||
Transition::Update(dt);
|
||||
|
||||
if (process_ < .5f)
|
||||
{
|
||||
out_layer_prop_.area = Rect(
|
||||
window_size_.x * process_,
|
||||
window_size_.y * process_,
|
||||
window_size_.x * (1 - process_ * 2),
|
||||
window_size_.y * (1 - process_ * 2)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_layer_prop_.opacity = 0;
|
||||
in_layer_prop_.opacity = 1;
|
||||
in_layer_prop_.area = Rect(
|
||||
window_size_.x * (1 - process_),
|
||||
window_size_.y * (1 - process_),
|
||||
window_size_.x * (2 * process_ - 1),
|
||||
window_size_.y * (2 * process_ - 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// EmergeTransition
|
||||
//-------------------------------------------------------
|
||||
|
||||
EmergeTransition::EmergeTransition(Duration duration)
|
||||
: Transition(duration)
|
||||
{
|
||||
}
|
||||
|
||||
void EmergeTransition::Init(ScenePtr const& prev, ScenePtr const& next)
|
||||
{
|
||||
Transition::Init(prev, next);
|
||||
|
||||
out_layer_prop_.opacity = 1;
|
||||
in_layer_prop_.opacity = 0;
|
||||
}
|
||||
|
||||
void EmergeTransition::Update(Duration dt)
|
||||
{
|
||||
Transition::Update(dt);
|
||||
|
||||
out_layer_prop_.opacity = 1 - process_;
|
||||
in_layer_prop_.opacity = process_;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// FadeTransition
|
||||
//-------------------------------------------------------
|
||||
|
||||
FadeTransition::FadeTransition(Duration duration)
|
||||
: Transition(duration)
|
||||
{
|
||||
}
|
||||
|
||||
void FadeTransition::Init(ScenePtr const& prev, ScenePtr const& next)
|
||||
{
|
||||
Transition::Init(prev, next);
|
||||
|
||||
out_layer_prop_.opacity = 1;
|
||||
in_layer_prop_.opacity = 0;
|
||||
}
|
||||
|
||||
void FadeTransition::Update(Duration dt)
|
||||
{
|
||||
Transition::Update(dt);
|
||||
|
||||
if (process_ < 0.5)
|
||||
{
|
||||
out_layer_prop_.opacity = 1 - process_ * 2;
|
||||
in_layer_prop_.opacity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
out_layer_prop_.opacity = 0;
|
||||
in_layer_prop_.opacity = (process_ - 0.5f) * 2;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MoveTransition
|
||||
//-------------------------------------------------------
|
||||
|
||||
MoveTransition::MoveTransition(Duration duration, Direction direction)
|
||||
: Transition(duration)
|
||||
, direction_(direction)
|
||||
{
|
||||
}
|
||||
|
||||
void MoveTransition::Init(ScenePtr const& prev, ScenePtr const& next)
|
||||
{
|
||||
Transition::Init(prev, next);
|
||||
|
||||
switch (direction_)
|
||||
{
|
||||
case Direction::Up:
|
||||
pos_delta_ = Point(0, -window_size_.y);
|
||||
start_pos_ = Point(0, window_size_.y);
|
||||
break;
|
||||
case Direction::Down:
|
||||
pos_delta_ = Point(0, window_size_.y);
|
||||
start_pos_ = Point(0, -window_size_.y);
|
||||
break;
|
||||
case Direction::Left:
|
||||
pos_delta_ = Point(-window_size_.x, 0);
|
||||
start_pos_ = Point(window_size_.x, 0);
|
||||
break;
|
||||
case Direction::Right:
|
||||
pos_delta_ = Point(window_size_.x, 0);
|
||||
start_pos_ = Point(-window_size_.x, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (out_scene_)
|
||||
{
|
||||
out_scene_->SetTransform(Transform{});
|
||||
}
|
||||
|
||||
if (in_scene_)
|
||||
{
|
||||
auto transform = Transform{};
|
||||
transform.position = start_pos_;
|
||||
in_scene_->SetTransform(transform);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveTransition::Update(Duration dt)
|
||||
{
|
||||
Transition::Update(dt);
|
||||
|
||||
if (out_scene_)
|
||||
{
|
||||
auto transform = Transform{};
|
||||
transform.position = pos_delta_ * process_;
|
||||
out_scene_->SetTransform(transform);
|
||||
}
|
||||
|
||||
if (in_scene_)
|
||||
{
|
||||
auto transform = Transform{};
|
||||
transform.position = start_pos_ + pos_delta_ * process_;
|
||||
in_scene_->SetTransform(transform);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveTransition::Reset()
|
||||
{
|
||||
if (out_scene_)
|
||||
{
|
||||
out_scene_->SetTransform(Transform{});
|
||||
}
|
||||
|
||||
if (in_scene_)
|
||||
{
|
||||
in_scene_->SetTransform(Transform{});
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// RotationTransition
|
||||
//-------------------------------------------------------
|
||||
|
||||
RotationTransition::RotationTransition(Duration duration, float rotation)
|
||||
: Transition(duration)
|
||||
, rotation_(rotation)
|
||||
{
|
||||
}
|
||||
|
||||
void RotationTransition::Init(ScenePtr const& prev, ScenePtr const& next)
|
||||
{
|
||||
Transition::Init(prev, next);
|
||||
|
||||
auto transform = Transform{};
|
||||
transform.position = Point{ window_size_.x / 2, window_size_.y / 2 };
|
||||
|
||||
if (out_scene_)
|
||||
{
|
||||
out_scene_->SetTransform(transform);
|
||||
out_scene_->SetAnchor(0.5f, 0.5f);
|
||||
}
|
||||
|
||||
if (in_scene_)
|
||||
{
|
||||
in_scene_->SetTransform(transform);
|
||||
in_scene_->SetAnchor(0.5f, 0.5f);
|
||||
}
|
||||
|
||||
in_layer_prop_.opacity = 0;
|
||||
}
|
||||
|
||||
void RotationTransition::Update(Duration dt)
|
||||
{
|
||||
Transition::Update(dt);
|
||||
|
||||
if (process_ < .5f)
|
||||
{
|
||||
if (out_scene_)
|
||||
{
|
||||
auto transform = out_scene_->GetTransform();
|
||||
transform.scale = Point{ (.5f - process_) * 2, (.5f - process_) * 2 };
|
||||
transform.rotation = rotation_ * (.5f - process_) * 2;
|
||||
out_scene_->SetTransform(transform);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_scene_)
|
||||
{
|
||||
out_layer_prop_.opacity = 0;
|
||||
in_layer_prop_.opacity = 1;
|
||||
|
||||
auto transform = in_scene_->GetTransform();
|
||||
transform.scale = Point{ (process_ - .5f) * 2, (process_ - .5f) * 2 };
|
||||
transform.rotation = rotation_ * (process_ - .5f) * 2;
|
||||
|
||||
in_scene_->SetTransform(transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RotationTransition::Reset()
|
||||
{
|
||||
if (out_scene_)
|
||||
{
|
||||
out_scene_->SetTransform(Transform{});
|
||||
out_scene_->SetAnchor(0.f, 0.f);
|
||||
}
|
||||
|
||||
if (in_scene_)
|
||||
{
|
||||
in_scene_->SetTransform(Transform{});
|
||||
in_scene_->SetAnchor(0.f, 0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "include-forwards.h"
|
||||
#include <d2d1.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class Scene;
|
||||
|
||||
// 场景过渡
|
||||
class E2D_API Transition
|
||||
: public virtual Object
|
||||
{
|
||||
friend class Application;
|
||||
|
||||
public:
|
||||
explicit Transition(
|
||||
Duration duration
|
||||
);
|
||||
|
||||
virtual ~Transition();
|
||||
|
||||
bool IsDone();
|
||||
|
||||
protected:
|
||||
virtual void Init(
|
||||
ScenePtr const& prev,
|
||||
ScenePtr const& next
|
||||
);
|
||||
|
||||
virtual void Update(Duration dt);
|
||||
|
||||
virtual void Render();
|
||||
|
||||
virtual void Stop();
|
||||
|
||||
virtual void Reset() { };
|
||||
|
||||
protected:
|
||||
bool done_;
|
||||
float process_;
|
||||
Duration duration_;
|
||||
Duration delta_;
|
||||
Size window_size_;
|
||||
ScenePtr out_scene_;
|
||||
ScenePtr in_scene_;
|
||||
ComPtr<ID2D1Layer> out_layer_;
|
||||
ComPtr<ID2D1Layer> in_layer_;
|
||||
LayerProperties out_layer_prop_;
|
||||
LayerProperties in_layer_prop_;
|
||||
};
|
||||
|
||||
|
||||
// 淡入淡出过渡
|
||||
class FadeTransition
|
||||
: public Transition
|
||||
{
|
||||
public:
|
||||
explicit FadeTransition(
|
||||
Duration duration /* 动画持续时长 */
|
||||
);
|
||||
|
||||
protected:
|
||||
// 更新动画
|
||||
void Update(Duration dt) override;
|
||||
|
||||
virtual void Init(
|
||||
ScenePtr const& prev,
|
||||
ScenePtr const& next
|
||||
) override;
|
||||
};
|
||||
|
||||
|
||||
// 渐变过渡
|
||||
class EmergeTransition
|
||||
: public Transition
|
||||
{
|
||||
public:
|
||||
explicit EmergeTransition(
|
||||
Duration duration /* 动画持续时长 */
|
||||
);
|
||||
|
||||
protected:
|
||||
void Update(Duration dt) override;
|
||||
|
||||
virtual void Init(
|
||||
ScenePtr const& prev,
|
||||
ScenePtr const& next
|
||||
) override;
|
||||
};
|
||||
|
||||
|
||||
// 盒状过渡
|
||||
class BoxTransition
|
||||
: public Transition
|
||||
{
|
||||
public:
|
||||
explicit BoxTransition(
|
||||
Duration duration /* 动画持续时长 */
|
||||
);
|
||||
|
||||
protected:
|
||||
void Update(Duration dt) override;
|
||||
|
||||
virtual void Init(
|
||||
ScenePtr const& prev,
|
||||
ScenePtr const& next
|
||||
) override;
|
||||
};
|
||||
|
||||
|
||||
// 位移过渡
|
||||
class MoveTransition
|
||||
: public Transition
|
||||
{
|
||||
public:
|
||||
explicit MoveTransition(
|
||||
Duration moveDuration, /* 动画持续时长 */
|
||||
Direction direction /* 移动方向 */
|
||||
);
|
||||
|
||||
protected:
|
||||
void Update(Duration dt) override;
|
||||
|
||||
virtual void Init(
|
||||
ScenePtr const& prev,
|
||||
ScenePtr const& next
|
||||
) override;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
protected:
|
||||
Direction direction_;
|
||||
Point pos_delta_;
|
||||
Point start_pos_;
|
||||
};
|
||||
|
||||
|
||||
// 旋转过渡
|
||||
class RotationTransition
|
||||
: public Transition
|
||||
{
|
||||
public:
|
||||
explicit RotationTransition(
|
||||
Duration moveDuration, /* 动画持续时长 */
|
||||
float rotation = 360 /* 旋转度数 */
|
||||
);
|
||||
|
||||
protected:
|
||||
void Update(Duration dt) override;
|
||||
|
||||
virtual void Init(
|
||||
ScenePtr const& prev,
|
||||
ScenePtr const& next
|
||||
) override;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
protected:
|
||||
float rotation_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Color.h"
|
||||
#include "../common/helper.h"
|
||||
#include "../common/ComPtr.hpp"
|
||||
#include "../common/Closure.hpp"
|
||||
#include "../common/Singleton.hpp"
|
||||
#include "../common/IntrusiveList.hpp"
|
||||
#include "../base/time.h"
|
||||
#include "../base/RefCounter.hpp"
|
||||
#include "../base/SmartPtr.hpp"
|
||||
#include "../base/Object.h"
|
||||
#include "../math/helper.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
E2D_DECLARE_SMART_PTR(Image);
|
||||
E2D_DECLARE_SMART_PTR(Frames);
|
||||
|
||||
E2D_DECLARE_SMART_PTR(Geometry);
|
||||
E2D_DECLARE_SMART_PTR(LineGeometry);
|
||||
E2D_DECLARE_SMART_PTR(RectangleGeometry);
|
||||
E2D_DECLARE_SMART_PTR(RoundedRectGeometry);
|
||||
E2D_DECLARE_SMART_PTR(CircleGeometry);
|
||||
E2D_DECLARE_SMART_PTR(EllipseGeometry);
|
||||
E2D_DECLARE_SMART_PTR(PathGeometry);
|
||||
|
||||
E2D_DECLARE_SMART_PTR(Node);
|
||||
E2D_DECLARE_SMART_PTR(Scene);
|
||||
E2D_DECLARE_SMART_PTR(Layer);
|
||||
E2D_DECLARE_SMART_PTR(Sprite);
|
||||
E2D_DECLARE_SMART_PTR(Text);
|
||||
E2D_DECLARE_SMART_PTR(Canvas);
|
||||
E2D_DECLARE_SMART_PTR(GeometryNode);
|
||||
|
||||
E2D_DECLARE_SMART_PTR(Action);
|
||||
E2D_DECLARE_SMART_PTR(ActionTween);
|
||||
E2D_DECLARE_SMART_PTR(ActionMoveBy);
|
||||
E2D_DECLARE_SMART_PTR(ActionMoveTo);
|
||||
E2D_DECLARE_SMART_PTR(ActionJumpBy);
|
||||
E2D_DECLARE_SMART_PTR(ActionJumpTo);
|
||||
E2D_DECLARE_SMART_PTR(ActionScaleBy);
|
||||
E2D_DECLARE_SMART_PTR(ActionScaleTo);
|
||||
E2D_DECLARE_SMART_PTR(ActionOpacityBy);
|
||||
E2D_DECLARE_SMART_PTR(ActionOpacityTo);
|
||||
E2D_DECLARE_SMART_PTR(ActionFadeIn);
|
||||
E2D_DECLARE_SMART_PTR(ActionFadeOut);
|
||||
E2D_DECLARE_SMART_PTR(ActionRotateBy);
|
||||
E2D_DECLARE_SMART_PTR(ActionRotateTo);
|
||||
E2D_DECLARE_SMART_PTR(ActionPath);
|
||||
E2D_DECLARE_SMART_PTR(Animation);
|
||||
E2D_DECLARE_SMART_PTR(ActionGroup);
|
||||
E2D_DECLARE_SMART_PTR(ActionSpawn);
|
||||
|
||||
E2D_DECLARE_SMART_PTR(Transition);
|
||||
E2D_DECLARE_SMART_PTR(FadeTransition);
|
||||
E2D_DECLARE_SMART_PTR(EmergeTransition);
|
||||
E2D_DECLARE_SMART_PTR(BoxTransition);
|
||||
E2D_DECLARE_SMART_PTR(MoveTransition);
|
||||
E2D_DECLARE_SMART_PTR(RotationTransition);
|
||||
|
||||
E2D_DECLARE_SMART_PTR(Button);
|
||||
E2D_DECLARE_SMART_PTR(Menu);
|
||||
}
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 画笔样式
|
||||
enum class StrokeStyle : int
|
||||
{
|
||||
Miter = 0, /* 斜切 */
|
||||
Bevel = 1, /* 斜角 */
|
||||
Round = 2 /* 圆角 */
|
||||
};
|
||||
|
||||
// 方向
|
||||
enum class Direction : int
|
||||
{
|
||||
Up, /* 上 */
|
||||
Down, /* 下 */
|
||||
Left, /* 左 */
|
||||
Right /* 右 */
|
||||
};
|
||||
|
||||
// 鼠标指针
|
||||
enum class MouseCursor : int
|
||||
{
|
||||
Arrow, /* 指针 */
|
||||
TextInput, /* 输入文本 */
|
||||
Hand, /* 手指 */
|
||||
SizeAll,
|
||||
SizeNESW,
|
||||
SizeNS,
|
||||
SizeNWSE,
|
||||
SizeWE,
|
||||
};
|
||||
|
||||
// 文字抗锯齿属性
|
||||
enum class TextAntialias
|
||||
{
|
||||
Default, // 系统默认
|
||||
ClearType, // ClearType 抗锯齿
|
||||
GrayScale, // 灰度抗锯齿
|
||||
None // 不启用抗锯齿
|
||||
};
|
||||
|
||||
// 图层属性
|
||||
struct LayerProperties
|
||||
{
|
||||
math::Rect area;
|
||||
float opacity;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClInclude Include="easy2d.h" />
|
||||
<ClInclude Include="config.h" />
|
||||
<ClInclude Include="macros.h" />
|
||||
<ClInclude Include="2d\include-forwards.h" />
|
||||
<ClInclude Include="2d\Action.h" />
|
||||
<ClInclude Include="2d\ActionGroup.h" />
|
||||
<ClInclude Include="2d\ActionHelper.h" />
|
||||
<ClInclude Include="2d\ActionManager.h" />
|
||||
<ClInclude Include="2d\ActionTween.h" />
|
||||
<ClInclude Include="2d\Animation.h" />
|
||||
<ClInclude Include="2d\Canvas.h" />
|
||||
<ClInclude Include="2d\Color.h" />
|
||||
<ClInclude Include="2d\DebugNode.h" />
|
||||
<ClInclude Include="2d\Font.hpp" />
|
||||
<ClInclude Include="2d\Frames.h" />
|
||||
<ClInclude Include="2d\Geometry.h" />
|
||||
<ClInclude Include="2d\GeometryNode.h" />
|
||||
<ClInclude Include="2d\Image.h" />
|
||||
<ClInclude Include="2d\Layer.h" />
|
||||
<ClInclude Include="2d\Node.h" />
|
||||
<ClInclude Include="2d\Scene.h" />
|
||||
<ClInclude Include="2d\Sprite.h" />
|
||||
<ClInclude Include="2d\Text.h" />
|
||||
<ClInclude Include="2d\TextStyle.hpp" />
|
||||
<ClInclude Include="2d\Transform.hpp" />
|
||||
<ClInclude Include="2d\Transition.h" />
|
||||
<ClInclude Include="base\AsyncTask.h" />
|
||||
<ClInclude Include="base\Component.h" />
|
||||
<ClInclude Include="base\Event.hpp" />
|
||||
<ClInclude Include="base\EventDispatcher.h" />
|
||||
<ClInclude Include="base\EventListener.h" />
|
||||
<ClInclude Include="base\Input.h" />
|
||||
<ClInclude Include="base\keys.hpp" />
|
||||
<ClInclude Include="base\logs.h" />
|
||||
<ClInclude Include="base\Object.h" />
|
||||
<ClInclude Include="base\RefCounter.hpp" />
|
||||
<ClInclude Include="base\Resource.h" />
|
||||
<ClInclude Include="base\SmartPtr.hpp" />
|
||||
<ClInclude Include="base\Timer.h" />
|
||||
<ClInclude Include="base\TimerManager.h" />
|
||||
<ClInclude Include="base\time.h" />
|
||||
<ClInclude Include="base\window.h" />
|
||||
<ClInclude Include="common\Array.h" />
|
||||
<ClInclude Include="common\closure.hpp" />
|
||||
<ClInclude Include="common\ComPtr.hpp" />
|
||||
<ClInclude Include="common\helper.h" />
|
||||
<ClInclude Include="common\IntrusiveList.hpp" />
|
||||
<ClInclude Include="common\IntrusivePtr.hpp" />
|
||||
<ClInclude Include="common\Json.h" />
|
||||
<ClInclude Include="common\noncopyable.hpp" />
|
||||
<ClInclude Include="common\Singleton.hpp" />
|
||||
<ClInclude Include="common\String.h" />
|
||||
<ClInclude Include="math\constants.hpp" />
|
||||
<ClInclude Include="math\ease.hpp" />
|
||||
<ClInclude Include="math\helper.h" />
|
||||
<ClInclude Include="math\Matrix.hpp" />
|
||||
<ClInclude Include="math\rand.h" />
|
||||
<ClInclude Include="math\Rect.hpp" />
|
||||
<ClInclude Include="math\scalar.hpp" />
|
||||
<ClInclude Include="math\Vec2.hpp" />
|
||||
<ClInclude Include="platform\Application.h" />
|
||||
<ClInclude Include="platform\modules.h" />
|
||||
<ClInclude Include="renderer\D2DDeviceResources.h" />
|
||||
<ClInclude Include="renderer\D3D10DeviceResources.h" />
|
||||
<ClInclude Include="renderer\D3D11DeviceResources.h" />
|
||||
<ClInclude Include="renderer\DeviceResources.h" />
|
||||
<ClInclude Include="renderer\helper.hpp" />
|
||||
<ClInclude Include="renderer\render.h" />
|
||||
<ClInclude Include="renderer\TextRenderer.h" />
|
||||
<ClInclude Include="ui\Button.h" />
|
||||
<ClInclude Include="ui\Menu.h" />
|
||||
<ClInclude Include="utils\DataUtil.h" />
|
||||
<ClInclude Include="utils\File.h" />
|
||||
<ClInclude Include="utils\Path.h" />
|
||||
<ClInclude Include="utils\ResLoader.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="2d\Action.cpp" />
|
||||
<ClCompile Include="2d\ActionGroup.cpp" />
|
||||
<ClCompile Include="2d\ActionManager.cpp" />
|
||||
<ClCompile Include="2d\ActionTween.cpp" />
|
||||
<ClCompile Include="2d\Animation.cpp" />
|
||||
<ClCompile Include="2d\Canvas.cpp" />
|
||||
<ClCompile Include="2d\Color.cpp" />
|
||||
<ClCompile Include="2d\DebugNode.cpp" />
|
||||
<ClCompile Include="2d\Frames.cpp" />
|
||||
<ClCompile Include="2d\Geometry.cpp" />
|
||||
<ClCompile Include="2d\GeometryNode.cpp" />
|
||||
<ClCompile Include="2d\Image.cpp" />
|
||||
<ClCompile Include="2d\Layer.cpp" />
|
||||
<ClCompile Include="2d\Node.cpp" />
|
||||
<ClCompile Include="2d\Scene.cpp" />
|
||||
<ClCompile Include="2d\Sprite.cpp" />
|
||||
<ClCompile Include="2d\Text.cpp" />
|
||||
<ClCompile Include="2d\Transition.cpp" />
|
||||
<ClCompile Include="base\AsyncTask.cpp" />
|
||||
<ClCompile Include="base\EventDispatcher.cpp" />
|
||||
<ClCompile Include="base\EventListener.cpp" />
|
||||
<ClCompile Include="base\Input.cpp" />
|
||||
<ClCompile Include="base\logs.cpp" />
|
||||
<ClCompile Include="base\Object.cpp" />
|
||||
<ClCompile Include="base\Resource.cpp" />
|
||||
<ClCompile Include="base\Timer.cpp" />
|
||||
<ClCompile Include="base\TimerManager.cpp" />
|
||||
<ClCompile Include="base\time.cpp" />
|
||||
<ClCompile Include="base\window.cpp" />
|
||||
<ClCompile Include="platform\Application.cpp" />
|
||||
<ClCompile Include="platform\modules.cpp" />
|
||||
<ClCompile Include="renderer\D2DDeviceResources.cpp" />
|
||||
<ClCompile Include="renderer\D3D10DeviceResources.cpp" />
|
||||
<ClCompile Include="renderer\D3D11DeviceResources.cpp" />
|
||||
<ClCompile Include="renderer\render.cpp" />
|
||||
<ClCompile Include="renderer\TextRenderer.cpp" />
|
||||
<ClCompile Include="ui\Button.cpp" />
|
||||
<ClCompile Include="ui\Menu.cpp" />
|
||||
<ClCompile Include="utils\DataUtil.cpp" />
|
||||
<ClCompile Include="utils\File.cpp" />
|
||||
<ClCompile Include="utils\Path.cpp" />
|
||||
<ClCompile Include="utils\ResLoader.cpp" />
|
||||
</ItemGroup>
|
||||
<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>{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}</ProjectGuid>
|
||||
<RootNamespace>Easy2D</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<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>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -1,378 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="math">
|
||||
<UniqueIdentifier>{80bc6386-2b70-4bae-993c-649a55163a1b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="utils">
|
||||
<UniqueIdentifier>{68eac919-ee87-4030-a033-c251731928f5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ui">
|
||||
<UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="common">
|
||||
<UniqueIdentifier>{86e2d0f2-a9d0-4456-b6a5-d480228bbf82}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="platform">
|
||||
<UniqueIdentifier>{c2654ccc-59f6-4c17-bb6b-99b07fc78702}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="2d">
|
||||
<UniqueIdentifier>{896bdedf-6e82-449b-9b6e-0bc69f3699b1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="base">
|
||||
<UniqueIdentifier>{2e18d99a-e906-499a-9e29-4e0783202644}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="renderer">
|
||||
<UniqueIdentifier>{7897afce-24cb-42b4-9443-56508e4ec89c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ui\Button.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ui\Menu.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Action.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\ActionGroup.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\ActionHelper.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\ActionManager.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\ActionTween.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Animation.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Canvas.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Color.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\DebugNode.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Font.hpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Frames.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Geometry.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\GeometryNode.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Image.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\include-forwards.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Layer.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Node.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Scene.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Sprite.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Text.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\TextStyle.hpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Transform.hpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="2d\Transition.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\Array.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\closure.hpp">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\ComPtr.hpp">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\helper.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\IntrusiveList.hpp">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\IntrusivePtr.hpp">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\noncopyable.hpp">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\Singleton.hpp">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\String.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\Component.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\Event.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\EventDispatcher.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\EventListener.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\keys.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\logs.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\RefCounter.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\Resource.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\time.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="renderer\D2DDeviceResources.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="renderer\D3D10DeviceResources.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="renderer\D3D11DeviceResources.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="renderer\DeviceResources.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="renderer\helper.hpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="renderer\render.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="renderer\TextRenderer.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="math\constants.hpp">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="math\ease.hpp">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="math\Matrix.hpp">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="math\rand.h">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="math\Rect.hpp">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="math\scalar.hpp">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="platform\Application.h">
|
||||
<Filter>platform</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="platform\modules.h">
|
||||
<Filter>platform</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="utils\File.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="utils\Path.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="utils\ResLoader.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="config.h" />
|
||||
<ClInclude Include="macros.h" />
|
||||
<ClInclude Include="math\helper.h">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="math\Vec2.hpp">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\Input.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\window.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\SmartPtr.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\Object.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="easy2d.h" />
|
||||
<ClInclude Include="utils\DataUtil.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common\Json.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\Timer.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\TimerManager.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\AsyncTask.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ui\Button.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ui\Menu.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Action.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\ActionGroup.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\ActionManager.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\ActionTween.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Animation.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Canvas.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Color.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\DebugNode.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Frames.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Geometry.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\GeometryNode.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Image.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Layer.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Node.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Scene.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Sprite.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Text.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2d\Transition.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\EventDispatcher.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\EventListener.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\logs.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\Resource.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\time.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="renderer\D2DDeviceResources.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="renderer\D3D10DeviceResources.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="renderer\D3D11DeviceResources.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="renderer\render.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="renderer\TextRenderer.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="platform\Application.cpp">
|
||||
<Filter>platform</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="platform\modules.cpp">
|
||||
<Filter>platform</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="utils\File.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="utils\Path.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="utils\ResLoader.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\Input.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\window.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\Object.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="utils\DataUtil.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\Timer.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\TimerManager.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\AsyncTask.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class Application;
|
||||
|
||||
class Component
|
||||
{
|
||||
public:
|
||||
virtual void SetupComponent(Application*) = 0;
|
||||
|
||||
virtual void DestroyComponent() = 0;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "keys.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
||||
// 鼠标事件
|
||||
struct MouseEvent
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
bool left_btn_down; // 左键是否按下
|
||||
bool right_btn_down; // 右键是否按下
|
||||
|
||||
union
|
||||
{
|
||||
struct // Events::MouseDown | Events::MouseUp | Events::MouseClick
|
||||
{
|
||||
int button;
|
||||
};
|
||||
|
||||
struct // Events::MouseWheel
|
||||
{
|
||||
float wheel;
|
||||
};
|
||||
};
|
||||
|
||||
static bool Check(UINT type);
|
||||
};
|
||||
|
||||
// 键盘事件
|
||||
struct KeyboardEvent
|
||||
{
|
||||
int count;
|
||||
union
|
||||
{
|
||||
struct // Events::KeyDown | Events::KeyUp
|
||||
{
|
||||
int code; // enum KeyCode
|
||||
};
|
||||
|
||||
struct // Events::Char
|
||||
{
|
||||
char c;
|
||||
};
|
||||
};
|
||||
|
||||
static bool Check(UINT type);
|
||||
};
|
||||
|
||||
// 窗口事件
|
||||
struct WindowEvent
|
||||
{
|
||||
union
|
||||
{
|
||||
struct // Events::WindowMoved
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct // Events::WindowResized
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct // Events::WindowFocusChanged
|
||||
{
|
||||
bool focus;
|
||||
};
|
||||
|
||||
struct // Events::WindowTitleChanged
|
||||
{
|
||||
const wchar_t* title;
|
||||
};
|
||||
};
|
||||
|
||||
static bool Check(UINT type);
|
||||
};
|
||||
|
||||
// 自定义事件
|
||||
struct CustomEvent
|
||||
{
|
||||
void* data;
|
||||
};
|
||||
|
||||
class Node;
|
||||
|
||||
// 事件
|
||||
struct E2D_API Event
|
||||
{
|
||||
enum Type : UINT
|
||||
{
|
||||
First,
|
||||
|
||||
// 鼠标事件
|
||||
MouseFirst,
|
||||
MouseMove, // 移动
|
||||
MouseBtnDown, // 鼠标按下
|
||||
MouseBtnUp, // 鼠标抬起
|
||||
MouseWheel, // 滚轮滚动
|
||||
MouseHover, // 鼠标移入
|
||||
MouseOut, // 鼠标移出
|
||||
Click, // 鼠标点击
|
||||
MouseLast,
|
||||
|
||||
// 按键事件
|
||||
KeyFirst,
|
||||
KeyDown, // 按键按下
|
||||
KeyUp, // 按键抬起
|
||||
Char, // 输出字符
|
||||
KeyLast,
|
||||
|
||||
// 窗口消息
|
||||
WindowFirst,
|
||||
WindowMoved, // 窗口移动
|
||||
WindowResized, // 窗口大小变化
|
||||
WindowFocusChanged, // 获得或失去焦点
|
||||
WindowTitleChanged, // 标题变化
|
||||
WindowClosed, // 窗口被关闭
|
||||
WindowLast,
|
||||
|
||||
Last
|
||||
};
|
||||
|
||||
UINT type;
|
||||
Node* target;
|
||||
|
||||
union
|
||||
{
|
||||
MouseEvent mouse;
|
||||
KeyboardEvent key;
|
||||
WindowEvent win;
|
||||
CustomEvent custom;
|
||||
};
|
||||
|
||||
Event(UINT type = Type::First) : type(type), target(nullptr) {}
|
||||
};
|
||||
|
||||
|
||||
// Check-functions
|
||||
|
||||
inline bool MouseEvent::Check(UINT type)
|
||||
{
|
||||
return type > Event::MouseFirst && type < Event::MouseLast;
|
||||
}
|
||||
|
||||
inline bool KeyboardEvent::Check(UINT type)
|
||||
{
|
||||
return type > Event::KeyFirst && type < Event::KeyLast;
|
||||
}
|
||||
|
||||
inline bool WindowEvent::Check(UINT type)
|
||||
{
|
||||
return type > Event::WindowFirst && type < Event::WindowLast;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "EventDispatcher.h"
|
||||
#include "../base/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
void EventDispatcher::Dispatch(Event& evt)
|
||||
{
|
||||
if (listeners_.IsEmpty())
|
||||
return;
|
||||
|
||||
EventListenerPtr next;
|
||||
for (auto listener = listeners_.First(); listener; listener = next)
|
||||
{
|
||||
next = listener->NextItem();
|
||||
|
||||
if (listener->type_ == evt.type)
|
||||
{
|
||||
listener->callback_(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EventListenerPtr EventDispatcher::AddListener(EventListenerPtr const & listener)
|
||||
{
|
||||
E2D_ASSERT(listener && "AddListener failed, NULL pointer exception");
|
||||
|
||||
if (listener)
|
||||
{
|
||||
listeners_.PushBack(listener);
|
||||
}
|
||||
return listener;
|
||||
}
|
||||
|
||||
void EventDispatcher::AddListener(UINT type, EventCallback callback, String const& name)
|
||||
{
|
||||
EventListenerPtr listener = new EventListener(type, callback, name);
|
||||
if (listener)
|
||||
{
|
||||
listeners_.PushBack(listener);
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::StartListeners(String const & listener_name)
|
||||
{
|
||||
for (auto listener = listeners_.First(); listener; listener = listener->NextItem())
|
||||
{
|
||||
if (listener->IsName(listener_name))
|
||||
{
|
||||
listener->Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::StopListeners(String const & listener_name)
|
||||
{
|
||||
for (auto listener = listeners_.First(); listener; listener = listener->NextItem())
|
||||
{
|
||||
if (listener->IsName(listener_name))
|
||||
{
|
||||
listener->Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::RemoveListeners(String const & listener_name)
|
||||
{
|
||||
EventListenerPtr next;
|
||||
for (auto listener = listeners_.First(); listener; listener = next)
|
||||
{
|
||||
next = listener->NextItem();
|
||||
|
||||
if (listener->IsName(listener_name))
|
||||
{
|
||||
listeners_.Remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::StartListeners(UINT type)
|
||||
{
|
||||
for (auto listener = listeners_.First(); listener; listener = listener->NextItem())
|
||||
{
|
||||
if (listener->type_ == type)
|
||||
{
|
||||
listener->Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::StopListeners(UINT type)
|
||||
{
|
||||
for (auto listener = listeners_.First(); listener; listener = listener->NextItem())
|
||||
{
|
||||
if (listener->type_ == type)
|
||||
{
|
||||
listener->Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::RemoveListeners(UINT type)
|
||||
{
|
||||
EventListenerPtr next;
|
||||
for (auto listener = listeners_.First(); listener; listener = next)
|
||||
{
|
||||
next = listener->NextItem();
|
||||
|
||||
if (listener->type_ == type)
|
||||
{
|
||||
listeners_.Remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "EventListener.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API EventDispatcher
|
||||
{
|
||||
using Listeners = IntrusiveList<EventListenerPtr>;
|
||||
|
||||
public:
|
||||
// 添加监听器
|
||||
EventListenerPtr AddListener(
|
||||
EventListenerPtr const& listener
|
||||
);
|
||||
|
||||
// 添加监听器
|
||||
void AddListener(
|
||||
UINT type,
|
||||
EventCallback callback,
|
||||
String const& name = L""
|
||||
);
|
||||
|
||||
// 启动监听器
|
||||
void StartListeners(
|
||||
String const& listener_name
|
||||
);
|
||||
|
||||
// 停止监听器
|
||||
void StopListeners(
|
||||
String const& listener_name
|
||||
);
|
||||
|
||||
// 移除监听器
|
||||
void RemoveListeners(
|
||||
String const& listener_name
|
||||
);
|
||||
|
||||
// 启动监听器
|
||||
void StartListeners(
|
||||
UINT type
|
||||
);
|
||||
|
||||
// 停止监听器
|
||||
void StopListeners(
|
||||
UINT type
|
||||
);
|
||||
|
||||
// 移除监听器
|
||||
void RemoveListeners(
|
||||
UINT type
|
||||
);
|
||||
|
||||
virtual void Dispatch(Event& evt);
|
||||
|
||||
protected:
|
||||
Listeners listeners_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "EventListener.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
EventListener::EventListener(UINT type, EventCallback const & callback, String const & name)
|
||||
: type_(type)
|
||||
, callback_(callback)
|
||||
, running_(true)
|
||||
{
|
||||
SetName(name);
|
||||
}
|
||||
|
||||
EventListener::~EventListener()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../base/SmartPtr.hpp"
|
||||
#include "../common/helper.h"
|
||||
#include "../common/IntrusiveList.hpp"
|
||||
#include "Object.h"
|
||||
#include "Event.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
typedef std::function<void(Event const&)> EventCallback;
|
||||
|
||||
class EventDispatcher;
|
||||
|
||||
E2D_DECLARE_SMART_PTR(EventListener);
|
||||
|
||||
// ʼþ¼àÌýÆ÷
|
||||
class E2D_API EventListener
|
||||
: public virtual Object
|
||||
, protected IntrusiveListItem<EventListenerPtr>
|
||||
{
|
||||
friend class EventDispatcher;
|
||||
friend class IntrusiveList<EventListenerPtr>;
|
||||
|
||||
public:
|
||||
EventListener(
|
||||
UINT type,
|
||||
EventCallback const& callback,
|
||||
String const& name = L""
|
||||
);
|
||||
|
||||
virtual ~EventListener();
|
||||
|
||||
inline void Start() { running_ = true; }
|
||||
|
||||
inline void Stop() { running_ = true; }
|
||||
|
||||
inline bool IsRunning() const { return running_; }
|
||||
|
||||
protected:
|
||||
bool running_;
|
||||
UINT type_;
|
||||
EventCallback callback_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "input.h"
|
||||
#include "logs.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Input::Input()
|
||||
: want_update_(false)
|
||||
, mouse_pos_x_(0.f)
|
||||
, mouse_pos_y_(0.f)
|
||||
{
|
||||
ZeroMemory(keys_, sizeof(keys_));
|
||||
ZeroMemory(keys_pressed_, sizeof(keys_pressed_));
|
||||
ZeroMemory(keys_released_, sizeof(keys_released_));
|
||||
}
|
||||
|
||||
Input::~Input()
|
||||
{
|
||||
}
|
||||
|
||||
void Input::Update()
|
||||
{
|
||||
if (want_update_)
|
||||
{
|
||||
want_update_ = false;
|
||||
|
||||
ZeroMemory(keys_pressed_, sizeof(keys_pressed_));
|
||||
ZeroMemory(keys_released_, sizeof(keys_released_));
|
||||
}
|
||||
}
|
||||
|
||||
void Input::UpdateKey(int key, bool down)
|
||||
{
|
||||
if (down && !keys_[key])
|
||||
keys_pressed_[key] = true;
|
||||
if (!down && keys_[key])
|
||||
keys_released_[key] = true;
|
||||
|
||||
keys_[key] = down;
|
||||
|
||||
want_update_ = true;
|
||||
}
|
||||
|
||||
void Input::UpdateMousePos(float x, float y)
|
||||
{
|
||||
mouse_pos_x_ = x;
|
||||
mouse_pos_y_ = y;
|
||||
}
|
||||
|
||||
bool Input::IsDown(int key_or_btn)
|
||||
{
|
||||
E2D_ASSERT(key_or_btn >= 0 && key_or_btn < KEY_NUM);
|
||||
return keys_[key_or_btn];
|
||||
}
|
||||
|
||||
bool Input::WasPressed(int key_or_btn)
|
||||
{
|
||||
E2D_ASSERT(key_or_btn >= 0 && key_or_btn < KEY_NUM);
|
||||
return keys_pressed_[key_or_btn];
|
||||
}
|
||||
|
||||
bool Input::WasReleased(int key_or_btn)
|
||||
{
|
||||
E2D_ASSERT(key_or_btn >= 0 && key_or_btn < KEY_NUM);
|
||||
return keys_released_[key_or_btn];
|
||||
}
|
||||
|
||||
float Input::GetMouseX()
|
||||
{
|
||||
return mouse_pos_x_;
|
||||
}
|
||||
|
||||
float Input::GetMouseY()
|
||||
{
|
||||
return mouse_pos_y_;
|
||||
}
|
||||
|
||||
Point Input::GetMousePos()
|
||||
{
|
||||
return Point{ mouse_pos_x_, mouse_pos_y_ };
|
||||
}
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../macros.h"
|
||||
#include "../common/Singleton.hpp"
|
||||
#include "../math/helper.h"
|
||||
#include "keys.hpp"
|
||||
#include "Component.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API Input
|
||||
: public Singleton<Input>
|
||||
, public Component
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(Input);
|
||||
|
||||
public:
|
||||
// 检测键盘或鼠标按键是否正被按下
|
||||
bool IsDown(
|
||||
int key_or_btn
|
||||
);
|
||||
|
||||
// 检测键盘或鼠标按键是否刚被点击
|
||||
bool WasPressed(
|
||||
int key_or_btn
|
||||
);
|
||||
|
||||
// 检测键盘或鼠标按键是否刚抬起
|
||||
bool WasReleased(
|
||||
int key_or_btn
|
||||
);
|
||||
|
||||
// 获得鼠标 x 坐标
|
||||
float GetMouseX();
|
||||
|
||||
// 获得鼠标 y 坐标
|
||||
float GetMouseY();
|
||||
|
||||
// 获得鼠标坐标
|
||||
Point GetMousePos();
|
||||
|
||||
public:
|
||||
void SetupComponent(Application*) override {}
|
||||
|
||||
void DestroyComponent() override {}
|
||||
|
||||
void Update();
|
||||
|
||||
void UpdateKey(int, bool);
|
||||
|
||||
void UpdateMousePos(float, float);
|
||||
|
||||
protected:
|
||||
Input();
|
||||
|
||||
~Input();
|
||||
|
||||
protected:
|
||||
static const int KEY_NUM = 256;
|
||||
|
||||
bool want_update_;
|
||||
bool keys_[KEY_NUM];
|
||||
bool keys_pressed_[KEY_NUM];
|
||||
bool keys_released_[KEY_NUM];
|
||||
float mouse_pos_x_;
|
||||
float mouse_pos_y_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Object.h"
|
||||
#include "logs.h"
|
||||
#include <typeinfo>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool tracing_leaks = false;
|
||||
Array<Object*> tracing_objects;
|
||||
}
|
||||
|
||||
unsigned int Object::last_object_id = 0;
|
||||
|
||||
Object::Object()
|
||||
: tracing_leak_(false)
|
||||
, user_data_(nullptr)
|
||||
, name_(nullptr)
|
||||
, id_(++last_object_id)
|
||||
{
|
||||
#ifdef E2D_DEBUG
|
||||
|
||||
Object::__AddObjectToTracingList(this);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Object::~Object()
|
||||
{
|
||||
if (name_)
|
||||
delete name_;
|
||||
|
||||
#ifdef E2D_DEBUG
|
||||
|
||||
Object::__RemoveObjectFromTracingList(this);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void * Object::GetUserData() const
|
||||
{
|
||||
return user_data_;
|
||||
}
|
||||
|
||||
void Object::SetUserData(void * data)
|
||||
{
|
||||
user_data_ = data;
|
||||
}
|
||||
|
||||
void Object::SetName(String const & name)
|
||||
{
|
||||
if (IsName(name))
|
||||
return;
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
if (name_)
|
||||
name_->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!name_)
|
||||
{
|
||||
name_ = new (std::nothrow) String(name);
|
||||
return;
|
||||
}
|
||||
|
||||
*name_ = name;
|
||||
}
|
||||
|
||||
String Object::DumpObject()
|
||||
{
|
||||
String name = typeid(*this).name();
|
||||
return String::format(L"{ class=\"%s\" id=%d refcount=%d name=\"%s\" }",
|
||||
name.c_str(), GetObjectID(), GetRefCount(), GetName().c_str());
|
||||
}
|
||||
|
||||
void Object::StartTracingLeaks()
|
||||
{
|
||||
tracing_leaks = true;
|
||||
}
|
||||
|
||||
void Object::StopTracingLeaks()
|
||||
{
|
||||
tracing_leaks = false;
|
||||
}
|
||||
|
||||
void Object::DumpTracingObjects()
|
||||
{
|
||||
E2D_LOG(L"-------------------------- All Objects --------------------------");
|
||||
for (const auto object : tracing_objects)
|
||||
{
|
||||
E2D_LOG(object->DumpObject().c_str());
|
||||
}
|
||||
E2D_LOG(L"------------------------- Total size: %d -------------------------", tracing_objects.size());
|
||||
}
|
||||
|
||||
Array<Object*>& easy2d::Object::__GetTracingObjects()
|
||||
{
|
||||
return tracing_objects;
|
||||
}
|
||||
|
||||
void Object::__AddObjectToTracingList(Object * obj)
|
||||
{
|
||||
#ifdef E2D_DEBUG
|
||||
|
||||
if (tracing_leaks && !obj->tracing_leak_)
|
||||
{
|
||||
obj->tracing_leak_ = true;
|
||||
tracing_objects.push_back(obj);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void Object::__RemoveObjectFromTracingList(Object * obj)
|
||||
{
|
||||
#ifdef E2D_DEBUG
|
||||
|
||||
if (tracing_leaks && obj->tracing_leak_)
|
||||
{
|
||||
obj->tracing_leak_ = false;
|
||||
|
||||
auto iter = std::find(tracing_objects.begin(), tracing_objects.end(), obj);
|
||||
if (iter != tracing_objects.end())
|
||||
{
|
||||
tracing_objects.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../macros.h"
|
||||
#include "../common/helper.h"
|
||||
#include "RefCounter.hpp"
|
||||
#include "SmartPtr.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
E2D_DECLARE_SMART_PTR(Object);
|
||||
|
||||
class E2D_API Object
|
||||
: public RefCounter
|
||||
{
|
||||
public:
|
||||
Object();
|
||||
|
||||
virtual ~Object();
|
||||
|
||||
void* GetUserData() const;
|
||||
|
||||
void SetUserData(void* data);
|
||||
|
||||
void SetName(String const& name);
|
||||
|
||||
inline String GetName() const { if (name_) return *name_; return String(); }
|
||||
|
||||
inline bool IsName(String const& name) const { return name_ ? (*name_ == name) : name.empty(); }
|
||||
|
||||
inline unsigned int GetObjectID() const { return id_; }
|
||||
|
||||
String DumpObject();
|
||||
|
||||
public:
|
||||
static void StartTracingLeaks();
|
||||
|
||||
static void StopTracingLeaks();
|
||||
|
||||
static void DumpTracingObjects();
|
||||
|
||||
public:
|
||||
static Array<Object*>& __GetTracingObjects();
|
||||
|
||||
static void __AddObjectToTracingList(Object*);
|
||||
|
||||
static void __RemoveObjectFromTracingList(Object*);
|
||||
|
||||
private:
|
||||
bool tracing_leak_;
|
||||
void* user_data_;
|
||||
String* name_;
|
||||
|
||||
const unsigned int id_;
|
||||
static unsigned int last_object_id;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../macros.h"
|
||||
#include "../common/noncopyable.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API RefCounter
|
||||
: protected Noncopyable
|
||||
{
|
||||
public:
|
||||
// 增加引用计数
|
||||
inline void Retain() { ++ref_count_; }
|
||||
|
||||
// 减少引用计数
|
||||
inline void Release()
|
||||
{
|
||||
if (--ref_count_ <= 0)
|
||||
delete this;
|
||||
}
|
||||
|
||||
// 获取引用计数
|
||||
inline long GetRefCount() const { return ref_count_; }
|
||||
|
||||
protected:
|
||||
RefCounter() : ref_count_(0) {}
|
||||
|
||||
virtual ~RefCounter() {}
|
||||
|
||||
protected:
|
||||
long ref_count_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Resource.h"
|
||||
#include "../base/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Resource::Resource(LPCWSTR file_name)
|
||||
: type_(Type::File)
|
||||
, file_name_(nullptr)
|
||||
{
|
||||
if (file_name)
|
||||
file_name_ = new (std::nothrow) String(file_name);
|
||||
}
|
||||
|
||||
Resource::Resource(String const& file_name)
|
||||
: type_(Type::File)
|
||||
, file_name_(nullptr)
|
||||
{
|
||||
if (!file_name.empty())
|
||||
file_name_ = new (std::nothrow) String(file_name);
|
||||
}
|
||||
|
||||
Resource::Resource(LPCWSTR name, LPCWSTR type)
|
||||
: type_(Type::Binary)
|
||||
, bin_name_(name)
|
||||
, bin_type_(type)
|
||||
{
|
||||
}
|
||||
|
||||
Resource::Resource(Resource const & rhs)
|
||||
{
|
||||
operator=(rhs);
|
||||
}
|
||||
|
||||
Resource::~Resource()
|
||||
{
|
||||
if (IsFileType() && file_name_)
|
||||
delete file_name_;
|
||||
}
|
||||
|
||||
size_t Resource::GetHashCode() const
|
||||
{
|
||||
if (type_ == Type::File)
|
||||
return std::hash<String>{}(GetFileName());
|
||||
return std::hash<LPCWSTR>{}(bin_name_);
|
||||
}
|
||||
|
||||
Resource & Resource::operator=(Resource const & rhs)
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
if (IsFileType() && file_name_)
|
||||
{
|
||||
delete file_name_;
|
||||
file_name_ = nullptr;
|
||||
}
|
||||
|
||||
type_ = rhs.type_;
|
||||
if (IsFileType())
|
||||
{
|
||||
if (rhs.file_name_)
|
||||
{
|
||||
file_name_ = new (std::nothrow) String(*rhs.file_name_);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bin_name_ = rhs.bin_name_;
|
||||
bin_type_ = rhs.bin_type_;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Resource::Load(LPVOID& buffer, DWORD& buffer_size) const
|
||||
{
|
||||
if (type_ != Type::Binary)
|
||||
{
|
||||
E2D_ERROR_LOG(L"Only binary resource can be loaded");
|
||||
return false;
|
||||
}
|
||||
|
||||
HGLOBAL res_data;
|
||||
HRSRC res_info;
|
||||
|
||||
res_info = FindResourceW(nullptr, bin_name_, bin_type_);
|
||||
if (res_info == nullptr)
|
||||
{
|
||||
E2D_ERROR_LOG(L"FindResource failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
res_data = LoadResource(nullptr, res_info);
|
||||
if (res_data == nullptr)
|
||||
{
|
||||
E2D_ERROR_LOG(L"LoadResource failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer_size = SizeofResource(nullptr, res_info);
|
||||
if (buffer_size == 0)
|
||||
{
|
||||
E2D_ERROR_LOG(L"SizeofResource failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer = LockResource(res_data);
|
||||
if (buffer == nullptr)
|
||||
{
|
||||
E2D_ERROR_LOG(L"LockResource failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../macros.h"
|
||||
#include "../common/helper.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 资源
|
||||
//
|
||||
// 资源可以是文件类型,也可以是保存在 exe 中的二进制资源
|
||||
// 例如, 一份音频资源的类型为 L"WAVE", 名称标识符为 IDR_WAVE_1,
|
||||
// 那么可以这样指定该资源: Resource res(MAKEINTRESOURCE(IDR_WAVE_1), L"WAVE");
|
||||
//
|
||||
// 了解资源的更多信息: https://docs.microsoft.com/en-us/windows/desktop/menurc/resources
|
||||
//
|
||||
class E2D_API Resource
|
||||
{
|
||||
enum class Type { File, Binary };
|
||||
|
||||
public:
|
||||
Resource(
|
||||
LPCWSTR file_name /* 文件路径 */
|
||||
);
|
||||
|
||||
Resource(
|
||||
String const& file_name /* 文件路径 */
|
||||
);
|
||||
|
||||
Resource(
|
||||
LPCWSTR name, /* 资源名称 */
|
||||
LPCWSTR type /* 资源类型 */
|
||||
);
|
||||
|
||||
Resource(
|
||||
Resource const& rhs
|
||||
);
|
||||
|
||||
virtual ~Resource();
|
||||
|
||||
inline bool IsFileType() const { return type_ == Type::File; }
|
||||
|
||||
inline String GetFileName() const { if (file_name_) return *file_name_; return String(); }
|
||||
|
||||
bool Load(
|
||||
LPVOID& buffer,
|
||||
DWORD& buffer_size
|
||||
) const;
|
||||
|
||||
size_t GetHashCode() const;
|
||||
|
||||
Resource& operator= (Resource const& rhs);
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
String* file_name_;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
LPCWSTR bin_name_;
|
||||
LPCWSTR bin_type_;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../base/RefCounter.hpp"
|
||||
#include "../common/IntrusivePtr.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
struct DefaultIntrusivePtrManager
|
||||
{
|
||||
static inline void AddRef(RefCounter* ptr)
|
||||
{
|
||||
if (ptr) ptr->Retain();
|
||||
}
|
||||
|
||||
static inline void Release(RefCounter* ptr)
|
||||
{
|
||||
if (ptr) ptr->Release();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename _Ty>
|
||||
using SmartPtr = IntrusivePtr<_Ty, DefaultIntrusivePtrManager, true>;
|
||||
|
||||
}
|
||||
|
||||
#ifndef E2D_DECLARE_SMART_PTR
|
||||
#define E2D_DECLARE_SMART_PTR(CLASS)\
|
||||
class CLASS;\
|
||||
using CLASS##Ptr = ::easy2d::SmartPtr< CLASS >
|
||||
#endif
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Timer.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Timer::Timer(Callback const& func, String const& name)
|
||||
: Timer(func, Duration{}, -1, name)
|
||||
{
|
||||
}
|
||||
|
||||
Timer::Timer(Callback const& func, Duration delay, int times, String const& name)
|
||||
: running_(true)
|
||||
, run_times_(0)
|
||||
, total_times_(times)
|
||||
, delay_(delay)
|
||||
, callback_(func)
|
||||
, delta_()
|
||||
{
|
||||
SetName(name);
|
||||
}
|
||||
|
||||
void Timer::Start()
|
||||
{
|
||||
running_ = true;
|
||||
}
|
||||
|
||||
void Timer::Stop()
|
||||
{
|
||||
running_ = false;
|
||||
}
|
||||
|
||||
void Timer::Update(Duration dt, bool& remove_after_update)
|
||||
{
|
||||
if (!running_)
|
||||
return;
|
||||
|
||||
if (total_times_ == 0)
|
||||
{
|
||||
remove_after_update = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!delay_.IsZero())
|
||||
{
|
||||
delta_ += dt;
|
||||
if (delta_ < delay_)
|
||||
return;
|
||||
}
|
||||
|
||||
++run_times_;
|
||||
|
||||
if (callback_)
|
||||
{
|
||||
callback_();
|
||||
}
|
||||
|
||||
if (run_times_ == total_times_)
|
||||
{
|
||||
remove_after_update = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::Reset()
|
||||
{
|
||||
delta_ = Duration{};
|
||||
run_times_ = 0;
|
||||
}
|
||||
|
||||
bool Timer::IsRunning() const
|
||||
{
|
||||
return running_;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../common/helper.h"
|
||||
#include "../common/IntrusiveList.hpp"
|
||||
#include "Object.h"
|
||||
#include "time.h"
|
||||
#include <functional>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class TimerManager;
|
||||
|
||||
E2D_DECLARE_SMART_PTR(Timer);
|
||||
|
||||
// 定时任务
|
||||
class E2D_API Timer
|
||||
: public virtual Object
|
||||
, protected IntrusiveListItem<TimerPtr>
|
||||
{
|
||||
friend class TimerManager;
|
||||
friend class IntrusiveList<TimerPtr>;
|
||||
|
||||
using Callback = std::function<void()>;
|
||||
|
||||
public:
|
||||
explicit Timer(
|
||||
Callback const& func, /* 执行函数 */
|
||||
String const& name = L"" /* 任务名称 */
|
||||
);
|
||||
|
||||
explicit Timer(
|
||||
Callback const& func, /* 执行函数 */
|
||||
Duration delay, /* 时间间隔(秒) */
|
||||
int times = -1, /* 执行次数(设 -1 为永久执行) */
|
||||
String const& name = L"" /* 任务名称 */
|
||||
);
|
||||
|
||||
// 启动任务
|
||||
void Start();
|
||||
|
||||
// 停止任务
|
||||
void Stop();
|
||||
|
||||
// 任务是否正在执行
|
||||
bool IsRunning() const;
|
||||
|
||||
protected:
|
||||
void Update(Duration dt, bool& remove_after_update);
|
||||
|
||||
void Reset();
|
||||
|
||||
protected:
|
||||
bool running_;
|
||||
int run_times_;
|
||||
int total_times_;
|
||||
Duration delay_;
|
||||
Duration delta_;
|
||||
Callback callback_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "TimerManager.h"
|
||||
#include "../base/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
void TimerManager::UpdateTimers(Duration dt)
|
||||
{
|
||||
if (timers_.IsEmpty())
|
||||
return;
|
||||
|
||||
TimerPtr next;
|
||||
for (auto timer = timers_.First(); timer; timer = next)
|
||||
{
|
||||
next = timer->NextItem();
|
||||
|
||||
bool remove_after_update = false;
|
||||
timer->Update(dt, remove_after_update);
|
||||
|
||||
if (remove_after_update)
|
||||
timers_.Remove(timer);
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::AddTimer(TimerPtr const& timer)
|
||||
{
|
||||
E2D_ASSERT(timer && "AddTimer failed, NULL pointer exception");
|
||||
|
||||
if (timer)
|
||||
{
|
||||
timer->Reset();
|
||||
timers_.PushBack(timer);
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::StopTimers(String const& name)
|
||||
{
|
||||
if (timers_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (auto timer = timers_.First().Get(); timer; timer = timer->NextItem().Get())
|
||||
{
|
||||
if (timer->IsName(name))
|
||||
{
|
||||
timer->Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::StartTimers(String const& name)
|
||||
{
|
||||
if (timers_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (auto timer = timers_.First().Get(); timer; timer = timer->NextItem().Get())
|
||||
{
|
||||
if (timer->IsName(name))
|
||||
{
|
||||
timer->Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::RemoveTimers(String const& name)
|
||||
{
|
||||
if (timers_.IsEmpty())
|
||||
return;
|
||||
|
||||
TimerPtr next;
|
||||
for (auto timer = timers_.First(); timer; timer = next)
|
||||
{
|
||||
next = timer->NextItem();
|
||||
if (timer->IsName(name))
|
||||
{
|
||||
timers_.Remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::StopAllTimers()
|
||||
{
|
||||
if (timers_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (auto timer = timers_.First().Get(); timer; timer = timer->NextItem().Get())
|
||||
{
|
||||
timer->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::StartAllTimers()
|
||||
{
|
||||
if (timers_.IsEmpty())
|
||||
return;
|
||||
|
||||
for (auto timer = timers_.First().Get(); timer; timer = timer->NextItem().Get())
|
||||
{
|
||||
timer->Start();
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::RemoveAllTimers()
|
||||
{
|
||||
timers_.Clear();
|
||||
}
|
||||
|
||||
const TimerManager::Timers & TimerManager::GetAllTimers() const
|
||||
{
|
||||
return timers_;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "Timer.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API TimerManager
|
||||
{
|
||||
using Timers = IntrusiveList<TimerPtr>;
|
||||
|
||||
public:
|
||||
// 添加任务
|
||||
void AddTimer(
|
||||
TimerPtr const& timer
|
||||
);
|
||||
|
||||
// 启动任务
|
||||
void StartTimers(
|
||||
String const& timer_name
|
||||
);
|
||||
|
||||
// 停止任务
|
||||
void StopTimers(
|
||||
String const& timer_name
|
||||
);
|
||||
|
||||
// 移除任务
|
||||
void RemoveTimers(
|
||||
String const& timer_name
|
||||
);
|
||||
|
||||
// 启动所有任务
|
||||
void StartAllTimers();
|
||||
|
||||
// 停止所有任务
|
||||
void StopAllTimers();
|
||||
|
||||
// 移除所有任务
|
||||
void RemoveAllTimers();
|
||||
|
||||
// 获取所有任务
|
||||
const Timers& GetAllTimers() const;
|
||||
|
||||
protected:
|
||||
void UpdateTimers(Duration dt);
|
||||
|
||||
protected:
|
||||
Timers timers_;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../macros.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// 報炎梓囚
|
||||
struct MouseButton
|
||||
{
|
||||
typedef int Value;
|
||||
|
||||
enum : Value
|
||||
{
|
||||
Left = VK_LBUTTON, // 報炎恣囚
|
||||
Right = VK_RBUTTON, // 報炎嘔囚
|
||||
Middle = VK_MBUTTON // 報炎嶄囚
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// 梓囚囚峙
|
||||
struct KeyCode
|
||||
{
|
||||
typedef int Value;
|
||||
|
||||
enum : Value
|
||||
{
|
||||
Unknown = 0,
|
||||
Up = VK_UP,
|
||||
Left = VK_LEFT,
|
||||
Right = VK_RIGHT,
|
||||
Down = VK_DOWN,
|
||||
Enter = VK_RETURN,
|
||||
Space = VK_SPACE,
|
||||
Esc = VK_ESCAPE,
|
||||
Ctrl = VK_CONTROL,
|
||||
Shift = VK_SHIFT,
|
||||
Alt = VK_MENU,
|
||||
Tab = VK_TAB,
|
||||
Delete = VK_DELETE,
|
||||
Back = VK_BACK,
|
||||
|
||||
A = 0x41,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
K,
|
||||
L,
|
||||
M,
|
||||
N,
|
||||
O,
|
||||
P,
|
||||
Q,
|
||||
R,
|
||||
S,
|
||||
T,
|
||||
U,
|
||||
V,
|
||||
W,
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
|
||||
Num0 = 0x30,
|
||||
Num1,
|
||||
Num2,
|
||||
Num3,
|
||||
Num4,
|
||||
Num5,
|
||||
Num6,
|
||||
Num7,
|
||||
Num8,
|
||||
Num9,
|
||||
|
||||
Numpad0 = VK_NUMPAD0,
|
||||
Numpad1,
|
||||
Numpad2,
|
||||
Numpad3,
|
||||
Numpad4,
|
||||
Numpad5,
|
||||
Numpad6,
|
||||
Numpad7,
|
||||
Numpad8,
|
||||
Numpad9,
|
||||
|
||||
F1 = VK_F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
F11,
|
||||
F12,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace __console_colors
|
||||
{
|
||||
const WORD _blue = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
|
||||
const WORD _green = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||
const WORD _red = FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||
const WORD _yellow = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||
const WORD _white = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||
|
||||
const WORD _blue_bg = _white | BACKGROUND_BLUE | BACKGROUND_INTENSITY;
|
||||
const WORD _green_bg = _white | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
|
||||
const WORD _red_bg = _white | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||
const WORD _yellow_bg = BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||
const WORD _white_bg = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||
|
||||
const WORD _reset = _white;
|
||||
|
||||
#define DECLARE_HANDLE_COLOR(NAME, HANDLE_NAME, COLOR)\
|
||||
inline std::wostream& (NAME)(std::wostream& _out)\
|
||||
{ ::SetConsoleTextAttribute(::GetStdHandle(HANDLE_NAME), _##COLOR); return _out; }
|
||||
|
||||
#define DECLARE_COLOR(COLOR) \
|
||||
DECLARE_HANDLE_COLOR(stdout_##COLOR, STD_OUTPUT_HANDLE, COLOR)\
|
||||
DECLARE_HANDLE_COLOR(stderr_##COLOR, STD_ERROR_HANDLE, COLOR)
|
||||
|
||||
#define DECLARE_BG_COLOR(COLOR) \
|
||||
DECLARE_HANDLE_COLOR(stdout_##COLOR##_bg, STD_OUTPUT_HANDLE, COLOR##_bg)\
|
||||
DECLARE_HANDLE_COLOR(stderr_##COLOR##_bg, STD_ERROR_HANDLE, COLOR##_bg)
|
||||
|
||||
DECLARE_COLOR(red);
|
||||
DECLARE_COLOR(green);
|
||||
DECLARE_COLOR(yellow);
|
||||
DECLARE_COLOR(blue);
|
||||
DECLARE_COLOR(white);
|
||||
DECLARE_COLOR(reset);
|
||||
|
||||
DECLARE_BG_COLOR(red);
|
||||
DECLARE_BG_COLOR(green);
|
||||
DECLARE_BG_COLOR(yellow);
|
||||
DECLARE_BG_COLOR(blue);
|
||||
DECLARE_BG_COLOR(white);
|
||||
|
||||
#undef DECLARE_COLOR
|
||||
#undef DECLARE_BG_COLOR
|
||||
}
|
||||
|
||||
Logger::Logger()
|
||||
{
|
||||
enabled_ = ::GetConsoleWindow() != nullptr;
|
||||
default_stdout_color_ = default_stderr_color_ = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO stdout_info;
|
||||
if (::GetConsoleScreenBufferInfo(::GetStdHandle(STD_OUTPUT_HANDLE), &stdout_info))
|
||||
{
|
||||
default_stdout_color_ = stdout_info.wAttributes;
|
||||
}
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO stderr_info;
|
||||
if (::GetConsoleScreenBufferInfo(::GetStdHandle(STD_ERROR_HANDLE), &stderr_info))
|
||||
{
|
||||
default_stderr_color_ = stderr_info.wAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,231 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../macros.h"
|
||||
#include "../common/Singleton.hpp"
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#ifndef E2D_LOG
|
||||
# ifdef E2D_DEBUG
|
||||
# define E2D_LOG(FORMAT, ...) easy2d::Logger::Instance().Messageln((FORMAT), __VA_ARGS__)
|
||||
# else
|
||||
# define E2D_LOG __noop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef E2D_WARNING_LOG
|
||||
# define E2D_WARNING_LOG(FORMAT, ...) easy2d::Logger::Instance().Warningln((FORMAT), __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef E2D_ERROR_LOG
|
||||
# define E2D_ERROR_LOG(FORMAT, ...) easy2d::Logger::Instance().Errorln((FORMAT), __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace __console_colors
|
||||
{
|
||||
using ConsoleColor = std::wostream&(*)(std::wostream&);
|
||||
|
||||
#define DECLARE_COLOR(COLOR)\
|
||||
extern std::wostream&(stdout_##COLOR)(std::wostream&);\
|
||||
extern std::wostream&(stderr_##COLOR)(std::wostream&);
|
||||
|
||||
#define DECLARE_BG_COLOR(COLOR)\
|
||||
extern std::wostream&(stdout_##COLOR##_bg)(std::wostream&);\
|
||||
extern std::wostream&(stderr_##COLOR##_bg)(std::wostream&);
|
||||
|
||||
DECLARE_COLOR(red);
|
||||
DECLARE_COLOR(green);
|
||||
DECLARE_COLOR(yellow);
|
||||
DECLARE_COLOR(blue);
|
||||
DECLARE_COLOR(white);
|
||||
DECLARE_COLOR(reset);
|
||||
|
||||
DECLARE_BG_COLOR(red);
|
||||
DECLARE_BG_COLOR(green);
|
||||
DECLARE_BG_COLOR(yellow);
|
||||
DECLARE_BG_COLOR(blue);
|
||||
DECLARE_BG_COLOR(white);
|
||||
|
||||
#undef DECLARE_COLOR
|
||||
#undef DECLARE_BG_COLOR
|
||||
}
|
||||
|
||||
class E2D_API Logger
|
||||
: public Singleton<Logger>
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(Logger);
|
||||
|
||||
public:
|
||||
inline void Enable()
|
||||
{
|
||||
enabled_ = true;
|
||||
}
|
||||
|
||||
inline void Disable()
|
||||
{
|
||||
enabled_ = false;
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void Print(const wchar_t* format, _Args&&... args) const
|
||||
{
|
||||
using namespace __console_colors;
|
||||
Output(std::wcout, stdout_white, nullptr, format, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void Println(const wchar_t* format, _Args&&... args) const
|
||||
{
|
||||
using namespace __console_colors;
|
||||
OutputLine(std::wcout, stdout_white, nullptr, format, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void Message(const wchar_t * format, _Args&&... args) const
|
||||
{
|
||||
using namespace __console_colors;
|
||||
Output(std::wcout, stdout_blue, nullptr, format, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void Messageln(const wchar_t * format, _Args&&... args) const
|
||||
{
|
||||
using namespace __console_colors;
|
||||
OutputLine(std::wcout, stdout_blue, nullptr, format, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void Warning(const wchar_t* format, _Args&&... args) const
|
||||
{
|
||||
using namespace __console_colors;
|
||||
Output(std::wcerr, stdout_yellow_bg, L"Warning: ", format, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void Warningln(const wchar_t* format, _Args&&... args) const
|
||||
{
|
||||
using namespace __console_colors;
|
||||
OutputLine(std::wcerr, stdout_yellow_bg, L"Warning: ", format, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void Error(const wchar_t* format, _Args&&... args) const
|
||||
{
|
||||
using namespace __console_colors;
|
||||
Output(std::wcerr, stderr_red_bg, L"Error: ", format, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void Errorln(const wchar_t* format, _Args&&... args) const
|
||||
{
|
||||
using namespace __console_colors;
|
||||
OutputLine(std::wcerr, stderr_red_bg, L"Error: ", format, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
Logger();
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void OutputLine(std::wostream& os, __console_colors::ConsoleColor color, const wchar_t* prompt, const wchar_t* format, _Args&&... args) const
|
||||
{
|
||||
if (!enabled_)
|
||||
return;
|
||||
|
||||
Output(os, color, prompt, format, std::forward<_Args>(args)...);
|
||||
|
||||
os << std::endl;
|
||||
::OutputDebugStringW(L"\r\n");
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline void Output(std::wostream& os, __console_colors::ConsoleColor color, const wchar_t* prompt, const wchar_t* format, _Args&&... args) const
|
||||
{
|
||||
if (!enabled_)
|
||||
return;
|
||||
|
||||
std::wstring output = MakeOutputString(prompt, format, std::forward<_Args>(args)...);
|
||||
|
||||
os << color << output;
|
||||
::OutputDebugStringW(output.c_str());
|
||||
|
||||
ResetColor();
|
||||
}
|
||||
|
||||
template <typename ..._Args>
|
||||
inline std::wstring MakeOutputString(const wchar_t* prompt, const wchar_t* format, _Args&&... args) const
|
||||
{
|
||||
static wchar_t temp_buffer[1024 * 3 + 1];
|
||||
|
||||
const auto len = ::_scwprintf(format, std::forward<_Args>(args)...);
|
||||
::swprintf_s(temp_buffer, len + 1, format, std::forward<_Args>(args)...);
|
||||
|
||||
std::wstringstream ss;
|
||||
ss << Logger::OutPrefix;
|
||||
|
||||
if (prompt)
|
||||
ss << prompt;
|
||||
|
||||
ss << temp_buffer;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline void ResetColor() const
|
||||
{
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), default_stdout_color_);
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), default_stderr_color_);
|
||||
}
|
||||
|
||||
static inline std::wostream& OutPrefix(std::wostream& out)
|
||||
{
|
||||
std::time_t unix = std::time(nullptr);
|
||||
std::tm tmbuf;
|
||||
localtime_s(&tmbuf, &unix);
|
||||
out << std::put_time(&tmbuf, L"[easy2d] %H:%M:%S ");
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
bool enabled_;
|
||||
WORD default_stdout_color_;
|
||||
WORD default_stderr_color_;
|
||||
};
|
||||
}
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
inline void ThrowIfFailed(HRESULT hr)
|
||||
{
|
||||
if (FAILED(hr))
|
||||
{
|
||||
E2D_ERROR_LOG(L"Fatal error with HRESULT of %08X", hr);
|
||||
|
||||
static char buffer[1024 + 1];
|
||||
sprintf_s(buffer, "Fatal error with HRESULT of %08X", hr);
|
||||
throw std::runtime_error(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,453 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "time.h"
|
||||
#include "logs.h"
|
||||
#include <regex>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace time
|
||||
{
|
||||
//-------------------------------------------------------
|
||||
// TimePoint
|
||||
//-------------------------------------------------------
|
||||
|
||||
TimePoint::TimePoint()
|
||||
{
|
||||
}
|
||||
|
||||
TimePoint::TimePoint(long dur)
|
||||
: dur_(dur)
|
||||
{
|
||||
}
|
||||
|
||||
const TimePoint TimePoint::operator+(const Duration & dur) const
|
||||
{
|
||||
return TimePoint{ dur_ + dur.Milliseconds() };
|
||||
}
|
||||
|
||||
const TimePoint TimePoint::operator-(const Duration & dur) const
|
||||
{
|
||||
return TimePoint{ dur_ - dur.Milliseconds() };
|
||||
}
|
||||
|
||||
TimePoint & TimePoint::operator+=(const Duration & other)
|
||||
{
|
||||
dur_ += other.Milliseconds();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
TimePoint & TimePoint::operator-=(const Duration &other)
|
||||
{
|
||||
dur_ -= other.Milliseconds();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const Duration TimePoint::operator-(const TimePoint & other) const
|
||||
{
|
||||
return Duration(dur_ - other.dur_);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Duration
|
||||
//-------------------------------------------------------
|
||||
|
||||
const Duration Millisecond = 1L;
|
||||
const Duration Second = 1000 * Millisecond;
|
||||
const Duration Minute = 60 * Second;
|
||||
const Duration Hour = 60 * Minute;
|
||||
|
||||
namespace
|
||||
{
|
||||
const auto duration_regex = std::wregex(LR"([-+]?([0-9]*(\.[0-9]*)?[a-z]+)+)");
|
||||
|
||||
typedef std::unordered_map<std::wstring, Duration> UnitMap;
|
||||
const auto unit_map = UnitMap
|
||||
{
|
||||
{L"ms", Millisecond},
|
||||
{L"s", Second},
|
||||
{L"m", Minute},
|
||||
{L"h", Hour}
|
||||
};
|
||||
}
|
||||
|
||||
Duration::Duration()
|
||||
: milliseconds_(0)
|
||||
{
|
||||
}
|
||||
|
||||
Duration::Duration(long milliseconds)
|
||||
: milliseconds_(milliseconds)
|
||||
{
|
||||
}
|
||||
|
||||
float Duration::Seconds() const
|
||||
{
|
||||
long long sec = milliseconds_ / Second.milliseconds_;
|
||||
long long ms = milliseconds_ % Second.milliseconds_;
|
||||
return static_cast<float>(sec) + static_cast<float>(ms) / 1000.f;
|
||||
}
|
||||
|
||||
float Duration::Minutes() const
|
||||
{
|
||||
long long min = milliseconds_ / Minute.milliseconds_;
|
||||
long long ms = milliseconds_ % Minute.milliseconds_;
|
||||
return static_cast<float>(min) + static_cast<float>(ms) / (60 * 1000.f);
|
||||
}
|
||||
|
||||
float Duration::Hours() const
|
||||
{
|
||||
long long hour = milliseconds_ / Hour.milliseconds_;
|
||||
long long ms = milliseconds_ % Hour.milliseconds_;
|
||||
return static_cast<float>(hour) + static_cast<float>(ms) / (60 * 60 * 1000.f);
|
||||
}
|
||||
|
||||
std::wstring easy2d::time::Duration::ToString() const
|
||||
{
|
||||
if (IsZero())
|
||||
{
|
||||
return std::wstring(L"0s");
|
||||
}
|
||||
|
||||
std::wstring result;
|
||||
long long hour = milliseconds_ / Hour.milliseconds_;
|
||||
long long min = milliseconds_ / Minute.milliseconds_ - hour * 60;
|
||||
long long sec = milliseconds_ / Second.milliseconds_ - (hour * 60 * 60 + min * 60);
|
||||
long long ms = milliseconds_ % Second.milliseconds_;
|
||||
|
||||
if (milliseconds_ < 0)
|
||||
result.append(L"-");
|
||||
|
||||
if (hour)
|
||||
{
|
||||
result.append(std::to_wstring(hour)).append(L"h");
|
||||
result.append(std::to_wstring(min)).append(L"m");
|
||||
}
|
||||
else if(min)
|
||||
{
|
||||
result.append(std::to_wstring(min)).append(L"m");
|
||||
}
|
||||
|
||||
if (ms != 0)
|
||||
{
|
||||
auto float_to_str = [](float val) -> std::wstring
|
||||
{
|
||||
wchar_t buf[10] = {};
|
||||
::swprintf_s(buf, L"%.2f", val);
|
||||
return std::wstring(buf);
|
||||
};
|
||||
|
||||
result.append(float_to_str(static_cast<float>(sec) + static_cast<float>(ms) / 1000.f))
|
||||
.append(L"s");
|
||||
}
|
||||
else if (sec != 0)
|
||||
{
|
||||
result.append(std::to_wstring(sec)).append(L"s");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Duration::operator==(const Duration & other) const
|
||||
{
|
||||
return milliseconds_ == other.milliseconds_;
|
||||
}
|
||||
|
||||
bool Duration::operator!=(const Duration & other) const
|
||||
{
|
||||
return milliseconds_ != other.milliseconds_;
|
||||
}
|
||||
|
||||
bool Duration::operator>(const Duration & other) const
|
||||
{
|
||||
return milliseconds_ > other.milliseconds_;
|
||||
}
|
||||
|
||||
bool Duration::operator>=(const Duration & other) const
|
||||
{
|
||||
return milliseconds_ >= other.milliseconds_;
|
||||
}
|
||||
|
||||
bool Duration::operator<(const Duration & other) const
|
||||
{
|
||||
return milliseconds_ < other.milliseconds_;
|
||||
}
|
||||
|
||||
bool Duration::operator<=(const Duration & other) const
|
||||
{
|
||||
return milliseconds_ <= other.milliseconds_;
|
||||
}
|
||||
|
||||
float easy2d::time::Duration::operator/(const Duration & other) const
|
||||
{
|
||||
return static_cast<float>(milliseconds_) / other.milliseconds_;
|
||||
}
|
||||
|
||||
const Duration Duration::operator+(const Duration & other) const
|
||||
{
|
||||
return Duration(milliseconds_ + other.milliseconds_);
|
||||
}
|
||||
|
||||
const Duration Duration::operator-(const Duration & other) const
|
||||
{
|
||||
return Duration(milliseconds_ - other.milliseconds_);
|
||||
}
|
||||
|
||||
const Duration Duration::operator-() const
|
||||
{
|
||||
return Duration(-milliseconds_);
|
||||
}
|
||||
|
||||
const Duration Duration::operator*(int val) const
|
||||
{
|
||||
return Duration(milliseconds_ * val);
|
||||
}
|
||||
|
||||
const Duration easy2d::time::Duration::operator*(unsigned long long val) const
|
||||
{
|
||||
return Duration(static_cast<long>(milliseconds_ * val));
|
||||
}
|
||||
|
||||
const Duration Duration::operator*(float val) const
|
||||
{
|
||||
return Duration(static_cast<long>(milliseconds_ * val));
|
||||
}
|
||||
|
||||
const Duration Duration::operator*(double val) const
|
||||
{
|
||||
return Duration(static_cast<long>(milliseconds_ * val));
|
||||
}
|
||||
|
||||
const Duration Duration::operator*(long double val) const
|
||||
{
|
||||
return Duration(static_cast<long>(milliseconds_ * val));
|
||||
}
|
||||
|
||||
const Duration Duration::operator/(int val) const
|
||||
{
|
||||
return Duration(milliseconds_ / val);
|
||||
}
|
||||
|
||||
const Duration Duration::operator/(float val) const
|
||||
{
|
||||
return Duration(static_cast<long>(milliseconds_ / val));
|
||||
}
|
||||
|
||||
const Duration Duration::operator/(double val) const
|
||||
{
|
||||
return Duration(static_cast<long>(milliseconds_ / val));
|
||||
}
|
||||
|
||||
Duration & Duration::operator+=(const Duration &other)
|
||||
{
|
||||
milliseconds_ += other.milliseconds_;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Duration & Duration::operator-=(const Duration &other)
|
||||
{
|
||||
milliseconds_ -= other.milliseconds_;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Duration & Duration::operator*=(int val)
|
||||
{
|
||||
milliseconds_ *= val;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Duration & Duration::operator/=(int val)
|
||||
{
|
||||
milliseconds_ = static_cast<long>(milliseconds_ / val);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Duration & Duration::operator*=(float val)
|
||||
{
|
||||
milliseconds_ = static_cast<long>(milliseconds_ * val);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Duration & Duration::operator/=(float val)
|
||||
{
|
||||
milliseconds_ = static_cast<long>(milliseconds_ / val);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Duration & Duration::operator*=(double val)
|
||||
{
|
||||
milliseconds_ = static_cast<long>(milliseconds_ * val);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Duration & Duration::operator/=(double val)
|
||||
{
|
||||
milliseconds_ = static_cast<long>(milliseconds_ / val);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const Duration easy2d::time::operator*(int val, const Duration & dur)
|
||||
{
|
||||
return dur * val;
|
||||
}
|
||||
|
||||
const Duration easy2d::time::operator/(int val, const Duration & dur)
|
||||
{
|
||||
return dur / val;
|
||||
}
|
||||
|
||||
const Duration easy2d::time::operator*(float val, const Duration & dur)
|
||||
{
|
||||
return dur * val;
|
||||
}
|
||||
|
||||
const Duration easy2d::time::operator/(float val, const Duration & dur)
|
||||
{
|
||||
return dur / val;
|
||||
}
|
||||
|
||||
const Duration easy2d::time::operator*(double val, const Duration & dur)
|
||||
{
|
||||
return dur * val;
|
||||
}
|
||||
|
||||
const Duration easy2d::time::operator/(double val, const Duration & dur)
|
||||
{
|
||||
return dur / val;
|
||||
}
|
||||
|
||||
const Duration easy2d::time::operator*(long double val, const Duration & dur)
|
||||
{
|
||||
return dur * val;
|
||||
}
|
||||
|
||||
std::wostream & easy2d::time::operator<<(std::wostream & out, const Duration & dur)
|
||||
{
|
||||
return out << dur.ToString();
|
||||
}
|
||||
|
||||
std::wistream & easy2d::time::operator>>(std::wistream & in, Duration & dur)
|
||||
{
|
||||
std::wstring str;
|
||||
in >> str;
|
||||
dur = time::ParseDuration(str);
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Functions
|
||||
//-------------------------------------------------------
|
||||
|
||||
TimePoint easy2d::time::Now() E2D_NOEXCEPT
|
||||
{
|
||||
static LARGE_INTEGER freq = {};
|
||||
if (freq.QuadPart == 0LL)
|
||||
{
|
||||
// the function will always succceed on systems that run Windows XP or later
|
||||
QueryPerformanceFrequency(&freq);
|
||||
}
|
||||
|
||||
LARGE_INTEGER count;
|
||||
QueryPerformanceCounter(&count);
|
||||
|
||||
const long long whole = (count.QuadPart / freq.QuadPart) * 1000LL;
|
||||
const long long part = (count.QuadPart % freq.QuadPart) * 1000LL / freq.QuadPart;
|
||||
return TimePoint{ static_cast<long>(whole + part) };
|
||||
}
|
||||
|
||||
Duration easy2d::time::ParseDuration(const std::wstring & str)
|
||||
{
|
||||
size_t len = str.length();
|
||||
size_t pos = 0;
|
||||
bool negative = false;
|
||||
Duration d;
|
||||
|
||||
if (!std::regex_match(str, duration_regex))
|
||||
{
|
||||
E2D_ERROR_LOG(L"time::ParseDuration failed, invalid duration");
|
||||
return Duration();
|
||||
}
|
||||
|
||||
if (str.empty() || str == L"0") { return d; }
|
||||
|
||||
// ·ûºÅλ
|
||||
if (str[0] == L'-' || str[0] == L'+')
|
||||
{
|
||||
negative = (str[0] == L'-');
|
||||
pos++;
|
||||
}
|
||||
|
||||
while (pos < len)
|
||||
{
|
||||
// ÊýÖµ
|
||||
size_t i = pos;
|
||||
for (; i < len; ++i)
|
||||
{
|
||||
wchar_t ch = str[i];
|
||||
if (!(ch == L'.' || L'0' <= ch && ch <= L'9'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring num_str = str.substr(pos, i - pos);
|
||||
pos = i;
|
||||
|
||||
if (num_str.empty() || num_str == L".")
|
||||
{
|
||||
E2D_ERROR_LOG(L"time::ParseDuration failed, invalid duration");
|
||||
return Duration();
|
||||
}
|
||||
|
||||
// µ¥Î»
|
||||
for (; i < len; ++i)
|
||||
{
|
||||
wchar_t ch = str[i];
|
||||
if (ch == L'.' || L'0' <= ch && ch <= L'9')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring unit_str = str.substr(pos, i - pos);
|
||||
pos = i;
|
||||
|
||||
if (unit_map.find(unit_str) == unit_map.end())
|
||||
{
|
||||
E2D_ERROR_LOG(L"time::ParseDuration failed, invalid duration");
|
||||
return Duration();
|
||||
}
|
||||
|
||||
double num = std::stod(num_str);
|
||||
Duration unit = unit_map.at(unit_str);
|
||||
d += unit * num;
|
||||
}
|
||||
|
||||
if (negative)
|
||||
{
|
||||
d = -d;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue