Skip to content

Commit

Permalink
Working scroll bar
Browse files Browse the repository at this point in the history
  • Loading branch information
jhhoward committed Mar 14, 2024
1 parent e9a1a7e commit 4489e0e
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 27 deletions.
9 changes: 8 additions & 1 deletion src/Interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ void AppInterface::GenerateInterfaceNodes()
rootInterfaceNode->AddChild(statusBarNode);
statusBarNode->style.fontSize = 0;

scrollBarNode = ScrollBarNode::Construct(allocator, scrollPositionY, app.page.pageHeight);
scrollBarNode = ScrollBarNode::Construct(allocator, scrollPositionY, app.page.pageHeight, OnScrollBarMoved);
scrollBarNode->style = rootInterfaceNode->style;
scrollBarNode->anchor.y = backButtonNode->anchor.y + backButtonNode->size.y + 3;
scrollBarNode->size.x = 16;
Expand Down Expand Up @@ -529,3 +529,10 @@ void AppInterface::CycleNodes(int direction)
}
}
}

void AppInterface::OnScrollBarMoved(Node* node)
{
ScrollBarNode::Data* data = static_cast<ScrollBarNode::Data*>(node->data);
AppInterface& ui = App::Get().ui;
ui.ScrollRelative(data->scrollPosition - ui.scrollPositionY);
}
2 changes: 1 addition & 1 deletion src/Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class AppInterface
static void OnBackButtonPressed(Node* node);
static void OnForwardButtonPressed(Node* node);
static void OnAddressBarSubmit(Node* node);

static void OnScrollBarMoved(Node* node);

App& app;

Expand Down
2 changes: 1 addition & 1 deletion src/Memory/MemBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ MemBlockAllocator::MemBlockAllocator()
void MemBlockAllocator::Init()
{
// Disable swap for now
swapFile = fopen("Microweb.swp", "wb+");
//swapFile = fopen("Microweb.swp", "wb+");

if (swapFile)
{
Expand Down
12 changes: 11 additions & 1 deletion src/Nodes/Field.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@
class TextFieldNode : public NodeHandler
{
public:
TextFieldNode() :
shiftPosition(0),
cursorPosition(0),
selectionStartPosition(0),
selectionLength(0),
pickedPosition(0)
{

}

class Data
{
public:
Expand All @@ -22,7 +32,7 @@ class TextFieldNode : public NodeHandler
static Node* Construct(Allocator& allocator, char* buffer, int bufferLength, NodeCallbackFunction onSubmit = NULL);
virtual void GenerateLayout(Layout& layout, Node* node) override;
virtual void Draw(DrawContext& context, Node* node) override;
virtual bool CanPick(Node* node) { return true; }
virtual bool CanPick(Node* node) override { return true; }
virtual bool HandleEvent(Node* node, const Event& event) override;

private:
Expand Down
100 changes: 79 additions & 21 deletions src/Nodes/Scroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#include "../Interface.h"
#include "../Draw/Surface.h"

Node* ScrollBarNode::Construct(Allocator& allocator, int scrollPosition, int maxScroll)
Node* ScrollBarNode::Construct(Allocator& allocator, int scrollPosition, int maxScroll, NodeCallbackFunction onScroll)
{
ScrollBarNode::Data* data = allocator.Alloc<ScrollBarNode::Data>(scrollPosition, maxScroll);
ScrollBarNode::Data* data = allocator.Alloc<ScrollBarNode::Data>(scrollPosition, maxScroll, onScroll);
if (data)
{
return allocator.Alloc<Node>(Node::ScrollBar, data);
Expand All @@ -16,40 +16,98 @@ Node* ScrollBarNode::Construct(Allocator& allocator, int scrollPosition, int max
return nullptr;
}

void ScrollBarNode::Draw(DrawContext& context, Node* node)
void ScrollBarNode::CalculateWidgetParams(Node* node, int& outPosition, int& outSize)
{
ScrollBarNode::Data* data = static_cast<ScrollBarNode::Data*>(node->data);

const int minWidgetSize = 15;
const int maxWidgetSize = node->size.y;
int scrollPosition = data->scrollPosition;

if (node == App::Get().ui.GetFocusedNode())
{
scrollPosition = draggingScrollPosition;
}

if (data->maxScroll == 0)
{
context.surface->VerticalScrollBar(context, node->anchor.x, node->anchor.y, node->size.y, 0, maxWidgetSize);
outPosition = 0;
outSize = maxWidgetSize;
}
else
{
int widgetSize = (int)(((int32_t)node->size.y * node->size.y) / data->maxScroll);
if (widgetSize < minWidgetSize)
outSize = (int)(((int32_t)node->size.y * node->size.y) / (data->maxScroll + node->size.y));
if (outSize < minWidgetSize)
{
widgetSize = minWidgetSize;
outSize = minWidgetSize;
}
if (widgetSize > maxWidgetSize)
if (outSize > maxWidgetSize)
{
widgetSize = maxWidgetSize;
outSize = maxWidgetSize;
}
int maxWidgetPosition = node->size.y - widgetSize;
int widgetPosition = (int32_t)maxWidgetPosition * data->scrollPosition / data->maxScroll;
if (widgetPosition < 0)
widgetPosition = 0;
if (widgetPosition > maxWidgetPosition)
widgetPosition = maxWidgetPosition;

context.surface->VerticalScrollBar(context, node->anchor.x, node->anchor.y, node->size.y, widgetPosition, widgetSize);
int maxWidgetPosition = node->size.y - outSize;
outPosition = (int32_t)maxWidgetPosition * scrollPosition / data->maxScroll;
if (outPosition < 0)
outPosition = 0;
if (outPosition > maxWidgetPosition)
outPosition = maxWidgetPosition;
}
}


// context.surface->FillRect(context, node->anchor.x, node->anchor.y, node->size.x, node->size.y, 0);

void ScrollBarNode::Draw(DrawContext& context, Node* node)
{
int widgetPosition, widgetSize;
CalculateWidgetParams(node, widgetPosition, widgetSize);
context.surface->VerticalScrollBar(context, node->anchor.x, node->anchor.y, node->size.y, widgetPosition, widgetSize);
}

bool ScrollBarNode::HandleEvent(Node* node, const Event& event)
{
AppInterface& ui = App::Get().ui;
ScrollBarNode::Data* data = static_cast<ScrollBarNode::Data*>(node->data);
int widgetPosition, widgetSize;
CalculateWidgetParams(node, widgetPosition, widgetSize);
int maxWidgetPosition = node->size.y - widgetSize;

switch (event.type)
{
case Event::MouseClick:
{
ui.FocusNode(node);
startDragOffset = (event.y - node->anchor.y) - widgetPosition;
draggingScrollPosition = data->scrollPosition;
}
return true;
case Event::MouseRelease:
{
ui.FocusNode(nullptr);

data->scrollPosition = draggingScrollPosition;
if (data->onScroll)
{
data->onScroll(node);
}
}
return true;
case Event::MouseDrag:
{
if (maxWidgetPosition > 0)
{
int dragPosition = (event.y - node->anchor.y) - startDragOffset;
int newScrollPosition = ((long)dragPosition * data->maxScroll) / maxWidgetPosition;
if (newScrollPosition < 0)
newScrollPosition = 0;
else if (newScrollPosition > data->maxScroll)
newScrollPosition = data->maxScroll;

if (newScrollPosition != draggingScrollPosition)
{
draggingScrollPosition = newScrollPosition;
node->Redraw();
}
}
}
return true;
}
return false;
}

12 changes: 10 additions & 2 deletions src/Nodes/Scroll.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ class ScrollBarNode : public NodeHandler
class Data
{
public:
Data(int inScrollPosition, int inMaxScroll) : scrollPosition(inScrollPosition), maxScroll(inMaxScroll) { }
Data(int inScrollPosition, int inMaxScroll, NodeCallbackFunction inOnScroll) : scrollPosition(inScrollPosition), maxScroll(inMaxScroll), onScroll(inOnScroll) { }
int scrollPosition;
int maxScroll;
NodeCallbackFunction onScroll;
};

static Node* Construct(Allocator& allocator, int scrollPosition = 0, int maxScroll = 0);
static Node* Construct(Allocator& allocator, int scrollPosition = 0, int maxScroll = 0, NodeCallbackFunction onScroll = nullptr);
virtual void Draw(DrawContext& context, Node* node) override;
virtual bool HandleEvent(Node* node, const Event& event) override;
virtual bool CanPick(Node* node) { return true; }

void CalculateWidgetParams(Node* node, int& outPosition, int& outSize);

int startDragOffset;
int draggingScrollPosition;
};

#endif

0 comments on commit 4489e0e

Please sign in to comment.