Commit 29dd0e2e authored by Petr Štětka's avatar Petr Štětka
Browse files

Added cookie-graph and color rectangles and full UI in process dialog.

Easier logic with graph and list update.
UI improvements.
Updated GLibTo VAPI to support 1024 processors,
parent 06881183
No preview for this file type
......@@ -20,4 +20,16 @@ rggraph#CpuGraphAllCores {
background-color: #232729;
background-size: 57px 57px;
background-image: repeating-linear-gradient(0deg, #2e2e2e, #2e2e2e 2px, transparent 2px, transparent 57px);
}
CookieGraph.used {
color: #4a90d9;
}
CookieGraph.others {
color: #4d5356;
}
CookieGraph.available {
color: #232729;
}
\ No newline at end of file
......@@ -18,4 +18,16 @@ rggraph#CpuGraphAllCores {
background-color: #ffffff;
background-size: 57px 57px;
background-image: repeating-linear-gradient(0deg, #f0f1f2, #f0f1f2 2px, transparent 2px, transparent 57px);
}
CookieGraph.used {
color: #4a90d9;
}
CookieGraph.others {
color: #707070;
}
CookieGraph.available {
color: #fafafa;
}
\ No newline at end of file
......@@ -24,6 +24,7 @@ vala_binary: src/gnome-usage
*vala_check_package: x11
c_library: gtop-2.0 ${CMAKE_SOURCE_DIR}/external/rg/librg.a ${CMAKE_SOURCE_DIR}/external/egg/libegg-private.a
*vala_source: application.vala
*vala_source: color-rectangle.vala
*vala_source: cookie-graph.vala
*vala_source: cpu-graph-table.vala
*vala_source: cpu-graph.vala
......@@ -31,6 +32,7 @@ c_library: gtop-2.0 ${CMAKE_SOURCE_DIR}/external/rg/librg.a ${CMAKE_SOURCE_DIR}/
*vala_source: data-view.vala
*vala_source: disk-sub-view.vala
*vala_source: gnome-usage.vala
*vala_source: graph-block-row.vala
*vala_source: graph-block.vala
*vala_source: graph-stack-switcher.vala
*vala_source: graph-switcher-button.vala
......@@ -63,33 +65,35 @@ h_folder: /usr/include/libgtop-2.0
translate: c src/better-box.c
*translate: vala src/cpu-graph-table.vala
*translate: vala src/cookie-graph.vala
*translate: vala src/process-row.vala
*translate: vala src/sub-process-sub-row.vala
*translate: vala src/application.vala
*translate: vala src/process-list-box-new.vala
*translate: vala src/header-bar.vala
*translate: vala src/system-monitor.vala
*translate: vala src/process-list-box.vala
*translate: vala src/network-sub-view.vala
*translate: vala src/settings.vala
*translate: vala src/performance-view.vala
*translate: vala src/graph-block.vala
*translate: vala src/process-list-box.vala
*translate: vala src/memory-graph-table.vala
*translate: vala src/view.vala
*translate: vala src/graph-switcher-button.vala
*translate: vala src/disk-sub-view.vala
*translate: vala src/sub-process-sub-row.vala
*translate: vala src/graph-block.vala
*translate: vala src/graph-stack-switcher.vala
*translate: vala src/system-monitor.vala
*translate: vala src/gnome-usage.vala
*translate: vala src/window.vala
*translate: vala src/memory-sub-view.vala
*translate: vala src/color-rectangle.vala
*translate: vala src/memory-graph.vala
*translate: vala src/process-dialog.vala
*translate: vala src/cpu-graph.vala
*translate: vala src/storage-view.vala
*translate: vala src/process-row.vala
*translate: vala src/sub-process-list-box.vala
*translate: vala src/cpu-sub-view.vala
*translate: vala src/memory-graph-table.vala
*translate: vala src/power-view.vala
*translate: vala src/process-dialog.vala
*translate: vala src/cookie-graph.vala
*translate: vala src/graph-block-row.vala
*translate: vala src/data-view.vala
*data: data/local
......
src/application.vala
src/color-rectangle.vala
src/cookie-graph.vala
src/cpu-graph-table.vala
src/cpu-graph.vala
......@@ -6,6 +7,7 @@ src/cpu-sub-view.vala
src/data-view.vala
src/disk-sub-view.vala
src/gnome-usage.vala
src/graph-block-row.vala
src/graph-block.vala
src/graph-stack-switcher.vala
src/graph-switcher-button.vala
......
......@@ -37,6 +37,7 @@ set (VALA_PACKAGES ${VALA_PACKAGES} x11)
set (APP_SOURCES ${APP_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/Config.vala)
set (APP_SOURCES ${APP_SOURCES} application.vala)
set (APP_SOURCES ${APP_SOURCES} color-rectangle.vala)
set (APP_SOURCES ${APP_SOURCES} cookie-graph.vala)
set (APP_SOURCES ${APP_SOURCES} cpu-graph-table.vala)
set (APP_SOURCES ${APP_SOURCES} cpu-graph.vala)
......@@ -44,6 +45,7 @@ set (APP_SOURCES ${APP_SOURCES} cpu-sub-view.vala)
set (APP_SOURCES ${APP_SOURCES} data-view.vala)
set (APP_SOURCES ${APP_SOURCES} disk-sub-view.vala)
set (APP_SOURCES ${APP_SOURCES} gnome-usage.vala)
set (APP_SOURCES ${APP_SOURCES} graph-block-row.vala)
set (APP_SOURCES ${APP_SOURCES} graph-block.vala)
set (APP_SOURCES ${APP_SOURCES} graph-stack-switcher.vala)
set (APP_SOURCES ${APP_SOURCES} graph-switcher-button.vala)
......
using Gtk;
namespace Usage {
public class ColorRectangle : Gtk.DrawingArea
{
Gdk.RGBA color;
class construct
{
set_css_name("CookieGraph");
}
public ColorRectangle(string css_class)
{
get_style_context().add_class(css_class);
color = get_style_context().get_color(get_style_context().get_state());
this.height_request = 17;
this.width_request = 17;
this.valign = Gtk.Align.CENTER;
this.draw.connect ((context) =>
{
int height = this.get_allocated_height ();
int width = this.get_allocated_width ();
double degrees = Math.PI / 180.0;
double x = 0;
double y = 0;
double radius = height / 5;
context.new_sub_path();
context.arc(x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
context.arc(x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
context.arc(x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
context.arc(x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
context.close_path();
Gdk.cairo_set_source_rgba (context, color);
context.fill();
return true;
});
}
}
}
......@@ -6,9 +6,19 @@ namespace Usage {
{
int used_percentages = 0;
int other_percentages = 0;
Gdk.RGBA used_color;
Gdk.RGBA others_color;
Gdk.RGBA available;
public CookieGraph(Gdk.RGBA used_color, Gdk.RGBA others_color, Gdk.RGBA available)
class construct
{
set_css_name("CookieGraph");
}
public CookieGraph()
{
set_styles();
this.draw.connect ((context) =>
{
int height = this.get_allocated_height ();
......@@ -53,6 +63,17 @@ namespace Usage {
});
}
private void set_styles()
{
var context = get_style_context();
context.add_class("used");
used_color = context.get_color(context.get_state());
context.add_class("others");
others_color = context.get_color(context.get_state());
context.add_class("available");
available = context.get_color(context.get_state());
}
public void update(int used_percentages, int other_percentages)
{
this.used_percentages = used_percentages;
......
......@@ -42,9 +42,9 @@ namespace Usage {
for (int i = 0; i < get_num_processors(); i++)
{
iter.set (i, monitor.x_cpu_load_graph[i], -1);
iter.set (i, monitor.x_cpu_load[i], -1);
if(monitor.x_cpu_load_graph[i] >= 90)
if(monitor.x_cpu_load[i] >= 90)
{
if(change_big_process_usage[i])
{
......@@ -93,12 +93,12 @@ namespace Usage {
push (out iter, get_monotonic_time ());
SystemMonitor monitor = (GLib.Application.get_default() as Application).monitor;
double most_used_core = monitor.x_cpu_load_graph[0];
double most_used_core = monitor.x_cpu_load[0];
for (int i = 1; i < get_num_processors(); i++)
{
if(monitor.x_cpu_load_graph[i] > most_used_core)
most_used_core = monitor.x_cpu_load_graph[i];
if(monitor.x_cpu_load[i] > most_used_core)
most_used_core = monitor.x_cpu_load[i];
}
iter.set (0, most_used_core, -1);
......
using Gtk;
namespace Usage {
public class GraphBlockRow : Gtk.Box
{
Gtk.Label value_label;
public GraphBlockRow(string label_text, string css_class)
{
Object(orientation: Gtk.Orientation.HORIZONTAL);
var color_rectangle = new ColorRectangle(css_class);
var label = new Gtk.Label(label_text);
label.margin = 5;
value_label = new Gtk.Label("0 %");
this.pack_start(color_rectangle, false, false);
this.pack_start(label, false, true, 5);
this.pack_end(value_label, false, true, 10);
}
public void update(int value)
{
value_label.set_text(value.to_string() + " %");
}
}
}
......@@ -2,108 +2,59 @@ using Gtk;
namespace Usage
{
public class GraphBlock : Gtk.Table
public class GraphBlock : Gtk.Grid
{
CookieGraph graph;
GraphBlockRow application_row;
GraphBlockRow others_row;
GraphBlockRow available_row;
Gdk.RGBA grey;
Gdk.RGBA blue;
Gdk.RGBA white;
Gtk.Label label;
string block_name;
public GraphBlock(string name, string app_name)
class construct
{
Object(n_rows: 2, n_columns: 2, homogeneous: false);
Gtk.AttachOptions flags = Gtk.AttachOptions.EXPAND;
blue.parse("#4a90d9"); //TODO load from css
grey.parse("#707070");
white.parse("#fafafa");
set_css_name("GraphBlock");
}
public GraphBlock(string block_name, string app_name)
{
this.expand = true;
var name_label = new Gtk.Label("<span font_desc=\"11.0\"><b>" + name + "</b></span>");
name_label.set_use_markup(true);
this.attach(name_label, 0, 1, 0, 1, flags, flags, 0, 0);
this.block_name = block_name;
label = new Gtk.Label("<span font_desc=\"11.0\"><b>" + block_name + "</b></span>");
label.set_use_markup(true);
this.attach(label, 0, 0, 1, 1);
graph = new CookieGraph(blue, grey, white);
graph = new CookieGraph();
graph.margin = 15;
graph.height_request = 90;
graph.width_request = 90;
graph.margin = 15;
this.attach(graph, 0, 1, 1, 2, flags, flags, 0, 0);
this.attach(graph, 0, 1, 1, 1);
application_row = new GraphBlockRow(app_name, blue);
others_row = new GraphBlockRow(_("Others"), grey);
available_row = new GraphBlockRow(_("Available"), white);
application_row = new GraphBlockRow(app_name, "used");
others_row = new GraphBlockRow(_("Others"), "others");
available_row = new GraphBlockRow(_("Available"), "available");
Gtk.Box box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
box.margin = 15;
box.pack_start(application_row);
box.pack_start(others_row);
box.pack_end(available_row);
this.attach(box, 1, 2, 1, 2, flags, flags, 0, 0);
box.margin_left = 15;
box.valign = Align.CENTER;
box.pack_start(application_row, false, false);
box.pack_start(others_row , false, false);
box.pack_start(available_row, false, false);
this.attach(box, 1, 1, 1, 1);
}
public void update(int application_percentages, int other_percentages)
public void update(int processor_core, int application_percentages, int other_percentages)
{
if(processor_core != -1)
{
label.set_text("<span font_desc=\"11.0\"><b>" + block_name + " " + processor_core.to_string() + "</b></span>");
label.use_markup = true;
}
graph.update(application_percentages, other_percentages);
application_row.update(application_percentages);
others_row.update(other_percentages);
others_row.update(other_percentages-application_percentages);
available_row.update(100-other_percentages);
}
}
public class GraphBlockRow : Gtk.Box
{
Gtk.Label value_label;
public GraphBlockRow(string label_text, Gdk.RGBA color)
{
Object(orientation: Gtk.Orientation.HORIZONTAL);
this.spacing = 5;
var color_rectangle = new ColorRectangle(color);
var label = new Gtk.Label(label_text);
label.margin = 5;
value_label = new Gtk.Label("0 %");
this.pack_start(color_rectangle, false, false);
this.pack_start(label, false, true);
this.pack_end(value_label, false, true);
}
public void update(int value)
{
value_label.set_text(value.to_string() + " %");
}
}
public class ColorRectangle : Gtk.DrawingArea
{
public ColorRectangle(Gdk.RGBA color)
{
this.height_request = 17;
this.width_request = 17;
this.valign = Gtk.Align.CENTER;
this.draw.connect ((context) =>
{
int height = this.get_allocated_height ();
int width = this.get_allocated_width ();
double degrees = Math.PI / 180.0;
double x = 0;
double y = 0;
double radius = height / 5;
context.new_sub_path();
context.arc(x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
context.arc(x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
context.arc(x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
context.arc(x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
context.close_path();
Gdk.cairo_set_source_rgba (context, color);
context.fill();
return true;
});
}
}
}
......@@ -25,8 +25,8 @@ namespace Usage {
{
Rg.TableIter iter;
push (out iter, get_monotonic_time ());
iter.set (column_ram_id, (GLib.Application.get_default() as Application).monitor.mem_usage_graph, -1);
iter.set (column_swap_id, (GLib.Application.get_default() as Application).monitor.swap_usage_graph, -1);
iter.set (column_ram_id, (GLib.Application.get_default() as Application).monitor.mem_usage, -1);
iter.set (column_swap_id, (GLib.Application.get_default() as Application).monitor.swap_usage, -1);
return true;
}
......
......@@ -5,6 +5,11 @@ namespace Usage
public class ProcessDialog : Gtk.Dialog
{
private pid_t pid;
GraphBlock processor_graph_block;
GraphBlock memory_graph_block;
GraphBlock disk_graph_block;
GraphBlock downloads_graph_block;
GraphBlock uploads_graph_block;
public ProcessDialog(pid_t pid, string name)
{
......@@ -23,37 +28,48 @@ namespace Usage
private void create_widgets()
{
Gtk.Box content = get_content_area() as Gtk.Box;
Gtk.AttachOptions flags = Gtk.AttachOptions.EXPAND;
Gtk.Table table = new Gtk.Table (2, 3, true);
table.vexpand = true;
Gtk.Grid grid = new Gtk.Grid();
grid.margin_top = 20;
grid.margin_start = 20;
grid.margin_end = 20;
var processor_graph_block = new GraphBlock(_("Processor"), this.title);
var memory_graph_block = new GraphBlock(_("Memory"), this.title);
var disk_graph_block = new GraphBlock(_("Disk I/O"), this.title);
var downloads_graph_block = new GraphBlock(_("Downloads"), this.title);
var uploads_graph_block = new GraphBlock(_("Uploads"), this.title);
processor_graph_block = new GraphBlock(_("Processor"), this.title);
memory_graph_block = new GraphBlock(_("Memory"), this.title);
disk_graph_block = new GraphBlock(_("Disk I/O"), this.title);
downloads_graph_block = new GraphBlock(_("Downloads"), this.title);
uploads_graph_block = new GraphBlock(_("Uploads"), this.title);
table.attach(processor_graph_block, 0, 1, 0, 1, flags, flags, 0, 0);
table.attach(memory_graph_block, 1, 2, 0, 1, flags, flags, 0, 0);
table.attach(disk_graph_block, 2, 3, 0, 1, flags, flags, 0, 0);
table.attach(downloads_graph_block, 0, 1, 1, 2, flags, flags, 0, 0);
table.attach(uploads_graph_block, 1, 2, 1, 2, flags, flags, 0, 0);
content.add(table);
grid.attach(processor_graph_block, 0, 0, 1, 1);
grid.attach(memory_graph_block, 1, 0, 1, 1);
grid.attach(disk_graph_block, 2, 0, 1, 1);
grid.attach(downloads_graph_block, 0, 1, 1, 1);
grid.attach(uploads_graph_block, 1, 1, 1, 1);
content.add(grid);
content.show_all();
int i = 1;
Timeout.add(1000, () => //testing
{
processor_graph_block.update(i, i*2);
i++;
return true;
});
Timeout.add((GLib.Application.get_default() as Application).settings.list_update_cookie_graphs_UI, update);
update();
add_button (_("Stop"), Gtk.ResponseType.HELP).get_style_context().add_class ("destructive-action");
}
private bool update()
{
unowned SystemMonitor monitor = (GLib.Application.get_default() as Application).monitor;
unowned Process data = monitor.get_data_for_pid(pid);
int app_cpu_load = 0;
int app_memory_usage = 0;
if(data != null)
{
app_cpu_load = (int) data.x_cpu_load;
app_memory_usage = (int) data.mem_usage;
}
processor_graph_block.update((int) data.last_processor, app_cpu_load, (int) monitor.x_cpu_load[data.last_processor]);
memory_graph_block.update(-1, app_memory_usage, (int) monitor.mem_usage);
return true;
}
private void connect_signals()
{
this.response.connect (on_response);
......
......@@ -2,7 +2,7 @@ using Gee;
namespace Usage
{
public class ProcessListBox : Gtk.Box //TODO rewrite it to ListBox
public class ProcessListBox : Gtk.Box //TODO rewrite it to ListBox and use model
{
HashTable<string, ProcessRow> process_rows_table;
......@@ -11,7 +11,7 @@ namespace Usage
orientation = Gtk.Orientation.VERTICAL;
process_rows_table = new HashTable<string, ProcessRow>(str_hash, str_equal);
Timeout.add((GLib.Application.get_default() as Application).settings.list_update_interval, update);
Timeout.add((GLib.Application.get_default() as Application).settings.list_update_interval_UI, update);
Timeout.add((GLib.Application.get_default() as Application).settings.first_update_interval, () => //on first load
{
update();
......@@ -26,6 +26,7 @@ namespace Usage
var duplicates = new HashSet<string>();
//TODO move this logic to SystemMonitor!
foreach(unowned Process process in (GLib.Application.get_default() as Application).monitor.get_processes())
{
if(duplicates.contains(process.cmdline))
......
......@@ -2,7 +2,7 @@ using Posix;
namespace Usage
{
public class ProcessRow : Gtk.Box
public class ProcessRow : Gtk.Box //TODO use Row
{
Gtk.Image icon;
Gtk.Label title_label;
......@@ -30,7 +30,7 @@ namespace Usage
this.margin = 0;
this.orientation = Gtk.Orientation.VERTICAL;
var main_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
main_box.margin = 12;
main_box.margin = 10;
load_label = new Gtk.Label(null);
load_label.ellipsize = Pango.EllipsizeMode.END;
load_label.max_width_chars = 30;
......@@ -101,21 +101,41 @@ namespace Usage
app_info = info;
}
bool not_have_icon = false;
if(app_info != null)
{
display_name = app_info.get_display_name();
title_label = new Gtk.Label(display_name);
if(app_info.get_icon() == null)
icon = new Gtk.Image.from_icon_name("system-run-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
not_have_icon = true;
else
icon = new Gtk.Image.from_gicon(app_info.get_icon(), Gtk.IconSize.LARGE_TOOLBAR);
{
var icon_theme = new Gtk.IconTheme();
var icon_info = icon_theme.lookup_by_gicon_for_scale(app_info.get_icon(), 24, 1, Gtk.IconLookupFlags.FORCE_SIZE);
if(icon_info != null)
{
var pixbuf = icon_info.load_icon();
icon = new Gtk.Image.from_pixbuf(pixbuf);
}
else
not_have_icon = true;
}
}
else
{
display_name = cmdline;
title_label = new Gtk.Label(display_name);
icon = new Gtk.Image.from_icon_name("system-run-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
not_have_icon = true;
}
if(not_have_icon)
{
icon = new Gtk.Image.from_icon_name("system-run-symbolic", Gtk.IconSize.BUTTON);
icon.width_request = 24;
icon.height_request = 24;
}
icon.margin_left = 10;
icon.margin_right = 10;
......
......@@ -7,7 +7,9 @@ namespace Usage {
public uint graph_timespan { get; set; default = 15000;}
public uint graph_max_samples { get; set; default = 20; }
public uint graph_update_interval { get { return 1000; }}
public uint list_update_interval { get; set; default = 5000; }
public uint list_update_interval_UI { get; set; default = 5000; }
public uint list_update_cookie_graphs_UI { get; set; default = 1000; }
public uint list_update_interval { get; set; default = 1000; }
public uint first_update_interval { get; set; default = 500; }
}