mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:37:36 +00:00
Add a visual bell to TerminalWidget. Also backspace.
This commit is contained in:
parent
20a1795218
commit
fb4ae12bc2
4 changed files with 82 additions and 14 deletions
|
@ -4,7 +4,16 @@
|
||||||
|
|
||||||
class Color {
|
class Color {
|
||||||
public:
|
public:
|
||||||
|
enum NamedColor {
|
||||||
|
Black,
|
||||||
|
White,
|
||||||
|
Red,
|
||||||
|
Green,
|
||||||
|
Blue,
|
||||||
|
};
|
||||||
|
|
||||||
Color() { }
|
Color() { }
|
||||||
|
Color(NamedColor);
|
||||||
Color(byte r, byte g, byte b);
|
Color(byte r, byte g, byte b);
|
||||||
|
|
||||||
dword value() const { return m_value; }
|
dword value() const { return m_value; }
|
||||||
|
|
|
@ -5,3 +5,24 @@ Color::Color(byte r, byte g, byte b)
|
||||||
{
|
{
|
||||||
m_value = SDL_MapRGB(FrameBufferSDL::the().surface()->format, r, g, b);
|
m_value = SDL_MapRGB(FrameBufferSDL::the().surface()->format, r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color::Color(NamedColor named)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
byte r;
|
||||||
|
byte g;
|
||||||
|
byte b;
|
||||||
|
} rgb;
|
||||||
|
|
||||||
|
switch (named) {
|
||||||
|
case Black: rgb = { 0, 0, 0 }; break;
|
||||||
|
case White: rgb = { 255, 255, 255 }; break;
|
||||||
|
case Red: rgb = { 255, 0, 0}; break;
|
||||||
|
case Green: rgb = { 0, 255, 0}; break;
|
||||||
|
case Blue: rgb = { 0, 0, 255}; break;
|
||||||
|
default: ASSERT_NOT_REACHED(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_value = SDL_MapRGB(FrameBufferSDL::the().surface()->format, rgb.r, rgb.g, rgb.g);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ CharacterWithAttributes& TerminalWidget::at(unsigned row, unsigned column)
|
||||||
void TerminalWidget::onPaint(PaintEvent&)
|
void TerminalWidget::onPaint(PaintEvent&)
|
||||||
{
|
{
|
||||||
Painter painter(*this);
|
Painter painter(*this);
|
||||||
painter.fillRect({ 0, 0, width(), height() }, Color(0, 0, 0));
|
painter.fillRect(rect(), Color(0, 0, 0));
|
||||||
|
|
||||||
auto& font = Font::defaultFont();
|
auto& font = Font::defaultFont();
|
||||||
|
|
||||||
|
@ -76,6 +76,9 @@ void TerminalWidget::onPaint(PaintEvent&)
|
||||||
painter.drawText({ x + 2, y + 2, width(), font.glyphHeight() }, buf, Painter::TextAlignment::TopLeft, Color(0xa0, 0xa0, 0xa0));
|
painter.drawText({ x + 2, y + 2, width(), font.glyphHeight() }, buf, Painter::TextAlignment::TopLeft, Color(0xa0, 0xa0, 0xa0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_belling)
|
||||||
|
painter.drawRect(rect(), Color::Red);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalWidget::onReceive(const ByteBuffer& buffer)
|
void TerminalWidget::onReceive(const ByteBuffer& buffer)
|
||||||
|
@ -105,20 +108,35 @@ void TerminalWidget::onReceive(byte ch)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ch == '\n') {
|
switch (ch) {
|
||||||
if (m_cursorRow < (m_rows - 1)) {
|
case '\n':
|
||||||
++m_cursorRow;
|
if (m_cursorRow < (m_rows - 1)) {
|
||||||
} else {
|
++m_cursorRow;
|
||||||
scrollScreen();
|
} else {
|
||||||
|
scrollScreen();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
m_cursorColumn = 0;
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
// FIXME: Respect terminal tab stops.
|
||||||
|
while ((m_cursorColumn % 8) != 0 && m_cursorColumn < m_columns) {
|
||||||
|
addChar(' ');
|
||||||
|
break;
|
||||||
|
case '\a':
|
||||||
|
bell();
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if (m_cursorColumn > 0) {
|
||||||
|
--m_cursorColumn;
|
||||||
|
at(m_cursorRow, m_cursorColumn).character = ' ';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
addChar(ch);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (ch == '\r') {
|
|
||||||
m_cursorColumn = 0;
|
|
||||||
} else if (ch == '\t') {
|
|
||||||
while ((m_cursorColumn % 8) != 0 && m_cursorColumn < m_columns) {
|
|
||||||
addChar(' ');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addChar(ch);
|
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -136,3 +154,18 @@ void TerminalWidget::onKeyUp(KeyEvent& event)
|
||||||
return Widget::onKeyUp(event);
|
return Widget::onKeyUp(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerminalWidget::bell()
|
||||||
|
{
|
||||||
|
if (m_belling)
|
||||||
|
stopTimer();
|
||||||
|
startTimer(250);
|
||||||
|
m_belling = true;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalWidget::onTimer(TimerEvent&)
|
||||||
|
{
|
||||||
|
m_belling = false;
|
||||||
|
stopTimer();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ private:
|
||||||
virtual void onPaint(PaintEvent&) override;
|
virtual void onPaint(PaintEvent&) override;
|
||||||
virtual void onKeyDown(KeyEvent&) override;
|
virtual void onKeyDown(KeyEvent&) override;
|
||||||
virtual void onKeyUp(KeyEvent&) override;
|
virtual void onKeyUp(KeyEvent&) override;
|
||||||
|
virtual void onTimer(TimerEvent&) override;
|
||||||
|
|
||||||
|
void bell();
|
||||||
|
|
||||||
unsigned m_columns { 80 };
|
unsigned m_columns { 80 };
|
||||||
unsigned m_rows { 25 };
|
unsigned m_rows { 25 };
|
||||||
|
@ -33,4 +36,6 @@ private:
|
||||||
unsigned m_cursorColumn { 0 };
|
unsigned m_cursorColumn { 0 };
|
||||||
|
|
||||||
CharacterWithAttributes* m_screen { nullptr };
|
CharacterWithAttributes* m_screen { nullptr };
|
||||||
|
|
||||||
|
bool m_belling { false };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue