Skip to content

Commit

Permalink
Set cursor to Ibeam when hovering over text field
Browse files Browse the repository at this point in the history
  • Loading branch information
codecat committed Aug 5, 2017
1 parent e3a982e commit 6d47369
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 1 deletion.
13 changes: 13 additions & 0 deletions include/nimble/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "widgets/page.h"

struct GLFWwindow;
struct GLFWcursor;
struct lay_context;
struct NVGcontext;

Expand All @@ -22,6 +23,15 @@ namespace na
GLFWwindow* m_window = nullptr;
NVGcontext* m_nvg = nullptr;

GLFWcursor* m_cursorArrow = nullptr;
GLFWcursor* m_cursorIbeam = nullptr;
GLFWcursor* m_cursorCrosshair = nullptr;
GLFWcursor* m_cursorHand = nullptr;
GLFWcursor* m_cursorHResize = nullptr;
GLFWcursor* m_cursorVResize = nullptr;

Cursor m_currentCursor = Cursor::Arrow;

bool m_initializedLayout = false;
bool m_initializedRendering = false;
bool m_initializedWindow = false;
Expand All @@ -31,6 +41,7 @@ namespace na

bool m_invalidatedLayout = true;
bool m_invalidatedRendering = true;
bool m_invalidatedCursor = true;

glm::ivec2 m_windowSize;
glm::ivec2 m_bufferSize;
Expand All @@ -50,6 +61,7 @@ namespace na
virtual void Run();
virtual void DoLayout();
virtual void Draw();
virtual void UpdateCursor();
virtual void Frame();

virtual void OnLoad();
Expand All @@ -64,6 +76,7 @@ namespace na
virtual bool IsInvalidated();
virtual void InvalidateLayout();
virtual void InvalidateRendering();
virtual void InvalidateCursor();

virtual void HandleHoverWidgets(Widget* w, const glm::ivec2 &point);
virtual void InvalidateInputWidgets();
Expand Down
15 changes: 15 additions & 0 deletions include/nimble/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ namespace na
AnchorFill = AnchorLeft | AnchorRight | AnchorTop | AnchorBottom,
};

enum class Cursor
{
Arrow,
Ibeam,
Crosshair,
Hand,
HResize,
VResize,
};

class Widget
{
//TODO: Add ref count
Expand All @@ -66,6 +76,8 @@ namespace na
s2::string m_class;
bool m_visible = true;

Cursor m_cursor = Cursor::Arrow;

s2::list<Widget*> m_children;

lay_id m_layID = 0;
Expand Down Expand Up @@ -141,6 +153,9 @@ namespace na
inline bool IsVisible() { return m_visible; }
virtual void SetVisible(bool visible);

inline Cursor GetCursor() { return m_cursor; }
virtual void SetCursor(Cursor cursor);

inline WidgetDirection GetLayoutDirection() { return m_layDir; }
virtual void SetLayoutDirection(WidgetDirection dir);

Expand Down
49 changes: 48 additions & 1 deletion src/nimble/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,32 @@ void na::Application::Draw()
glfwSwapBuffers(m_window);
}

void na::Application::UpdateCursor()
{
if (m_hoveringWidgets.len() == 0) {
m_currentCursor = Cursor::Arrow;
glfwSetCursor(m_window, nullptr);
return;
}

Cursor cursor = m_hoveringWidgets.top()->GetCursor();
if (m_currentCursor == cursor) {
return;
}

GLFWcursor* p = nullptr;
switch (cursor) {
case Cursor::Arrow: p = m_cursorArrow; break;
case Cursor::Ibeam: p = m_cursorIbeam; break;
case Cursor::Crosshair: p = m_cursorCrosshair; break;
case Cursor::Hand: p = m_cursorHand; break;
case Cursor::HResize: p = m_cursorHResize; break;
case Cursor::VResize: p = m_cursorVResize; break;
}
m_currentCursor = cursor;
glfwSetCursor(m_window, p);
}

void na::Application::Frame()
{
HandlePageQueue();
Expand All @@ -199,6 +225,11 @@ void na::Application::Frame()
m_invalidatedRendering = false;
Draw();
}

if (m_invalidatedCursor) {
m_invalidatedCursor = false;
UpdateCursor();
}
}

void na::Application::OnLoad()
Expand Down Expand Up @@ -267,13 +298,19 @@ void na::Application::InvalidateRendering()
m_invalidatedRendering = true;
}

void na::Application::InvalidateCursor()
{
m_invalidatedCursor = true;
}

void na::Application::HandleHoverWidgets(Widget* w, const glm::ivec2 &point)
{
if (!w->Contains(point)) {
return;
}

if (!w->IsHovering()) {
InvalidateCursor();
m_hoveringWidgets.add(w);
w->OnMouseEnter();
}
Expand All @@ -289,6 +326,7 @@ void na::Application::InvalidateInputWidgets()
w->OnMouseLeave();
}
m_hoveringWidgets.clear();
InvalidateCursor();

SetFocusWidget(nullptr);
}
Expand Down Expand Up @@ -320,6 +358,8 @@ void na::Application::CallbackCursorPosition(const glm::ivec2 &point)

w->OnMouseLeave();
m_hoveringWidgets.remove(i);

InvalidateCursor();
}

for (int i = m_pages.len() - 1; i >= 0; i--) {
Expand All @@ -337,7 +377,7 @@ void na::Application::CallbackMouseButton(int button, int action, int mods)
return;
}

Widget* w = m_hoveringWidgets[m_hoveringWidgets.len() - 1];
Widget* w = m_hoveringWidgets.top();
if (action == GLFW_PRESS) {
w->OnMouseDown(button, w->ToRelativePoint(m_lastCursorPos));
if (w->CanHaveFocus()) {
Expand Down Expand Up @@ -436,6 +476,13 @@ void na::Application::InitializeWindow()
glfwSetCharModsCallback(m_window, char_mods_callback);
glfwMakeContextCurrent(m_window);

m_cursorArrow = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
m_cursorIbeam = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
m_cursorCrosshair = glfwCreateStandardCursor(GLFW_CROSSHAIR_CURSOR);
m_cursorHand = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
m_cursorHResize = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
m_cursorVResize = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR);

glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
printf("Glew failed\n");
Expand Down
23 changes: 23 additions & 0 deletions src/nimble/widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,21 @@ void na::Widget::Load(ContentNode &node)
SetLayoutWrapping(node.GetBool("wrapping", false, m_layWrap));

SetMargin(node.GetBounds("margin", false, m_margin));

s2::string cursor = node.GetString("cursor", false);
if (cursor == "" || cursor == "arrow") {
SetCursor(Cursor::Arrow);
} else if (cursor == "ibeam") {
SetCursor(Cursor::Ibeam);
} else if (cursor == "crosshair") {
SetCursor(Cursor::Crosshair);
} else if (cursor == "hand") {
SetCursor(Cursor::Hand);
} else if (cursor == "hresize") {
SetCursor(Cursor::HResize);
} else if (cursor == "vresize") {
SetCursor(Cursor::VResize);
}
}

void na::Widget::DoLayout(lay_context* l, lay_id parent)
Expand Down Expand Up @@ -314,6 +329,14 @@ void na::Widget::SetVisible(bool visible)
m_visible = visible;
}

void na::Widget::SetCursor(Cursor cursor)
{
if (m_cursor != cursor) {
m_app->InvalidateCursor();
}
m_cursor = cursor;
}

void na::Widget::SetLayoutDirection(WidgetDirection dir)
{
if (m_layDir != dir) {
Expand Down
2 changes: 2 additions & 0 deletions src/nimble/widgets/text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ void na::TextWidget::Load(ContentNode &node)
{
Widget::Load(node);

SetCursor(Cursor::Ibeam);

if (m_font != nullptr) {
SetFont(node.GetString("font", false, m_font->Filename));
} else {
Expand Down

0 comments on commit 6d47369

Please sign in to comment.