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

New ProcessListBox widget.

parent 12320393
......@@ -36,6 +36,7 @@ set(MODULES_TO_CHECK ${MODULES_TO_CHECK} atk)
set(MODULES_TO_CHECK ${MODULES_TO_CHECK} cairo)
set(MODULES_TO_CHECK ${MODULES_TO_CHECK} gdk-3.0)
set(MODULES_TO_CHECK ${MODULES_TO_CHECK} gdk-pixbuf-2.0)
set(MODULES_TO_CHECK ${MODULES_TO_CHECK} gee-0.8)
set(MODULES_TO_CHECK ${MODULES_TO_CHECK} gio-2.0)
set(MODULES_TO_CHECK ${MODULES_TO_CHECK} glib-2.0)
set(MODULES_TO_CHECK ${MODULES_TO_CHECK} gobject-2.0)
......
No preview for this file type
.processListBoxRow-opened { background: #3b4043; }
.processListBoxRow:hover { background: #4d5356; }
.processListBoxRow { background: #232729; }
.processListBoxRow-hover { background: #4d5356; }
.processListBoxRow-max { background: #8E0000; }
.processListBoxRow-max-opened { background: #b40000; }
.processListBoxRow-max:hover { background: #b40000; }
.processListBoxRow-max-hover { background: #b40000; }
.processDetailListBoxRow { background: #2c3032; }
.processDetailListBoxRow:hover { background: #4d5356; }
row { padding: 0 }
\ No newline at end of file
row { padding: 0 }
.sidebar-buttons {
border-style: none;
background-color: #2b3032;
border-radius: 0;
}
\ No newline at end of file
.processListBoxRow-opened { background: #9c9c9c; }
.processListBoxRow:hover { background: #e2e2e2; }
.processListBoxRow { background: #ffffff; }
.processListBoxRow-hover { background: #e2e2e2; }
.processListBoxRow-max { background: #fabbbb; }
.processListBoxRow-max-opened { background: #faa5a2; }
.processListBoxRow-max:hover { background: #faa5a2; }
.processListBoxRow-max-hover { background: #faa5a2; }
.processDetailListBoxRow { background: #f2f2f2; }
.processDetailListBoxRow:hover { background: #e2e2e2; }
......
......@@ -15,6 +15,7 @@ vala_binary: src/gnome-usage
*vala_check_package: cairo
*vala_check_package: gdk-3.0
*vala_check_package: gdk-pixbuf-2.0
*vala_check_package: gee-0.8
*vala_check_package: gio-2.0
*vala_check_package: glib-2.0
*vala_check_package: gobject-2.0
......@@ -39,6 +40,7 @@ c_library: gtop-2.0 ${CMAKE_SOURCE_DIR}/external/rg/librg.a ${CMAKE_SOURCE_DIR}/
*vala_source: performance-view.vala
*vala_source: power-view.vala
*vala_source: process-list.vala
*vala_source: process-row.vala
*vala_source: settings.vala
*vala_source: storage-view.vala
*vala_source: system-monitor.vala
......@@ -55,7 +57,7 @@ h_folder: /usr/include/libgtop-2.0
translate: c src/better-box.c
*translate: vala src/cpu-graph-table.vala
*translate: vala src/process-list.vala
*translate: vala src/cpu-sub-view.vala
*translate: vala src/application.vala
*translate: vala src/window.vala
*translate: vala src/header-bar.vala
......@@ -64,14 +66,15 @@ translate: c src/better-box.c
*translate: vala src/cpu-graph.vala
*translate: vala src/performance-view.vala
*translate: vala src/memory-graph-table.vala
*translate: vala src/system-monitor.vala
*translate: vala src/process-list.vala
*translate: vala src/view.vala
*translate: vala src/graph-switcher-button.vala
*translate: vala src/disk-sub-view.vala
*translate: vala src/cpu-sub-view.vala
*translate: vala src/graph-stack-switcher.vala
*translate: vala src/gnome-usage.vala
*translate: vala src/graph-switcher-button.vala
*translate: vala src/process-row.vala
*translate: vala src/memory-graph.vala
*translate: vala src/system-monitor.vala
*translate: vala src/settings.vala
*translate: vala src/storage-view.vala
*translate: vala src/power-view.vala
......
......@@ -15,6 +15,7 @@ src/network-sub-view.vala
src/performance-view.vala
src/power-view.vala
src/process-list.vala
src/process-row.vala
src/settings.vala
src/storage-view.vala
src/system-monitor.vala
......
......@@ -27,6 +27,7 @@ set (VALA_PACKAGES ${VALA_PACKAGES} atk)
set (VALA_PACKAGES ${VALA_PACKAGES} cairo)
set (VALA_PACKAGES ${VALA_PACKAGES} gdk-3.0)
set (VALA_PACKAGES ${VALA_PACKAGES} gdk-pixbuf-2.0)
set (VALA_PACKAGES ${VALA_PACKAGES} gee-0.8)
set (VALA_PACKAGES ${VALA_PACKAGES} gio-2.0)
set (VALA_PACKAGES ${VALA_PACKAGES} glib-2.0)
set (VALA_PACKAGES ${VALA_PACKAGES} gobject-2.0)
......@@ -52,6 +53,7 @@ set (APP_SOURCES ${APP_SOURCES} network-sub-view.vala)
set (APP_SOURCES ${APP_SOURCES} performance-view.vala)
set (APP_SOURCES ${APP_SOURCES} power-view.vala)
set (APP_SOURCES ${APP_SOURCES} process-list.vala)
set (APP_SOURCES ${APP_SOURCES} process-row.vala)
set (APP_SOURCES ${APP_SOURCES} settings.vala)
set (APP_SOURCES ${APP_SOURCES} storage-view.vala)
set (APP_SOURCES ${APP_SOURCES} system-monitor.vala)
......
......@@ -2,8 +2,6 @@ namespace Usage
{
public class ProcessorSubView : View
{
ProcessListBox process_list_box;
List<ProcessListBoxRow> process_row_list;
bool show_active_process = true;
public ProcessorSubView()
......@@ -15,8 +13,6 @@ namespace Usage
label.margin_top = 20;
label.margin_bottom = 15;
process_list_box = new ProcessListBox();
var cpu_graph = new CpuGraphAllCores();
var cpu_graph_frame = new Gtk.Frame(null);
cpu_graph_frame.height_request = 225;
......@@ -26,7 +22,8 @@ namespace Usage
var process_list_box_frame = new Gtk.Frame(null);
process_list_box_frame.margin_top = 30;
process_list_box_frame.add(process_list_box);
process_list_box_frame.margin_bottom = 20;
process_list_box_frame.add(new ProcessBox());
var cpu_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
cpu_box.pack_start(label, false, false, 0);
......@@ -43,84 +40,13 @@ namespace Usage
scrolled_window.add(better_box);
scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
construct_menu_button();
add(scrolled_window);
Timeout.add((GLib.Application.get_default() as Application).settings.list_update_interval, update_process);
}
//TODO better management
private bool update_process()
{
process_list_box.foreach((widget) => { widget.destroy(); });
process_row_list = new List<ProcessListBoxRow>();
foreach(unowned Process process in monitor.get_processes())
{
if(show_active_process)
{
if((int) process.cpu_load > 0)
insert_process_row(process);
}
else
insert_process_row(process);
}
for(int i = 0; i < process_row_list.length(); i++)
process_list_box.add(process_row_list.nth_data (i));
return true;
}
private void insert_process_row(Process process)
{
var process_row = new ProcessListBoxRow(process.cmdline,(int) process.cpu_load);
process_row.sort_id =(int)(10 * process.cpu_load);
process_row_list.insert_sorted(process_row,(a, b) => {
return(b as ProcessListBoxRow).sort_id -(a as ProcessListBoxRow).sort_id;
});
}
private void construct_menu_button()
{
var popover_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
popover_box.margin = 7;
var active = new Gtk.RadioButton.with_label_from_widget(null, _("Active process"));
popover_box.pack_start(active, false, false, 0);
active.toggled.connect(() => {
monitor.set_process_mode(SystemMonitor.ProcessMode.ALL);
show_active_process = true;
update_process();
});
var all = new Gtk.RadioButton.with_label_from_widget(active, _("All process"));
popover_box.pack_start(all, false, false, 0);
all.toggled.connect(() => {
show_active_process = false;
monitor.set_process_mode(SystemMonitor.ProcessMode.ALL);
monitor.update_data();
update_process();
});
var my = new Gtk.RadioButton.with_label_from_widget(active, _("My process"));
popover_box.pack_start(my, false, false, 0);
my.toggled.connect(() => {
show_active_process = false;
monitor.set_process_mode(SystemMonitor.ProcessMode.USER);
monitor.update_data();
update_process();
});
popover_box.show_all();
header_bar.set_menu_button(popover_box);
}
public override void update_header_bar()
{
header_bar.clear();
//header_bar.show_menu_button();
header_bar.show_stack_switcher();
}
}
......
......@@ -3,9 +3,7 @@ namespace Usage
{
public class MemorySubView : View
{
ProcessListBox process_list_box;
Gtk.Label memory_load_label;
List<ProcessListBoxRow> process_row_list;
bool show_active_process = true;
public MemorySubView()
......@@ -18,8 +16,6 @@ namespace Usage
label.margin_top = 20;
label.margin_bottom = 15;
process_list_box = new ProcessListBox();
var memory_graph = new MemoryGraph();
var memory_graph_frame = new Gtk.Frame(null);
memory_graph_frame.height_request = 225;
......@@ -29,8 +25,7 @@ namespace Usage
var process_list_box_frame = new Gtk.Frame(null);
process_list_box_frame.margin_top = 30;
process_list_box_frame.add(process_list_box);
var memory_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
memory_box.pack_start(label, false, false, 0);
memory_box.pack_start(memory_graph_frame, false, false, 0);
......@@ -47,41 +42,6 @@ namespace Usage
scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
add(scrolled_window);
Timeout.add(1000, update_process);
}
//TODO better management
private bool update_process()
{
process_list_box.foreach((widget) => { widget.destroy(); });
memory_load_label.set_text(((int) monitor.mem_usage).to_string() + " %");
process_row_list = new List<ProcessListBoxRow>();
foreach(unowned Process process in monitor.get_processes())
{
if(show_active_process)
{
if((int) process.cpu_load > 0)
insert_process_row(process);
}
else
insert_process_row(process);
}
for(int i = 0; i < process_row_list.length(); i++)
process_list_box.add(process_row_list.nth_data (i));
return true;
}
private void insert_process_row(Process process)
{
var process_row = new ProcessListBoxRow(process.cmdline,(int) process.mem_usage);
process_row.sort_id =(int)(10 * process.mem_usage);
process_row_list.insert_sorted(process_row,(a, b) => {
return(b as ProcessListBoxRow).sort_id -(a as ProcessListBoxRow).sort_id;
});
}
public override void update_header_bar()
......
using Gee;
namespace Usage
{
public class ProcessListBoxRow : Gtk.ListBoxRow
public class ProcessListBox : Gtk.ListBox
{
Gtk.Image icon;
Gtk.Label title_label;
Gtk.Label load_label;
Gtk.Revealer revealer;
Gtk.EventBox event_box;
ProcessListBox sub_process_list_box;
public int sort_id;
public bool is_headline { get; private set; }
public bool showing_details { get; private set; }
public bool max_usage { get; private set; }
public ProcessListBoxRow(string title, int load)
public ProcessListBox()
{
if(load >= 90)
max_usage = true;
this.margin = 0;
var main_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
var box_vertical = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
box_vertical.margin = 0;
main_box.margin = 12;
title_label = new Gtk.Label(title);
load_label = new Gtk.Label(load.to_string() + " %");
icon = new Gtk.Image.from_icon_name("dialog-error", Gtk.IconSize.BUTTON); //TODO implement give icon
main_box.pack_start(icon, false, false, 10);
main_box.pack_start(title_label, false, true, 5);
main_box.pack_end(load_label, false, true, 10);
set_selection_mode (Gtk.SelectionMode.NONE);
set_header_func (update_header);
}
sub_process_list_box = new ProcessListBox();
for(int i = 4; i > 0; i--)
private void update_header(Gtk.ListBoxRow row, Gtk.ListBoxRow? before_row)
{
if(before_row == null)
row.set_header(null);
else
{
var row = new ProcessDetailListBoxRow("Title " + i.to_string(), 50); //TODO realy values
sub_process_list_box.insert(row, 0);
}
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
separator.show();
row.set_header(separator);
}
}
}
revealer = new Gtk.Revealer();
revealer.add(sub_process_list_box);
public class ProcessBox : Gtk.Box
{
private Gee.ArrayList<ProcessRow> rows;
event_box = new Gtk.EventBox();
event_box.add(main_box);
HashTable<uint, ProcessRow> process_rows_table;
event_box.button_press_event.connect ((event) => {
switch_details();
return false;
});
public ProcessBox()
{
orientation = Gtk.Orientation.VERTICAL;
rows = new Gee.ArrayList<ProcessRow>();
process_rows_table = new HashTable<uint, ProcessRow>(direct_hash, direct_equal);
box_vertical.pack_start(event_box, false, true, 0);
box_vertical.pack_end(revealer, false, true, 0);
Timeout.add((GLib.Application.get_default() as Application).settings.list_update_interval, () =>
{
update();
return true;
});
add(box_vertical);
style(false);
show_all();
}
private void style(bool opened)
public void update()
{
if(max_usage)
foreach(ProcessRow row in rows)
row.alive = false;
foreach(unowned Process process in (GLib.Application.get_default() as Application).monitor.get_processes())
{
if(opened)
if(!(process.pid in process_rows_table))
{
this.get_style_context().remove_class("processListBoxRow-max");
this.get_style_context().add_class("processListBoxRow-max-opened");
if((int) process.cpu_load > 0)
{
ProcessRow row = new ProcessRow(process.pid, (int) process.cpu_load, process.cmdline);
rows.add(row);
process_rows_table.insert (process.pid, row);
}
}
else
{
this.get_style_context().remove_class("processListBoxRow-max-opened");
this.get_style_context().add_class("processListBoxRow-max");
if((int) process.cpu_load > 0)
{
unowned ProcessRow row = process_rows_table[process.pid];
row.alive = true;
row.set_value((int) process.cpu_load);
}
else
{
unowned ProcessRow row = process_rows_table[process.pid];
rows.remove(row);
process_rows_table.remove(process.pid);
}
}
}
else
sort();
this.forall ((element) => this.remove (element)); //clear box
for(int i = 0; i < rows.size; i++)
{
if(opened)
if(rows[i].alive)
{
this.get_style_context().remove_class("processListBoxRow");
this.get_style_context().add_class("processListBoxRow-opened");
this.add(rows[i]);
}
else
{
this.get_style_context().remove_class("processListBoxRow-opened");
this.get_style_context().add_class("processListBoxRow");
process_rows_table.remove(rows[i].get_pid());
rows.remove(rows[i]);
}
}
}
private void hide_details()
{
showing_details = false;
revealer.set_reveal_child(false);
load_label.visible = true;
style(false);
}
private void show_details()
{
showing_details = true;
revealer.set_reveal_child(true);
load_label.visible = false;
style(true);
}
private void switch_details()
{
if(showing_details)
hide_details();
else
show_details();
}
}
public class ProcessListBox : Gtk.ListBox
{
public ProcessListBox()
{
set_selection_mode (Gtk.SelectionMode.NONE);
set_header_func (update_header);
}
private void update_header(Gtk.ListBoxRow row, Gtk.ListBoxRow? before_row)
public void sort()
{
if(before_row == null)
row.set_header(null);
else
{
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
separator.show();
row.set_header(separator);
}
rows.sort((a, b) => {
return(b as ProcessRow).get_value() - ( a as ProcessRow).get_value();
});
}
}
......
namespace Usage
{
public class ProcessRow : Gtk.Box
{
Gtk.Image icon;
Gtk.Label title_label;
Gtk.Label load_label;
Gtk.Revealer revealer;
Gtk.EventBox event_box;
ProcessListBox sub_process_list_box; //TODO subprocess
bool in_box = false;
/*private Gee.ArrayList<String> names;
private Gee.ArrayList<int> values;
public Gee.ArrayList<uint> pids;*/
private uint pid;
private int value;
string name;
public bool alive = true;
//public bool is_headline { get; private set; }
public bool showing_details { get; private set; }
public bool max_usage { get; private set; }
public ProcessRow(/*Gee.ArrayList<uint> pids, Gee.ArrayList<int> values, Gee.ArrayList<int> values*/uint pid, int value, string name)
{
/*this.pids = pids;
this.names = names;
this.values = values;*/
this.pid = pid;
this.name = name;
this.margin = 0;
this.orientation = Gtk.Orientation.VERTICAL;
var main_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
main_box.margin = 12;
title_label = new Gtk.Label(name); //TODO implement give name
load_label = new Gtk.Label(null);
icon = new Gtk.Image.from_icon_name("dialog-error", Gtk.IconSize.BUTTON); //TODO implement give icon
main_box.pack_start(icon, false, false, 10);
main_box.pack_start(title_label, false, true, 5);
main_box.pack_end(load_label, false, true, 10);
sub_process_list_box = new ProcessListBox();
for(int i = 4; i > 0; i--)
{
var row = new ProcessDetailListBoxRow("Title " + i.to_string(), 50); //TODO realy values
sub_process_list_box.insert(row, 0);
}
revealer = new Gtk.Revealer();
revealer.add(sub_process_list_box);
event_box = new Gtk.EventBox();
event_box.add(main_box);
event_box.button_press_event.connect ((event) => {
switch_details();
return false;
});
event_box.enter_notify_event.connect ((event) => {
in_box = true;
style();
return false;
});
event_box.leave_notify_event.connect ((event) => {
in_box = false;
style();
return false;
});
var separator = new Gtk.Separator(Gtk.Orientation.VERTICAL);
this.pack_start(event_box, false, true, 0);
this.pack_end(revealer, false, true, 0);
this.pack_end(separator, false, true, 0);// TODO Fix for last element
set_value(value);
show_all();
}
public uint get_pid()
{
return pid;
}
public int get_value()
{
return value;
}
public void set_value(int value)
{
this.value = int.min(value, 100);
update();
}
private void update()
{
if(value >= 90)
max_usage = true;
else
max_usage = false;
load_label.set_label(value.to_string() + "%");
style();
}
private void style()
{
if(max_usage)
{
event_box.get_style_context().remove_class("processListBoxRow");
event_box.get_style_context().remove_class("processListBoxRow-hover");