Skip to content

Commit

Permalink
Implement line brush drawer
Browse files Browse the repository at this point in the history
  • Loading branch information
altalk23 committed Jun 22, 2024
1 parent 351700d commit f2a1e0e
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ project(Allium VERSION 1.0.0)
add_library(${PROJECT_NAME} SHARED
src/main.cpp
src/hooks/EditorUI.cpp
src/manager/BrushManager.cpp
src/ui/AlliumPopup.cpp
src/util/BrushDrawer.cpp
src/util/LineBrushDrawer.cpp
)

target_include_directories(${PROJECT_NAME} PUBLIC
Expand Down
22 changes: 22 additions & 0 deletions include/Allium/manager/BrushManager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <Geode/Geode.hpp>

namespace allium {
enum class BrushType {
None,
Line,
Curve,
Free
};

class BrushDrawer;

class BrushManager {
public:
static BrushManager* get();

BrushType m_currentBrush = BrushType::None;
BrushDrawer* m_currentDrawer = nullptr;
};
}
2 changes: 2 additions & 0 deletions include/Allium/ui/AlliumPopup.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

#include <Geode/ui/Popup.hpp>

namespace allium {
Expand Down
21 changes: 21 additions & 0 deletions include/Allium/util/BrushDrawer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <Geode/Geode.hpp>

namespace allium {
class BrushDrawer : public cocos2d::CCNode {
protected:
cocos2d::CCDrawNode* m_overlay = nullptr;
public:
bool init() override;

virtual bool handleTouchStart(cocos2d::CCPoint const& point);
virtual void handleTouchMove(cocos2d::CCPoint const& point);
virtual void handleTouchEnd(cocos2d::CCPoint const& point);

virtual void updateOverlay();
void clearOverlay();

virtual void updateLine();
};
}
28 changes: 28 additions & 0 deletions include/Allium/util/LineBrushDrawer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include "BrushDrawer.hpp"

namespace allium {
class LineBrushDrawer : public BrushDrawer {
protected:
cocos2d::CCPoint m_firstPoint = ccp(0, 0);
cocos2d::CCPoint m_lastPoint = ccp(0, 0);

// Todo: Implement adjustable line width
float m_lineWidth = 5.0f;
// Todo: Implement adjustable line color
cocos2d::ccColor3B m_lineColor = cocos2d::ccc3(255, 255, 255);

public:
static LineBrushDrawer* create();
bool init() override;

bool handleTouchStart(cocos2d::CCPoint const& point) override;
void handleTouchMove(cocos2d::CCPoint const& point) override;
void handleTouchEnd(cocos2d::CCPoint const& point) override;

void updateOverlay() override;

void updateLine() override;
};
}
38 changes: 38 additions & 0 deletions src/hooks/EditorUI.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <Geode/Geode.hpp>
#include <manager/BrushManager.hpp>
#include <ui/AlliumPopup.hpp>
#include <util/BrushDrawer.hpp>

using namespace geode::prelude;
using namespace allium;
Expand Down Expand Up @@ -36,4 +38,40 @@ struct EditorUIHook : Modify<EditorUIHook, EditorUI> {

return true;
}

CCPoint getLayerPosition(CCTouch* touch) {
auto objectLayer = LevelEditorLayer::get()->m_objectLayer;
auto glPoint = CCDirector::get()->convertToGL(touch->getLocationInView());
return objectLayer->convertToNodeSpace(this->convertToWorldSpace(glPoint));
}

bool ccTouchBegan(CCTouch* touch, CCEvent* event) {
if (BrushManager::get()->m_currentDrawer) {
auto layerPosition = this->getLayerPosition(touch);
BrushManager::get()->m_currentDrawer->handleTouchStart(layerPosition);

return true;
}
return EditorUI::ccTouchBegan(touch, event);
}

void ccTouchMoved(CCTouch* touch, CCEvent* event) {
if (BrushManager::get()->m_currentDrawer) {
auto layerPosition = this->getLayerPosition(touch);
BrushManager::get()->m_currentDrawer->handleTouchMove(layerPosition);

return;
}
return EditorUI::ccTouchMoved(touch, event);
}

void ccTouchEnded(CCTouch* touch, CCEvent* event) {
if (BrushManager::get()->m_currentDrawer) {
auto layerPosition = this->getLayerPosition(touch);
BrushManager::get()->m_currentDrawer->handleTouchEnd(layerPosition);

return;
}
return EditorUI::ccTouchEnded(touch, event);
}
};
12 changes: 12 additions & 0 deletions src/manager/BrushManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <manager/BrushManager.hpp>

using namespace geode::prelude;
using namespace allium;

BrushManager* BrushManager::get() {
static BrushManager* instance = nullptr;
if (!instance) {
instance = new (std::nothrow) BrushManager();
}
return instance;
}
37 changes: 36 additions & 1 deletion src/ui/AlliumPopup.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <Geode/Geode.hpp>
#include <manager/BrushManager.hpp>
#include <ui/AlliumPopup.hpp>
#include <util/BrushDrawer.hpp>
#include <util/LineBrushDrawer.hpp>

using namespace geode::prelude;
using namespace allium;
Expand All @@ -19,6 +22,25 @@ void AlliumPopup::brushToggleCallback(CCMenuItemToggler* toggle) {
if (toggle != m_lineBrushToggle) m_lineBrushToggle->toggle(false);
if (toggle != m_curveBrushToggle) m_curveBrushToggle->toggle(false);
if (toggle != m_freeBrushToggle) m_freeBrushToggle->toggle(false);

auto objectLayer = LevelEditorLayer::get()->m_objectLayer;
auto brushDrawer = static_cast<BrushDrawer*>(objectLayer->getChildByID("brush-drawer"_spr));
if (brushDrawer) {
brushDrawer->removeFromParent();
}

if (toggle == m_lineBrushToggle) {
brushDrawer = LineBrushDrawer::create();
brushDrawer->setID("brush-drawer"_spr);
objectLayer->addChild(brushDrawer);

BrushManager::get()->m_currentDrawer = brushDrawer;
BrushManager::get()->m_currentBrush = BrushType::Line;
}
else {
BrushManager::get()->m_currentDrawer = nullptr;
BrushManager::get()->m_currentBrush = BrushType::None;
}
}

void AlliumPopup::createBrushToggle(std::string_view name, std::string const& id, CCMenuItemToggler*& toggle) {
Expand Down Expand Up @@ -74,7 +96,20 @@ bool AlliumPopup::setup() {
createBrushToggle("Curve", "curve-brush", m_curveBrushToggle);
createBrushToggle("Free", "free-brush", m_freeBrushToggle);

m_noneBrushToggle->toggle(true);
switch (BrushManager::get()->m_currentBrush) {
case BrushType::None:
m_noneBrushToggle->toggle(true);
break;
case BrushType::Line:
m_lineBrushToggle->toggle(true);
break;
case BrushType::Curve:
m_curveBrushToggle->toggle(true);
break;
case BrushType::Free:
m_freeBrushToggle->toggle(true);
break;
}

m_brushMenu->updateLayout();
m_mainColumn->updateLayout();
Expand Down
24 changes: 24 additions & 0 deletions src/util/BrushDrawer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <util/BrushDrawer.hpp>

using namespace geode::prelude;
using namespace allium;

bool BrushDrawer::init() {
m_overlay = cocos2d::CCDrawNode::create();
this->addChild(m_overlay);

return true;
}

bool BrushDrawer::handleTouchStart(cocos2d::CCPoint const& point) {
return true;
}
void BrushDrawer::handleTouchMove(cocos2d::CCPoint const& point) {}
void BrushDrawer::handleTouchEnd(cocos2d::CCPoint const& point) {}

void BrushDrawer::updateOverlay() {}
void BrushDrawer::clearOverlay() {
m_overlay->clear();
}

void BrushDrawer::updateLine() {}
71 changes: 71 additions & 0 deletions src/util/LineBrushDrawer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <util/LineBrushDrawer.hpp>

using namespace geode::prelude;
using namespace allium;

LineBrushDrawer* LineBrushDrawer::create() {
auto ret = new (std::nothrow) LineBrushDrawer();
if (ret && ret->init()) {
ret->autorelease();
return ret;
}
delete ret;
return nullptr;
}

bool LineBrushDrawer::init() {
if (!BrushDrawer::init()) return false;

return true;
}

bool LineBrushDrawer::handleTouchStart(cocos2d::CCPoint const& point) {
m_firstPoint = point;
m_lastPoint = point;
this->updateOverlay();
return true;
}
void LineBrushDrawer::handleTouchMove(cocos2d::CCPoint const& point) {
m_lastPoint = point;
this->updateOverlay();
}
void LineBrushDrawer::handleTouchEnd(cocos2d::CCPoint const& point) {
m_lastPoint = point;
this->clearOverlay();
this->updateLine();
}

void LineBrushDrawer::updateOverlay() {
this->clearOverlay();
m_overlay->drawSegment(m_firstPoint, m_lastPoint, m_lineWidth / 2.f, ccc4FFromccc3B(m_lineColor));
}

void LineBrushDrawer::updateLine() {
static constexpr int SQUARE_OBJECT_ID = 211;
static constexpr int WHITE_COLOR_ID = 1011;

auto center = (m_firstPoint + m_lastPoint) / 2.0f;

auto angle = std::atan2(m_lastPoint.y - m_firstPoint.y, m_lastPoint.x - m_firstPoint.x);

auto offsetFirst = m_firstPoint - ccp(m_lineWidth / 2.f, 0).rotateByAngle(ccp(0, 0), angle);
auto offsetLast = m_lastPoint + ccp(m_lineWidth / 2.f, 0).rotateByAngle(ccp(0, 0), angle);

auto object = LevelEditorLayer::get()->createObject(SQUARE_OBJECT_ID, center, false);
object->setRotation(-angle * 180.0f / M_PI);

auto scaleX = offsetFirst.getDistance(offsetLast) / 30.f;
auto scaleY = m_lineWidth / 30.f;

object->updateCustomScaleX(scaleX);
object->updateCustomScaleY(scaleY);

if (object->m_baseColor) {
object->m_baseColor->m_colorID = WHITE_COLOR_ID;
object->m_shouldUpdateColorSprite = true;
}
if (object->m_detailColor) {
object->m_detailColor->m_colorID = WHITE_COLOR_ID;
object->m_shouldUpdateColorSprite = true;
}
}

0 comments on commit f2a1e0e

Please sign in to comment.