ui: bind monitor settings to page context

parent be73278c
namespace TunerDisplays {
public class MonitorChoiceLoader : Tuner.ChoiceLoader {
private MonitorSettingsContext context;
public string field { get; set; default = ""; }
construct {
context = MonitorSettingsState.current;
}
public override void load(ListStore model) {
switch (field) {
case "mode":
......@@ -70,8 +76,8 @@ namespace TunerDisplays {
}
}
private static void load_modes(ListStore model) {
foreach (var mode in MonitorSettingsState.current.monitor.modes) {
private void load_modes(ListStore model) {
foreach (var mode in context.monitor.modes) {
add_choice(
model,
mode.label,
......@@ -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>();
foreach (var mode in MonitorSettingsState.current.monitor.modes) {
foreach (var mode in context.monitor.modes) {
var key = MonitorSettingBinding.resolution_key(mode.width, mode.height);
if (values.contains(key))
continue;
......@@ -91,8 +97,8 @@ namespace TunerDisplays {
}
}
private static void load_refresh_rates(ListStore model) {
var monitor = MonitorSettingsState.current.monitor;
private void load_refresh_rates(ListStore model) {
var monitor = context.monitor;
foreach (var mode in monitor.modes) {
if (mode.width != monitor.width || mode.height != monitor.height || mode.variable_refresh_rate)
continue;
......@@ -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(
MonitorSettingsState.current.monitor.width,
MonitorSettingsState.current.monitor.height
monitor,
monitor.width,
monitor.height
);
if (mode == null)
return;
......@@ -112,8 +120,7 @@ namespace TunerDisplays {
add_choice(model, "%.0f%%".printf(scale * 100), "%.3f".printf(scale).replace(",", "."));
}
private static void load_mirrors(ListStore model) {
var context = MonitorSettingsState.current;
private void load_mirrors(ListStore model) {
add_choice(model, _("None"), "");
foreach (var monitor in context.all_monitors) {
if (monitor != context.monitor)
......
namespace TunerDisplays {
public class MonitorSettingBinding : Tuner.Binding {
private MonitorSettingsContext context;
public string field { get; set; default = ""; }
public double lower { get; set; default = 0; }
public double upper { get; set; default = 100; }
public double step { get; set; default = 1; }
construct {
context = MonitorSettingsState.current;
}
public override Type expected_type {
get {
switch (field) {
......@@ -40,7 +46,7 @@ namespace TunerDisplays {
}
public override bool get_value(ref Value value) {
var monitor = MonitorSettingsState.current.monitor;
var monitor = context.monitor;
switch (field) {
case "enabled":
......@@ -97,7 +103,6 @@ namespace TunerDisplays {
}
public override void set_value(Value value) {
var context = MonitorSettingsState.current;
var monitor = context.monitor;
var repair_layout = affects_layout_size(field);
var old_width = monitor.logical_width;
......@@ -177,8 +182,8 @@ namespace TunerDisplays {
return Math.fabs(old_width - width) > 0.01 || Math.fabs(old_height - height) > 0.01;
}
private static string get_string_value(string field) {
var monitor = MonitorSettingsState.current.monitor;
private string get_string_value(string field) {
var monitor = context.monitor;
switch (field) {
case "mode":
return mode_key(monitor.width, monitor.height, monitor.refresh, monitor.variable_refresh_rate);
......@@ -216,8 +221,7 @@ namespace TunerDisplays {
}
}
private static void set_string_value(string field, string text) {
var context = MonitorSettingsState.current;
private void set_string_value(string field, string text) {
var monitor = context.monitor;
switch (field) {
case "mode":
......@@ -269,53 +273,54 @@ namespace TunerDisplays {
}
}
private static void set_variable_refresh(bool active) {
var monitor = MonitorSettingsState.current.monitor;
private void set_variable_refresh(bool active) {
var monitor = context.monitor;
monitor.variable_refresh_rate = active;
DisplayMode? mode = active
? find_variable_mode_for_resolution(monitor.width, monitor.height)
: find_best_fixed_mode_for_resolution(monitor.width, monitor.height);
? find_variable_mode_for_resolution(monitor, monitor.width, monitor.height)
: find_best_fixed_mode_for_resolution(monitor, monitor.width, monitor.height);
if (mode != null)
apply_mode(mode);
apply_mode(monitor, mode);
}
private static void apply_mode_key(string key) {
foreach (var mode in MonitorSettingsState.current.monitor.modes) {
private void apply_mode_key(string key) {
var monitor = context.monitor;
foreach (var mode in monitor.modes) {
if (mode_key(mode.width, mode.height, mode.refresh, mode.variable_refresh_rate) == key) {
apply_mode(mode);
apply_mode(monitor, mode);
return;
}
}
}
private static void apply_resolution_key(string key) {
private void apply_resolution_key(string key) {
var parts = key.split("x");
if (parts.length != 2)
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)
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 monitor = MonitorSettingsState.current.monitor;
var monitor = context.monitor;
foreach (var mode in monitor.modes) {
if (mode.width == monitor.width
&& mode.height == monitor.height
&& !mode.variable_refresh_rate
&& Math.fabs(mode.refresh - refresh) < 0.02) {
apply_mode(mode);
apply_mode(monitor, mode);
monitor.variable_refresh_rate = false;
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;
var monitor = MonitorSettingsState.current.monitor;
foreach (var mode in monitor.modes) {
if (mode.width != width || mode.height != height)
continue;
......@@ -328,9 +333,9 @@ namespace TunerDisplays {
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;
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)
continue;
if (fallback == null || mode.refresh > fallback.refresh)
......@@ -339,16 +344,15 @@ namespace TunerDisplays {
return fallback;
}
internal static DisplayMode? find_variable_mode_for_resolution(int width, int height) {
foreach (var mode in MonitorSettingsState.current.monitor.modes) {
internal static DisplayMode? find_variable_mode_for_resolution(MonitorConfig monitor, int width, int height) {
foreach (var mode in monitor.modes) {
if (mode.width == width && mode.height == height && mode.variable_refresh_rate)
return mode;
}
return null;
}
internal static void apply_mode(DisplayMode mode) {
var monitor = MonitorSettingsState.current.monitor;
internal static void apply_mode(MonitorConfig monitor, DisplayMode mode) {
monitor.width = mode.width;
monitor.height = mode.height;
monitor.refresh = mode.refresh;
......
namespace TunerDisplays {
public class MonitorSettingValidator : Tuner.Validator {
private MonitorSettingsContext context;
public string 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) {
update(native_widget);
Idle.add(() => {
update(native_widget);
return false;
});
MonitorSettingsState.current.changed.connect(() => update(native_widget));
context.changed.connect(() => update(native_widget));
DisplaysContext.controller.changed.connect(() => update(native_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));
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) {
var context = MonitorSettingsState.current;
internal static bool monitor_feature_visible(string feature, MonitorSettingsContext? settings_context = null) {
var context = settings_context ?? MonitorSettingsState.current;
var backend = context.backend;
var monitor = context.monitor;
switch (feature) {
......@@ -38,9 +44,9 @@ namespace TunerDisplays {
case "single-monitor-display":
return DisplaysContext.controller.single_monitor_mode();
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":
return DisplaysContext.controller.single_monitor_mode() && monitor_feature_visible("hdr");
return DisplaysContext.controller.single_monitor_mode() && monitor_feature_visible("hdr", context);
case "combined-mode":
return !backend.uses_separate_refresh_rate_controls;
case "separate-refresh":
......@@ -50,11 +56,11 @@ namespace TunerDisplays {
case "variable-refresh":
return backend.uses_separate_refresh_rate_controls
&& 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":
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":
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":
return backend.supports_output_mirroring && context.all_monitors.size > 1;
case "adaptive-sync":
......@@ -91,9 +97,8 @@ namespace TunerDisplays {
}
}
private static bool selected_mode_has_scales() {
var monitor = MonitorSettingsState.current.monitor;
var mode = MonitorSettingBinding.find_best_mode_for_resolution(monitor.width, monitor.height);
private static bool selected_mode_has_scales(MonitorConfig monitor) {
var mode = MonitorSettingBinding.find_best_mode_for_resolution(monitor, monitor.width, monitor.height);
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