mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-22 17:31:58 -05:00
Add a basic Listbox widget.
This commit is contained in:
parent
8016139430
commit
f20977c65f
5 changed files with 93 additions and 2 deletions
58
Widgets/ListBox.cpp
Normal file
58
Widgets/ListBox.cpp
Normal 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
24
Widgets/ListBox.h
Normal 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;
|
||||
};
|
||||
|
|
@ -25,6 +25,7 @@ VFS_OBJS = \
|
|||
ClockWidget.o \
|
||||
CBitmap.o \
|
||||
CheckBox.o \
|
||||
ListBox.o \
|
||||
test.o
|
||||
|
||||
OBJS = $(AK_OBJS) $(VFS_OBJS)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue