Add a basic Listbox widget.

This commit is contained in:
Andreas Kling 2018-10-13 00:20:44 +02:00
parent 8016139430
commit f20977c65f
5 changed files with 93 additions and 2 deletions

58
Widgets/ListBox.cpp Normal file
View file

@ -0,0 +1,58 @@
#include "ListBox.h"
#include "Painter.h"
#include "Font.h"
ListBox::ListBox(Widget* parent)
: Widget(parent)
{
}
ListBox::~ListBox()
{
}
unsigned ListBox::itemHeight() const
{
return Font::defaultFont().glyphHeight() + 2;
}
void ListBox::onPaint(PaintEvent&)
{
Painter painter(*this);
painter.fillRect(rect(), Color::White);
painter.drawRect(rect(), Color::Black);
for (unsigned i = m_scrollOffset; i < m_items.size(); ++i) {
Rect itemRect(1, 1 + (i * itemHeight()), width() - 2, itemHeight());
Rect textRect(itemRect.x() + 1, itemRect.y() + 1, itemRect.width() - 2, itemRect.height() - 2);
Color itemTextColor = foregroundColor();
if (m_selectedIndex == i) {
painter.fillRect(itemRect, Color(0, 32, 128));
itemTextColor = Color::White;
}
painter.drawText(textRect, m_items[i], Painter::TextAlignment::TopLeft, itemTextColor);
}
}
void ListBox::onMouseDown(MouseEvent& event)
{
printf("ListBox::onMouseDown %d,%d\n", event.x(), event.y());
for (unsigned i = m_scrollOffset; i < m_items.size(); ++i) {
Rect itemRect(1, 1 + (i * itemHeight()), width() - 2, itemHeight());
if (itemRect.contains(event.position())) {
m_selectedIndex = i;
printf("ListBox: selected item %u (\"%s\")\n", i, m_items[i].characters());
update();
return;
}
}
}
void ListBox::addItem(String&& item)
{
m_items.append(std::move(item));
if (m_selectedIndex == -1)
m_selectedIndex = 0;
}

24
Widgets/ListBox.h Normal file
View file

@ -0,0 +1,24 @@
#pragma once
#include "Widget.h"
class ListBox final : public Widget {
public:
explicit ListBox(Widget* parent);
virtual ~ListBox() override;
void addItem(String&&);
int selectedIndex() const { return m_selectedIndex; }
private:
virtual void onPaint(PaintEvent&) override;
virtual void onMouseDown(MouseEvent&) override;
unsigned itemHeight() const;
unsigned m_scrollOffset { 0 };
int m_selectedIndex { -1 };
Vector<String> m_items;
};

View file

@ -25,6 +25,7 @@ VFS_OBJS = \
ClockWidget.o \
CBitmap.o \
CheckBox.o \
ListBox.o \
test.o
OBJS = $(AK_OBJS) $(VFS_OBJS)

View file

@ -50,7 +50,7 @@ void Window::event(Event& event)
{
if (event.isMouseEvent()) {
auto& me = static_cast<MouseEvent&>(event);
printf("Window{%p}: %s %d,%d\n", this, me.name(), me.x(), me.y());
//printf("Window{%p}: %s %d,%d\n", this, me.name(), me.x(), me.y());
if (m_mainWidget) {
auto result = m_mainWidget->hitTest(me.x(), me.y());
//printf("hit test for %d,%d found: %s{%p} %d,%d\n", me.x(), me.y(), result.widget->className(), result.widget, result.localX, result.localY);

View file

@ -8,6 +8,7 @@
#include "Window.h"
#include "ClockWidget.h"
#include "CheckBox.h"
#include "ListBox.h"
#include <cstdio>
int main(int argc, char** argv)
@ -47,7 +48,7 @@ int main(int argc, char** argv)
{
auto* widgetTestWindow = new Window;
widgetTestWindow->setTitle("Widget test");
widgetTestWindow->setRect({ 20, 40, 100, 60 });
widgetTestWindow->setRect({ 20, 40, 100, 160 });
auto* widgetTestWindowWidget = new Widget;
widgetTestWindowWidget->setWindowRelativeRect({ 0, 0, 100, 100 });
@ -64,6 +65,13 @@ int main(int argc, char** argv)
auto* c = new CheckBox(widgetTestWindowWidget);
c->setWindowRelativeRect({ 0, 40, 100, 20 });
c->setCaption("CheckBox");
auto *lb = new ListBox(widgetTestWindowWidget);
lb->setWindowRelativeRect({0, 60, 100, 100 });
lb->addItem("This");
lb->addItem("is");
lb->addItem("a");
lb->addItem("ListBox");
}
auto* win = new Window;