mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-29 08:11:13 +00:00
Start poking at a TerminalWidget.
This commit is contained in:
parent
f337616741
commit
c61cbf4234
Notes:
sideshowbarker
2024-07-19 18:51:03 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c61cbf4234c
|
@ -18,6 +18,7 @@ VFS_OBJS = \
|
||||||
Painter.o \
|
Painter.o \
|
||||||
Label.o \
|
Label.o \
|
||||||
Button.o \
|
Button.o \
|
||||||
|
TerminalWidget.o \
|
||||||
test.o
|
test.o
|
||||||
|
|
||||||
OBJS = $(AK_OBJS) $(VFS_OBJS)
|
OBJS = $(AK_OBJS) $(VFS_OBJS)
|
||||||
|
|
69
Widgets/TerminalWidget.cpp
Normal file
69
Widgets/TerminalWidget.cpp
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#include "TerminalWidget.h"
|
||||||
|
#include "Painter.h"
|
||||||
|
|
||||||
|
TerminalWidget::TerminalWidget(Widget* parent)
|
||||||
|
: Widget(parent)
|
||||||
|
{
|
||||||
|
setRect({ 100, 300, columns() * 8, rows() * 8 });
|
||||||
|
m_screen = new CharacterWithAttributes[rows() * columns() * 2];
|
||||||
|
for (unsigned row = 0; row < m_rows; ++row) {
|
||||||
|
for (unsigned column = 0; column < m_columns; ++column) {
|
||||||
|
at(row, column).character = ' ';
|
||||||
|
at(row, column).attribute = 0x07;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onReceive(String("Serenity/OS").toByteBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalWidget::~TerminalWidget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CharacterWithAttributes& TerminalWidget::at(unsigned row, unsigned column)
|
||||||
|
{
|
||||||
|
ASSERT(m_screen);
|
||||||
|
ASSERT(row < m_rows);
|
||||||
|
ASSERT(column < m_columns);
|
||||||
|
return m_screen[row * columns() + column];
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalWidget::onPaint(PaintEvent&)
|
||||||
|
{
|
||||||
|
Painter painter(*this);
|
||||||
|
|
||||||
|
painter.fillRect({ 0, 0, width(), height() }, Color(0, 0, 0));
|
||||||
|
|
||||||
|
char buf[2] = { 0, 0 };
|
||||||
|
for (unsigned row = 0; row < m_rows; ++row) {
|
||||||
|
int y = row * 8;
|
||||||
|
for (unsigned column = 0; column < m_columns; ++column) {
|
||||||
|
int x = column * 8;
|
||||||
|
buf[0] = at(row, column).character;
|
||||||
|
painter.drawText({ x, y, width(), 8 }, buf, Painter::TextAlignment::TopLeft, Color(0xa0, 0xa0, 0xa0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalWidget::onReceive(const ByteBuffer& buffer)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < buffer.size(); ++i) {
|
||||||
|
onReceive(buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalWidget::onReceive(byte ch)
|
||||||
|
{
|
||||||
|
at(m_cursorRow, m_cursorColumn).character = ch;
|
||||||
|
printf("%2u,%2u -> ", m_cursorRow, m_cursorColumn);
|
||||||
|
if (++m_cursorColumn > m_columns) {
|
||||||
|
m_cursorColumn = 0;
|
||||||
|
if (m_cursorRow < (m_rows - 1)) {
|
||||||
|
++m_cursorRow;
|
||||||
|
} else {
|
||||||
|
// FIXME: Scroll it!
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("%2u,%2u\n", m_cursorRow, m_cursorColumn);
|
||||||
|
}
|
||||||
|
|
33
Widgets/TerminalWidget.h
Normal file
33
Widgets/TerminalWidget.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Widget.h"
|
||||||
|
#include <AK/ByteBuffer.h>
|
||||||
|
|
||||||
|
struct CharacterWithAttributes {
|
||||||
|
byte character;
|
||||||
|
byte attribute;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TerminalWidget final : public Widget {
|
||||||
|
public:
|
||||||
|
explicit TerminalWidget(Widget* parent);
|
||||||
|
virtual ~TerminalWidget() override;
|
||||||
|
|
||||||
|
unsigned rows() const { return m_rows; }
|
||||||
|
unsigned columns() const { return m_columns; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
CharacterWithAttributes& at(unsigned row, unsigned column);
|
||||||
|
|
||||||
|
virtual void onPaint(PaintEvent&) override;
|
||||||
|
void onReceive(const ByteBuffer&);
|
||||||
|
void onReceive(byte);
|
||||||
|
|
||||||
|
unsigned m_columns { 80 };
|
||||||
|
unsigned m_rows { 25 };
|
||||||
|
|
||||||
|
unsigned m_cursorRow { 0 };
|
||||||
|
unsigned m_cursorColumn { 0 };
|
||||||
|
|
||||||
|
CharacterWithAttributes* m_screen { nullptr };
|
||||||
|
};
|
|
@ -3,6 +3,7 @@
|
||||||
#include "RootWidget.h"
|
#include "RootWidget.h"
|
||||||
#include "Label.h"
|
#include "Label.h"
|
||||||
#include "Button.h"
|
#include "Button.h"
|
||||||
|
#include "TerminalWidget.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
int main(int c, char** v)
|
int main(int c, char** v)
|
||||||
|
@ -31,13 +32,11 @@ int main(int c, char** v)
|
||||||
l4->setRect(Rect(100, 160, 300, 20));
|
l4->setRect(Rect(100, 160, 300, 20));
|
||||||
l4->setText("!\"#$%&'()*+,-./:;<=>?@[\\]^_{|}~");
|
l4->setText("!\"#$%&'()*+,-./:;<=>?@[\\]^_{|}~");
|
||||||
|
|
||||||
auto* l5 = new Label(&w);
|
|
||||||
l5->setRect(Rect(200, 200, 400, 50));
|
|
||||||
l5->setText("Welcome to the Serenity Operating System");
|
|
||||||
|
|
||||||
auto* b = new Button(&w);
|
auto* b = new Button(&w);
|
||||||
b->setRect(Rect(10, 10, 100, 30));
|
b->setRect(Rect(10, 10, 100, 30));
|
||||||
b->setCaption("Button!");
|
b->setCaption("Button!");
|
||||||
|
|
||||||
|
auto* t = new TerminalWidget(&w);
|
||||||
|
|
||||||
return loop.exec();
|
return loop.exec();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue