mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
More rage hacking on Widgets. Some very basic text drawing. :^)
This commit is contained in:
parent
6f37429f57
commit
77bac7216c
Notes:
sideshowbarker
2024-07-19 18:51:16 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/77bac7216cb
7 changed files with 341 additions and 28 deletions
|
@ -5,17 +5,25 @@
|
|||
Label::Label(Widget* parent)
|
||||
: Widget(parent)
|
||||
{
|
||||
setRect(Rect(100, 100, 100, 100));
|
||||
}
|
||||
|
||||
Label::~Label()
|
||||
{
|
||||
}
|
||||
|
||||
void Label::setText(String&& text)
|
||||
{
|
||||
if (text == m_text)
|
||||
return;
|
||||
m_text = std::move(text);
|
||||
update();
|
||||
}
|
||||
|
||||
void Label::onPaint(PaintEvent&)
|
||||
{
|
||||
Painter painter(*this);
|
||||
painter.fillRect({ 0, 0, width(), height() }, Color(0xc0, 0xc0, 0xc0));
|
||||
painter.drawText({ 4, 4 }, text());
|
||||
}
|
||||
|
||||
void Label::onMouseMove(MouseEvent& event)
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widget.h"
|
||||
#include <AK/String.h>
|
||||
|
||||
class Label final : public Widget {
|
||||
public:
|
||||
explicit Label(Widget* parent);
|
||||
virtual ~Label() override;
|
||||
|
||||
String text() const { return m_text; }
|
||||
void setText(String&&);
|
||||
|
||||
private:
|
||||
virtual void onPaint(PaintEvent&) override;
|
||||
virtual void onMouseMove(MouseEvent&) override;
|
||||
|
||||
virtual const char* className() const override { return "Label"; }
|
||||
|
||||
String m_text;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,16 +15,281 @@ Painter::~Painter()
|
|||
ASSERT(rc == 0);
|
||||
}
|
||||
|
||||
void Painter::fillRect(Rect rect, Color color)
|
||||
static dword* scanline(int y)
|
||||
{
|
||||
rect.moveBy(m_widget.x(), m_widget.y());
|
||||
|
||||
SDL_Rect sdlRect;
|
||||
sdlRect.x = rect.x();
|
||||
sdlRect.y = rect.y();
|
||||
sdlRect.w = rect.width();
|
||||
sdlRect.h = rect.height();
|
||||
|
||||
int rc = SDL_FillRect(FrameBufferSDL::the().surface(), &sdlRect, color.value());
|
||||
ASSERT(rc == 0);
|
||||
auto& surface = *FrameBufferSDL::the().surface();
|
||||
return (dword*)(((byte*)surface.pixels) + (y * surface.pitch));
|
||||
}
|
||||
|
||||
void Painter::fillRect(const Rect& rect, Color color)
|
||||
{
|
||||
Rect r = rect;
|
||||
r.moveBy(m_widget.x(), m_widget.y());
|
||||
|
||||
for (int y = r.top(); y < r.bottom(); ++y) {
|
||||
dword* bits = scanline(y);
|
||||
for (int x = r.left(); x < r.right(); ++x) {
|
||||
bits[x] = color.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* peanut8x7[] {
|
||||
" #### "
|
||||
" # # "
|
||||
" # # "
|
||||
" ###### "
|
||||
" # # "
|
||||
" # # "
|
||||
"### ###",
|
||||
|
||||
" ##### "
|
||||
" # # "
|
||||
" # # "
|
||||
" ###### "
|
||||
" # # "
|
||||
" # # "
|
||||
" ##### ",
|
||||
|
||||
" #### "
|
||||
" # # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # # "
|
||||
" #### ",
|
||||
|
||||
" ##### "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" ##### ",
|
||||
|
||||
" ###### "
|
||||
" # # "
|
||||
" # "
|
||||
" #### "
|
||||
" # "
|
||||
" # # "
|
||||
" ###### ",
|
||||
|
||||
" ###### "
|
||||
" # # "
|
||||
" # "
|
||||
" #### "
|
||||
" # "
|
||||
" # "
|
||||
" # ",
|
||||
|
||||
" #### "
|
||||
" # # "
|
||||
" # "
|
||||
" # ###"
|
||||
" # # "
|
||||
" # # "
|
||||
" #### ",
|
||||
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" ###### "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # ",
|
||||
|
||||
" ### "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" ### ",
|
||||
|
||||
" ##### "
|
||||
" # # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # # "
|
||||
" ### ",
|
||||
|
||||
" ### ###"
|
||||
" # # "
|
||||
" # # "
|
||||
" ### "
|
||||
" # # "
|
||||
" # # "
|
||||
" ### ###",
|
||||
|
||||
" ### "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # # "
|
||||
" ###### ",
|
||||
|
||||
" # # "
|
||||
" ## ## "
|
||||
" # ## # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
"### ###",
|
||||
|
||||
" # # "
|
||||
" ## # "
|
||||
" # # # "
|
||||
" # # # "
|
||||
" # ## "
|
||||
" # # "
|
||||
" # # ",
|
||||
|
||||
" #### "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" #### ",
|
||||
|
||||
" ##### "
|
||||
" # # "
|
||||
" # # "
|
||||
" #### "
|
||||
" # "
|
||||
" # "
|
||||
" ### ",
|
||||
|
||||
" #### "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # # "
|
||||
" # # "
|
||||
" ### # ",
|
||||
|
||||
" ##### "
|
||||
" # # "
|
||||
" # # "
|
||||
" #### "
|
||||
" # # "
|
||||
" # # "
|
||||
" ### # ",
|
||||
|
||||
" #### "
|
||||
" # # "
|
||||
" # "
|
||||
" #### "
|
||||
" # "
|
||||
" # # "
|
||||
" #### ",
|
||||
|
||||
" ##### "
|
||||
"# # # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" ### ",
|
||||
|
||||
"### ###"
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" #### ",
|
||||
|
||||
"### ### "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # "
|
||||
" # ",
|
||||
|
||||
"### ###"
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # ## # "
|
||||
" ## ## "
|
||||
" # # ",
|
||||
|
||||
"## ## "
|
||||
" # # "
|
||||
" # # "
|
||||
" # "
|
||||
" # # "
|
||||
" # # "
|
||||
"## ## ",
|
||||
|
||||
"## ## "
|
||||
" # # "
|
||||
" # # "
|
||||
" # # "
|
||||
" # "
|
||||
" # "
|
||||
" ### ",
|
||||
|
||||
" ###### "
|
||||
" # # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # # "
|
||||
" ###### ",
|
||||
|
||||
" #### "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" #### ",
|
||||
|
||||
" # "
|
||||
" ## "
|
||||
" ## "
|
||||
" ## "
|
||||
" ## "
|
||||
" ## "
|
||||
" # ",
|
||||
|
||||
" #### "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" # "
|
||||
" #### ",
|
||||
|
||||
};
|
||||
|
||||
void Painter::drawText(const Point& point, const String& text, const Color& color)
|
||||
{
|
||||
Point p = point;
|
||||
p.moveBy(m_widget.x(), m_widget.y());
|
||||
|
||||
byte fontWidth = 8;
|
||||
byte fontHeight = 7;
|
||||
auto* font = peanut8x7;
|
||||
|
||||
for (int row = 0; row < fontHeight; ++row) {
|
||||
int y = p.y() + row;
|
||||
dword* bits = scanline(y);
|
||||
for (unsigned i = 0; i < text.length(); ++i) {
|
||||
const char* fontCharacter = font[text[i] - 'A'];
|
||||
int x = p.x() + i * fontWidth;
|
||||
for (unsigned j = 0; j < fontWidth; ++j) {
|
||||
char fc = fontCharacter[row * fontWidth + j];
|
||||
if (fc == '#')
|
||||
bits[x + j] = color.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "Color.h"
|
||||
#include "Point.h"
|
||||
#include "Rect.h"
|
||||
#include <AK/String.h>
|
||||
|
||||
class Widget;
|
||||
|
||||
|
@ -9,7 +11,8 @@ class Painter {
|
|||
public:
|
||||
explicit Painter(Widget&);
|
||||
~Painter();
|
||||
void fillRect(Rect, Color);
|
||||
void fillRect(const Rect&, Color);
|
||||
void drawText(const Point&, const String&, const Color& = Color());
|
||||
|
||||
private:
|
||||
Widget& m_widget;
|
||||
|
|
23
Widgets/Point.h
Normal file
23
Widgets/Point.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
class Point {
|
||||
public:
|
||||
Point() { }
|
||||
Point(int x, int y) : m_x(x) , m_y(y) { }
|
||||
|
||||
int x() const { return m_x; }
|
||||
int y() const { return m_y; }
|
||||
|
||||
void setX(int x) { m_x = x; }
|
||||
void setY(int y) { m_y = y; }
|
||||
|
||||
void moveBy(int dx, int dy)
|
||||
{
|
||||
m_x += dx;
|
||||
m_y += dy;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_x { 0 };
|
||||
int m_y { 0 };
|
||||
};
|
|
@ -1,11 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "Point.h"
|
||||
|
||||
class Rect {
|
||||
public:
|
||||
Rect() { }
|
||||
Rect(int x, int y, int width, int height)
|
||||
: m_x(x)
|
||||
, m_y(y)
|
||||
: m_location(x, y)
|
||||
, m_width(width)
|
||||
, m_height(height)
|
||||
{
|
||||
|
@ -13,33 +14,38 @@ public:
|
|||
|
||||
void moveBy(int dx, int dy)
|
||||
{
|
||||
m_x += dx;
|
||||
m_y += dy;
|
||||
m_location.moveBy(dx, dy);
|
||||
}
|
||||
|
||||
bool contains(int x, int y) const
|
||||
{
|
||||
return x >= m_x && x <= right() && y >= m_y && y <= bottom();
|
||||
return x >= m_location.x() && x <= right() && y >= m_location.y() && y <= bottom();
|
||||
}
|
||||
|
||||
int left() const { return m_x; }
|
||||
int right() const { return m_x + m_width; }
|
||||
int top() const { return m_y; }
|
||||
int bottom() const { return m_y + m_height; }
|
||||
bool contains(const Point& point) const
|
||||
{
|
||||
return contains(point.x(), point.y());
|
||||
}
|
||||
|
||||
int x() const { return m_x; }
|
||||
int y() const { return m_y; }
|
||||
int left() const { return x(); }
|
||||
int right() const { return x() + width(); }
|
||||
int top() const { return y(); }
|
||||
int bottom() const { return y() + height(); }
|
||||
|
||||
int x() const { return location().x(); }
|
||||
int y() const { return location().y(); }
|
||||
int width() const { return m_width; }
|
||||
int height() const { return m_height; }
|
||||
|
||||
void setX(int x) { m_x = x; }
|
||||
void setY(int y) { m_y = y; }
|
||||
void setX(int x) { m_location.setX(x); }
|
||||
void setY(int y) { m_location.setY(y); }
|
||||
void setWidth(int width) { m_width = width; }
|
||||
void setHeight(int height) { m_height = height; }
|
||||
|
||||
Point location() const { return m_location; }
|
||||
|
||||
private:
|
||||
int m_x { 0 };
|
||||
int m_y { 0 };
|
||||
Point m_location;
|
||||
int m_width { 0 };
|
||||
int m_height { 0 };
|
||||
};
|
||||
|
|
|
@ -15,6 +15,8 @@ int main(int c, char** v)
|
|||
fb.setRootWidget(&w);
|
||||
|
||||
Label l(&w);
|
||||
l.setRect(Rect(100, 100, 300, 100));
|
||||
l.setText("ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]");
|
||||
|
||||
return loop.exec();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue