Codebase list lightdm-gtk-greeter-settings / 72aa93f
"position" option - dragging window by mouse Andrew P. 9 years ago
5 changed file(s) with 137 addition(s) and 74 deletion(s). Raw diff Collapse all Expand all
10361036 </object>
10371037 </child>
10381038 <child type="overlay">
1039 <object class="GtkFrame" id="greeter_position_window_frame">
1040 <property name="width_request">100</property>
1041 <property name="height_request">80</property>
1039 <object class="GtkEventBox" id="greeter_position_window_box">
10421040 <property name="visible">True</property>
10431041 <property name="can_focus">False</property>
1042 <property name="events">GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_STRUCTURE_MASK</property>
10441043 <property name="halign">start</property>
10451044 <property name="valign">start</property>
1046 <property name="border_width">2</property>
1047 <property name="label_xalign">0</property>
1048 <property name="shadow_type">in</property>
10491045 <child>
1050 <object class="GtkGrid" id="greeter_position_window_grid">
1046 <object class="GtkFrame" id="greeter_position_window_frame">
1047 <property name="width_request">100</property>
1048 <property name="height_request">80</property>
10511049 <property name="visible">True</property>
10521050 <property name="can_focus">False</property>
1053 <property name="column_spacing">30</property>
1054 <property name="row_homogeneous">True</property>
1055 <property name="column_homogeneous">True</property>
1051 <property name="border_width">2</property>
1052 <property name="label_xalign">0</property>
1053 <property name="shadow_type">in</property>
10561054 <child>
1057 <placeholder/>
1055 <object class="GtkGrid" id="greeter_position_window_grid">
1056 <property name="visible">True</property>
1057 <property name="can_focus">False</property>
1058 <property name="column_spacing">30</property>
1059 <property name="row_homogeneous">True</property>
1060 <property name="column_homogeneous">True</property>
1061 <child>
1062 <placeholder/>
1063 </child>
1064 <child>
1065 <placeholder/>
1066 </child>
1067 <child>
1068 <placeholder/>
1069 </child>
1070 <child>
1071 <placeholder/>
1072 </child>
1073 <child>
1074 <placeholder/>
1075 </child>
1076 <child>
1077 <placeholder/>
1078 </child>
1079 <child>
1080 <placeholder/>
1081 </child>
1082 <child>
1083 <placeholder/>
1084 </child>
1085 <child>
1086 <placeholder/>
1087 </child>
1088 </object>
10581089 </child>
1059 <child>
1060 <placeholder/>
1061 </child>
1062 <child>
1063 <placeholder/>
1064 </child>
1065 <child>
1066 <placeholder/>
1067 </child>
1068 <child>
1069 <placeholder/>
1070 </child>
1071 <child>
1072 <placeholder/>
1073 </child>
1074 <child>
1075 <placeholder/>
1076 </child>
1077 <child>
1078 <placeholder/>
1079 </child>
1080 <child>
1090 <child type="label_item">
10811091 <placeholder/>
10821092 </child>
10831093 </object>
1084 </child>
1085 <child type="label_item">
1086 <placeholder/>
10871094 </child>
10881095 </object>
10891096 </child>
109109 'reader': (OptionEntry.StringPathEntry, None),
110110 'a11y-states': (OptionEntry.AccessibilityStatesEntry, ''),
111111 'allow-debugging': (OptionEntry.BooleanEntry, 'false'), }),
112 MonitorsGroup(WidgetsWrapper(self.builder)))
112 MonitorsGroup(self.builder))
113113
114114 for group in self._groups:
115115 group.entry_added.connect(self.on_entry_added)
656656 self._tools_menu = Gtk.Menu()
657657 self._tools_menu.attach_to_widget(self._tools)
658658
659 unused_item = Gtk.CheckMenuItem(
660 C_('option-entry|indicators', 'Show unused items'))
659 unused_item = Gtk.CheckMenuItem(C_('option-entry|indicators', 'Show unused items'))
661660 unused_item.connect('toggled', self._tools_show_unused_toggled)
662661 self._tools_menu.append(unused_item)
663662
664 header_item = Gtk.MenuItem(
665 C_('option-entry|indicators', 'Predefined templates:'))
663 header_item = Gtk.MenuItem(C_('option-entry|indicators', 'Predefined templates:'))
666664 header_item.props.sensitive = False
667665 self._tools_menu.append(Gtk.SeparatorMenuItem())
668666 self._tools_menu.append(header_item)
677675
678676 for title, value in templates:
679677 item = Gtk.MenuItem(title)
680 item.connect(
681 'activate', self._on_tools_template_clicked, value)
678 item.connect('activate', self._on_tools_template_clicked, value)
682679 self._tools_menu.append(item)
683680
684681 self._tools_menu.show_all()
1616
1717 from itertools import product
1818
19 from gi.repository import Gtk
19 from gi.repository import (
20 Gdk,
21 Gtk)
2022
2123 from lightdm_gtk_greeter_settings.helpers import WidgetsWrapper
2224 from lightdm_gtk_greeter_settings.OptionEntry import BaseEntry
5254
5355 @value.setter
5456 def value(self, s):
55 value, _, anchor = s.partition(',')
56
57 percents = value and value[-1] == '%'
58 if percents:
59 value = value[:-1]
60
61 try:
62 p = int(value)
63 except ValueError:
64 p = 0
65
66 negative = (p < 0) or (p == 0 and value and value[0] == '-')
67
68 if not anchor or anchor not in ('start', 'center', 'end'):
69 if negative:
70 anchor = 'end'
71 else:
72 anchor = 'start'
57 if isinstance(s, tuple):
58 p, percents, negative, anchor = s
59 else:
60 value, __, anchor = s.partition(',')
61
62 percents = value and value[-1] == '%'
63 if percents:
64 value = value[:-1]
65
66 try:
67 p = int(value)
68 except ValueError:
69 p = 0
70
71 negative = (p < 0) or (p == 0 and value and value[0] == '-')
72
73 if not anchor or anchor not in ('start', 'center', 'end'):
74 if negative:
75 anchor = 'end'
76 else:
77 anchor = 'start'
78
7379 self._anchor = anchor
74
7580 self._percents.props.active = percents
7681 self._adjustment.props.upper = 100 if self._percents.props.active else 10000
7782 self._mirror.props.active = negative
8691 def anchor(self, value):
8792 self._anchor = value
8893
94 @property
95 def negative(self):
96 return self._mirror.props.active
97
98 @negative.setter
99 def negative(self, value):
100 self._mirror.props.active = value
101
89102 def get_value_for_screen(self, screen: int):
90103 p = int(self._adjustment.props.value)
91104
97110 return int(p)
98111
99112 def _on_percents_toggled(self, toggle):
100 self._adjustment.props.upper = 100 if toggle.props.active \
101 else 10000
113 self._adjustment.props.upper = 100 if toggle.props.active else 10000
102114 self._on_changed(self)
103115
104116 def _on_mirror_toggled(self, toggle):
107119 def _on_value_changed(self, widget):
108120 self._on_changed(self)
109121
110 ASSUMED_WINDOW_SIZE = 430, 240
122 AssumedWindowSize = 430, 240
111123
112124 def __init__(self, widgets):
113125 super().__init__(widgets)
118130
119131 self._screen_frame = widgets['screen_frame']
120132 self._screen_overlay = widgets['screen_overlay']
121 self._window_frame = widgets['window_frame']
122 self._grid = widgets['window_grid']
133 window_box = widgets['window_box']
134 grid = widgets['window_grid']
135
136 self._motion = False
137
138 window_box.connect('motion-notify-event', self._on_window_motion)
139 window_box.connect('button-press-event', self._on_window_button_press)
140 window_box.connect('button-release-event', self._on_window_button_release)
123141
124142 # Creating points grid
125143 anchors_align = (Gtk.Align.START, Gtk.Align.CENTER, Gtk.Align.END)
133151 if w != anchors[0][-1]:
134152 w.props.group = anchors[0][-1]
135153 w.connect('toggled', self._on_anchor_toggled, x_anchor, y_anchor)
136 self._grid.attach(w, left, top, 1, 1)
154 grid.attach(w, left, top, 1, 1)
137155 self._anchors[x_anchor, y_anchor] = w
138156
139 self._grid.show_all()
157 grid.show_all()
140158
141159 self._x = PositionEntry.Dimension(WidgetsWrapper(widgets, 'x'), self._on_dimension_changed)
142160 self._y = PositionEntry.Dimension(WidgetsWrapper(widgets, 'y'), self._on_dimension_changed)
143161
144162 self._on_gdk_screen_changed()
145163
146 self._screen_overlay.connect(
147 'get-child-position', self._on_screen_overlay_get_child_position)
164 self._screen_overlay.connect('get-child-position',
165 self._on_screen_overlay_get_child_position)
148166 self._screen_overlay.connect('screen-changed', self._on_gdk_screen_changed)
149167
150168 def _get_value(self):
191209
192210 scale = screen.width / self._screen_size[0]
193211
194 width = int(self.ASSUMED_WINDOW_SIZE[0] * scale)
195 height = int(self.ASSUMED_WINDOW_SIZE[1] * scale)
212 width = int(self.AssumedWindowSize[0] * scale)
213 height = int(self.AssumedWindowSize[1] * scale)
196214
197215 # Set desired size
198216 child.set_size_request(width, height)
224242 geometry = screen.get_monitor_geometry(screen.get_primary_monitor())
225243 self._screen_size = geometry.width, geometry.height
226244 self._screen_frame.props.ratio = geometry.width / geometry.height
245
246 def _on_window_motion(self, widget, event):
247 if not event.state & Gdk.ModifierType.BUTTON1_MASK:
248 return False
249
250 screen = self._screen_overlay.get_allocation()
251 x, y = widget.translate_coordinates(self._screen_overlay, event.x, event.y)
252
253 for d, p in ((self._x, int(100 * x / screen.width)),
254 (self._y, int(100 * y / screen.height))):
255 if p < 0:
256 p = 0
257 elif p > 100:
258 p = 100
259 if d.negative:
260 d.value = p - 100, True, True, d.anchor
261 else:
262 d.value = p, True, False, d.anchor
263
264 self._motion = True
265 self._last_window_allocation = None
266 self._screen_overlay.queue_resize()
267 return True
268
269 def _on_window_button_press(self, widget, event):
270 if event.button == 1:
271 self._motion = False
272
273 def _on_window_button_release(self, widget, event):
274 if self._motion and event.button == 1:
275 self._motion = False
276 self._emit_changed()
5757 __all__ = [
5858 'bool2string',
5959 'C_',
60 'clamp',
6061 'check_path_accessibility',
6162 'DefaultValueDict',
6263 'file_is_readable_by_greeter',
197198 return None
198199
199200
201 def clamp(v, a, b):
202 if v < a:
203 return a
204 if v > b:
205 return b
206 return v
207
208
200209 class DefaultValueDict(defaultdict):
201210
202211 def __init__(self, *items, default=None, factory=None, source=None):