diff --git a/AK/printf.cpp b/AK/printf.cpp index cd5fe310e2..8948734512 100644 --- a/AK/printf.cpp +++ b/AK/printf.cpp @@ -191,6 +191,11 @@ one_more: ret += print_number(putch, bufptr, va_arg(ap, dword), leftPad, zeroPad, fieldWidth); break; + case 'f': + // FIXME: Print as float! + ret += print_number(putch, bufptr, (int)va_arg(ap, double), leftPad, zeroPad, fieldWidth); + break; + case 'o': ret += print_octal_number(putch, bufptr, va_arg(ap, dword), leftPad, zeroPad, fieldWidth); break; diff --git a/Applications/ProcessManager/ProcessTableModel.cpp b/Applications/ProcessManager/ProcessTableModel.cpp index 74cd8209d4..b72af1e5bd 100644 --- a/Applications/ProcessManager/ProcessTableModel.cpp +++ b/Applications/ProcessManager/ProcessTableModel.cpp @@ -87,19 +87,19 @@ static String pretty_byte_size(size_t size) 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 })); auto it = m_processes.find(m_pids[row]); auto& process = *(*it).value; 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::User: return process.current_state.user; case Column::Priority: return process.current_state.priority; case Column::Linear: return pretty_byte_size(process.current_state.linear); 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; } ASSERT_NOT_REACHED(); diff --git a/Applications/ProcessManager/ProcessTableModel.h b/Applications/ProcessManager/ProcessTableModel.h index 544aaeb5e8..93ba789dfc 100644 --- a/Applications/ProcessManager/ProcessTableModel.h +++ b/Applications/ProcessManager/ProcessTableModel.h @@ -17,7 +17,7 @@ public: virtual ColumnMetadata column_metadata(int column) const override; virtual GModelIndex selected_index() const 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; pid_t selected_pid() const; diff --git a/LibGUI/GTableModel.h b/LibGUI/GTableModel.h index 7a5d71e815..9c1a4bcbef 100644 --- a/LibGUI/GTableModel.h +++ b/LibGUI/GTableModel.h @@ -5,6 +5,7 @@ #include #include #include +#include #include class GTableView; @@ -23,7 +24,7 @@ public: virtual String row_name(int) const { return { }; } virtual String column_name(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 GModelIndex selected_index() const { return GModelIndex(); } virtual void update() = 0; diff --git a/LibGUI/GTableView.cpp b/LibGUI/GTableView.cpp index f8f908bf5e..2300aef6ae 100644 --- a/LibGUI/GTableView.cpp +++ b/LibGUI/GTableView.cpp @@ -100,7 +100,7 @@ void GTableView::paint_event(GPaintEvent&) auto column_metadata = m_model->column_metadata(column_index); int column_width = column_metadata.preferred_width; 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; } ++painted_item_index; diff --git a/LibGUI/GVariant.cpp b/LibGUI/GVariant.cpp new file mode 100644 index 0000000000..aa921f5f52 --- /dev/null +++ b/LibGUI/GVariant.cpp @@ -0,0 +1,69 @@ +#include + +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(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(&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(); +} + diff --git a/LibGUI/GVariant.h b/LibGUI/GVariant.h new file mode 100644 index 0000000000..c682d9d656 --- /dev/null +++ b/LibGUI/GVariant.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include + +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 }; +}; diff --git a/LibGUI/Makefile b/LibGUI/Makefile index b324290a32..11a0bd563e 100644 --- a/LibGUI/Makefile +++ b/LibGUI/Makefile @@ -30,6 +30,7 @@ LIBGUI_OBJS = \ GToolBar.o \ GTableView.o \ GTableModel.o \ + GVariant.o \ GWindow.o OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)