LibGUI: Add GVariant class and use it for table model data.

This commit is contained in:
Andreas Kling 2019-02-28 16:20:29 +01:00
parent c1f5f2694b
commit 75fabef57b
Notes: sideshowbarker 2024-07-19 15:35:37 +09:00
8 changed files with 152 additions and 6 deletions

View file

@ -191,6 +191,11 @@ one_more:
ret += print_number(putch, bufptr, va_arg(ap, dword), leftPad, zeroPad, fieldWidth); ret += print_number(putch, bufptr, va_arg(ap, dword), leftPad, zeroPad, fieldWidth);
break; break;
case 'f':
// FIXME: Print as float!
ret += print_number(putch, bufptr, (int)va_arg(ap, double), leftPad, zeroPad, fieldWidth);
break;
case 'o': case 'o':
ret += print_octal_number(putch, bufptr, va_arg(ap, dword), leftPad, zeroPad, fieldWidth); ret += print_octal_number(putch, bufptr, va_arg(ap, dword), leftPad, zeroPad, fieldWidth);
break; break;

View file

@ -87,19 +87,19 @@ static String pretty_byte_size(size_t size)
return String::format("%uK", size / 1024); return String::format("%uK", size / 1024);
} }
String ProcessTableModel::data(int row, int column) const GVariant ProcessTableModel::data(int row, int column) const
{ {
ASSERT(is_valid({ row, column })); ASSERT(is_valid({ row, column }));
auto it = m_processes.find(m_pids[row]); auto it = m_processes.find(m_pids[row]);
auto& process = *(*it).value; auto& process = *(*it).value;
switch (column) { switch (column) {
case Column::PID: return String::format("%d", process.current_state.pid); case Column::PID: return process.current_state.pid;
case Column::State: return process.current_state.state; case Column::State: return process.current_state.state;
case Column::User: return process.current_state.user; case Column::User: return process.current_state.user;
case Column::Priority: return process.current_state.priority; case Column::Priority: return process.current_state.priority;
case Column::Linear: return pretty_byte_size(process.current_state.linear); case Column::Linear: return pretty_byte_size(process.current_state.linear);
case Column::Physical: return pretty_byte_size(process.current_state.physical); case Column::Physical: return pretty_byte_size(process.current_state.physical);
case Column::CPU: return String::format("%d", (int)process.current_state.cpu_percent); case Column::CPU: return process.current_state.cpu_percent;
case Column::Name: return process.current_state.name; case Column::Name: return process.current_state.name;
} }
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();

View file

@ -17,7 +17,7 @@ public:
virtual ColumnMetadata column_metadata(int column) const override; virtual ColumnMetadata column_metadata(int column) const override;
virtual GModelIndex selected_index() const override; virtual GModelIndex selected_index() const override;
virtual void set_selected_index(GModelIndex) override; virtual void set_selected_index(GModelIndex) override;
virtual String data(int row, int column) const override; virtual GVariant data(int row, int column) const override;
virtual void update() override; virtual void update() override;
pid_t selected_pid() const; pid_t selected_pid() const;

View file

@ -5,6 +5,7 @@
#include <AK/Function.h> #include <AK/Function.h>
#include <AK/HashTable.h> #include <AK/HashTable.h>
#include <LibGUI/GModelIndex.h> #include <LibGUI/GModelIndex.h>
#include <LibGUI/GVariant.h>
#include <SharedGraphics/TextAlignment.h> #include <SharedGraphics/TextAlignment.h>
class GTableView; class GTableView;
@ -23,7 +24,7 @@ public:
virtual String row_name(int) const { return { }; } virtual String row_name(int) const { return { }; }
virtual String column_name(int) const { return { }; } virtual String column_name(int) const { return { }; }
virtual ColumnMetadata column_metadata(int) const { return { }; } virtual ColumnMetadata column_metadata(int) const { return { }; }
virtual String data(int row, int column) const = 0; virtual GVariant data(int row, int column) const = 0;
virtual void set_selected_index(GModelIndex) { } virtual void set_selected_index(GModelIndex) { }
virtual GModelIndex selected_index() const { return GModelIndex(); } virtual GModelIndex selected_index() const { return GModelIndex(); }
virtual void update() = 0; virtual void update() = 0;

View file

@ -100,7 +100,7 @@ void GTableView::paint_event(GPaintEvent&)
auto column_metadata = m_model->column_metadata(column_index); auto column_metadata = m_model->column_metadata(column_index);
int column_width = column_metadata.preferred_width; int column_width = column_metadata.preferred_width;
Rect cell_rect(horizontal_padding + x_offset, y, column_width, item_height()); Rect cell_rect(horizontal_padding + x_offset, y, column_width, item_height());
painter.draw_text(cell_rect, m_model->data(row_index, column_index), column_metadata.text_alignment, text_color); painter.draw_text(cell_rect, m_model->data(row_index, column_index).to_string(), column_metadata.text_alignment, text_color);
x_offset += column_width + horizontal_padding * 2; x_offset += column_width + horizontal_padding * 2;
} }
++painted_item_index; ++painted_item_index;

69
LibGUI/GVariant.cpp Normal file
View file

@ -0,0 +1,69 @@
#include <LibGUI/GVariant.h>
GVariant::~GVariant()
{
switch (m_type) {
case Type::String:
if (m_value.as_string)
m_value.as_string->release();
break;
case Type::Bitmap:
if (m_value.as_bitmap)
m_value.as_bitmap->release();
break;
default:
break;
}
}
GVariant::GVariant(int value)
: m_type(Type::Int)
{
m_value.as_int = value;
}
GVariant::GVariant(float value)
: m_type(Type::Float)
{
m_value.as_float = value;
}
GVariant::GVariant(bool value)
: m_type(Type::Bool)
{
m_value.as_bool = value;
}
GVariant::GVariant(const String& value)
: m_type(Type::String)
{
m_value.as_string = const_cast<StringImpl*>(value.impl());
AK::retain_if_not_null(m_value.as_string);
}
GVariant::GVariant(const GraphicsBitmap& value)
: m_type(Type::Bitmap)
{
m_value.as_bitmap = const_cast<GraphicsBitmap*>(&value);
AK::retain_if_not_null(m_value.as_bitmap);
}
String GVariant::to_string() const
{
switch (m_type) {
case Type::Bool:
return as_bool() ? "True" : "False";
case Type::Int:
return String::format("%d", as_int());
case Type::Float:
return String::format("%f", as_float());
case Type::String:
return as_string();
case Type::Bitmap:
return "[GraphicsBitmap]";
case Type::Invalid:
break;
}
ASSERT_NOT_REACHED();
}

70
LibGUI/GVariant.h Normal file
View file

@ -0,0 +1,70 @@
#pragma once
#include <AK/AKString.h>
#include <SharedGraphics/GraphicsBitmap.h>
class GVariant {
public:
GVariant();
GVariant(bool);
GVariant(float);
GVariant(int);
GVariant(const String&);
GVariant(const GraphicsBitmap&);
~GVariant();
enum class Type {
Invalid,
Bool,
Int,
Float,
String,
Bitmap,
};
bool is_valid() const { return m_type != Type::Invalid; }
Type type() const { return m_type; }
bool as_bool() const
{
ASSERT(type() == Type::Bool);
return m_value.as_bool;
}
int as_int() const
{
ASSERT(type() == Type::Int);
return m_value.as_int;
}
float as_float() const
{
ASSERT(type() == Type::Float);
return m_value.as_float;
}
String as_string() const
{
ASSERT(type() == Type::String);
return *m_value.as_string;
}
const GraphicsBitmap& as_bitmap() const
{
ASSERT(type() == Type::Bitmap);
return *m_value.as_bitmap;
}
String to_string() const;
private:
union {
StringImpl* as_string;
GraphicsBitmap* as_bitmap;
bool as_bool;
int as_int;
float as_float;
} m_value;
Type m_type { Type::Invalid };
};

View file

@ -30,6 +30,7 @@ LIBGUI_OBJS = \
GToolBar.o \ GToolBar.o \
GTableView.o \ GTableView.o \
GTableModel.o \ GTableModel.o \
GVariant.o \
GWindow.o GWindow.o
OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS) OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)