Add more controls, fix vertical wrapping, add automatic wrap support
This commit is contained in:
parent
5f66019580
commit
449620a1b1
|
|
@ -51,6 +51,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
this._monitor_wrapping_scheme_binding = null;
|
||||
this._viewport_offset_x_binding = null;
|
||||
this._viewport_offset_y_binding = null;
|
||||
this._monitor_spacing_binding = null;
|
||||
this._distance_connection = null;
|
||||
this._follow_threshold_connection = null;
|
||||
this._widescreen_mode_settings_connection = null;
|
||||
|
|
@ -333,6 +334,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
this._monitor_wrapping_scheme_binding = this.settings.bind('monitor-wrapping-scheme', this._overlay_content, 'monitor-wrapping-scheme', Gio.SettingsBindFlags.DEFAULT);
|
||||
this._viewport_offset_x_binding = this.settings.bind('viewport-offset-x', this._overlay_content, 'viewport-offset-x', Gio.SettingsBindFlags.DEFAULT);
|
||||
this._viewport_offset_y_binding = this.settings.bind('viewport-offset-y', this._overlay_content, 'viewport-offset-y', Gio.SettingsBindFlags.DEFAULT);
|
||||
this._monitor_spacing_binding = this.settings.bind('monitor-spacing', this._overlay_content, 'monitor-spacing', Gio.SettingsBindFlags.DEFAULT);
|
||||
this._distance_binding = this.settings.bind('display-distance', this._overlay_content, 'display-distance', Gio.SettingsBindFlags.DEFAULT);
|
||||
this._distance_connection = this.settings.connect('changed::display-distance', this._update_display_distance.bind(this));
|
||||
this._follow_threshold_connection = this.settings.connect('changed::follow-threshold', this._update_follow_threshold.bind(this));
|
||||
|
|
@ -598,6 +600,10 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
this.settings.unbind(this._distance_binding);
|
||||
this._distance_binding = null;
|
||||
}
|
||||
if (this._monitor_spacing_binding) {
|
||||
this.settings.unbind(this._monitor_spacing_binding);
|
||||
this._monitor_spacing_binding = null;
|
||||
}
|
||||
if (this._viewport_offset_x_binding) {
|
||||
this.settings.unbind(this._viewport_offset_x_binding);
|
||||
this._viewport_offset_x_binding = null;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ function degreesToRadians(degrees) {
|
|||
/***
|
||||
* @returns {Object} - containing `start`, `center`, and `end` radians for rotating the given monitor
|
||||
*/
|
||||
function monitorWrap(cachedMonitorWrap, radiusPixels, monitorBeginPixel, monitorLengthPixels) {
|
||||
function monitorWrap(cachedMonitorWrap, radiusPixels, monitorSpacingPixels, monitorBeginPixel, monitorLengthPixels) {
|
||||
let closestWrap = cachedMonitorWrap.reduce((previous, current) => {
|
||||
return (!previous || Math.abs(current.pixel - monitorBeginPixel) < Math.abs(previous.pixel - monitorBeginPixel)) ? current : previous;
|
||||
}, undefined);
|
||||
|
|
@ -84,8 +84,9 @@ function monitorWrap(cachedMonitorWrap, radiusPixels, monitorBeginPixel, monitor
|
|||
cachedMonitorWrap.push(closestWrap);
|
||||
}
|
||||
|
||||
const spacingRadians = monitorBeginPixel === 0 ? 0 : Math.asin(monitorSpacingPixels / 2 / radiusPixels);
|
||||
const monitorHalfRadians = Math.asin(monitorLengthPixels / 2 / radiusPixels);
|
||||
const centerRadians = closestWrap.radians + monitorHalfRadians;
|
||||
const centerRadians = closestWrap.radians + spacingRadians + monitorHalfRadians;
|
||||
const endRadians = centerRadians + monitorHalfRadians;
|
||||
|
||||
// since we're computing the end values for this monitor, cache them too in case they line up with a future monitor
|
||||
|
|
@ -107,7 +108,7 @@ function monitorWrap(cachedMonitorWrap, radiusPixels, monitorBeginPixel, monitor
|
|||
* @returns {Object[]} - contains NWU vectors pointing to `topLeftNoRotate` and `center` of each monitor
|
||||
* and a `rotation` angle for the given wrapping scheme
|
||||
*/
|
||||
function monitorsToPlacements(fovDetails, monitorDetailsList, monitorWrappingScheme) {
|
||||
function monitorsToPlacements(fovDetails, monitorDetailsList, monitorWrappingScheme, monitorSpacing) {
|
||||
const aspect = fovDetails.widthPixels / fovDetails.heightPixels;
|
||||
const fovVerticalRadians = degreesToRadians(fovDetails.fovDegrees / Math.sqrt(1 + aspect * aspect));
|
||||
|
||||
|
|
@ -126,7 +127,7 @@ function monitorsToPlacements(fovDetails, monitorDetailsList, monitorWrappingSch
|
|||
|
||||
cachedMonitorWrap.push({ pixel: 0, radians: -fovHorizontalRadians / 2 });
|
||||
monitorDetailsList.forEach(monitorDetails => {
|
||||
const monitorWrapDetails = monitorWrap(cachedMonitorWrap, edgeRadius, monitorDetails.x, monitorDetails.width);
|
||||
const monitorWrapDetails = monitorWrap(cachedMonitorWrap, edgeRadius, monitorSpacing * fovDetails.widthPixels, monitorDetails.x, monitorDetails.width);
|
||||
const monitorCenterRadius = Math.sqrt(Math.pow(edgeRadius, 2) - Math.pow(monitorDetails.width / 2, 2))
|
||||
|
||||
monitorPlacements.push({
|
||||
|
|
@ -145,7 +146,10 @@ function monitorsToPlacements(fovDetails, monitorDetailsList, monitorWrappingSch
|
|||
// up is flat when wrapping horizontally
|
||||
-(monitorDetails.y + monitorDetails.height / 2 - fovDetails.heightPixels / 2)
|
||||
],
|
||||
rotationAngleRadians: -monitorWrapDetails.center
|
||||
rotationAngleRadians: {
|
||||
x: 0,
|
||||
y: -monitorWrapDetails.center
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (monitorWrappingScheme === 'vertical') {
|
||||
|
|
@ -156,14 +160,14 @@ function monitorsToPlacements(fovDetails, monitorDetailsList, monitorWrappingSch
|
|||
|
||||
cachedMonitorWrap.push({ pixel: 0, radians: -fovVerticalRadians / 2 });
|
||||
monitorDetailsList.forEach(monitorDetails => {
|
||||
const monitorWrapDetails = monitorWrap(cachedMonitorWrap, edgeRadius, monitorDetails.y, monitorDetails.height);
|
||||
const monitorWrapDetails = monitorWrap(cachedMonitorWrap, edgeRadius, monitorSpacing * fovDetails.heightPixels, monitorDetails.y, monitorDetails.height);
|
||||
const monitorCenterRadius = Math.sqrt(Math.pow(edgeRadius, 2) - Math.pow(monitorDetails.height / 2, 2)) ;
|
||||
|
||||
monitorPlacements.push({
|
||||
topLeftNoRotate: [
|
||||
monitorCenterRadius,
|
||||
-monitorDetails.x,
|
||||
-(monitorDetails.height - fovDetails.heightPixels) / 2
|
||||
monitorDetails.x,
|
||||
(monitorDetails.height - fovDetails.heightPixels) / 2
|
||||
],
|
||||
center: [
|
||||
// north is adjacent where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
||||
|
|
@ -175,7 +179,10 @@ function monitorsToPlacements(fovDetails, monitorDetailsList, monitorWrappingSch
|
|||
// up is opposite where radius is the hypotenuse, using monitorWrapDetails.center as the radians
|
||||
-monitorCenterRadius * Math.sin(monitorWrapDetails.center)
|
||||
],
|
||||
rotationAngleRadians: -monitorWrapDetails.center
|
||||
rotationAngleRadians: {
|
||||
x: -monitorWrapDetails.center,
|
||||
y: 0
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
|
@ -184,7 +191,7 @@ function monitorsToPlacements(fovDetails, monitorDetailsList, monitorWrappingSch
|
|||
monitorPlacements.push({
|
||||
topLeftNoRotate: [
|
||||
centerRadius,
|
||||
-monitorDetails.x,
|
||||
monitorDetails.x,
|
||||
-monitorDetails.y
|
||||
],
|
||||
center: [
|
||||
|
|
@ -192,7 +199,10 @@ function monitorsToPlacements(fovDetails, monitorDetailsList, monitorWrappingSch
|
|||
-(monitorDetails.x + monitorDetails.width / 2 - fovDetails.widthPixels / 2),
|
||||
-(monitorDetails.y + monitorDetails.height / 2 - fovDetails.heightPixels / 2)
|
||||
],
|
||||
rotationAngleRadians: 0
|
||||
rotationAngleRadians: {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -266,13 +276,6 @@ export const VirtualMonitorEffect = GObject.registerClass({
|
|||
GObject.ParamFlags.READWRITE,
|
||||
1, 10000, 1080
|
||||
),
|
||||
'monitor-wrapping-scheme': GObject.ParamSpec.string(
|
||||
'monitor-wrapping-scheme',
|
||||
'Monitor Wrapping Scheme',
|
||||
'How the monitors are wrapped around the viewport',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
'horizontal', ['horizontal', 'vertical', 'none']
|
||||
),
|
||||
'focused-monitor-index': GObject.ParamSpec.int(
|
||||
'focused-monitor-index',
|
||||
'Focused Monitor Index',
|
||||
|
|
@ -391,10 +394,8 @@ export const VirtualMonitorEffect = GObject.registerClass({
|
|||
[-noRotationVector[1], -noRotationVector[2], this._current_display_distance * -noRotationVector[0]]);
|
||||
|
||||
const rotation_radians = this.monitor_placements[this.monitor_index].rotationAngleRadians;
|
||||
this.set_uniform_float(this.get_uniform_location("u_rotation_x_radians"), 1,
|
||||
[this.monitor_wrapping_scheme === 'vertical' ? rotation_radians : 0.0]);
|
||||
this.set_uniform_float(this.get_uniform_location("u_rotation_y_radians"), 1,
|
||||
[this.monitor_wrapping_scheme === 'horizontal' ? rotation_radians : 0.0]);
|
||||
this.set_uniform_float(this.get_uniform_location("u_rotation_x_radians"), 1, [rotation_radians.x]);
|
||||
this.set_uniform_float(this.get_uniform_location("u_rotation_y_radians"), 1, [rotation_radians.y]);
|
||||
}
|
||||
|
||||
perspective(fovDiagonalRadians, aspect, near, far) {
|
||||
|
|
@ -559,6 +560,13 @@ export const VirtualMonitorsActor = GObject.registerClass({
|
|||
GObject.ParamFlags.READWRITE,
|
||||
'horizontal', ['horizontal', 'vertical', 'none']
|
||||
),
|
||||
'monitor-spacing': GObject.ParamSpec.double(
|
||||
'monitor-spacing',
|
||||
'Monitor Spacing',
|
||||
'Visual spacing between monitors',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0.0, 1.0, 0.0
|
||||
),
|
||||
'target-monitor': GObject.ParamSpec.jsobject(
|
||||
'target-monitor',
|
||||
'Target Monitor',
|
||||
|
|
@ -700,14 +708,12 @@ export const VirtualMonitorsActor = GObject.registerClass({
|
|||
monitor_placements: this.monitor_placements,
|
||||
display_distance: this.display_distance,
|
||||
display_distance_default: Math.max(this.toggle_display_distance_start, this.toggle_display_distance_end),
|
||||
monitor_wrapping_scheme: this.monitor_wrapping_scheme,
|
||||
actor_to_display_ratios: actorToDisplayRatios,
|
||||
actor_to_display_offsets: actorToDisplayOffsets
|
||||
});
|
||||
containerActor.add_effect_with_name('viewport-effect', effect);
|
||||
this.add_child(containerActor);
|
||||
this.bind_property('monitor-placements', effect, 'monitor-placements', GObject.BindingFlags.DEFAULT);
|
||||
this.bind_property('monitor-wrapping-scheme', effect, 'monitor-wrapping-scheme', GObject.BindingFlags.DEFAULT);
|
||||
this.bind_property('imu-snapshots', effect, 'imu-snapshots', GObject.BindingFlags.DEFAULT);
|
||||
this.bind_property('focused-monitor-index', effect, 'focused-monitor-index', GObject.BindingFlags.DEFAULT);
|
||||
this.bind_property('display-distance', effect, 'display-distance', GObject.BindingFlags.DEFAULT);
|
||||
|
|
@ -751,13 +757,30 @@ export const VirtualMonitorsActor = GObject.registerClass({
|
|||
this.connect('notify::toggle-display-distance-start', this._handle_display_distance_properties_change.bind(this));
|
||||
this.connect('notify::toggle-display-distance-end', this._handle_display_distance_properties_change.bind(this));
|
||||
this.connect('notify::display-distance', this._handle_display_distance_properties_change.bind(this));
|
||||
this.connect('notify::monitor-wrapping-scheme', this._update_monitor_placements.bind(this));
|
||||
this.connect('notify::monitor-spacing', this._update_monitor_placements.bind(this));
|
||||
this.connect('notify::viewport-offset-x', this._update_monitor_placements.bind(this));
|
||||
this.connect('notify::viewport-offset-y', this._update_monitor_placements.bind(this));
|
||||
this._handle_display_distance_properties_change();
|
||||
}
|
||||
|
||||
_update_monitor_placements() {
|
||||
Globals.logger.log_debug(`\t\t\tUpdating monitor placements ${this.viewport_offset_x}, ${this.viewport_offset_y} ${Globals.data_stream.device_data.displayFov}`);
|
||||
// collect minimum and maximum x and y values of monitors
|
||||
let actualWrapScheme = this.monitor_wrapping_scheme;
|
||||
if (actualWrapScheme === 'automatic') {
|
||||
const minX = Math.min(...this._all_monitors.map(monitor => monitor.x));
|
||||
const minY = Math.min(...this._all_monitors.map(monitor => monitor.y));
|
||||
const maxX = Math.max(...this._all_monitors.map(monitor => monitor.x + monitor.width));
|
||||
const maxY = Math.max(...this._all_monitors.map(monitor => monitor.y + monitor.height));
|
||||
|
||||
// check if there are more monitors in the horizontal or vertical direction, prefer horizontal if equal
|
||||
if ((maxX - minX) / this.width >= (maxY - minY) / this.height) {
|
||||
actualWrapScheme = 'horizontal';
|
||||
} else {
|
||||
actualWrapScheme = 'vertical';
|
||||
}
|
||||
}
|
||||
|
||||
this.monitor_placements = monitorsToPlacements(
|
||||
{
|
||||
fovDegrees: Globals.data_stream.device_data.displayFov,
|
||||
|
|
@ -772,7 +795,8 @@ export const VirtualMonitorsActor = GObject.registerClass({
|
|||
width: monitor.width,
|
||||
height: monitor.height
|
||||
})),
|
||||
this.monitor_wrapping_scheme
|
||||
actualWrapScheme,
|
||||
this.monitor_spacing
|
||||
);
|
||||
|
||||
// normalize the center vectors
|
||||
|
|
|
|||
|
|
@ -118,6 +118,15 @@
|
|||
How the monitors are wrapped around the viewport
|
||||
</description>
|
||||
</key>
|
||||
<key name="monitor-spacing" type="d">
|
||||
<default>
|
||||
0.0
|
||||
</default>
|
||||
<summary>Monitor spacing</summary>
|
||||
<description>
|
||||
How far apart the monitors are visually (not logically)
|
||||
</description>
|
||||
</key>
|
||||
<key name="curved-display" type="b">
|
||||
<default>
|
||||
false
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ class ConnectedDevice(Gtk.Box):
|
|||
text_scaling_scale = Gtk.Template.Child()
|
||||
text_scaling_adjustment = Gtk.Template.Child()
|
||||
monitor_wrapping_scheme_menu = Gtk.Template.Child()
|
||||
monitor_spacing_scale = Gtk.Template.Child()
|
||||
monitor_spacing_adjustment = Gtk.Template.Child()
|
||||
viewport_offset_x_scale = Gtk.Template.Child()
|
||||
viewport_offset_x_adjustment = Gtk.Template.Child()
|
||||
viewport_offset_y_scale = Gtk.Template.Child()
|
||||
viewport_offset_y_adjustment = Gtk.Template.Child()
|
||||
|
||||
|
||||
def __init__(self):
|
||||
|
|
@ -68,7 +74,10 @@ class ConnectedDevice(Gtk.Box):
|
|||
self.set_toggle_display_distance_start_button,
|
||||
self.set_toggle_display_distance_end_button,
|
||||
self.movement_look_ahead_scale,
|
||||
self.monitor_wrapping_scheme_menu
|
||||
self.monitor_wrapping_scheme_menu,
|
||||
self.monitor_spacing_scale,
|
||||
self.viewport_offset_x_scale,
|
||||
self.viewport_offset_y_scale
|
||||
]
|
||||
|
||||
self.settings = SettingsManager.get_instance().settings
|
||||
|
|
@ -86,10 +95,13 @@ class ConnectedDevice(Gtk.Box):
|
|||
self.settings.bind('use-highest-refresh-rate', self.use_highest_refresh_rate_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('fast-sbs-mode-switching', self.fast_sbs_mode_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('look-ahead-override', self.movement_look_ahead_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('monitor-spacing', self.monitor_spacing_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('viewport-offset-x', self.viewport_offset_x_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('viewport-offset-y', self.viewport_offset_y_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.connect('changed::monitor-wrapping-scheme', self._handle_monitor_wrapping_scheme_setting_changed)
|
||||
self.desktop_settings.bind('text-scaling-factor', self.text_scaling_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.monitor_wrapping_scheme_menu.connect('changed', self._handle_monitor_wrapping_scheme_menu_changed)
|
||||
self._handle_monitor_wrapping_scheme_setting_changed()
|
||||
self._handle_monitor_wrapping_scheme_setting_changed(self.settings, self.settings.get_string('monitor-wrapping-scheme'))
|
||||
|
||||
bind_shortcut_settings(self.get_parent(), [
|
||||
[self.reassign_toggle_xr_effect_shortcut_button, self.toggle_xr_effect_shortcut_label],
|
||||
|
|
@ -126,9 +138,8 @@ class ConnectedDevice(Gtk.Box):
|
|||
|
||||
self.connect("destroy", self._on_widget_destroy)
|
||||
|
||||
def _handle_monitor_wrapping_scheme_setting_changed(self):
|
||||
current_scheme = self.settings.get_string('monitor-wrapping-scheme')
|
||||
self.monitor_wrapping_scheme_menu.set_active_id(current_scheme)
|
||||
def _handle_monitor_wrapping_scheme_setting_changed(self, settings, val):
|
||||
self.monitor_wrapping_scheme_menu.set_active_id(val)
|
||||
|
||||
def _handle_monitor_wrapping_scheme_menu_changed(self, widget):
|
||||
self.settings.set_string('monitor-wrapping-scheme', widget.get_active_id())
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@
|
|||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes"><!-- dropdown menu -->Multi-monitor wrapping</property>
|
||||
<property name="subtitle" translatable="yes">When displaying multiple monitors, choose how they should wrap around you</property>
|
||||
<property name="subtitle" translatable="yes">When there are multiple monitors, choose how they should wrap around you.</property>
|
||||
<property name="valign">2</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
|
|
@ -176,6 +176,97 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes"><!-- adjustment slider -->Multi-monitor spacing</property>
|
||||
<property name="subtitle" translatable="yes">Put empty space between monitors, when there are multiple.</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="monitor_spacing_scale">
|
||||
<property name="valign">3</property>
|
||||
<property name="draw-value">true</property>
|
||||
<property name="value-pos">0</property>
|
||||
<property name="digits">2</property>
|
||||
<property name="width-request">350</property>
|
||||
<property name="has-origin">false</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="monitor_spacing_adjustment">
|
||||
<property name="lower">0.0</property>
|
||||
<property name="upper">0.5</property>
|
||||
<property name="step-increment">0.01</property>
|
||||
<property name="value">0.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<marks>
|
||||
<mark value="0.0" position="bottom"></mark>
|
||||
<mark value="0.25" position="bottom"></mark>
|
||||
<mark value="0.5" position="bottom"></mark>
|
||||
</marks>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes"><!-- adjustment slider -->Viewport horizontal offset</property>
|
||||
<property name="subtitle" translatable="yes">By default, the viewport will center on the primary display. Use this slider to move the viewport to the left or right.</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="viewport_offset_x_scale">
|
||||
<property name="valign">3</property>
|
||||
<property name="draw-value">true</property>
|
||||
<property name="value-pos">0</property>
|
||||
<property name="digits">1</property>
|
||||
<property name="width-request">350</property>
|
||||
<property name="has-origin">false</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="viewport_offset_x_adjustment">
|
||||
<property name="lower">-2.5</property>
|
||||
<property name="upper">2.5</property>
|
||||
<property name="step-increment">0.1</property>
|
||||
<property name="value">0.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<marks>
|
||||
<mark value="-2.0" position="bottom"></mark>
|
||||
<mark value="-1.0" position="bottom"></mark>
|
||||
<mark value="0.0" position="bottom"></mark>
|
||||
<mark value="1.0" position="bottom"></mark>
|
||||
<mark value="2.0" position="bottom"></mark>
|
||||
</marks>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes"><!-- adjustment slider -->Viewport vertical offset</property>
|
||||
<property name="subtitle" translatable="yes">By default, the viewport will center on the primary display. Use this slider to move the viewport up or down.</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="viewport_offset_y_scale">
|
||||
<property name="valign">3</property>
|
||||
<property name="draw-value">true</property>
|
||||
<property name="value-pos">0</property>
|
||||
<property name="digits">1</property>
|
||||
<property name="width-request">350</property>
|
||||
<property name="has-origin">false</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="viewport_offset_y_adjustment">
|
||||
<property name="lower">-2.5</property>
|
||||
<property name="upper">2.5</property>
|
||||
<property name="step-increment">0.1</property>
|
||||
<property name="value">0.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<marks>
|
||||
<mark value="-2.0" position="bottom"></mark>
|
||||
<mark value="-1.0" position="bottom"></mark>
|
||||
<mark value="0.0" position="bottom"></mark>
|
||||
<mark value="1.0" position="bottom"></mark>
|
||||
<mark value="2.0" position="bottom"></mark>
|
||||
</marks>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
|||
Loading…
Reference in New Issue