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

rework resetting item properties on style change #565

Merged
merged 3 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions data/se.sjoerd.Graphs.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@
<key name="hide-unselected" type="b">
<default>false</default>
</key>
<key name="override-item-properties" type="b">
<default>true</default>
</key>
</schema>

<schema id="se.sjoerd.Graphs.figure">
Expand Down
10 changes: 0 additions & 10 deletions data/ui/preferences.blp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ template $GraphsPreferencesWindow : Adw.PreferencesWindow {

Adw.PreferencesPage {
Adw.PreferencesGroup {
title: _("General");

Adw.ComboRow center {
title: _("Center Action Behaviour");
subtitle: _("Which value to center on when performing a center action");
Expand All @@ -25,18 +23,10 @@ template $GraphsPreferencesWindow : Adw.PreferencesWindow {
strings [_("Auto-rename duplicates"), _("Ignore duplicates"), _("Add duplicates"), _("Override existing items")]
};
}
}

Adw.PreferencesGroup {
title: _("Figure");

Adw.SwitchRow hide_unselected {
title: _("Hide Unselected Items");
}

Adw.SwitchRow override_item_properties {
title: _("Override Item Properties on Style Change");
}
}
}
}
2 changes: 1 addition & 1 deletion src/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ def optimize_limits(self):
for direction in ("bottom", "left", "top", "right")
]
for item_ in self:
if item_.__gtype_name__ != "GraphsDataItem":
if not isinstance(item_, item.DataItem):
continue
for index in \
item_.get_xposition() * 2, 1 + item_.get_yposition() * 2:
Expand Down
8 changes: 3 additions & 5 deletions src/edit_item.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from gi.repository import Adw, GObject, Graphs, Gtk

from graphs import ui
from graphs import item, ui

_IGNORELIST = [
"alpha", "color", "item_type", "uuid", "selected", "xdata", "xlabel",
Expand Down Expand Up @@ -52,15 +52,13 @@ def on_select(self, _action, _target):

@Gtk.Template.Callback()
def on_item_change(self, _a, _b):
self.set_title(self.props.item.props.name)
self.set_title(self.props.item.get_name())
for binding in self.props.bindings:
binding.unbind()
self.props.bindings = ui.bind_values_to_object(
self.props.item, self, ignorelist=_IGNORELIST,
)
self.item_group.set_visible(
self.props.item.__gtype_name__ == "GraphsDataItem",
)
self.item_group.set_visible(isinstance(self.props.item, item.DataItem))

@Gtk.Template.Callback()
def on_close(self, _a):
Expand Down
61 changes: 38 additions & 23 deletions src/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,25 @@ def to_dict(item):
return dictionary


class DataItem(Graphs.Item):
class _ItemMixin():
def reset(self, old_style, new_style):
for prop, (key, function) in self._style_properties.items():
old_value = old_style[key]
new_value = new_style[key]
if function is not None:
old_value = function(old_value)
new_value = function(new_value)
if self.get_property(prop) == old_value:
self.set_property(prop, new_value)

def _extract_params(self, style):
return {
prop: style[key] if function is None else function(style[key])
for prop, (key, function) in self._style_properties.items()
}


class DataItem(Graphs.Item, _ItemMixin):
__gtype_name__ = "GraphsDataItem"

xdata = GObject.Property(type=object)
Expand All @@ -34,14 +52,18 @@ class DataItem(Graphs.Item):
markerstyle = GObject.Property(type=int, default=0)
markersize = GObject.Property(type=float, default=7)

_style_properties = {
"linestyle": ("lines.linestyle", misc.LINESTYLES.index),
"linewidth": ("lines.linewidth", None),
"markerstyle": ("lines.marker", misc.MARKERSTYLES.index),
"markersize": ("lines.markersize", None),
}

@classmethod
def new(cls, params, xdata=None, ydata=None, **kwargs):
def new(cls, style, xdata=None, ydata=None, **kwargs):
return cls(
linestyle=misc.LINESTYLES.index(params["lines.linestyle"]),
linewidth=params["lines.linewidth"],
markerstyle=misc.MARKERSTYLES.index(params["lines.marker"]),
markersize=params["lines.markersize"],
xdata=xdata, ydata=ydata, **kwargs,
xdata=xdata, ydata=ydata,
**cls._extract_params(cls, style), **kwargs,
)

def __init__(self, **kwargs):
Expand All @@ -50,16 +72,8 @@ def __init__(self, **kwargs):
if self.get_property(prop) is None:
self.set_property(prop, [])

def reset(self, params):
self.props.linestyle = misc.LINESTYLES.index(params["lines.linestyle"])
self.props.linewidth = params["lines.linewidth"]
self.props.markerstyle = \
misc.MARKERSTYLES.index(params["lines.marker"])
self.props.markersize = params["lines.markersize"]
self.color = "000000"


class TextItem(Graphs.Item):
class TextItem(Graphs.Item, _ItemMixin):
__gtype_name__ = "GraphsTextItem"

xanchor = GObject.Property(type=float, default=0)
Expand All @@ -68,17 +82,18 @@ class TextItem(Graphs.Item):
size = GObject.Property(type=float, default=12)
rotation = GObject.Property(type=int, default=0, minimum=0, maximum=360)

_style_properties = {
"size": ("font.size", None),
"color": ("text.color", None),
}

@classmethod
def new(cls, params, xanchor=0, yanchor=0, text="", **kwargs):
def new(cls, style, xanchor=0, yanchor=0, text="", **kwargs):
return cls(
size=params["font.size"], color=params["text.color"],
xanchor=xanchor, yanchor=yanchor, text=text, **kwargs,
xanchor=xanchor, yanchor=yanchor, text=text,
**cls._extract_params(cls, style), **kwargs,
)

def reset(self, params):
self.props.size = params["font.size"]
self.props.color = params["text.color"]


class FillItem(Graphs.Item):
__gtype_name__ = "GraphsFillItem"
Expand Down
6 changes: 3 additions & 3 deletions src/item_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ def move_down(self, _action, _shortcut):
@Gtk.Template.Callback()
def on_toggle(self, _a, _b):
new_value = self.check_button.get_active()
if self.props.item.props.selected != new_value:
self.props.item.props.selected = new_value
if self.props.item.get_selected() != new_value:
self.props.item.set_selected(new_value)
self.get_application().get_data().add_history_state()

@Gtk.Template.Callback()
Expand All @@ -123,7 +123,7 @@ def on_color_dialog_accept(self, dialog, result):
self.get_application().get_data().add_history_state()

def delete(self, _action, _shortcut):
name = self.props.item.props.name
name = self.props.item.get_name()
self.get_application().get_data().delete_items([self.props.item])
toast = Adw.Toast.new(_("Deleted {name}").format(name=name))
toast.set_button_label("Undo")
Expand Down
1 change: 0 additions & 1 deletion src/migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"export_figure_transparent": ("export-figure", "transparent"),
"handle_duplicates": ("general", "handle-duplicates"),
"hide_unselected": ("general", "hide-unselected"),
"override_style_change": ("general", "override-item-properties"),
"plot_custom_style": ("figure", "custom-style"),
"plot_legend": ("figure", "legend"),
"plot_right_label": ("figure", "right-label"),
Expand Down
20 changes: 10 additions & 10 deletions src/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ def get_data(self, item):
Retrieve item from datadict with start and stop index.
If interaction_mode is set to "SELECT"
"""
xdata = item.xdata
ydata = item.ydata
xdata = item.props.xdata
ydata = item.props.ydata
new_xdata = xdata.copy()
new_ydata = ydata.copy()
start_index = 0
Expand Down Expand Up @@ -71,7 +71,7 @@ def perform_operation(self, callback, *args):
data = self.get_data()
old_limits = data.get_figure_settings().get_limits()
for item in data:
if not item.get_selected() or item.__gtype_name__ != "GraphsDataItem":
if not (item.get_selected() and isinstance(item, DataItem)):
continue
xdata, ydata, start_index, stop_index = get_data(self, item)
if xdata is not None and len(xdata) != 0:
Expand All @@ -80,12 +80,12 @@ def perform_operation(self, callback, *args):
item, xdata, ydata, *args)
if discard:
logging.debug("Discard is true")
item.xdata = new_xdata
item.ydata = new_ydata
item.props.xdata = new_xdata
item.props.ydata = new_ydata
else:
logging.debug("Discard is false")
item.xdata[start_index:stop_index] = new_xdata
item.ydata[start_index:stop_index] = new_ydata
item.props.xdata[start_index:stop_index] = new_xdata
item.props.ydata[start_index:stop_index] = new_ydata
if sort:
logging.debug("Sorting data")
item.xdata, item.ydata = sort_data(item.xdata, item.ydata)
Expand Down Expand Up @@ -176,7 +176,7 @@ def shift(item, xdata, ydata, left_scale, right_scale, items, ranges):
"""
data_list = [
item for item in items
if item.get_selected() and item.__gtype_name__ == "GraphsDataItem"
if item.get_selected() and isinstance(item, DataItem)
]

y_range = ranges[1] if item.get_yposition() else ranges[0]
Expand All @@ -191,7 +191,7 @@ def shift(item, xdata, ydata, left_scale, right_scale, items, ranges):
previous_item = data_list[index - 1]

# Only use selected span when obtaining values to determine shift value
full_xdata = numpy.asarray(data_list[index].xdata)
full_xdata = numpy.asarray(data_list[index].props.xdata)
start = 0
stop = len(data_list[index].ydata)
with contextlib.suppress(IndexError):
Expand Down Expand Up @@ -276,7 +276,7 @@ def combine(self):
"""Combine the selected data into a new data set"""
new_xdata, new_ydata = [], []
for item in self.get_data():
if not item.get_selected() or item.__gtype_name__ != "GraphsDataItem":
if not (item.get_selected() and isinstance(item, DataItem)):
continue
xdata, ydata = get_data(self, item)[:2]
new_xdata.extend(xdata)
Expand Down
3 changes: 0 additions & 3 deletions src/preferences.vala
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ namespace Graphs {
[GtkChild]
public unowned Adw.SwitchRow hide_unselected { get; }

[GtkChild]
public unowned Adw.SwitchRow override_item_properties { get; }

public PreferencesWindow (Application application) {
Object (
application: application,
Expand Down
39 changes: 19 additions & 20 deletions src/styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from gi.repository import Adw, GLib, GObject, Gdk, Gio, Graphs, Gtk, Pango

import graphs
from graphs import style_io, ui, utilities
from graphs import item, style_io, ui, utilities

from matplotlib import RcParams

Expand Down Expand Up @@ -48,7 +48,7 @@ def __init__(self, application: Graphs.Application):
application=application,
style_model=Gio.ListStore.new(Graphs.Style),
)
self._stylenames = []
self._stylenames, self._selected_style_params = [], None
directory = Gio.File.new_for_uri("resource:///se/sjoerd/Graphs/styles")
enumerator = directory.enumerate_children("default::*", 0, None)
for file in map(enumerator.get_child, enumerator):
Expand Down Expand Up @@ -87,13 +87,13 @@ def __init__(self, application: Graphs.Application):
figure_settings.bind_property(
"custom_style", self, "custom_style", 1 | 2,
)
application.get_style_manager().connect(
"notify", self._on_style_select,
)

def on_style_select(_a, _b):
self._on_style_change(True)

application.get_style_manager().connect("notify", on_style_select)
for prop in ("use-custom-style", "custom-style"):
figure_settings.connect(
f"notify::{prop}", self._on_style_select,
)
figure_settings.connect(f"notify::{prop}", on_style_select)
self._on_style_change()

def _add_user_style(
Expand Down Expand Up @@ -165,25 +165,24 @@ def _on_file_change(
and self.props.custom_style == stylename:
self._on_style_change()

def _on_style_select(self, _a, _b) -> None:
settings = self.props.application.get_settings("general")
self._on_style_change(settings.get_boolean("override-item-properties"))

def _on_style_change(self, override: bool = False) -> None:
old_style = self._selected_style_params
self._update_system_style()
self._update_selected_style()
data = self.props.application.get_data()
if override:
if old_style is not None and override:
old_colors = old_style["axes.prop_cycle"].by_key()["color"]
color_cycle = self._selected_style_params[
"axes.prop_cycle"].by_key()["color"]
for item in data:
item.reset(self._selected_style_params)
for item_ in data:
item_.reset(old_style, self._selected_style_params)
count = 0
for item in data:
if item.__gtype_name__ == "GraphsDataItem":
for item_ in data:
if isinstance(item_, item.DataItem) \
and item_.get_color() in old_colors:
if count > len(color_cycle):
count = 0
item.props.color = color_cycle[count]
item_.set_color(color_cycle[count])
count += 1

canvas = graphs.canvas.Canvas(
Expand Down Expand Up @@ -507,8 +506,8 @@ def save_style(self):
if value is not None:
with contextlib.suppress(KeyError):
value = VALUE_DICT[key][value]
for item in STYLE_DICT[key]:
self.style_params[item] = value
for item_ in STYLE_DICT[key]:
self.style_params[item_] = value

# font
font_description = self.font_chooser.get_font_desc()
Expand Down