vw::VirtualWindow window{};
window.draw([](const RectF& sceneScreen) {
// something…
});
-
-
Save tyanmahou/a9fce1c3662fde8a5645756f9023e20c to your computer and use it in GitHub Desktop.
Siv3D VirtualWindow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Component.hpp" | |
#include "GrabCtrl.hpp" | |
#include "ScrollCtrl.hpp" | |
#include "WindowMover.hpp" | |
#include "WindowResizer.hpp" | |
namespace vw::detail | |
{ | |
Component::Component(WindowParam& param) : | |
m_param(param), | |
m_grabCtrl(std::make_unique<GrabCtrl>(this)), | |
m_resizer(std::make_unique<WindowResizer>(this)), | |
m_scrollCtrl(std::make_unique<ScrollCtrl>(this)), | |
m_mover(std::make_unique<WindowMover>(this)) | |
{ | |
} | |
Component::~Component() | |
{ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <memory> | |
namespace vw::detail | |
{ | |
struct WindowParam; | |
class GrabCtrl; | |
class WindowResizer; | |
class ScrollCtrl; | |
class WindowMover; | |
/// <summary> | |
/// 機能統括 | |
/// </summary> | |
class Component | |
{ | |
public: | |
Component(WindowParam& param); | |
~Component(); | |
WindowParam& param() const | |
{ | |
return m_param; | |
} | |
GrabCtrl& grabCtrl() const | |
{ | |
return *m_grabCtrl.get(); | |
} | |
WindowResizer& resizer() const | |
{ | |
return *m_resizer.get(); | |
} | |
ScrollCtrl& scrollCtrl() const | |
{ | |
return *m_scrollCtrl.get(); | |
} | |
WindowMover& mover() const | |
{ | |
return *m_mover.get(); | |
} | |
private: | |
WindowParam& m_param; | |
std::unique_ptr<GrabCtrl> m_grabCtrl; | |
std::unique_ptr<WindowResizer> m_resizer; | |
std::unique_ptr<ScrollCtrl> m_scrollCtrl; | |
std::unique_ptr<WindowMover> m_mover; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <Siv3D/Vector2D.hpp> | |
namespace vw::detail | |
{ | |
/// <summary> | |
/// 定数 | |
/// </summary> | |
class Constants | |
{ | |
public: | |
static constexpr double Margin = 5.0; | |
static constexpr double ScrollMargin = 15.0; | |
static constexpr double ScrollBarSize = 20.0; | |
static constexpr s3d::Vec2 WinMinSize{ | |
ScrollMargin * 3.0 + Margin + ScrollBarSize, | |
ScrollMargin * 3.0 + Margin + ScrollBarSize | |
}; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "GrabCtrl.hpp" | |
#include "Component.hpp" | |
#include "WindowParam.hpp" | |
#include <Siv3D.hpp> | |
namespace | |
{ | |
using namespace vw::detail; | |
s3d::Optional<s3d::CursorStyle> GetCursorStyle(GrabState grab) | |
{ | |
switch (grab) { | |
case GrabState::Tl: | |
return CursorStyle::ResizeNWSE; | |
case GrabState::Tr: | |
return CursorStyle::ResizeNESW; | |
case GrabState::Bl: | |
return CursorStyle::ResizeNESW; | |
case GrabState::Br: | |
return CursorStyle::ResizeNWSE; | |
case GrabState::Top: | |
return CursorStyle::ResizeUpDown; | |
case GrabState::Bottom: | |
return CursorStyle::ResizeUpDown; | |
case GrabState::Left: | |
return CursorStyle::ResizeLeftRight; | |
case GrabState::Right: | |
return CursorStyle::ResizeLeftRight; | |
case GrabState::Move: | |
return CursorStyle::Default; | |
default: | |
break; | |
} | |
return s3d::none; | |
} | |
} | |
namespace vw::detail | |
{ | |
GrabCtrl::GrabCtrl(Component* pComp) : | |
m_pComp(pComp) | |
{ | |
} | |
void GrabCtrl::update() | |
{ | |
if (!m_isGrab) { | |
bool isPromised = false; | |
for (auto* handler : m_handlers) { | |
if (handler->onGrabPromise()) { | |
isPromised = true; | |
m_promosedHandler = handler; | |
break; | |
} | |
} | |
for (auto* handler : m_handlers) { | |
handler->onPreGrabCheck(m_promosedHandler == handler); | |
} | |
if (isPromised) { | |
if (auto grabState = m_promosedHandler->onGrabCheck()) { | |
m_isGrab = true; | |
m_grabState = *grabState; | |
m_grabPos = m_pComp->param().pos; | |
m_grabSize = m_pComp->param().size; | |
m_grabScenePos = m_pComp->param().scenePos; | |
m_grabCursorPos = s3d::Cursor::PosF(); | |
m_promosedHandler->onGrab(m_grabState); | |
} | |
} | |
} else if (!MouseL.pressed()) { | |
m_isGrab = false; | |
m_promosedHandler->onGrabRelease(); | |
m_promosedHandler = nullptr; | |
} | |
if (m_isGrab) { | |
::GetCursorStyle(m_grabState).then([](CursorStyle stlye) { | |
s3d::Cursor::RequestStyle(stlye); | |
}); | |
m_promosedHandler->onGrabUpdate(m_grabState); | |
} | |
} | |
void GrabCtrl::registHandler(IGrabHandler* handler) | |
{ | |
m_handlers << handler; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <Siv3D/Array.hpp> | |
#include <Siv3D/CursorStyle.hpp> | |
#include <Siv3D/Optional.hpp> | |
#include <Siv3D/Vector2D.hpp> | |
namespace vw::detail | |
{ | |
class Component; | |
enum class GrabState | |
{ | |
None, | |
Top, Bottom, Left, Right, | |
Tl, Tr, Bl, Br, | |
Move, | |
ScrollV, ScrollH, | |
ScrollUp, ScrollDown, ScrollLeft, ScrollRight, | |
ScrollVTo, ScrollHTo, | |
}; | |
class IGrabHandler | |
{ | |
public: | |
virtual ~IGrabHandler() = default; | |
/// <summary> | |
/// 掴めるかどうか | |
/// </summary> | |
/// <returns>掴めるなら true で以降の他のハンドラはスルーされる</returns> | |
virtual bool onGrabPromise() = 0; | |
/// <summary> | |
/// 掴みチェックの前の更新処理 | |
/// 全てのハンドラに呼ばれる | |
/// </summary> | |
/// <param name="isPromised"></param> | |
virtual void onPreGrabCheck(bool isPromised) = 0; | |
/// <summary> | |
/// 掴みチェック | |
/// </summary> | |
/// <returns></returns> | |
virtual s3d::Optional<GrabState> onGrabCheck() = 0; | |
/// <summary> | |
/// 捕まれた | |
/// </summary> | |
/// <param name="state"></param> | |
virtual void onGrab(GrabState state) = 0; | |
/// <summary> | |
/// 捕まれ中 | |
/// </summary> | |
/// <param name="state"></param> | |
virtual void onGrabUpdate(GrabState state) = 0; | |
/// <summary> | |
/// 離された | |
/// </summary> | |
virtual void onGrabRelease() = 0; | |
}; | |
/// <summary> | |
/// 掴み制御 | |
/// </summary> | |
class GrabCtrl | |
{ | |
public: | |
GrabCtrl(Component* pComp); | |
bool isGrab() const { return m_isGrab; } | |
const s3d::Vec2& grabCursorPos() const | |
{ | |
return m_grabCursorPos; | |
} | |
const s3d::Vec2& grabPos() const | |
{ | |
return m_grabPos; | |
} | |
const s3d::Vec2& grabSize() const | |
{ | |
return m_grabSize; | |
} | |
const s3d::Vec2& grabScenePos() const | |
{ | |
return m_grabScenePos; | |
} | |
void update(); | |
void registHandler(IGrabHandler* handler); | |
private: | |
Component* m_pComp; | |
bool m_isGrab = false; | |
GrabState m_grabState{}; | |
s3d::Vec2 m_grabCursorPos{}; | |
s3d::Vec2 m_grabPos{}; | |
s3d::Vec2 m_grabSize{}; | |
s3d::Vec2 m_grabScenePos{}; | |
s3d::Array<IGrabHandler*> m_handlers; | |
IGrabHandler* m_promosedHandler = nullptr; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ScrollCtrl.hpp" | |
#include "Constants.hpp" | |
#include "Component.hpp" | |
#include "WindowParam.hpp" | |
#include <Siv3D.hpp> | |
namespace vw::detail | |
{ | |
class ScrollCtrl::View | |
{ | |
public: | |
View(const WindowParam& param) : | |
m_param(param) | |
{} | |
s3d::RectF barV() const | |
{ | |
double minusH = this->hasScrollH() ? Constants::ScrollMargin : 0; | |
return { | |
m_param.region.x + m_param.region.w - Constants::ScrollMargin, m_param.region.y, | |
Constants::ScrollMargin, m_param.size.y - minusH | |
}; | |
} | |
s3d::RectF gripV(bool isFixMargin = true) const | |
{ | |
auto bar = this->barV(); | |
auto [hight, offsetMax] = this->gripVHightAndOffsetMax(); | |
auto yOffs = s3d::Math::Lerp( | |
0, | |
offsetMax, | |
s3d::Saturate(m_param.scenePos.y / (m_param.sceneSize.y - m_param.size.y)) | |
); | |
double pushMargin = 1.0; | |
if (!isFixMargin) { | |
pushMargin = m_onTimeV; | |
} | |
return { | |
bar.x + (5.0 - pushMargin), | |
bar.y + bar.w + yOffs, | |
bar.w - (5.0 - pushMargin) * 2.0, | |
hight | |
}; | |
} | |
RectF upBtn() const | |
{ | |
RectF bar = this->barV(); | |
return { bar.pos, bar.w, bar.w }; | |
} | |
RectF downBtn() const | |
{ | |
RectF bar = this->barV(); | |
const Vec2 basePos{ bar.x, bar.y + bar.h - Constants::ScrollMargin }; | |
return { basePos, bar.w, bar.w }; | |
} | |
bool hasScrollV() const | |
{ | |
return m_param.sceneSize.y > m_param.size.y; | |
} | |
bool isBarVClicked() const | |
{ | |
if (!this->hasScrollV()) { | |
return false; | |
} | |
return this->barV().leftClicked(); | |
} | |
bool isBarVMouseOver() const | |
{ | |
if (!this->hasScrollV()) { | |
return false; | |
} | |
return this->barV().mouseOver(); | |
} | |
bool isGripVClicked() const | |
{ | |
if (!this->hasScrollV()) { | |
return false; | |
} | |
return this->gripV().leftClicked(); | |
} | |
std::pair<double, double> gripVHightAndOffsetMax() const | |
{ | |
auto bar = this->barV(); | |
auto hight = s3d::Math::Lerp( | |
Constants::ScrollBarSize, | |
bar.h - bar.w * 2.0, | |
s3d::Saturate(m_param.size.y / m_param.sceneSize.y) | |
); | |
return { hight, bar.h - bar.w * 2.0 - hight }; | |
} | |
double toSceneYFromGripDiff(const s3d::Vec2& scenePos, double diff) const | |
{ | |
const double moveable = (m_param.sceneSize.y - m_param.region.size.y); | |
if (moveable <= 0) { | |
return 0; | |
} | |
auto [hight, offsetMax] = this->gripVHightAndOffsetMax(); | |
return s3d::Clamp(scenePos.y + diff * moveable / offsetMax, 0.0, moveable); | |
} | |
bool isUpBtnMouseOver() const | |
{ | |
if (!hasScrollV()) { | |
return false; | |
} | |
return this->upBtn().mouseOver(); | |
} | |
bool isUpBtnClicked() const | |
{ | |
if (!hasScrollV()) { | |
return false; | |
} | |
return this->upBtn().leftClicked(); | |
} | |
bool isDownBtnMouseOver() const | |
{ | |
if (!hasScrollV()) { | |
return false; | |
} | |
return this->downBtn().mouseOver(); | |
} | |
bool isDownBtnClicked() const | |
{ | |
if (!hasScrollV()) { | |
return false; | |
} | |
return this->downBtn().leftClicked(); | |
} | |
void drawV(const ColorF& barColor, const ColorF& scrollColor) const | |
{ | |
// スクロールバー | |
RectF bar = this->barV(); | |
bar.draw(barColor); | |
{ | |
const double pushMargin = m_pushUpBtn ? 0.0 : 1.0; | |
Triangle( | |
{ bar.x + bar.w * 0.5, bar.y + (5.0 - pushMargin) }, | |
{ bar.x + (4.0 - pushMargin), bar.y + bar.w - (5.0 - pushMargin) }, | |
{ bar.x + bar.w - (4.0 - pushMargin) , bar.y + bar.w - (5.0 - pushMargin) } | |
).draw(ColorF(scrollColor, m_onTimeV)); | |
} | |
{ | |
const Vec2 basePos{ bar.x, bar.y + bar.h - Constants::ScrollMargin }; | |
const double pushMargin = m_pushDownBtn ? 0.0 : 1.0; | |
Triangle( | |
{ bar.x + bar.w * 0.5, bar.y + bar.h - (5.0 - pushMargin) }, | |
{ bar.x + (4.0 - pushMargin), bar.y + bar.h - (bar.w - (5.0 - pushMargin)) }, | |
{ bar.x + bar.w - (4.0 - pushMargin), bar.y + bar.h - (bar.w - (5.0 - pushMargin)) } | |
).draw(ColorF(scrollColor, m_onTimeV)); | |
} | |
{ | |
RoundRect(this->gripV(false), 2.0).draw(scrollColor); | |
} | |
} | |
s3d::RectF barH() const | |
{ | |
double minusW = this->hasScrollV() ? Constants::ScrollMargin : 0; | |
return { | |
m_param.region.x, m_param.region.y + m_param.region.h - Constants::ScrollMargin, | |
m_param.size.x - minusW, Constants::ScrollMargin | |
}; | |
} | |
s3d::RectF gripH(bool isFixMargin = true) const | |
{ | |
auto bar = this->barH(); | |
auto [width, offsetMax] = this->gripHWidthAndOffsetMax(); | |
auto xOffs = s3d::Math::Lerp( | |
0, | |
offsetMax, | |
s3d::Saturate(m_param.scenePos.x / (m_param.sceneSize.x - m_param.size.x)) | |
); | |
double pushMargin = 1.0; | |
if (!isFixMargin) { | |
pushMargin = m_onTimeH; | |
} | |
return{ | |
bar.x + bar.h + xOffs, | |
bar.y + (5.0 - pushMargin), | |
width, | |
bar.h - (5.0 - pushMargin) * 2.0 | |
}; | |
} | |
RectF leftBtn() const | |
{ | |
RectF bar = this->barH(); | |
return { bar.pos, bar.h, bar.h }; | |
} | |
RectF rightBtn() const | |
{ | |
RectF bar = this->barH(); | |
const Vec2 basePos{ bar.x + bar.w - Constants::ScrollMargin, bar.y }; | |
return { basePos, bar.h, bar.h }; | |
} | |
bool hasScrollH() const | |
{ | |
return m_param.sceneSize.x > m_param.size.x; | |
} | |
bool isBarHClicked() const | |
{ | |
if (!this->hasScrollH()) { | |
return false; | |
} | |
return this->barH().leftClicked(); | |
} | |
bool isBarHMouseOver() const | |
{ | |
if (!this->hasScrollH()) { | |
return false; | |
} | |
return this->barH().mouseOver(); | |
} | |
bool isGripHClicked() const | |
{ | |
if (!this->hasScrollH()) { | |
return false; | |
} | |
return this->gripH().leftClicked(); | |
} | |
std::pair<double, double> gripHWidthAndOffsetMax() const | |
{ | |
auto bar = this->barH(); | |
auto width = s3d::Math::Lerp( | |
Constants::ScrollBarSize, | |
bar.w - bar.h * 2.0, | |
s3d::Saturate(m_param.size.x / m_param.sceneSize.x) | |
); | |
return { width, bar.w - bar.h * 2.0 - width }; | |
} | |
double toSceneXFromGripDiff(const s3d::Vec2& scenePos, double diff) const | |
{ | |
const double moveable = (m_param.sceneSize.x - m_param.size.x); | |
if (moveable <= 0) { | |
return 0; | |
} | |
auto [hight, offsetMax] = this->gripHWidthAndOffsetMax(); | |
return s3d::Clamp(scenePos.x + diff * moveable / offsetMax, 0.0, moveable); | |
} | |
bool isLeftBtnMouseOver() const | |
{ | |
if (!hasScrollH()) { | |
return false; | |
} | |
return this->leftBtn().mouseOver(); | |
} | |
bool isLeftBtnClicked() const | |
{ | |
if (!hasScrollH()) { | |
return false; | |
} | |
return this->leftBtn().leftClicked(); | |
} | |
bool isRightBtnMouseOver() const | |
{ | |
if (!hasScrollH()) { | |
return false; | |
} | |
return this->rightBtn().mouseOver(); | |
} | |
bool isRightBtnClicked() const | |
{ | |
if (!hasScrollH()) { | |
return false; | |
} | |
return this->rightBtn().leftClicked(); | |
} | |
void drawH(const ColorF& barColor, const ColorF& gripColor) const | |
{ | |
// スクロールバー | |
RectF bar = this->barH(); | |
bar.draw(barColor); | |
{ | |
const double pushMargin = m_pushLeftBtn ? 0.0 : 1.0; | |
Triangle( | |
{ bar.x + (5.0 - pushMargin), bar.y + bar.h * 0.5 }, | |
{ bar.x + bar.h - (5.0 - pushMargin), bar.y + (4.0 - pushMargin) }, | |
{ bar.x + bar.h - (5.0 - pushMargin) , bar.y + bar.h - (4.0 - pushMargin) } | |
).draw(ColorF(gripColor, m_onTimeH)); | |
} | |
{ | |
const Vec2 basePos{ bar.x + bar.w - Constants::ScrollMargin, bar.y }; | |
const double pushMargin = m_pushRightBtn ? 0.0 : 1.0; | |
Triangle( | |
{ bar.x + bar.w - (5.0 - pushMargin), bar.y + bar.h * 0.5 }, | |
{ bar.x + bar.w - (bar.h - (5.0 - pushMargin)) , bar.y + (4.0 - pushMargin) }, | |
{ bar.x + bar.w - (bar.h - (5.0 - pushMargin)) , bar.y + bar.h - (4.0 - pushMargin) } | |
).draw(ColorF(gripColor, m_onTimeH)); | |
} | |
{ | |
RoundRect(this->gripH(false), 2.0).draw(gripColor); | |
} | |
} | |
void draw(const ColorF& barColor, const ColorF& gripColor) const | |
{ | |
const Vec2& size = m_param.size; | |
bool hasScrollV = m_param.sceneSize.y > size.y; | |
bool hasScrollH = m_param.sceneSize.x > size.x; | |
if (hasScrollV) { | |
this->drawV(barColor, gripColor); | |
} | |
if (hasScrollH) { | |
this->drawH(barColor, gripColor); | |
} | |
if (hasScrollH && hasScrollV) { | |
RectF( | |
m_param.region.x + m_param.region.w - Constants::ScrollMargin, | |
m_param.region.y + m_param.region.h - Constants::ScrollMargin, | |
Constants::ScrollMargin, | |
Constants::ScrollMargin | |
).draw(barColor); | |
} | |
} | |
void updateOnTime(bool isBarVMouseOver, bool isBarHMouseOver, double dt) | |
{ | |
if (isBarVMouseOver) { | |
m_onTimeV = s3d::Saturate(m_onTimeV + dt * 5.0); | |
} else { | |
m_onTimeV = s3d::Saturate(m_onTimeV - dt * 2.0); | |
} | |
if (isBarHMouseOver) { | |
m_onTimeH = s3d::Saturate(m_onTimeH + dt * 5.0); | |
} else { | |
m_onTimeH = s3d::Saturate(m_onTimeH - dt * 2.0); | |
} | |
} | |
void pushUpBtn() | |
{ | |
m_pushUpBtn = true; | |
} | |
void pushDownBtn() | |
{ | |
m_pushDownBtn = true; | |
} | |
void pushLeftBtn() | |
{ | |
m_pushLeftBtn = true; | |
} | |
void pushRightBtn() | |
{ | |
m_pushRightBtn = true; | |
} | |
void resetPush() | |
{ | |
m_pushUpBtn = false; | |
m_pushDownBtn = false; | |
m_pushLeftBtn = false; | |
m_pushRightBtn = false; | |
} | |
private: | |
const WindowParam& m_param; | |
double m_onTimeV = 0; | |
double m_onTimeH = 0; | |
bool m_pushUpBtn = false; | |
bool m_pushDownBtn = false; | |
bool m_pushLeftBtn = false; | |
bool m_pushRightBtn = false; | |
}; | |
ScrollCtrl::ScrollCtrl(Component* pComp) : | |
m_pComp(pComp), | |
m_view(std::make_unique<View>(pComp->param())) | |
{ | |
grab().registHandler(this); | |
} | |
void ScrollCtrl::update() | |
{ | |
if (!m_pComp->param().canScroll) { | |
return; | |
} | |
if (grab().isGrab()) { | |
return; | |
} | |
if (m_pComp->param().region.mouseOver()) { | |
constexpr double speed = 30.0; | |
if (KeyShift.pressed()) { | |
m_pComp->param().scenePos.x += Mouse::Wheel() * speed; | |
} else { | |
m_pComp->param().scenePos.y += Mouse::Wheel() * speed; | |
m_pComp->param().scenePos.x += Mouse::WheelH() * speed; | |
} | |
} | |
} | |
void ScrollCtrl::draw(const ColorF& barColor, const ColorF& gripColor) const | |
{ | |
m_view->draw(barColor, gripColor); | |
} | |
bool ScrollCtrl::onGrabPromise() | |
{ | |
if (!m_pComp->param().canScroll) { | |
return false; | |
} | |
if (m_view->isBarVMouseOver()) { | |
return true; | |
} else if (m_view->isBarHMouseOver()) { | |
return true; | |
} | |
return false; | |
} | |
void ScrollCtrl::onPreGrabCheck(bool isPromised) | |
{ | |
bool isBarVMouseOver = false; | |
bool isBarHMouseOver = false; | |
if (isPromised) { | |
if (m_view->isBarVMouseOver()) { | |
isBarVMouseOver = true; | |
} else if (m_view->isBarHMouseOver()) { | |
isBarHMouseOver = true; | |
} | |
} | |
const double dt = Scene::DeltaTime(); | |
// スクロールバーの演出 | |
m_view->updateOnTime(isBarVMouseOver, isBarHMouseOver, dt); | |
} | |
s3d::Optional<GrabState> ScrollCtrl::onGrabCheck() | |
{ | |
if (m_view->isUpBtnClicked()) { | |
return GrabState::ScrollUp; | |
} else if (m_view->isDownBtnClicked()) { | |
return GrabState::ScrollDown; | |
} else if (m_view->isGripVClicked()) { | |
return GrabState::ScrollV; | |
} else if (m_view->isBarVClicked()) { | |
return GrabState::ScrollVTo; | |
} else if (m_view->isLeftBtnClicked()) { | |
return GrabState::ScrollLeft; | |
} else if (m_view->isRightBtnClicked()) { | |
return GrabState::ScrollRight; | |
} else if (m_view->isGripHClicked()) { | |
return GrabState::ScrollH; | |
} else if (m_view->isBarHClicked()) { | |
return GrabState::ScrollHTo; | |
} | |
return s3d::none; | |
} | |
void ScrollCtrl::onGrab(GrabState state) | |
{ | |
m_waitTimer = 0; | |
auto& param = m_pComp->param(); | |
const auto& grabCursorPos = grab().grabCursorPos(); | |
const auto& grabScenePos = grab().grabScenePos(); | |
if (state == GrabState::ScrollUp) { | |
m_view->pushUpBtn(); | |
param.scenePos.y -= 1; | |
} else if (state == GrabState::ScrollDown) { | |
m_view->pushDownBtn(); | |
param.scenePos.y += 1; | |
} else if (state == GrabState::ScrollLeft) { | |
m_view->pushLeftBtn(); | |
param.scenePos.x -= 1; | |
} else if (state == GrabState::ScrollRight) { | |
m_view->pushRightBtn(); | |
param.scenePos.x += 1; | |
} else if (state == GrabState::ScrollVTo) { | |
auto moveDiff = m_view->gripVHightAndOffsetMax().first; | |
const auto gripV = m_view->gripV(); | |
if (gripV.y > grabCursorPos.y) { | |
moveDiff *= -1.0; | |
} else if (gripV.y + gripV.h < grabCursorPos.y) { | |
moveDiff *= 1.0; | |
} else { | |
moveDiff *= 0.0; | |
} | |
param.scenePos.y = m_view->toSceneYFromGripDiff(grabScenePos, moveDiff); | |
} else if (state == GrabState::ScrollHTo) { | |
auto moveDiff = m_view->gripHWidthAndOffsetMax().first; | |
const auto gripH = m_view->gripH(); | |
if (gripH.x > grabCursorPos.x) { | |
moveDiff *= -1.0; | |
} else if (gripH.x + gripH.w < grabCursorPos.x) { | |
moveDiff *= 1.0; | |
} else { | |
moveDiff *= 0.0; | |
} | |
param.scenePos.x = m_view->toSceneXFromGripDiff(grabScenePos, moveDiff); | |
} | |
} | |
void ScrollCtrl::onGrabUpdate(GrabState state) | |
{ | |
auto dt = Scene::DeltaTime(); | |
m_waitTimer += dt; | |
auto& param = m_pComp->param(); | |
const auto& grabCursorPos = grab().grabCursorPos(); | |
const auto& grabScenePos = grab().grabScenePos(); | |
auto delta = Cursor::PosF() - grabCursorPos; | |
if (state == GrabState::ScrollV) { | |
// スクロール | |
param.scenePos.y = m_view->toSceneYFromGripDiff(grabScenePos, delta.y); | |
} else if (state == GrabState::ScrollH) { | |
// スクロール | |
param.scenePos.x = m_view->toSceneXFromGripDiff(grabScenePos, delta.x); | |
} else if (state == GrabState::ScrollUp) { | |
if (m_waitTimer >= 0.5) { | |
if (m_view->isUpBtnMouseOver()) { | |
param.scenePos.y -= 200.0 * dt; | |
} | |
} | |
} else if (state == GrabState::ScrollDown) { | |
if (m_waitTimer >= 0.5) { | |
if (m_view->isDownBtnMouseOver()) { | |
param.scenePos.y += 200.0 * dt; | |
} | |
} | |
} else if (state == GrabState::ScrollLeft) { | |
if (m_waitTimer >= 0.5) { | |
if (m_view->isLeftBtnMouseOver()) { | |
param.scenePos.x -= 200.0 * dt; | |
} | |
} | |
} else if (state == GrabState::ScrollRight) { | |
if (m_waitTimer >= 0.5) { | |
if (m_view->isRightBtnMouseOver()) { | |
param.scenePos.x += 200.0 * dt; | |
} | |
} | |
} else if (state == GrabState::ScrollVTo) { | |
if (m_waitTimer >= 0.5) { | |
if (m_view->isBarVMouseOver()) { | |
auto moveDiff = m_view->gripVHightAndOffsetMax().first * 60.0 * dt; | |
const auto gripV = m_view->gripV(); | |
if (gripV.y > grabCursorPos.y) { | |
moveDiff *= -1.0; | |
} else if (gripV.y + gripV.h < grabCursorPos.y) { | |
moveDiff *= 1.0; | |
} else { | |
moveDiff *= 0.0; | |
} | |
param.scenePos.y = m_view->toSceneYFromGripDiff(param.scenePos, moveDiff); | |
} | |
} | |
} else if (state == GrabState::ScrollHTo) { | |
if (m_waitTimer >= 0.5) { | |
if (m_view->isBarHMouseOver()) { | |
auto moveDiff = m_view->gripHWidthAndOffsetMax().first * 60.0 * dt; | |
const auto gripH = m_view->gripH(); | |
if (gripH.x > grabCursorPos.x) { | |
moveDiff *= -1.0; | |
} else if (gripH.x + gripH.w < grabCursorPos.x) { | |
moveDiff *= 1.0; | |
} else { | |
moveDiff *= 0.0; | |
} | |
param.scenePos.x = m_view->toSceneXFromGripDiff(param.scenePos, moveDiff); | |
} | |
} | |
} | |
} | |
void ScrollCtrl::onGrabRelease() | |
{ | |
m_view->resetPush(); | |
} | |
GrabCtrl& ScrollCtrl::grab() const | |
{ | |
return m_pComp->grabCtrl(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <memory> | |
#include "GrabCtrl.hpp" | |
namespace vw::detail | |
{ | |
class Component; | |
/// <summary> | |
/// シーンスクロール制御 | |
/// </summary> | |
class ScrollCtrl : public IGrabHandler | |
{ | |
public: | |
class View; | |
public: | |
ScrollCtrl(Component* pComp); | |
void update(); | |
void draw(const s3d::ColorF& barColor, const s3d::ColorF& gripColor) const; | |
public: | |
bool onGrabPromise() override; | |
void onPreGrabCheck(bool isPromised) override; | |
s3d::Optional<GrabState> onGrabCheck() override; | |
void onGrab(GrabState state); | |
void onGrabUpdate(GrabState state); | |
void onGrabRelease(); | |
private: | |
GrabCtrl& grab() const; | |
private: | |
Component* m_pComp; | |
std::unique_ptr<View> m_view; | |
double m_waitTimer = 0; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "WindowMover.hpp" | |
#include "Constants.hpp" | |
#include "Component.hpp" | |
#include "WindowParam.hpp" | |
namespace vw::detail | |
{ | |
WindowMover::WindowMover(Component* pComp) : | |
m_pComp(pComp) | |
{ | |
grab().registHandler(this); | |
} | |
bool WindowMover::onGrabPromise() | |
{ | |
auto& param = m_pComp->param(); | |
if (!param.canMove) { | |
return false; | |
} | |
const auto rect = param.region; | |
return rect.mouseOver(); | |
} | |
void WindowMover::onPreGrabCheck([[maybe_unused]] bool isPromised) | |
{ | |
} | |
s3d::Optional<GrabState> WindowMover::onGrabCheck() | |
{ | |
auto& param = m_pComp->param(); | |
const auto rect = param.region; | |
if (rect.leftClicked()) { | |
return GrabState::Move; | |
} | |
return s3d::none; | |
} | |
void WindowMover::onGrab([[maybe_unused]] GrabState state) | |
{ | |
} | |
void WindowMover::onGrabUpdate(GrabState state) | |
{ | |
const auto& grabPos = grab().grabPos(); | |
auto& param = m_pComp->param(); | |
auto delta = Cursor::PosF() - grab().grabCursorPos(); | |
if (state == GrabState::Move) { | |
// 移動 | |
param.pos = grabPos + delta; | |
} | |
} | |
void WindowMover::onGrabRelease() | |
{ | |
} | |
GrabCtrl& WindowMover::grab() const | |
{ | |
return m_pComp->grabCtrl(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "GrabCtrl.hpp" | |
namespace vw::detail | |
{ | |
class Component; | |
/// <summary> | |
/// ウィンドウ移動制御 | |
/// </summary> | |
class WindowMover : public IGrabHandler | |
{ | |
public: | |
WindowMover(Component* pComp); | |
public: | |
bool onGrabPromise() override; | |
void onPreGrabCheck(bool isPromised) override; | |
s3d::Optional<GrabState> onGrabCheck() override; | |
void onGrab(GrabState state); | |
void onGrabUpdate(GrabState state); | |
void onGrabRelease(); | |
private: | |
GrabCtrl& grab() const; | |
private: | |
Component* m_pComp; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <Siv3D/RectF.hpp> | |
namespace vw::detail | |
{ | |
struct WindowParam | |
{ | |
SIV3D_DISABLE_MSVC_WARNINGS_PUSH(4201) | |
union { | |
struct { | |
s3d::Vec2 pos; | |
s3d::Vec2 size; | |
}; | |
struct { | |
s3d::RectF region; | |
}; | |
}; | |
SIV3D_DISABLE_MSVC_WARNINGS_POP() | |
s3d::Vec2 scenePos; | |
s3d::Vec2 sceneSize; | |
s3d::Optional<ColorF> backGroundColor; | |
s3d::Optional<ColorF> frameColor; | |
s3d::ColorF scrollBarColor; | |
s3d::ColorF scrollGripColor; | |
bool canResize; | |
bool isResizeClampSceneSize; | |
bool canMove; | |
bool canScroll; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "WindowResizer.hpp" | |
#include "Constants.hpp" | |
#include "Component.hpp" | |
#include "WindowParam.hpp" | |
#include <Siv3D.hpp> | |
namespace vw::detail | |
{ | |
WindowResizer::WindowResizer(Component* pComp) : | |
m_pComp(pComp) | |
{ | |
grab().registHandler(this); | |
} | |
bool WindowResizer::onGrabPromise() | |
{ | |
auto& param = m_pComp->param(); | |
if (!param.canResize) { | |
return false; | |
} | |
constexpr auto margin = Constants::Margin; | |
const auto rect = param.region; | |
const RectF tl{ rect.x - margin, rect.y - margin, margin, margin }; | |
const RectF tr{ rect.x + rect.w, rect.y - margin, margin, margin }; | |
const RectF bl{ rect.x - margin, rect.y + rect.h, margin, margin }; | |
const RectF br{ rect.x + rect.w, rect.y + rect.h, margin, margin }; | |
const RectF top{ rect.x, rect.y - margin , rect.w, margin }; | |
const RectF bottom{ rect.x, rect.y + rect.h , rect.w, margin }; | |
const RectF left{ rect.x - margin, rect.y, margin, rect.h }; | |
const RectF right{ rect.x + rect.w, rect.y, margin, rect.h }; | |
if (param.canMove && tl.mouseOver()) { | |
s3d::Cursor::RequestStyle(CursorStyle::ResizeNWSE); | |
} else if (param.canMove && tr.mouseOver()) { | |
s3d::Cursor::RequestStyle(CursorStyle::ResizeNESW); | |
} else if (param.canMove && bl.mouseOver()) { | |
s3d::Cursor::RequestStyle(CursorStyle::ResizeNESW); | |
} else if (br.mouseOver()) { | |
s3d::Cursor::RequestStyle(CursorStyle::ResizeNWSE); | |
} else if ((param.canMove && top.mouseOver()) || bottom.mouseOver()) { | |
s3d::Cursor::RequestStyle(CursorStyle::ResizeUpDown); | |
} else if ((param.canMove && left.mouseOver()) || right.mouseOver()) { | |
s3d::Cursor::RequestStyle(CursorStyle::ResizeLeftRight); | |
} else { | |
return false; | |
} | |
return true; | |
} | |
void WindowResizer::onPreGrabCheck([[maybe_unused]] bool isPromised) | |
{ | |
} | |
s3d::Optional<GrabState> WindowResizer::onGrabCheck() | |
{ | |
constexpr auto margin = Constants::Margin; | |
auto& param = m_pComp->param(); | |
const auto rect = param.region; | |
const RectF tl{ rect.x - margin, rect.y - margin, margin, margin }; | |
const RectF tr{ rect.x + rect.w, rect.y - margin, margin, margin }; | |
const RectF bl{ rect.x - margin, rect.y + rect.h, margin, margin }; | |
const RectF br{ rect.x + rect.w, rect.y + rect.h, margin, margin }; | |
const RectF top{ rect.x, rect.y - margin , rect.w, margin }; | |
const RectF bottom{ rect.x, rect.y + rect.h , rect.w, margin }; | |
const RectF left{ rect.x - margin, rect.y, margin, rect.h }; | |
const RectF right{ rect.x + rect.w, rect.y, margin, rect.h }; | |
if (param.canMove && tl.leftClicked()) { | |
return GrabState::Tl; | |
} else if (param.canMove && tr.leftClicked()) { | |
return GrabState::Tr; | |
} else if (param.canMove && bl.leftClicked()) { | |
return GrabState::Bl; | |
} else if (br.leftClicked()) { | |
return GrabState::Br; | |
} else if (param.canMove && top.leftClicked()) { | |
return GrabState::Top; | |
} else if (bottom.leftClicked()) { | |
return GrabState::Bottom; | |
} else if (param.canMove && left.leftClicked()) { | |
return GrabState::Left; | |
} else if (right.leftClicked()) { | |
return GrabState::Right; | |
} | |
return s3d::none; | |
} | |
void WindowResizer::onGrab([[maybe_unused]] GrabState state) | |
{ | |
} | |
void WindowResizer::onGrabUpdate(GrabState state) | |
{ | |
constexpr auto minSize = Constants::WinMinSize; | |
auto& param = m_pComp->param(); | |
const auto& grabPos = grab().grabPos(); | |
const auto& grabSize = grab().grabSize(); | |
auto delta = Cursor::PosF() - grab().grabCursorPos(); | |
if (state == GrabState::Top || state == GrabState::Tl || state == GrabState::Tr) { | |
// 上 | |
if (grabSize.y - delta.y < minSize.y) { | |
delta.y = -(minSize.y - grabSize.y); | |
} | |
param.pos.y = grabPos.y + delta.y; | |
param.size.y = grabSize.y - delta.y; | |
} else if (state == GrabState::Bottom || state == GrabState::Bl || state == GrabState::Br) { | |
// 下 | |
if (grabSize.y + delta.y < minSize.y) { | |
delta.y = minSize.y - grabSize.y; | |
} | |
param.size.y = grabSize.y + delta.y; | |
} | |
if (state == GrabState::Left || state == GrabState::Tl || state == GrabState::Bl) { | |
// 左 | |
if (grabSize.x - delta.x < minSize.x) { | |
delta.x = -(minSize.x - grabSize.x); | |
} | |
param.pos.x = grabPos.x + delta.x; | |
param.size.x = grabSize.x - delta.x; | |
} else if (state == GrabState::Right || state == GrabState::Tr || state == GrabState::Br) { | |
// 右 | |
if (grabSize.x + delta.x < minSize.x) { | |
delta.x = minSize.x - grabSize.x; | |
} | |
param.size.x = grabSize.x + delta.x; | |
} | |
} | |
void WindowResizer::onGrabRelease() | |
{ | |
} | |
GrabCtrl& WindowResizer::grab() const | |
{ | |
return m_pComp->grabCtrl(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "GrabCtrl.hpp" | |
namespace vw::detail | |
{ | |
class Component; | |
/// <summary> | |
/// ウィンドウサイズ制御 | |
/// </summary> | |
class WindowResizer : public IGrabHandler | |
{ | |
public: | |
WindowResizer(Component* pComp); | |
public: | |
bool onGrabPromise() override; | |
void onPreGrabCheck(bool isPromised) override; | |
s3d::Optional<GrabState> onGrabCheck() override; | |
void onGrab(GrabState state); | |
void onGrabUpdate(GrabState state); | |
void onGrabRelease(); | |
private: | |
GrabCtrl& grab() const; | |
private: | |
Component* m_pComp; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# include <Siv3D.hpp> // OpenSiv3D v0.6.4 | |
# include "VirtualWindow.hpp" | |
void Main() | |
{ | |
// 通常のフォントを作成 | Create a new font | |
const Font font{ 60 }; | |
// 絵文字用フォントを作成 | Create a new emoji font | |
const Font emojiFont{ 60, Typeface::ColorEmoji }; | |
// `font` が絵文字用フォントも使えるようにする | Set emojiFont as a fallback | |
font.addFallback(emojiFont); | |
// 画像ファイルからテクスチャを作成 | Create a texture from an image file | |
const Texture texture{ U"example/windmill.png" }; | |
// 絵文字からテクスチャを作成 | Create a texture from an emoji | |
const Texture emoji{ U"🐈"_emoji }; | |
// 絵文字を描画する座標 | Coordinates of the emoji | |
Vec2 emojiPos{ 300, 150 }; | |
const Vec2 pos{ 0, 0 }; | |
const Vec2 windowSize{ 300, 300 }; | |
const Vec2 sceneSize = Scene::Size(); | |
vw::VirtualWindow window(vw::WindowContext(pos, windowSize, sceneSize) | |
.setBackGroundColor(ColorF{ 0.8, 0.9, 1.0 }) | |
); | |
while (System::Update()) | |
{ | |
window.draw([&](const s3d::RectF&) { | |
#pragma region 描画するもの | |
// テクスチャを描く | Draw a texture | |
auto r = texture.draw(200, 200); | |
if (r.mouseOver()) { | |
r.draw(ColorF(1, 0, 0, 0.1)); | |
} | |
// テキストを画面の中心に描く | Put a text in the middle of the screen | |
font(U"Hello, Siv3D!🚀").drawAt(Scene::Center(), Palette::Black); | |
// サイズをアニメーションさせて絵文字を描く | Draw a texture with animated size | |
emoji.resized(100 + Periodic::Sine0_1(1s) * 20).drawAt(emojiPos); | |
// もし [A] キーが押されたら | When [A] key is down | |
if (KeyA.down()) { | |
// 選択肢からランダムに選ばれたメッセージをデバッグ表示 | Print a randomly selected text | |
Print << Sample({ U"Hello!", U"こんにちは", U"你好", U"안녕하세요?" }); | |
} | |
// もし [Button] が押されたら | When [Button] is pushed | |
if (SimpleGUI::Button(U"Button", Vec2{ 640, 40 })) { | |
// 画面内のランダムな場所に座標を移動 | |
// Move the coordinates to a random position in the screen | |
emojiPos = RandomVec2(Scene::Rect()); | |
} | |
#pragma endregion | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "VirtualWindow.hpp" | |
#include "detail/Component.hpp" | |
#include "detail/Constants.hpp" | |
#include "detail/GrabCtrl.hpp" | |
#include "detail/ScrollCtrl.hpp" | |
#include "detail/WindowParam.hpp" | |
#include <Siv3D.hpp> | |
namespace vw | |
{ | |
using namespace detail; | |
WindowContext::WindowContext() : | |
WindowContext({ 300, 300 }) | |
{} | |
WindowContext::WindowContext(const s3d::Vec2& _size) : | |
WindowContext({ 0, 0 }, _size, _size) | |
{} | |
WindowContext::WindowContext(const s3d::Vec2& _pos, const s3d::Vec2& _size) : | |
WindowContext(_pos, _size, _size) | |
{} | |
WindowContext::WindowContext(const s3d::Vec2& _pos, const s3d::Vec2& _size, const s3d::Vec2& _sceneSize) : | |
pos(_pos), | |
size(_size), | |
sceneSize(_sceneSize), | |
backGroundColor(Palette::White), | |
frameColor(Color(240)), | |
scrollBarColor(Color(240)), | |
scrollGripColor(Color(133)) | |
{} | |
WindowContext& WindowContext::setBackGroundColor(const s3d::Optional<s3d::ColorF>& color) | |
{ | |
backGroundColor = color; | |
return *this; | |
} | |
WindowContext& WindowContext::setFrameColor(const s3d::Optional<s3d::ColorF>& color) | |
{ | |
frameColor = color; | |
return *this; | |
} | |
WindowContext& WindowContext::setScrollBarColor(const s3d::ColorF& color) | |
{ | |
scrollBarColor = color; | |
return *this; | |
} | |
WindowContext& WindowContext::setScrollGripColor(const s3d::ColorF& color) | |
{ | |
scrollGripColor = color; | |
return *this; | |
} | |
class VirtualWindow::Handle : public WindowParam | |
{ | |
public: | |
Handle(const WindowContext& context) : | |
m_comp(*this) | |
{ | |
this->pos = context.pos; | |
this->setSize(context.size); | |
this->sceneSize = context.sceneSize; | |
this->scenePos = {}; | |
this->backGroundColor = context.backGroundColor; | |
this->frameColor = context.frameColor; | |
this->scrollBarColor = context.scrollBarColor; | |
this->scrollGripColor = context.scrollGripColor; | |
this->canResize = context.canResize; | |
this->isResizeClampSceneSize = context.isResizeClampSceneSize; | |
this->canMove = context.canMove; | |
this->canScroll = context.canScroll; | |
} | |
void setSize(const s3d::Vec2& _size) | |
{ | |
if (this->sceneSize.x > _size.x) { | |
this->size.x = s3d::Max(_size.x, Constants::WinMinSize.x); | |
} else { | |
this->size.x = _size.x; | |
} | |
if (this->sceneSize.y > _size.y) { | |
this->size.y = s3d::Max(_size.y, Constants::WinMinSize.x); | |
} else { | |
this->size.y = _size.y; | |
} | |
} | |
void setScenePos(const s3d::Vec2& _pos) | |
{ | |
this->scenePos.x = s3d::Clamp(_pos.x, 0.0, Max(sceneSize.x - size.x, 0.0)); | |
this->scenePos.y = s3d::Clamp(_pos.y, 0.0, Max(sceneSize.y - size.y, 0.0)); | |
} | |
void setScenePosToBottom() | |
{ | |
Vec2 nextScenePos = this->scenePos; | |
nextScenePos.y = Max(sceneSize.y - size.y, 0.0); | |
this->setScenePos(nextScenePos); | |
} | |
bool isScrollBottom() const | |
{ | |
return scenePos.y >= Max(sceneSize.y - size.y, 0.0); | |
} | |
void update() | |
{ | |
m_comp.grabCtrl().update(); | |
m_comp.scrollCtrl().update(); | |
// Clamp | |
if (isResizeClampSceneSize) { | |
size.x = Min(size.x, sceneSize.x); | |
size.y = Min(size.y, sceneSize.y); | |
} | |
this->setScenePos(this->scenePos); | |
} | |
s3d::Rect region() const | |
{ | |
return this->regionF().asRect(); | |
} | |
const s3d::RectF& regionF() const | |
{ | |
return WindowParam::region; | |
} | |
s3d::ScopedViewport2D startViewport() const | |
{ | |
return s3d::ScopedViewport2D{ this->region() }; | |
} | |
s3d::Transformer2D transformer() const | |
{ | |
return { Mat3x2::Translate(-scenePos), Mat3x2::Translate(pos - scenePos) }; | |
} | |
const s3d::RectF& draw(std::function<void(const s3d::RectF&)> scene) | |
{ | |
this->update(); | |
const auto& region = this->regionF(); | |
if (backGroundColor) { | |
region.draw(*backGroundColor); | |
} | |
{ | |
auto t2d = this->transformer(); | |
auto viewport = this->startViewport(); | |
scene(s3d::RectF{ scenePos, size }); | |
} | |
if (this->canScroll) { | |
m_comp.scrollCtrl().draw(scrollBarColor, scrollGripColor); | |
} | |
if (frameColor) { | |
region.drawFrame(0, 1, *frameColor); | |
} | |
return region; | |
} | |
private: | |
detail::Component m_comp; | |
}; | |
VirtualWindow::VirtualWindow() : | |
VirtualWindow({ 100, 100 }) | |
{} | |
VirtualWindow::VirtualWindow(const s3d::Vec2& size) : | |
VirtualWindow({ 0, 0 }, size) | |
{} | |
VirtualWindow::VirtualWindow(const s3d::Vec2& pos, const s3d::Vec2& size) : | |
VirtualWindow(pos, size, size) | |
{} | |
VirtualWindow::VirtualWindow( | |
const s3d::Vec2& pos, | |
const s3d::Vec2& size, | |
const s3d::Vec2& sceneSize | |
) : | |
VirtualWindow(WindowContext{ pos, size, sceneSize }) | |
{} | |
VirtualWindow::VirtualWindow(const WindowContext& context) : | |
m_pHandle(std::make_shared<Handle>(context)) | |
{} | |
VirtualWindow& VirtualWindow::setPos(const s3d::Vec2& pos) | |
{ | |
m_pHandle->pos = pos; | |
return *this; | |
} | |
VirtualWindow& VirtualWindow::setSize(const s3d::Vec2& size) | |
{ | |
m_pHandle->setSize(size); | |
return *this; | |
} | |
VirtualWindow& VirtualWindow::setScenePos(const s3d::Vec2& scenePos) | |
{ | |
m_pHandle->setScenePos(scenePos); | |
return *this; | |
} | |
VirtualWindow& VirtualWindow::setScenePosToBottom() | |
{ | |
m_pHandle->setScenePosToBottom(); | |
return *this; | |
} | |
bool VirtualWindow::isScrollBottom() const | |
{ | |
return m_pHandle->isScrollBottom(); | |
} | |
VirtualWindow& VirtualWindow::setSceneSize(const s3d::Vec2& sceneSize) | |
{ | |
m_pHandle->sceneSize = sceneSize; | |
return *this; | |
} | |
VirtualWindow& VirtualWindow::setBackGroundColor(const s3d::Optional<s3d::ColorF>& color) | |
{ | |
m_pHandle->backGroundColor = color; | |
return *this; | |
} | |
VirtualWindow& VirtualWindow::setFrameColor(const s3d::Optional<s3d::ColorF>& color) | |
{ | |
m_pHandle->frameColor = color; | |
return *this; | |
} | |
VirtualWindow& VirtualWindow::setScrollBarColor(const s3d::ColorF& color) | |
{ | |
m_pHandle->scrollBarColor = color; | |
return *this; | |
} | |
VirtualWindow& VirtualWindow::setScrollGripColor(const s3d::ColorF& color) | |
{ | |
m_pHandle->scrollGripColor = color; | |
return *this; | |
} | |
const s3d::RectF& VirtualWindow::region() const | |
{ | |
return m_pHandle->regionF(); | |
} | |
const s3d::RectF& VirtualWindow::draw(std::function<void(const s3d::RectF&)> scene) const | |
{ | |
return m_pHandle->draw(std::move(scene)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <memory> | |
#include <Siv3D/Rect.hpp> | |
#include <Siv3D/RectF.hpp> | |
#include <Siv3D/Vector2D.hpp> | |
#include <Siv3D/Optional.hpp> | |
namespace vw | |
{ | |
struct WindowContext | |
{ | |
public: | |
WindowContext(); | |
WindowContext(const s3d::Vec2& _size); | |
WindowContext(const s3d::Vec2& _pos, const s3d::Vec2& _size); | |
WindowContext(const s3d::Vec2& _pos, const s3d::Vec2& _size, const s3d::Vec2& _sceneSize); | |
WindowContext& setBackGroundColor(const s3d::Optional<s3d::ColorF>& color); | |
WindowContext& setFrameColor(const s3d::Optional<s3d::ColorF>& color); | |
WindowContext& setScrollBarColor(const s3d::ColorF& color); | |
WindowContext& setScrollGripColor(const s3d::ColorF& color); | |
WindowContext& setCanResize(bool _canResize) | |
{ | |
this->canResize = _canResize; | |
return *this; | |
} | |
WindowContext& setIsResizeClampSceneSize(bool _isResizeClampSceneSize) | |
{ | |
this->isResizeClampSceneSize = _isResizeClampSceneSize; | |
return *this; | |
} | |
WindowContext& setCanMove(bool _canMove) | |
{ | |
this->canMove = _canMove; | |
return *this; | |
} | |
WindowContext& setCanScroll(bool _canScroll) | |
{ | |
this->canScroll = _canScroll; | |
return *this; | |
} | |
public: | |
s3d::Vec2 pos; | |
s3d::Vec2 size; | |
s3d::Vec2 sceneSize; | |
s3d::Optional<ColorF> backGroundColor; | |
s3d::Optional<ColorF> frameColor; | |
s3d::ColorF scrollBarColor; | |
s3d::ColorF scrollGripColor; | |
bool canResize = true; | |
bool isResizeClampSceneSize = true; | |
bool canMove = true; | |
bool canScroll = true; | |
}; | |
/// <summary> | |
/// 仮想ウィンドウ | |
/// </summary> | |
class VirtualWindow | |
{ | |
class Handle; | |
public: | |
VirtualWindow(); | |
VirtualWindow(const s3d::Vec2& size); | |
VirtualWindow(const s3d::Vec2& pos, const s3d::Vec2& size); | |
VirtualWindow(const s3d::Vec2& pos, const s3d::Vec2& size, const s3d::Vec2& sceneSize); | |
VirtualWindow(const WindowContext& context); | |
/// <summary> | |
/// ウィンドウの座標を設定 | |
/// </summary> | |
VirtualWindow& setPos(const s3d::Vec2& pos); | |
/// <summary> | |
/// ウィンドウのサイズを設定 | |
/// </summary> | |
VirtualWindow& setSize(const s3d::Vec2& size); | |
/// <summary> | |
/// シーンの座標を設定 | |
/// </summary> | |
VirtualWindow& setScenePos(const s3d::Vec2& scenePos); | |
/// <summary> | |
/// シーンの座標を一番下にする | |
/// </summary> | |
VirtualWindow& setScenePosToBottom(); | |
/// <summary> | |
/// スクロールが一番下にあるか | |
/// </summary> | |
bool isScrollBottom() const; | |
/// <summary> | |
/// シーンのサイズを設定する | |
/// </summary> | |
VirtualWindow& setSceneSize(const s3d::Vec2& sceneSize); | |
VirtualWindow& setBackGroundColor(const s3d::Optional<s3d::ColorF>& color); | |
VirtualWindow& setFrameColor(const s3d::Optional<s3d::ColorF>& color); | |
VirtualWindow& setScrollBarColor(const s3d::ColorF& color); | |
VirtualWindow& setScrollGripColor(const s3d::ColorF& color); | |
/// <summary> | |
/// ウィンドウ領域 | |
/// </summary> | |
const s3d::RectF& region() const; | |
/// <summary> | |
/// 描画 | |
/// </summary> | |
const s3d::RectF& draw(std::function<void(const s3d::RectF&)> scene) const; | |
private: | |
std::shared_ptr<Handle> m_pHandle; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment