Added ogfx::gui::RawTextInput
This commit is contained in:
parent
b9e85f20f5
commit
c298d7614b
19 changed files with 674 additions and 75 deletions
23
.vscode/settings.json
vendored
23
.vscode/settings.json
vendored
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"C_Cpp.errorSquiggles": "Enabled",
|
||||
"C_Cpp.errorSquiggles": "enabled",
|
||||
"files.associations": {
|
||||
"functional": "cpp",
|
||||
"thread": "cpp",
|
||||
|
|
@ -100,22 +100,23 @@
|
|||
},
|
||||
|
||||
"workbench.colorCustomizations": {
|
||||
"editor.background": "#131313",
|
||||
"tab.hoverBackground": "#111",
|
||||
// "editor.background": "#131313",
|
||||
"tab.hoverBackground": "#022809",
|
||||
"tab.inactiveBackground": "#000",
|
||||
"tab.activeBackground": "#1b1b1b",
|
||||
"tab.activeBorder": "#bb5400",
|
||||
"tab.activeBackground": "#001804",
|
||||
"editor.foldBackground": "#20070bcc",
|
||||
"tab.activeBorder": "#15ff00",
|
||||
"editorIndentGuide.background1": "#252525",
|
||||
"editorWhitespace.foreground": "#683700",
|
||||
"editor.lineHighlightBorder": "#1a1a1a",
|
||||
"editor.lineHighlightBackground": "#490050",
|
||||
"editor.lineHighlightBackground": "#0a200a",
|
||||
"editorBracketMatch.background": "#444",
|
||||
"editorBracketMatch.border": "#b80318",
|
||||
"editor.selectionBackground": "#3b3b3b",
|
||||
"editor.selectionHighlightBackground": "#702900",
|
||||
"statusBar.background": "#2e2850",
|
||||
"minimap.background" : "#1b1b1b",
|
||||
"sideBar.background": "#1b1b1b"
|
||||
"editor.selectionBackground": "#0e3616",
|
||||
"editor.selectionHighlightBackground": "#9c3e08c5",
|
||||
// "statusBar.background": "#2e2850",
|
||||
"minimap.background" : "#0f0f0f",
|
||||
"sideBar.background": "#0b0b0b"
|
||||
},
|
||||
|
||||
"workbench.editor.wrapTabs": true,
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ list(APPEND OGFX_SOURCE_FILES
|
|||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/FontUtils.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/WindowBase.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/BasicRenderer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/RawTextInput.cpp
|
||||
)
|
||||
list(APPEND TEST_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/test.cpp
|
||||
|
|
@ -78,6 +79,7 @@ target_include_directories(${TEST_TARGET} PUBLIC ${INCLUDE_DIRS})
|
|||
|
||||
target_link_libraries(${OMNIA_GFX_LIB} PUBLIC ${OMNIA_STD_LIB})
|
||||
target_link_libraries(${TEST_TARGET} PUBLIC ${OMNIA_STD_LIB})
|
||||
target_link_libraries(${TEST_TARGET} PUBLIC ${OMNIA_GFX_LIB})
|
||||
|
||||
#TODO: Different flags for Release/Debug
|
||||
add_compile_options(-O3 -m32 -MMD -MP -Wall -ggdb -fsanitize=address)
|
||||
|
|
|
|||
2
build.nr
2
build.nr
|
|
@ -1 +1 @@
|
|||
1856
|
||||
1859
|
||||
|
|
|
|||
BIN
extra/res/ttf/Courier Prime.ttf
Normal file
BIN
extra/res/ttf/Courier Prime.ttf
Normal file
Binary file not shown.
BIN
extra/res/ttf/MonospaceTypewriter.ttf
Normal file
BIN
extra/res/ttf/MonospaceTypewriter.ttf
Normal file
Binary file not shown.
BIN
extra/res/ttf/NK57 Monospace Cd Rg.otf
Normal file
BIN
extra/res/ttf/NK57 Monospace Cd Rg.otf
Normal file
Binary file not shown.
BIN
extra/res/ttf/Roboto-Regular.ttf
Normal file
BIN
extra/res/ttf/Roboto-Regular.ttf
Normal file
Binary file not shown.
BIN
extra/res/ttf/Roboto-Thin.ttf
Normal file
BIN
extra/res/ttf/Roboto-Thin.ttf
Normal file
Binary file not shown.
BIN
extra/res/ttf/UbuntuMono-R.ttf
Normal file
BIN
extra/res/ttf/UbuntuMono-R.ttf
Normal file
Binary file not shown.
BIN
extra/res/ttf/cmunorm.ttf
Normal file
BIN
extra/res/ttf/cmunorm.ttf
Normal file
Binary file not shown.
BIN
extra/res/ttf/digital7mono.ttf
Normal file
BIN
extra/res/ttf/digital7mono.ttf
Normal file
Binary file not shown.
BIN
extra/res/ttf/joystix monospace.otf
Normal file
BIN
extra/res/ttf/joystix monospace.otf
Normal file
Binary file not shown.
BIN
extra/res/ttf/monofonto rg.otf
Normal file
BIN
extra/res/ttf/monofonto rg.otf
Normal file
Binary file not shown.
287
src/ogfx/RawTextInput.cpp
Normal file
287
src/ogfx/RawTextInput.cpp
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
#include "RawTextInput.hpp"
|
||||
#include <ogfx/WindowBase.hpp>
|
||||
#include <ostd/Logger.hpp>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
RawTextInput::EventListener::EventListener(RawTextInput& _parent) : parent(_parent)
|
||||
{
|
||||
connectSignal(ostd::tBuiltinSignals::KeyPressed);
|
||||
connectSignal(ostd::tBuiltinSignals::KeyReleased);
|
||||
connectSignal(ostd::tBuiltinSignals::TextEntered);
|
||||
connectSignal(ostd::tBuiltinSignals::MouseDragged);
|
||||
connectSignal(ostd::tBuiltinSignals::MouseMoved);
|
||||
connectSignal(ostd::tBuiltinSignals::MousePressed);
|
||||
connectSignal(ostd::tBuiltinSignals::MouseReleased);
|
||||
connectSignal(ostd::tBuiltinSignals::OnGuiEvent);
|
||||
connectSignal(ostd::tBuiltinSignals::WindowResized);
|
||||
}
|
||||
|
||||
void RawTextInput::EventListener::handleSignal(ostd::tSignal& signal)
|
||||
{
|
||||
if (signal.ID == ostd::tBuiltinSignals::TextEntered)
|
||||
{
|
||||
if (m_lastEvent != eEventType::TextEntered)
|
||||
{
|
||||
m_lastEvent = eEventType::TextEntered;
|
||||
// parent.m_keyRepeatCounter.start();
|
||||
}
|
||||
auto& data = (ogfx::KeyEventData&)signal.userData;
|
||||
if (parent.m_charFilter == nullptr)
|
||||
{
|
||||
OX_ERROR("Invalid character filter in RawTextInput event listener.");
|
||||
return; //TODO: Better error
|
||||
}
|
||||
if (parent.m_charFilter->isValidChar(data.text))
|
||||
{
|
||||
if (parent.m_lastChar == data.text && parent.m_keyRepeatCounter.isCounting())
|
||||
{
|
||||
onSignalHandled(signal);
|
||||
return;
|
||||
}
|
||||
ostd::String s1 = parent.m_text.new_substr(0, parent.m_cursorPosition);
|
||||
ostd::String s2 = "";
|
||||
if (parent.m_cursorPosition < parent.m_text.len())
|
||||
s2 = parent.m_text.new_substr(parent.m_cursorPosition);
|
||||
s1.addChar(data.text).add(s2);
|
||||
parent.m_text = s1;
|
||||
parent.m_cursorPosition++;
|
||||
parent.m_lastChar = data.text;
|
||||
parent.m_keyRepeatCounter.start();
|
||||
if (parent.m_theme.cursorBlink)
|
||||
parent.m_theme.cursorBlinkCounter.start();
|
||||
parent.m_cursorState = true;
|
||||
}
|
||||
}
|
||||
else if (signal.ID == ostd::tBuiltinSignals::KeyPressed)
|
||||
{
|
||||
if (m_lastEvent != eEventType::KeyPressed)
|
||||
{
|
||||
m_lastEvent = eEventType::KeyPressed;
|
||||
// parent.m_keyRepeatCounter.start();
|
||||
}
|
||||
auto& data = (ogfx::KeyEventData&)signal.userData;
|
||||
if (parent.m_lastKeyCode == data.keyCode && parent.m_keyRepeatCounter.isCounting())
|
||||
{
|
||||
onSignalHandled(signal);
|
||||
return;
|
||||
}
|
||||
if (data.keyCode == SDLK_BACKSPACE)
|
||||
{
|
||||
parent.m_keyRepeatCounter.start();
|
||||
if (parent.m_theme.cursorBlink)
|
||||
parent.m_theme.cursorBlinkCounter.start();
|
||||
parent.m_cursorState = true;
|
||||
parent.m_lastKeyCode = data.keyCode;
|
||||
if (parent.m_cursorPosition == 0 || parent.m_text == "")
|
||||
{
|
||||
onSignalHandled(signal);
|
||||
return;
|
||||
}
|
||||
ostd::String s1 = parent.m_text.new_substr(0, parent.m_cursorPosition - 1);
|
||||
ostd::String s2 = "";
|
||||
if (parent.m_cursorPosition < parent.m_text.len())
|
||||
s2 = parent.m_text.new_substr(parent.m_cursorPosition);
|
||||
parent.m_text = s1 + s2;
|
||||
parent.m_cursorPosition--;
|
||||
}
|
||||
else if (data.keyCode == SDLK_LEFT)
|
||||
{
|
||||
parent.m_keyRepeatCounter.start();
|
||||
if (parent.m_theme.cursorBlink)
|
||||
parent.m_theme.cursorBlinkCounter.start();
|
||||
parent.m_cursorState = true;
|
||||
parent.m_lastKeyCode = data.keyCode;
|
||||
if (parent.m_cursorPosition > 0)
|
||||
parent.m_cursorPosition--;
|
||||
}
|
||||
else if (data.keyCode == SDLK_RIGHT)
|
||||
{
|
||||
parent.m_keyRepeatCounter.start();
|
||||
if (parent.m_theme.cursorBlink)
|
||||
parent.m_theme.cursorBlinkCounter.start();
|
||||
parent.m_cursorState = true;
|
||||
parent.m_lastKeyCode = data.keyCode;
|
||||
if (parent.m_cursorPosition < parent.m_text.len())
|
||||
parent.m_cursorPosition++;
|
||||
}
|
||||
else if (data.keyCode == SDLK_RETURN)
|
||||
{
|
||||
parent.m_keyRepeatCounter.start();
|
||||
parent.m_lastKeyCode = data.keyCode;
|
||||
ActionEventData aed(parent, parent.getName(), eActionEventType::Enter, ostd::BaseObject::InvalidRef());
|
||||
ostd::SignalHandler::emitSignal(RawTextInput::actionEventSignalID, ostd::tSignalPriority::RealTime, aed);
|
||||
}
|
||||
else if (data.keyCode == SDLK_TAB)
|
||||
{
|
||||
parent.m_keyRepeatCounter.start();
|
||||
parent.m_lastKeyCode = data.keyCode;
|
||||
ActionEventData aed(parent, parent.getName(), eActionEventType::Tab, ostd::BaseObject::InvalidRef());
|
||||
ostd::SignalHandler::emitSignal(RawTextInput::actionEventSignalID, ostd::tSignalPriority::RealTime, aed);
|
||||
}
|
||||
}
|
||||
else if (signal.ID == ostd::tBuiltinSignals::MouseMoved)
|
||||
{
|
||||
auto& data = (ogfx::MouseEventData&)signal.userData;
|
||||
if (parent.contains((float)data.position_x, (float)data.position_y))
|
||||
parent.m_mouseInside = true;
|
||||
else
|
||||
parent.m_mouseInside = false;
|
||||
}
|
||||
else if (signal.ID == ostd::tBuiltinSignals::MousePressed)
|
||||
{
|
||||
auto& data = (ogfx::MouseEventData&)signal.userData;
|
||||
if (data.button == ogfx::MouseEventData::eButton::Left && parent.m_gfx != nullptr && parent.m_mouseInside)
|
||||
{
|
||||
ostd::String text = parent.m_text;
|
||||
ostd::Vec2 relativePosition = { (float)data.position_x, (float)data.position_y };
|
||||
relativePosition -= (parent.getPosition() + parent.m_paddingX + parent.m_theme.extraPaddingLeft);
|
||||
if (text.len() > 0)
|
||||
{
|
||||
ostd::String tmpStr1 = "";
|
||||
ostd::String tmpStr2 = "";
|
||||
bool found = false;
|
||||
for (int32_t i = 0; i < text.len(); i++)
|
||||
{
|
||||
tmpStr2 = "";
|
||||
char c = text[i];
|
||||
tmpStr1 += c;
|
||||
int32_t strWidth1 = parent.m_gfx->getStringSize(tmpStr1, parent.m_fontSize).x;
|
||||
if (relativePosition.x > strWidth1)
|
||||
continue;
|
||||
found = true;
|
||||
tmpStr2 = tmpStr1.new_substr(0, tmpStr1.len() - 1);
|
||||
int32_t strWidth2 = (tmpStr2.len() > 0 ? parent.m_gfx->getStringSize(tmpStr2, parent.m_fontSize).x : 0);
|
||||
int32_t d1 = (int32_t)std::abs(relativePosition.x - strWidth2);
|
||||
int32_t d2 = (int32_t)std::abs(strWidth1 - relativePosition.x);
|
||||
if (d1 > d2)
|
||||
parent.m_cursorPosition = tmpStr1.len();
|
||||
else
|
||||
parent.m_cursorPosition = tmpStr2.len();
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
parent.m_cursorPosition = text.len();
|
||||
}
|
||||
parent.m_cursorState = true;
|
||||
}
|
||||
|
||||
}
|
||||
onSignalHandled(signal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
RawTextInput& RawTextInput::create(const ostd::Vec2& position, const ostd::Vec2& size, const ostd::String& name)
|
||||
{
|
||||
setPosition(position);
|
||||
setSize(size);
|
||||
m_name = name;
|
||||
m_eventListener = new EventListener(*this); //TODO: Delete -- Memory Leak
|
||||
m_charFilter = new CharacterFilter(); //TODO: Delete -- Memory Leak
|
||||
m_theme = tDefaultThemes::DefaultTheme;
|
||||
if (m_theme.cursorBlink)
|
||||
m_theme.cursorBlinkCounter.start();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void RawTextInput::render(ogfx::BasicRenderer2D& gfx)
|
||||
{
|
||||
m_gfx = &gfx;
|
||||
double text_size_scale = 0.66666666666666;
|
||||
m_paddingX = (4.0f * geth()) / 30.0f;
|
||||
m_fontSize = (int32_t)(geth() * 0.66);
|
||||
float cursor_height_scale = 0.75f;
|
||||
|
||||
ostd::IPoint strSize { 0, 0 };
|
||||
if (m_cursorPosition > 0 && m_text != "")
|
||||
{
|
||||
ostd::String s1 = m_text.new_substr(0, m_cursorPosition);
|
||||
strSize = gfx.getStringSize(s1, m_fontSize);
|
||||
}
|
||||
|
||||
gfx.outlinedRect(*this, m_theme.backgroundColor, m_theme.borderColor, 2);
|
||||
if (m_text.len() > 0)
|
||||
gfx.drawString(m_text, getPosition() + ostd::Vec2 { m_paddingX + m_theme.extraPaddingLeft, m_paddingX + m_theme.extraPaddingTop}, m_theme.textColor, m_fontSize);
|
||||
|
||||
if (m_cursorState || !m_theme.cursorBlink)
|
||||
gfx.fillRect({ getx() + m_paddingX + m_theme.extraPaddingLeft + strSize.x - 1, gety() + m_paddingX + m_theme.extraPaddingTop, (float)m_theme.cursorWidth, (float)m_fontSize * cursor_height_scale }, m_theme.cursorColor);
|
||||
|
||||
onRender(gfx);
|
||||
}
|
||||
|
||||
void RawTextInput::update(void)
|
||||
{
|
||||
m_keyRepeatCounter.update();
|
||||
onUpdate();
|
||||
}
|
||||
|
||||
void RawTextInput::fixedUpdate(void)
|
||||
{
|
||||
if (m_theme.cursorBlink)
|
||||
{
|
||||
m_theme.cursorBlinkCounter.update();
|
||||
if (m_theme.cursorBlinkCounter.isDone())
|
||||
{
|
||||
m_cursorState = !m_cursorState;
|
||||
m_theme.cursorBlinkCounter.start();
|
||||
}
|
||||
}
|
||||
onFixedUpdate();
|
||||
}
|
||||
|
||||
void RawTextInput::setText(const ostd::String& text)
|
||||
{
|
||||
m_text = text;
|
||||
m_cursorPosition = m_text.len();
|
||||
}
|
||||
|
||||
void RawTextInput::appendText(const ostd::String& text)
|
||||
{
|
||||
m_text.add(text);
|
||||
m_cursorPosition = m_text.len();
|
||||
}
|
||||
|
||||
void RawTextInput::setCursorPosition(uint16_t cursorPos)
|
||||
{
|
||||
if (cursorPos > m_text.len())
|
||||
cursorPos = m_text.len();
|
||||
m_cursorPosition = m_text.len();
|
||||
}
|
||||
|
||||
void RawTextInput::setTheme(Theme theme)
|
||||
{
|
||||
m_theme = theme;
|
||||
if (m_theme.cursorBlink)
|
||||
m_theme.cursorBlinkCounter.start();
|
||||
else
|
||||
m_theme.cursorBlinkCounter.stop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RawTextInputEventListener::onSignalHandled(ostd::tSignal& signal)
|
||||
{
|
||||
if (signal.ID == ostd::tBuiltinSignals::MouseMoved)
|
||||
{
|
||||
auto& data = (ogfx::MouseEventData&)signal.userData;
|
||||
if (getParent().isMouseInside())
|
||||
{
|
||||
if (!m_ibeamCursorSet)
|
||||
window.setCursor(ogfx::WindowBase::eCursor::IBeam);
|
||||
m_ibeamCursorSet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_ibeamCursorSet)
|
||||
window.setCursor(ogfx::WindowBase::eCursor::Arrow);
|
||||
m_ibeamCursorSet = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
165
src/ogfx/RawTextInput.hpp
Normal file
165
src/ogfx/RawTextInput.hpp
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
#pragma once
|
||||
|
||||
#include <ogfx/BasicRenderer.hpp>
|
||||
#include <ostd/Utils.hpp>
|
||||
namespace ogfx
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
class RawTextInput : public ostd::Rectangle
|
||||
{
|
||||
public: class EventListener : public ostd::BaseObject
|
||||
{
|
||||
public: enum class eEventType { None = 0, TextEntered, KeyPressed, KeyReleased };
|
||||
public:
|
||||
EventListener(RawTextInput& _parent);
|
||||
virtual void handleSignal(ostd::tSignal& signal) override;
|
||||
inline virtual void onSignalHandled(ostd::tSignal& signal) { }
|
||||
inline RawTextInput& getParent(void) { return parent; }
|
||||
|
||||
private:
|
||||
RawTextInput& parent;
|
||||
eEventType m_lastEvent { eEventType::None };
|
||||
};
|
||||
public: class CharacterFilter
|
||||
{
|
||||
public:
|
||||
inline virtual bool isValidChar(char c) { return true; }
|
||||
};
|
||||
public: class Theme
|
||||
{
|
||||
public:
|
||||
ostd::Color textColor { 0, 0, 0, 0 };
|
||||
ostd::Color borderColor { 0, 0, 0, 0 };
|
||||
ostd::Color backgroundColor { 0, 0, 0, 0 };
|
||||
ostd::Color cursorColor { 0, 0, 0, 0 };
|
||||
|
||||
uint8_t cursorWidth { 0 };
|
||||
uint8_t extraPaddingTop { 0 };
|
||||
uint8_t extraPaddingLeft { 0 };
|
||||
|
||||
bool cursorBlink { true };
|
||||
ostd::Counter cursorBlinkCounter { 1 };
|
||||
};
|
||||
public: struct tDefaultThemes
|
||||
{
|
||||
inline static const Theme DebugTheme {
|
||||
{ 220, 220, 255 }, //Text Color
|
||||
{ 10, 20, 120 }, //Border Color
|
||||
{ 0, 0, 22 }, //Background Color
|
||||
{ 220, 10, 10 }, //Cursor Color
|
||||
|
||||
2, //Cursor Width
|
||||
0, //Extra Padding Top
|
||||
0, //Extra Padding Left
|
||||
|
||||
true, //Cursor Blink
|
||||
{ 1 } //Cursor Blink Timer
|
||||
};
|
||||
inline static const Theme DefaultTheme {
|
||||
{ 120, 120, 180 }, //Text Color
|
||||
{ 10, 20, 120 }, //Border Color
|
||||
{ 0, 2, 10 }, //Background Color
|
||||
{ 20, 100, 255 }, //Cursor Color
|
||||
|
||||
2, //Cursor Width
|
||||
0, //Extra Padding Top
|
||||
0, //Extra Padding Left
|
||||
|
||||
true, //Cursor Blink
|
||||
{ 1 } //Cursor Blink Timer
|
||||
};
|
||||
};
|
||||
public: enum eActionEventType { None = 0, Enter, Tab };
|
||||
public: class ActionEventData : public ostd::BaseObject
|
||||
{
|
||||
public:
|
||||
inline ActionEventData(RawTextInput& _sender, const ostd::String& _senderName, eActionEventType _eventType, ostd::BaseObject& _userData) :
|
||||
sender(_sender),
|
||||
senderName(_senderName),
|
||||
eventType(_eventType),
|
||||
userData(_userData)
|
||||
{
|
||||
setTypeName("ogfx::gui::RawTextInput::ActionEventData");
|
||||
validate();
|
||||
}
|
||||
|
||||
public:
|
||||
RawTextInput& sender;
|
||||
ostd::String senderName { "" };
|
||||
eActionEventType eventType { eActionEventType::None };
|
||||
ostd::BaseObject& userData { ostd::BaseObject::InvalidRef() };
|
||||
};
|
||||
|
||||
public:
|
||||
inline RawTextInput(void) { create({ 0.0f, 0.0f }, { 200.0f, 30.0f }, "UnnamedRawTextInput"); }
|
||||
inline RawTextInput(const ostd::Vec2& position, const ostd::Vec2& size, const ostd::String& name) { create(position, size, name); }
|
||||
RawTextInput& create(const ostd::Vec2& position, const ostd::Vec2& size, const ostd::String& name);
|
||||
|
||||
virtual void render(ogfx::BasicRenderer2D& gfx);
|
||||
virtual void update(void);
|
||||
virtual void fixedUpdate(void);
|
||||
|
||||
virtual inline void onRender(ogfx::BasicRenderer2D& gfx) { }
|
||||
virtual inline void onUpdate(void) { }
|
||||
virtual inline void onFixedUpdate(void) { }
|
||||
|
||||
void setText(const ostd::String& text);
|
||||
void appendText(const ostd::String& text);
|
||||
void setCursorPosition(uint16_t cursorPos);
|
||||
void setTheme(Theme theme);
|
||||
|
||||
inline void setEventListener(EventListener& evtl) { m_eventListener = &evtl; }
|
||||
inline void setCharacterFilter(CharacterFilter& chrf) { m_charFilter = &chrf; }
|
||||
inline void setName(const ostd::String& name) { m_name = name; }
|
||||
|
||||
inline EventListener* getEventListener(void) const { return m_eventListener; }
|
||||
inline CharacterFilter* getCharacterFilter(void) const { return m_charFilter; }
|
||||
inline ostd::String getText(void) const { return m_text; }
|
||||
inline uint16_t getCursorPosition(void) const { return m_cursorPosition; }
|
||||
inline Theme& getTheme(void) { return m_theme; }
|
||||
inline ostd::String getName(void) const { return m_name; }
|
||||
inline bool isMouseInside(void) const { return m_mouseInside; }
|
||||
|
||||
private:
|
||||
EventListener* m_eventListener { nullptr };
|
||||
CharacterFilter* m_charFilter { nullptr };
|
||||
ogfx::BasicRenderer2D* m_gfx { nullptr };
|
||||
int32_t m_fontSize { 20 };
|
||||
float m_paddingX { 0 };
|
||||
|
||||
protected:
|
||||
ostd::String m_name { "" };
|
||||
|
||||
ostd::String m_text { "" };
|
||||
uint16_t m_cursorPosition { 0 };
|
||||
bool m_cursorState { true };
|
||||
|
||||
ostd::Counter m_keyRepeatCounter { 80 };
|
||||
char m_lastChar { 0 };
|
||||
int32_t m_lastKeyCode { 0 };
|
||||
|
||||
Theme m_theme;
|
||||
|
||||
bool m_mouseInside { false };
|
||||
|
||||
public:
|
||||
inline static const uint32_t actionEventSignalID { ostd::SignalHandler::newCustomSignal(11400) };
|
||||
};
|
||||
class RawTextInputEventListener : public RawTextInput::EventListener
|
||||
{
|
||||
public:
|
||||
inline RawTextInputEventListener(ogfx::gui::RawTextInput& _parent, ogfx::WindowBase& _window) : ogfx::gui::RawTextInput::EventListener::EventListener(_parent), window(_window) { }
|
||||
void onSignalHandled(ostd::tSignal& signal) override;
|
||||
|
||||
public:
|
||||
ogfx::WindowBase& window;
|
||||
bool m_ibeamCursorSet { false };
|
||||
};
|
||||
class RawTextInputNumberCharacterFilter : public RawTextInput::CharacterFilter
|
||||
{
|
||||
public:
|
||||
inline bool isValidChar(char c) override { return c >= '0' && c <= '9'; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@ namespace ogfx
|
|||
WindowBase::~WindowBase(void)
|
||||
{
|
||||
onDestroy();
|
||||
SDL_FreeCursor(m_cursor_IBeam);
|
||||
SDL_FreeCursor(m_cursor_Arrow);
|
||||
SDL_DestroyRenderer(m_renderer);
|
||||
SDL_DestroyWindow(m_window);
|
||||
// IMG_Quit();
|
||||
|
|
@ -18,7 +20,7 @@ namespace ogfx
|
|||
m_windowWidth = width;
|
||||
m_windowHeight = height;
|
||||
m_title = windowTitle;
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
{
|
||||
printf( "SDL could not initialize! Error: %s\n", SDL_GetError() );
|
||||
exit(1);
|
||||
|
|
@ -35,6 +37,9 @@ namespace ogfx
|
|||
SDL_SetWindowMinimumSize(m_window, m_windowWidth, m_windowHeight);
|
||||
SDL_SetWindowTitle(m_window, m_title.c_str());
|
||||
|
||||
m_cursor_Arrow = SDL_CreateSystemCursor(SDL_SystemCursor::SDL_SYSTEM_CURSOR_ARROW);
|
||||
m_cursor_IBeam = SDL_CreateSystemCursor(SDL_SystemCursor::SDL_SYSTEM_CURSOR_IBEAM);
|
||||
|
||||
m_initialized = true;
|
||||
m_running = true;
|
||||
|
||||
|
|
@ -89,6 +94,22 @@ namespace ogfx
|
|||
SDL_SetWindowTitle(m_window, m_title.c_str());
|
||||
}
|
||||
|
||||
void WindowBase::setCursor(eCursor cursor)
|
||||
{
|
||||
switch (cursor)
|
||||
{
|
||||
case eCursor::Arrow:
|
||||
SDL_SetCursor(m_cursor_Arrow);
|
||||
break;
|
||||
case eCursor::IBeam:
|
||||
SDL_SetCursor(m_cursor_IBeam);
|
||||
break;
|
||||
default:
|
||||
SDL_SetCursor(m_cursor_Arrow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowBase::handleEvents(void)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ namespace ogfx
|
|||
{
|
||||
class WindowBase : public ostd::BaseObject
|
||||
{
|
||||
public: enum class eCursor { Arrow = 0, IBeam };
|
||||
public:
|
||||
inline WindowBase(void) { }
|
||||
~WindowBase(void);
|
||||
|
|
@ -17,6 +18,7 @@ namespace ogfx
|
|||
void update(void);
|
||||
void setSize(int32_t width, int32_t height);
|
||||
void setTitle(const ostd::String& title);
|
||||
void setCursor(eCursor cursor);
|
||||
|
||||
inline virtual void onRender(void) { }
|
||||
inline virtual void onUpdate(void) { }
|
||||
|
|
@ -27,6 +29,7 @@ namespace ogfx
|
|||
|
||||
inline bool isInitialized(void) const { return m_initialized; }
|
||||
inline bool isRunning(void) const { return m_running; }
|
||||
inline void close(void) { m_running = false; }
|
||||
inline void hide(void) { SDL_HideWindow(m_window); }
|
||||
inline void show(void) { SDL_ShowWindow(m_window); }
|
||||
inline ostd::String getTitle(void) const { return m_title; }
|
||||
|
|
@ -63,6 +66,9 @@ namespace ogfx
|
|||
bool m_deagEventEnabled { false };
|
||||
bool m_running { false };
|
||||
bool m_initialized { false };
|
||||
|
||||
SDL_Cursor* m_cursor_IBeam { nullptr };
|
||||
SDL_Cursor* m_cursor_Arrow { nullptr };
|
||||
};
|
||||
class WindowResizedData : public ostd::BaseObject
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,6 +33,39 @@ namespace ostd
|
|||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class _Counter
|
||||
{
|
||||
public:
|
||||
inline _Counter(void) { m_count = 200; m_current = 0; }
|
||||
inline _Counter(T count, T step = 1) { m_count = count; m_current = 0; m_step = step; }
|
||||
inline void setCount(T count) { m_count = count; m_counting = false; m_current = 0; }
|
||||
inline T getCount(void) { return m_count; }
|
||||
inline T getCurrent(void) { return m_current; };
|
||||
inline T getStep(void) { return m_step; }
|
||||
inline void start(void) { m_current = 0; m_counting = true; }
|
||||
inline void stop(void) { m_current = 0; m_counting = false; }
|
||||
inline bool isDone(void) { return !m_counting; }
|
||||
inline bool isCounting(void) { return m_counting; }
|
||||
inline void update(void)
|
||||
{
|
||||
if (!m_counting) return;
|
||||
m_current += m_step;
|
||||
if (m_current > m_count)
|
||||
stop();
|
||||
}
|
||||
|
||||
private:
|
||||
T m_current { 0 };
|
||||
T m_count { 200 };
|
||||
T m_step { 1 };
|
||||
bool m_counting { false };
|
||||
};
|
||||
|
||||
typedef _Counter<uint64_t> Counter;
|
||||
typedef _Counter<float> FloatCounter;
|
||||
typedef _Counter<double> DoubleCounter;
|
||||
|
||||
class OutputHandlerBase;
|
||||
class Timer
|
||||
{
|
||||
|
|
|
|||
208
src/test.cpp
208
src/test.cpp
|
|
@ -1,74 +1,158 @@
|
|||
#include <ostd/String.hpp>
|
||||
#include <ostd/IOHandlers.hpp>
|
||||
#include <ostd/Logger.hpp>
|
||||
#include <ostd/Console.hpp>
|
||||
// #include <ostd/String.hpp>
|
||||
// #include <ostd/IOHandlers.hpp>
|
||||
// #include <ostd/Logger.hpp>
|
||||
// #include <ostd/Console.hpp>
|
||||
|
||||
#include <ogfx/WindowBase.hpp>
|
||||
#include <ogfx/RawTextInput.hpp>
|
||||
#include <ostd/Signals.hpp>
|
||||
|
||||
ostd::ConsoleOutputHandler out;
|
||||
|
||||
void test2(const std::string& str) {}
|
||||
void test3(const ostd::String& str) {}
|
||||
void test4(const char* str) {}
|
||||
class Window : public ogfx::WindowBase
|
||||
{
|
||||
public:
|
||||
inline Window(void) : m_sigHandler(m_textInput, *this) { }
|
||||
inline void onInitialize(void) override
|
||||
{
|
||||
enableSignals();
|
||||
connectSignal(ostd::tBuiltinSignals::KeyReleased);
|
||||
connectSignal(ogfx::gui::RawTextInput::actionEventSignalID);
|
||||
|
||||
m_gfx.init(*this);
|
||||
m_gfx.setFont("res/ttf/Courier Prime.ttf");
|
||||
|
||||
float w = getWindowWidth();
|
||||
float h = 40.0f;
|
||||
m_textInput.create({ 0.0f, (float)(getWindowHeight() - h) }, { w, h }, "MainInputTXT");
|
||||
m_textInput.setEventListener(m_sigHandler);
|
||||
// m_textInput.setCharacterFilter(m_numCharFilter);
|
||||
m_textInput.getTheme().extraPaddingTop = 3;
|
||||
}
|
||||
|
||||
inline void handleSignal(ostd::tSignal& signal) override
|
||||
{
|
||||
if (signal.ID == ostd::tBuiltinSignals::KeyReleased)
|
||||
{
|
||||
auto& evtData = (ogfx::KeyEventData&)signal.userData;
|
||||
if (evtData.keyCode == SDLK_ESCAPE)
|
||||
close();
|
||||
}
|
||||
if (signal.ID == ogfx::gui::RawTextInput::actionEventSignalID)
|
||||
{
|
||||
auto& data = (ogfx::gui::RawTextInput::ActionEventData&)signal.userData;
|
||||
if (data.senderName != "MainInputTXT")
|
||||
return;
|
||||
if (data.eventType == ogfx::gui::RawTextInput::eActionEventType::Enter)
|
||||
{
|
||||
out.fg(ostd::ConsoleColors::Green).p(data.sender.getText()).reset().nl();
|
||||
data.sender.setText("");
|
||||
}
|
||||
else if (data.eventType == ogfx::gui::RawTextInput::eActionEventType::Tab)
|
||||
{
|
||||
out.fg(ostd::ConsoleColors::Red).p("TAB").reset().nl();
|
||||
data.sender.appendText("TAB");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void onRender(void) override
|
||||
{
|
||||
m_textInput.render(m_gfx);
|
||||
}
|
||||
|
||||
inline void onFixedUpdate(void) override
|
||||
{
|
||||
m_textInput.fixedUpdate();
|
||||
}
|
||||
|
||||
inline void onUpdate(void) override
|
||||
{
|
||||
m_textInput.update ();
|
||||
}
|
||||
|
||||
private:
|
||||
ogfx::gui::RawTextInput m_textInput;
|
||||
ogfx::BasicRenderer2D m_gfx;
|
||||
ogfx::gui::RawTextInputEventListener m_sigHandler;
|
||||
ogfx::gui::RawTextInputNumberCharacterFilter m_numCharFilter;
|
||||
};
|
||||
|
||||
// void test2(const std::string& str) {}
|
||||
// void test3(const ostd::String& str) {}
|
||||
// void test4(const char* str) {}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
out.fg(ostd::ConsoleColors::Red).p("Hello World!!").reset().nl();
|
||||
|
||||
ostd::String str1, str2 = "Hello";
|
||||
bool b = str1 == str2;
|
||||
const ostd::String str3 = "CIAO";
|
||||
b = str2 == str1;
|
||||
b = str3 == "CICCIO";
|
||||
// b = "ciao" == str2;
|
||||
str2 = str3;
|
||||
std::string str = "cc";
|
||||
str1 = str;
|
||||
test2(str1);
|
||||
test3(str);
|
||||
str1 = str2 + str;
|
||||
str1 = str2 + "str";
|
||||
str1 = str2 + str3;
|
||||
str1 = str2 + str1;
|
||||
test4(str1);
|
||||
test4(str3);
|
||||
|
||||
str1 += "ciao";
|
||||
str1 += str;
|
||||
str1 += str1;
|
||||
str1 += str3;
|
||||
str1 += 'c';
|
||||
|
||||
OX_FATAL(str2);
|
||||
|
||||
ostd::RegexRichString rgxrstr("Hello World");
|
||||
rgxrstr.fg("Hello", "Blue");
|
||||
std::cout << rgxrstr << "\n";
|
||||
|
||||
out.nl().nl();
|
||||
ostd::String test_str = "Hello World, my love";
|
||||
ostd::String test_str_2 = "HEELO";
|
||||
ostd::String test_str_3 = "0123456789";
|
||||
out.p("==========\n");
|
||||
test_str.fixedLength(10, ' ', "..........");
|
||||
test_str_2.fixedLength(10);
|
||||
test_str_3.fixedLength(10);
|
||||
out.p(test_str).p("|").nl();
|
||||
out.p(test_str_2).p("|").nl();
|
||||
out.p(test_str_3).p("|").nl();
|
||||
|
||||
ostd::KeyboardController keyboard;
|
||||
keyboard.disableCommandBuffer();
|
||||
Window window;
|
||||
window.initialize(1280, 720, "OmniaFramework - Test Window");
|
||||
window.setClearColor({ 0, 2 , 15 });
|
||||
|
||||
out.p("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");
|
||||
out.p("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
|
||||
out.p("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
|
||||
out.p(" ");
|
||||
out.p("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
|
||||
|
||||
ostd::eKeys k = ostd::eKeys::NoKeyPressed;
|
||||
do
|
||||
while (window.isRunning())
|
||||
{
|
||||
k = keyboard.waitForKeyPress();
|
||||
} while (k != ostd::eKeys::Escape);
|
||||
window.update();
|
||||
}
|
||||
|
||||
|
||||
// out.fg(ostd::ConsoleColors::Red).p("Hello World!!").reset().nl();
|
||||
|
||||
// ostd::String str1, str2 = "Hello";
|
||||
// bool b = str1 == str2;
|
||||
// const ostd::String str3 = "CIAO";
|
||||
// b = str2 == str1;
|
||||
// b = str3 == "CICCIO";
|
||||
// // b = "ciao" == str2;
|
||||
// str2 = str3;
|
||||
// std::string str = "cc";
|
||||
// str1 = str;
|
||||
// test2(str1);
|
||||
// test3(str);
|
||||
// str1 = str2 + str;
|
||||
// str1 = str2 + "str";
|
||||
// str1 = str2 + str3;
|
||||
// str1 = str2 + str1;
|
||||
// test4(str1);
|
||||
// test4(str3);
|
||||
|
||||
// str1 += "ciao";
|
||||
// str1 += str;
|
||||
// str1 += str1;
|
||||
// str1 += str3;
|
||||
// str1 += 'c';
|
||||
|
||||
// OX_FATAL(str2);
|
||||
|
||||
// ostd::RegexRichString rgxrstr("Hello World");
|
||||
// rgxrstr.fg("Hello", "Blue");
|
||||
// std::cout << rgxrstr << "\n";
|
||||
|
||||
// out.nl().nl();
|
||||
// ostd::String test_str = "Hello World, my love";
|
||||
// ostd::String test_str_2 = "HEELO";
|
||||
// ostd::String test_str_3 = "0123456789";
|
||||
// out.p("==========\n");
|
||||
// test_str.fixedLength(10, ' ', "..........");
|
||||
// test_str_2.fixedLength(10);
|
||||
// test_str_3.fixedLength(10);
|
||||
// out.p(test_str).p("|").nl();
|
||||
// out.p(test_str_2).p("|").nl();
|
||||
// out.p(test_str_3).p("|").nl();
|
||||
|
||||
// ostd::KeyboardController keyboard;
|
||||
// keyboard.disableCommandBuffer();
|
||||
|
||||
// out.p("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");
|
||||
// out.p("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
|
||||
// out.p("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
|
||||
// out.p(" ");
|
||||
// out.p("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
|
||||
|
||||
// ostd::eKeys k = ostd::eKeys::NoKeyPressed;
|
||||
// do
|
||||
// {
|
||||
// k = keyboard.waitForKeyPress();
|
||||
// } while (k != ostd::eKeys::Escape);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue