Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add column for checkboxes/radiobuttons/menu icons #32

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
124 changes: 123 additions & 1 deletion src/Command.vala
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,45 @@ namespace Plotinus {
}

public abstract void execute();

public virtual bool is_active() {
return false;
}

public virtual Gtk.ButtonRole get_check_type() {
return Gtk.ButtonRole.NORMAL;
}

[DBus(visible=false)]
public virtual bool set_image(Gtk.CellRendererPixbuf cell) {
return false;
}

protected bool set_image_from_widget(Gtk.CellRendererPixbuf cell, Gtk.Widget? widget) {
if(widget == null || !(widget is Gtk.Image))
return false;

var image = widget as Gtk.Image;

cell.stock_size = Gtk.IconSize.MENU;

switch(image.get_storage_type()) {
case Gtk.ImageType.PIXBUF:
cell.pixbuf = image.pixbuf;
return true;
case Gtk.ImageType.ICON_NAME:
cell.icon_name = image.icon_name;
return true;
case Gtk.ImageType.GICON:
cell.gicon = image.gicon;
return true;
case Gtk.ImageType.STOCK:
cell.stock_id = image.stock;
return true;
default:
return false;
}
}
}

class SignalCommand : Command {
Expand All @@ -45,16 +84,48 @@ namespace Plotinus {
class ActionCommand : Command {
private Action action;
private Variant? parameter;
private Variant? icon;

public ActionCommand(string[] path, string label, string[] accelerators, Action action, Variant? parameter) {
public ActionCommand(string[] path, string label, string[] accelerators, Action action, Variant? parameter, Variant? icon) {
base(path, label, accelerators);
this.action = action;
this.parameter = parameter;
this.icon = icon;
}

public override void execute() {
action.activate(parameter);
}

public override bool is_active() {
switch(get_check_type()) {
case Gtk.ButtonRole.RADIO:
return parameter.equal(action.get_state());
case Gtk.ButtonRole.CHECK:
return action.get_state().get_boolean();
default:
return false;
}
}

public override Gtk.ButtonRole get_check_type() {
if(parameter != null && action.get_state() != null)
return Gtk.ButtonRole.RADIO;

if(action.get_state_type() != null && VariantType.BOOLEAN.equal(action.get_state_type()))
return Gtk.ButtonRole.CHECK;

return Gtk.ButtonRole.NORMAL;
}

public override bool set_image(Gtk.CellRendererPixbuf cell) {
if(this.icon == null)
return base.set_image(cell);

var icon = Icon.deserialize(this.icon);
cell.gicon = icon;
return true;
}
}

class MenuItemCommand : Command {
Expand All @@ -68,6 +139,36 @@ namespace Plotinus {
public override void execute() {
menu_item.activate();
}

public override bool is_active() {
if(get_check_type() != Gtk.ButtonRole.NORMAL)
return (menu_item as Gtk.CheckMenuItem).active;

return false;
}
public override Gtk.ButtonRole get_check_type() {
if(menu_item is Gtk.CheckMenuItem) {
var checkable = menu_item as Gtk.CheckMenuItem;
if((menu_item is Gtk.RadioMenuItem) || checkable.draw_as_radio)
return Gtk.ButtonRole.RADIO;

return Gtk.ButtonRole.CHECK;
}

return Gtk.ButtonRole.NORMAL;
}

public override bool set_image(Gtk.CellRendererPixbuf cell) {
if(!(menu_item is Gtk.ImageMenuItem))
return base.set_image(cell);

var image_menu_item = menu_item as Gtk.ImageMenuItem;
if(!(image_menu_item.always_show_image || Gtk.Settings.get_default().gtk_menu_images))
return base.set_image(cell);

var widget = image_menu_item.get_image();
return base.set_image_from_widget(cell, widget);
}
}

class ButtonCommand : Command {
Expand All @@ -81,6 +182,27 @@ namespace Plotinus {
public override void execute() {
button.clicked();
}

public override bool is_active() {
if(get_check_type() != Gtk.ButtonRole.NORMAL)
return (button as Gtk.CheckButton).active;

return false;
}

public override Gtk.ButtonRole get_check_type() {
if(button is Gtk.RadioButton)
return Gtk.ButtonRole.RADIO;

if(button is Gtk.CheckButton)
return Gtk.ButtonRole.CHECK;

return Gtk.ButtonRole.NORMAL;
}

public override bool set_image(Gtk.CellRendererPixbuf cell) {
return base.set_image_from_widget(cell, button.get_image());
}
}

}
10 changes: 9 additions & 1 deletion src/CommandExtractor.vala
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,19 @@ class Plotinus.CommandExtractor : Object {
var action_value = menu_model.get_item_attribute_value(i, Menu.ATTRIBUTE_ACTION, VariantType.STRING);
var action_name = (action_value != null) ? action_value.get_string() : null;
var action = (action_name != null) ? get_action(action_name) : null;
var icon = menu_model.get_item_attribute_value(i, Menu.ATTRIBUTE_ICON, null);

if(icon == null) {
var verb = menu_model.get_item_attribute_value(i, "verb-icon", VariantType.STRING);
if(verb != null) {
icon = (Icon.new_for_string(verb.get_string())).serialize();
}
}

if (label != null && label != "" && action != null && action.enabled) {
var accelerators = (application != null) ? application.get_accels_for_action(action_name) : new string[0];
var target = menu_model.get_item_attribute_value(i, Menu.ATTRIBUTE_TARGET, null);
commands += new ActionCommand(path, label, accelerators, action, target);
commands += new ActionCommand(path, label, accelerators, action, target, icon);
}

var link_iterator = menu_model.iterate_item_links(i);
Expand Down
32 changes: 28 additions & 4 deletions src/CommandList.vala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,30 @@ class Plotinus.CommandList : Gtk.TreeView {
}
}

private class IconColumn : Gtk.TreeViewColumn {
public IconColumn() {
var toggle_renderer = new Gtk.CellRendererToggle();
var pixbuf_renderer = new Gtk.CellRendererPixbuf();

pack_start(toggle_renderer, false);
pack_start(pixbuf_renderer, false);

set_cell_data_func(toggle_renderer, (cell_layout, cell, tree_model, tree_iter) => {
var toggle = (cell as Gtk.CellRendererToggle);
var command = get_iter_command(tree_model, tree_iter);
toggle.visible = command.get_check_type() != Gtk.ButtonRole.NORMAL;
toggle.radio = command.get_check_type() == Gtk.ButtonRole.RADIO;
toggle.active = command.is_active();
});

set_cell_data_func(pixbuf_renderer, (cell_layout, cell, tree_model, tree_iter) => {
var pixbuf = (cell as Gtk.CellRendererPixbuf);
var command = get_iter_command(tree_model, tree_iter);
pixbuf.visible = command.set_image(pixbuf);
});
}
}

private const string COLUMN_PADDING = " ";

private string filter = "";
Expand Down Expand Up @@ -70,17 +94,17 @@ class Plotinus.CommandList : Gtk.TreeView {
text_color.alpha = 0.4;
append_column(new ListColumn((command) => {
return COLUMN_PADDING +
highlight_words(string.joinv(" \u25B6 ", command.path), filter_words) +
COLUMN_PADDING;
highlight_words(string.joinv(" \u25B6 ", command.path), filter_words);
}, true, text_color));

append_column(new IconColumn());

append_column(new ListColumn((command) => {
return highlight_words(command.label, filter_words);
}, false, null, 1.4));

append_column(new ListColumn((command) => {
return COLUMN_PADDING +
Markup.escape_text(string.joinv(", ", map_string(command.accelerators, format_accelerator))) +
return Markup.escape_text(string.joinv(", ", map_string(command.accelerators, format_accelerator))) +
COLUMN_PADDING;
}, true, selection_color));
});
Expand Down