ui: bind monitor settings to page context

parent be73278c
namespace TunerDisplays { namespace TunerDisplays {
public class MonitorChoiceLoader : Tuner.ChoiceLoader { public class MonitorChoiceLoader : Tuner.ChoiceLoader {
private MonitorSettingsContext context;
public string field { get; set; default = ""; } public string field { get; set; default = ""; }
construct {
context = MonitorSettingsState.current;
}
public override void load(ListStore model) { public override void load(ListStore model) {
switch (field) { switch (field) {
case "mode": case "mode":
...@@ -70,8 +76,8 @@ namespace TunerDisplays { ...@@ -70,8 +76,8 @@ namespace TunerDisplays {
} }
} }
private static void load_modes(ListStore model) { private void load_modes(ListStore model) {
foreach (var mode in MonitorSettingsState.current.monitor.modes) { foreach (var mode in context.monitor.modes) {
add_choice( add_choice(
model, model,
mode.label, mode.label,
...@@ -80,9 +86,9 @@ namespace TunerDisplays { ...@@ -80,9 +86,9 @@ namespace TunerDisplays {
} }
} }
private static void load_resolutions(ListStore model) { private void load_resolutions(ListStore model) {
var values = new Gee.ArrayList<string>(); var values = new Gee.ArrayList<string>();
foreach (var mode in MonitorSettingsState.current.monitor.modes) { foreach (var mode in context.monitor.modes) {
var key = MonitorSettingBinding.resolution_key(mode.width, mode.height); var key = MonitorSettingBinding.resolution_key(mode.width, mode.height);
if (values.contains(key)) if (values.contains(key))
continue; continue;
...@@ -91,8 +97,8 @@ namespace TunerDisplays { ...@@ -91,8 +97,8 @@ namespace TunerDisplays {
} }
} }
private static void load_refresh_rates(ListStore model) { private void load_refresh_rates(ListStore model) {
var monitor = MonitorSettingsState.current.monitor; var monitor = context.monitor;
foreach (var mode in monitor.modes) { foreach (var mode in monitor.modes) {
if (mode.width != monitor.width || mode.height != monitor.height || mode.variable_refresh_rate) if (mode.width != monitor.width || mode.height != monitor.height || mode.variable_refresh_rate)
continue; continue;
...@@ -100,10 +106,12 @@ namespace TunerDisplays { ...@@ -100,10 +106,12 @@ namespace TunerDisplays {
} }
} }
private static void load_scales(ListStore model) { private void load_scales(ListStore model) {
var monitor = context.monitor;
var mode = MonitorSettingBinding.find_best_mode_for_resolution( var mode = MonitorSettingBinding.find_best_mode_for_resolution(
MonitorSettingsState.current.monitor.width, monitor,
MonitorSettingsState.current.monitor.height monitor.width,
monitor.height
); );
if (mode == null) if (mode == null)
return; return;
...@@ -112,8 +120,7 @@ namespace TunerDisplays { ...@@ -112,8 +120,7 @@ namespace TunerDisplays {
add_choice(model, "%.0f%%".printf(scale * 100), "%.3f".printf(scale).replace(",", ".")); add_choice(model, "%.0f%%".printf(scale * 100), "%.3f".printf(scale).replace(",", "."));
} }
private static void load_mirrors(ListStore model) { private void load_mirrors(ListStore model) {
var context = MonitorSettingsState.current;
add_choice(model, _("None"), ""); add_choice(model, _("None"), "");
foreach (var monitor in context.all_monitors) { foreach (var monitor in context.all_monitors) {
if (monitor != context.monitor) if (monitor != context.monitor)
......
namespace TunerDisplays { namespace TunerDisplays {
public class MonitorSettingBinding : Tuner.Binding { public class MonitorSettingBinding : Tuner.Binding {
private MonitorSettingsContext context;
public string field { get; set; default = ""; } public string field { get; set; default = ""; }
public double lower { get; set; default = 0; } public double lower { get; set; default = 0; }
public double upper { get; set; default = 100; } public double upper { get; set; default = 100; }
public double step { get; set; default = 1; } public double step { get; set; default = 1; }
construct {
context = MonitorSettingsState.current;
}
public override Type expected_type { public override Type expected_type {
get { get {
switch (field) { switch (field) {
...@@ -40,7 +46,7 @@ namespace TunerDisplays { ...@@ -40,7 +46,7 @@ namespace TunerDisplays {
} }
public override bool get_value(ref Value value) { public override bool get_value(ref Value value) {
var monitor = MonitorSettingsState.current.monitor; var monitor = context.monitor;
switch (field) { switch (field) {
case "enabled": case "enabled":
...@@ -97,7 +103,6 @@ namespace TunerDisplays { ...@@ -97,7 +103,6 @@ namespace TunerDisplays {
} }
public override void set_value(Value value) { public override void set_value(Value value) {
var context = MonitorSettingsState.current;
var monitor = context.monitor; var monitor = context.monitor;
var repair_layout = affects_layout_size(field); var repair_layout = affects_layout_size(field);
var old_width = monitor.logical_width; var old_width = monitor.logical_width;
...@@ -177,8 +182,8 @@ namespace TunerDisplays { ...@@ -177,8 +182,8 @@ namespace TunerDisplays {
return Math.fabs(old_width - width) > 0.01 || Math.fabs(old_height - height) > 0.01; return Math.fabs(old_width - width) > 0.01 || Math.fabs(old_height - height) > 0.01;
} }
private static string get_string_value(string field) { private string get_string_value(string field) {
var monitor = MonitorSettingsState.current.monitor; var monitor = context.monitor;
switch (field) { switch (field) {
case "mode": case "mode":
return mode_key(monitor.width, monitor.height, monitor.refresh, monitor.variable_refresh_rate); return mode_key(monitor.width, monitor.height, monitor.refresh, monitor.variable_refresh_rate);
...@@ -216,8 +221,7 @@ namespace TunerDisplays { ...@@ -216,8 +221,7 @@ namespace TunerDisplays {
} }
} }
private static void set_string_value(string field, string text) { private void set_string_value(string field, string text) {
var context = MonitorSettingsState.current;
var monitor = context.monitor; var monitor = context.monitor;
switch (field) { switch (field) {
case "mode": case "mode":
...@@ -269,53 +273,54 @@ namespace TunerDisplays { ...@@ -269,53 +273,54 @@ namespace TunerDisplays {
} }
} }
private static void set_variable_refresh(bool active) { private void set_variable_refresh(bool active) {
var monitor = MonitorSettingsState.current.monitor; var monitor = context.monitor;
monitor.variable_refresh_rate = active; monitor.variable_refresh_rate = active;
DisplayMode? mode = active DisplayMode? mode = active
? find_variable_mode_for_resolution(monitor.width, monitor.height) ? find_variable_mode_for_resolution(monitor, monitor.width, monitor.height)
: find_best_fixed_mode_for_resolution(monitor.width, monitor.height); : find_best_fixed_mode_for_resolution(monitor, monitor.width, monitor.height);
if (mode != null) if (mode != null)
apply_mode(mode); apply_mode(monitor, mode);
} }
private static void apply_mode_key(string key) { private void apply_mode_key(string key) {
foreach (var mode in MonitorSettingsState.current.monitor.modes) { var monitor = context.monitor;
foreach (var mode in monitor.modes) {
if (mode_key(mode.width, mode.height, mode.refresh, mode.variable_refresh_rate) == key) { if (mode_key(mode.width, mode.height, mode.refresh, mode.variable_refresh_rate) == key) {
apply_mode(mode); apply_mode(monitor, mode);
return; return;
} }
} }
} }
private static void apply_resolution_key(string key) { private void apply_resolution_key(string key) {
var parts = key.split("x"); var parts = key.split("x");
if (parts.length != 2) if (parts.length != 2)
return; return;
var mode = find_best_mode_for_resolution(int.parse(parts[0]), int.parse(parts[1])); var monitor = context.monitor;
var mode = find_best_mode_for_resolution(monitor, int.parse(parts[0]), int.parse(parts[1]));
if (mode != null) if (mode != null)
apply_mode(mode); apply_mode(monitor, mode);
} }
private static void apply_refresh_key(string key) { private void apply_refresh_key(string key) {
var refresh = double.parse(key); var refresh = double.parse(key);
var monitor = MonitorSettingsState.current.monitor; var monitor = context.monitor;
foreach (var mode in monitor.modes) { foreach (var mode in monitor.modes) {
if (mode.width == monitor.width if (mode.width == monitor.width
&& mode.height == monitor.height && mode.height == monitor.height
&& !mode.variable_refresh_rate && !mode.variable_refresh_rate
&& Math.fabs(mode.refresh - refresh) < 0.02) { && Math.fabs(mode.refresh - refresh) < 0.02) {
apply_mode(mode); apply_mode(monitor, mode);
monitor.variable_refresh_rate = false; monitor.variable_refresh_rate = false;
return; return;
} }
} }
} }
internal static DisplayMode? find_best_mode_for_resolution(int width, int height) { internal static DisplayMode? find_best_mode_for_resolution(MonitorConfig monitor, int width, int height) {
DisplayMode? fallback = null; DisplayMode? fallback = null;
var monitor = MonitorSettingsState.current.monitor;
foreach (var mode in monitor.modes) { foreach (var mode in monitor.modes) {
if (mode.width != width || mode.height != height) if (mode.width != width || mode.height != height)
continue; continue;
...@@ -328,9 +333,9 @@ namespace TunerDisplays { ...@@ -328,9 +333,9 @@ namespace TunerDisplays {
return fallback; return fallback;
} }
internal static DisplayMode? find_best_fixed_mode_for_resolution(int width, int height) { internal static DisplayMode? find_best_fixed_mode_for_resolution(MonitorConfig monitor, int width, int height) {
DisplayMode? fallback = null; DisplayMode? fallback = null;
foreach (var mode in MonitorSettingsState.current.monitor.modes) { foreach (var mode in monitor.modes) {
if (mode.width != width || mode.height != height || mode.variable_refresh_rate) if (mode.width != width || mode.height != height || mode.variable_refresh_rate)
continue; continue;
if (fallback == null || mode.refresh > fallback.refresh) if (fallback == null || mode.refresh > fallback.refresh)
...@@ -339,16 +344,15 @@ namespace TunerDisplays { ...@@ -339,16 +344,15 @@ namespace TunerDisplays {
return fallback; return fallback;
} }
internal static DisplayMode? find_variable_mode_for_resolution(int width, int height) { internal static DisplayMode? find_variable_mode_for_resolution(MonitorConfig monitor, int width, int height) {
foreach (var mode in MonitorSettingsState.current.monitor.modes) { foreach (var mode in monitor.modes) {
if (mode.width == width && mode.height == height && mode.variable_refresh_rate) if (mode.width == width && mode.height == height && mode.variable_refresh_rate)
return mode; return mode;
} }
return null; return null;
} }
internal static void apply_mode(DisplayMode mode) { internal static void apply_mode(MonitorConfig monitor, DisplayMode mode) {
var monitor = MonitorSettingsState.current.monitor;
monitor.width = mode.width; monitor.width = mode.width;
monitor.height = mode.height; monitor.height = mode.height;
monitor.refresh = mode.refresh; monitor.refresh = mode.refresh;
......
namespace TunerDisplays { namespace TunerDisplays {
public class MonitorSettingValidator : Tuner.Validator { public class MonitorSettingValidator : Tuner.Validator {
private MonitorSettingsContext context;
public string feature { get; set; default = ""; } public string feature { get; set; default = ""; }
public string group_feature { get; set; default = ""; } public string group_feature { get; set; default = ""; }
construct {
context = MonitorSettingsState.current;
}
public override void apply(Tuner.Binding binding, Gtk.Widget native_widget) { public override void apply(Tuner.Binding binding, Gtk.Widget native_widget) {
update(native_widget); update(native_widget);
Idle.add(() => { Idle.add(() => {
update(native_widget); update(native_widget);
return false; return false;
}); });
MonitorSettingsState.current.changed.connect(() => update(native_widget)); context.changed.connect(() => update(native_widget));
DisplaysContext.controller.changed.connect(() => update(native_widget)); DisplaysContext.controller.changed.connect(() => update(native_widget));
} }
private void update(Gtk.Widget widget) { private void update(Gtk.Widget widget) {
widget.visible = monitor_feature_visible(feature); widget.visible = monitor_feature_visible(feature, context);
var group = widget.get_ancestor(typeof(Adw.PreferencesGroup)); var group = widget.get_ancestor(typeof(Adw.PreferencesGroup));
if (group != null && group_feature != "") if (group != null && group_feature != "")
group.visible = monitor_feature_visible(group_feature); group.visible = monitor_feature_visible(group_feature, context);
} }
} }
internal static bool monitor_feature_visible(string feature) { internal static bool monitor_feature_visible(string feature, MonitorSettingsContext? settings_context = null) {
var context = MonitorSettingsState.current; var context = settings_context ?? MonitorSettingsState.current;
var backend = context.backend; var backend = context.backend;
var monitor = context.monitor; var monitor = context.monitor;
switch (feature) { switch (feature) {
...@@ -38,9 +44,9 @@ namespace TunerDisplays { ...@@ -38,9 +44,9 @@ namespace TunerDisplays {
case "single-monitor-display": case "single-monitor-display":
return DisplaysContext.controller.single_monitor_mode(); return DisplaysContext.controller.single_monitor_mode();
case "single-monitor-hyprland": case "single-monitor-hyprland":
return DisplaysContext.controller.single_monitor_mode() && monitor_feature_visible("hyprland"); return DisplaysContext.controller.single_monitor_mode() && monitor_feature_visible("hyprland", context);
case "single-monitor-hdr": case "single-monitor-hdr":
return DisplaysContext.controller.single_monitor_mode() && monitor_feature_visible("hdr"); return DisplaysContext.controller.single_monitor_mode() && monitor_feature_visible("hdr", context);
case "combined-mode": case "combined-mode":
return !backend.uses_separate_refresh_rate_controls; return !backend.uses_separate_refresh_rate_controls;
case "separate-refresh": case "separate-refresh":
...@@ -50,11 +56,11 @@ namespace TunerDisplays { ...@@ -50,11 +56,11 @@ namespace TunerDisplays {
case "variable-refresh": case "variable-refresh":
return backend.uses_separate_refresh_rate_controls return backend.uses_separate_refresh_rate_controls
&& monitor.supports_variable_refresh_rate && monitor.supports_variable_refresh_rate
&& MonitorSettingBinding.find_variable_mode_for_resolution(monitor.width, monitor.height) != null; && MonitorSettingBinding.find_variable_mode_for_resolution(monitor, monitor.width, monitor.height) != null;
case "scale-choice": case "scale-choice":
return backend.uses_separate_refresh_rate_controls && selected_mode_has_scales(); return backend.uses_separate_refresh_rate_controls && selected_mode_has_scales(monitor);
case "scale-spin": case "scale-spin":
return !backend.uses_separate_refresh_rate_controls || !selected_mode_has_scales(); return !backend.uses_separate_refresh_rate_controls || !selected_mode_has_scales(monitor);
case "mirror": case "mirror":
return backend.supports_output_mirroring && context.all_monitors.size > 1; return backend.supports_output_mirroring && context.all_monitors.size > 1;
case "adaptive-sync": case "adaptive-sync":
...@@ -91,9 +97,8 @@ namespace TunerDisplays { ...@@ -91,9 +97,8 @@ namespace TunerDisplays {
} }
} }
private static bool selected_mode_has_scales() { private static bool selected_mode_has_scales(MonitorConfig monitor) {
var monitor = MonitorSettingsState.current.monitor; var mode = MonitorSettingBinding.find_best_mode_for_resolution(monitor, monitor.width, monitor.height);
var mode = MonitorSettingBinding.find_best_mode_for_resolution(monitor.width, monitor.height);
return mode != null && mode.supported_scales.size > 0; return mode != null && mode.supported_scales.size > 0;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment