mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:37:35 +00:00
IRCClient+LibGUI: Add an input box so we can send messages to channels.
Implement this using a GTextEditor with a special single-line mode. This new mode needs some polishing, but it's already very useful.
This commit is contained in:
parent
ad08165a25
commit
1fc283ed7d
12 changed files with 126 additions and 23 deletions
|
@ -8,6 +8,7 @@
|
|||
#include <LibGUI/GVariant.h>
|
||||
#include <SharedGraphics/TextAlignment.h>
|
||||
|
||||
class Font;
|
||||
class GTableView;
|
||||
|
||||
enum class GSortOrder { None, Ascending, Descending };
|
||||
|
@ -38,6 +39,7 @@ public:
|
|||
struct ColumnMetadata {
|
||||
int preferred_width { 0 };
|
||||
TextAlignment text_alignment { TextAlignment::CenterLeft };
|
||||
const Font* font { nullptr };
|
||||
};
|
||||
|
||||
enum class Role { Display, Sort, Custom };
|
||||
|
|
|
@ -167,6 +167,7 @@ void GTableView::paint_event(GPaintEvent& event)
|
|||
for (int column_index = 0; column_index < m_model->column_count(); ++column_index) {
|
||||
auto column_metadata = m_model->column_metadata(column_index);
|
||||
int column_width = column_metadata.preferred_width;
|
||||
const Font& font = column_metadata.font ? *column_metadata.font : this->font();
|
||||
bool is_key_column = m_model->key_column() == column_index;
|
||||
Rect cell_rect(horizontal_padding() + x_offset, y, column_width, item_height());
|
||||
if (is_key_column) {
|
||||
|
@ -177,7 +178,7 @@ void GTableView::paint_event(GPaintEvent& event)
|
|||
if (data.is_bitmap())
|
||||
painter.blit(cell_rect.location(), data.as_bitmap(), data.as_bitmap().rect());
|
||||
else
|
||||
painter.draw_text(cell_rect, data.to_string(), column_metadata.text_alignment, text_color);
|
||||
painter.draw_text(cell_rect, data.to_string(), font, column_metadata.text_alignment, text_color);
|
||||
x_offset += column_width + horizontal_padding() * 2;
|
||||
}
|
||||
++painted_item_index;
|
||||
|
|
|
@ -9,13 +9,15 @@
|
|||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
GTextEditor::GTextEditor(GWidget* parent)
|
||||
GTextEditor::GTextEditor(Type type, GWidget* parent)
|
||||
: GWidget(parent)
|
||||
, m_type(type)
|
||||
{
|
||||
set_font(GFontDatabase::the().get_by_name("Csilla Thin"));
|
||||
|
||||
m_vertical_scrollbar = new GScrollBar(Orientation::Vertical, this);
|
||||
m_vertical_scrollbar->set_step(4);
|
||||
m_vertical_scrollbar->set_visible(is_multi_line());
|
||||
m_vertical_scrollbar->on_change = [this] (int) {
|
||||
update();
|
||||
};
|
||||
|
@ -23,12 +25,14 @@ GTextEditor::GTextEditor(GWidget* parent)
|
|||
m_horizontal_scrollbar = new GScrollBar(Orientation::Horizontal, this);
|
||||
m_horizontal_scrollbar->set_step(4);
|
||||
m_horizontal_scrollbar->set_big_step(30);
|
||||
m_horizontal_scrollbar->set_visible(is_multi_line());
|
||||
m_horizontal_scrollbar->on_change = [this] (int) {
|
||||
update();
|
||||
};
|
||||
|
||||
m_corner_widget = new GWidget(this);
|
||||
m_corner_widget->set_fill_with_background_color(true);
|
||||
m_corner_widget->set_visible(is_multi_line());
|
||||
|
||||
m_lines.append(make<Line>());
|
||||
}
|
||||
|
@ -63,9 +67,11 @@ void GTextEditor::set_text(const String& text)
|
|||
void GTextEditor::resize_event(GResizeEvent& event)
|
||||
{
|
||||
update_scrollbar_ranges();
|
||||
m_vertical_scrollbar->set_relative_rect(event.size().width() - m_vertical_scrollbar->preferred_size().width(), 0, m_vertical_scrollbar->preferred_size().width(), event.size().height() - m_horizontal_scrollbar->preferred_size().height());
|
||||
m_horizontal_scrollbar->set_relative_rect(0, event.size().height() - m_horizontal_scrollbar->preferred_size().height(), event.size().width() - m_vertical_scrollbar->preferred_size().width(), m_horizontal_scrollbar->preferred_size().height());
|
||||
m_corner_widget->set_relative_rect(m_horizontal_scrollbar->rect().right() + 1, m_vertical_scrollbar->rect().bottom() + 1, m_horizontal_scrollbar->height(), m_vertical_scrollbar->width());
|
||||
if (is_multi_line()) {
|
||||
m_vertical_scrollbar->set_relative_rect(event.size().width() - m_vertical_scrollbar->preferred_size().width(), 0, m_vertical_scrollbar->preferred_size().width(), event.size().height() - m_horizontal_scrollbar->preferred_size().height());
|
||||
m_horizontal_scrollbar->set_relative_rect(0, event.size().height() - m_horizontal_scrollbar->preferred_size().height(), event.size().width() - m_vertical_scrollbar->preferred_size().width(), m_horizontal_scrollbar->preferred_size().height());
|
||||
m_corner_widget->set_relative_rect(m_horizontal_scrollbar->rect().right() + 1, m_vertical_scrollbar->rect().bottom() + 1, m_horizontal_scrollbar->height(), m_vertical_scrollbar->width());
|
||||
}
|
||||
}
|
||||
|
||||
void GTextEditor::update_scrollbar_ranges()
|
||||
|
@ -441,6 +447,11 @@ void GTextEditor::insert_at_cursor(char ch)
|
|||
bool at_head = m_cursor.column() == 0;
|
||||
bool at_tail = m_cursor.column() == current_line().length();
|
||||
if (ch == '\n') {
|
||||
if (is_single_line()) {
|
||||
if (on_return_pressed)
|
||||
on_return_pressed(*this);
|
||||
return;
|
||||
}
|
||||
if (at_tail || at_head) {
|
||||
m_lines.insert(m_cursor.line() + (at_tail ? 1 : 0), make<Line>());
|
||||
update_scrollbar_ranges();
|
||||
|
@ -689,6 +700,27 @@ bool GTextEditor::write_to_file(const String& path)
|
|||
return true;
|
||||
}
|
||||
|
||||
String GTextEditor::text() const
|
||||
{
|
||||
StringBuilder builder;
|
||||
for (int i = 0; i < line_count(); ++i) {
|
||||
auto& line = *m_lines[i];
|
||||
builder.append(line.characters(), line.length());
|
||||
if (i != line_count() - 1)
|
||||
builder.append('\n');
|
||||
}
|
||||
return builder.to_string();
|
||||
}
|
||||
|
||||
void GTextEditor::clear()
|
||||
{
|
||||
m_lines.clear();
|
||||
m_lines.append(make<Line>());
|
||||
m_selection.clear();
|
||||
set_cursor(0, 0);
|
||||
update();
|
||||
}
|
||||
|
||||
String GTextEditor::selected_text() const
|
||||
{
|
||||
if (!has_selection())
|
||||
|
|
|
@ -62,9 +62,14 @@ private:
|
|||
|
||||
class GTextEditor : public GWidget {
|
||||
public:
|
||||
explicit GTextEditor(GWidget* parent);
|
||||
enum Type { MultiLine, SingleLine };
|
||||
GTextEditor(Type, GWidget* parent);
|
||||
virtual ~GTextEditor() override;
|
||||
|
||||
Type type() const { return m_type; }
|
||||
bool is_single_line() const { return m_type == SingleLine; }
|
||||
bool is_multi_line() const { return m_type == MultiLine; }
|
||||
|
||||
Function<void(GTextEditor&)> on_cursor_change;
|
||||
|
||||
void set_text(const String&);
|
||||
|
@ -84,11 +89,16 @@ public:
|
|||
|
||||
bool has_selection() const { return m_selection.is_valid(); }
|
||||
String selected_text() const;
|
||||
String text() const;
|
||||
|
||||
void clear();
|
||||
|
||||
void cut();
|
||||
void copy();
|
||||
void paste();
|
||||
|
||||
Function<void(GTextEditor&)> on_return_pressed;
|
||||
|
||||
private:
|
||||
virtual void paint_event(GPaintEvent&) override;
|
||||
virtual void resize_event(GResizeEvent&) override;
|
||||
|
@ -141,6 +151,8 @@ private:
|
|||
void insert_at_cursor_or_replace_selection(const String&);
|
||||
void delete_selection();
|
||||
|
||||
Type m_type { MultiLine };
|
||||
|
||||
GScrollBar* m_vertical_scrollbar { nullptr };
|
||||
GScrollBar* m_horizontal_scrollbar { nullptr };
|
||||
GWidget* m_corner_widget { nullptr };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue