mirror of
				https://gitlab.gnome.org/julianschacher/top-bar-organizer.git
				synced 2025-10-27 15:19:09 +00:00 
			
		
		
		
	Refactor: Setup Drag Source and Drop Targets in UI files
This commit is contained in:
		
							parent
							
								
									5362629f94
								
							
						
					
					
						commit
						596c8d3cdc
					
				| @ -24,5 +24,20 @@ | |||||||
|                 </style> |                 </style> | ||||||
|             </object> |             </object> | ||||||
|         </child> |         </child> | ||||||
|  |         <child> | ||||||
|  |             <object class="GtkDragSource"> | ||||||
|  |                 <property name="actions">move</property> | ||||||
|  |                 <signal name="prepare" handler="onDragPrepare"/> | ||||||
|  |                 <signal name="drag-begin" handler="onDragBegin"/> | ||||||
|  |                 <signal name="drag-end" handler="onDragEnd"/> | ||||||
|  |             </object> | ||||||
|  |         </child> | ||||||
|  |         <child> | ||||||
|  |             <object class="GtkDropTarget"> | ||||||
|  |                 <property name="actions">move</property> | ||||||
|  |                 <property name="formats">PrefsBoxOrderItemRow</property> | ||||||
|  |                 <signal name="drop" handler="onDrop"/> | ||||||
|  |             </object> | ||||||
|  |         </child> | ||||||
|     </template> |     </template> | ||||||
| </interface> | </interface> | ||||||
|  | |||||||
| @ -19,5 +19,12 @@ | |||||||
|                 </child> |                 </child> | ||||||
|             </object> |             </object> | ||||||
|         </child> |         </child> | ||||||
|  |         <child> | ||||||
|  |             <object class="GtkDropTarget"> | ||||||
|  |                 <property name="actions">move</property> | ||||||
|  |                 <property name="formats">PrefsBoxOrderItemRow</property> | ||||||
|  |                 <signal name="drop" handler="onDrop"/> | ||||||
|  |             </object> | ||||||
|  |         </child> | ||||||
|     </template> |     </template> | ||||||
| </interface> | </interface> | ||||||
|  | |||||||
| @ -23,95 +23,6 @@ var PrefsBoxOrderItemRow = GObject.registerClass({ | |||||||
| 
 | 
 | ||||||
|         this._associateItem(item); |         this._associateItem(item); | ||||||
|         this._configureMenu(); |         this._configureMenu(); | ||||||
| 
 |  | ||||||
|         // Make `this` draggable by creating a drag source and adding it to
 |  | ||||||
|         // `this`.
 |  | ||||||
|         let dragSource = new Gtk.DragSource(); |  | ||||||
|         dragSource.set_actions(Gdk.DragAction.MOVE); |  | ||||||
|         dragSource.connect("prepare", (source, x, y) => { |  | ||||||
|             this._drag_starting_point_x = x; |  | ||||||
|             this._drag_starting_point_y = y; |  | ||||||
|             return Gdk.ContentProvider.new_for_value(this); |  | ||||||
|         }); |  | ||||||
|         // Stop all scrolling, which is due to this DND operation.
 |  | ||||||
|         dragSource.connect("drag-end", () => { |  | ||||||
|             scrollManager.stopScrollAll(); |  | ||||||
|         }); |  | ||||||
|         dragSource.connect("drag-begin", (source, drag) => { |  | ||||||
|             let dragWidget = new Gtk.ListBox(); |  | ||||||
|             let allocation = this.get_allocation(); |  | ||||||
|             dragWidget.set_size_request(allocation.width, allocation.height); |  | ||||||
| 
 |  | ||||||
|             let dragPrefsBoxOrderItemRow = new PrefsBoxOrderItemRow({}, this.item) |  | ||||||
|             dragWidget.append(dragPrefsBoxOrderItemRow); |  | ||||||
|             dragWidget.drag_highlight_row(dragPrefsBoxOrderItemRow); |  | ||||||
| 
 |  | ||||||
|             let currentDragIcon = Gtk.DragIcon.get_for_drag(drag); |  | ||||||
|             currentDragIcon.set_child(dragWidget); |  | ||||||
|             drag.set_hotspot(this._drag_starting_point_x, this._drag_starting_point_y); |  | ||||||
|         }); |  | ||||||
|         this.add_controller(dragSource); |  | ||||||
| 
 |  | ||||||
|         /// Make `this` accept drops by creating a drop target and adding it to
 |  | ||||||
|         /// `this`.
 |  | ||||||
|         let dropTarget = new Gtk.DropTarget(); |  | ||||||
|         dropTarget.set_gtypes([this.constructor.$gtype]); |  | ||||||
|         dropTarget.set_actions(Gdk.DragAction.MOVE); |  | ||||||
|         // Handle a new drop on `this` properly.
 |  | ||||||
|         // `value` is the thing getting dropped.
 |  | ||||||
|         dropTarget.connect("drop", (target, value) => { |  | ||||||
|             // If `this` got dropped onto itself, do nothing.
 |  | ||||||
|             if (value === this) { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Get the GtkListBoxes of `this` and the drop value.
 |  | ||||||
|             const ownListBox = this.get_parent(); |  | ||||||
|             const valueListBox = value.get_parent(); |  | ||||||
| 
 |  | ||||||
|             // Get the position of `this` and the drop value.
 |  | ||||||
|             const ownPosition = this.get_index(); |  | ||||||
|             const valuePosition = value.get_index(); |  | ||||||
| 
 |  | ||||||
|             // Remove the drop value from its list box.
 |  | ||||||
|             valueListBox.remove(value); |  | ||||||
| 
 |  | ||||||
|             // Since an element got potentially removed from the list of `this`,
 |  | ||||||
|             // get the position of `this` again.
 |  | ||||||
|             const updatedOwnPosition = this.get_index(); |  | ||||||
| 
 |  | ||||||
|             if (ownListBox !== valueListBox) { |  | ||||||
|                 // First handle the case where `this` and the drop value are in
 |  | ||||||
|                 // different list boxes.
 |  | ||||||
|                 if ((ownListBox.boxOrder === "right-box-order" && valueListBox.boxOrder === "left-box-order") |  | ||||||
|                     || (ownListBox.boxOrder === "right-box-order" && valueListBox.boxOrder === "center-box-order") |  | ||||||
|                     || (ownListBox.boxOrder === "center-box-order" && valueListBox.boxOrder === "left-box-order")) { |  | ||||||
|                     // If the list box of the drop value comes before the list
 |  | ||||||
|                     // box of `this`, add the drop value after `this`.
 |  | ||||||
|                     ownListBox.insert(value, updatedOwnPosition + 1); |  | ||||||
|                 } else { |  | ||||||
|                     // Otherwise, add the drop value where `this` currently is.
 |  | ||||||
|                     ownListBox.insert(value, updatedOwnPosition); |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 if (valuePosition < ownPosition) { |  | ||||||
|                     // If the drop value was before `this`, add the drop value
 |  | ||||||
|                     // after `this`.
 |  | ||||||
|                     ownListBox.insert(value, updatedOwnPosition + 1); |  | ||||||
|                 } else { |  | ||||||
|                     // Otherwise, add the drop value where `this` currently is.
 |  | ||||||
|                     ownListBox.insert(value, updatedOwnPosition); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             /// Finally save the box order(/s) to settings.
 |  | ||||||
|             ownListBox.saveBoxOrderToSettings(); |  | ||||||
|             // If the list boxes of `this` and the drop value were different,
 |  | ||||||
|             // save an updated box order for the list were the drop value was in
 |  | ||||||
|             // as well.
 |  | ||||||
|             if (ownListBox !== valueListBox) valueListBox.saveBoxOrderToSettings(); |  | ||||||
|         }); |  | ||||||
|         this.add_controller(dropTarget); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -147,4 +58,88 @@ var PrefsBoxOrderItemRow = GObject.registerClass({ | |||||||
|         actionGroup.add_action(forgetAction); |         actionGroup.add_action(forgetAction); | ||||||
|         this.insert_action_group(`prefsBoxOrderItemRow-${this.item}`, actionGroup); |         this.insert_action_group(`prefsBoxOrderItemRow-${this.item}`, actionGroup); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     onDragPrepare(_source, x, y) { | ||||||
|  |         const value = new GObject.Value(); | ||||||
|  |         value.init(PrefsBoxOrderItemRow); | ||||||
|  |         value.set_object(this); | ||||||
|  | 
 | ||||||
|  |         this._drag_starting_point_x = x; | ||||||
|  |         this._drag_starting_point_y = y; | ||||||
|  |         return Gdk.ContentProvider.new_for_value(value); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     onDragBegin(_source, drag) { | ||||||
|  |         let dragWidget = new Gtk.ListBox(); | ||||||
|  |         let allocation = this.get_allocation(); | ||||||
|  |         dragWidget.set_size_request(allocation.width, allocation.height); | ||||||
|  | 
 | ||||||
|  |         let dragPrefsBoxOrderItemRow = new PrefsBoxOrderItemRow({}, this.item) | ||||||
|  |         dragWidget.append(dragPrefsBoxOrderItemRow); | ||||||
|  |         dragWidget.drag_highlight_row(dragPrefsBoxOrderItemRow); | ||||||
|  | 
 | ||||||
|  |         let currentDragIcon = Gtk.DragIcon.get_for_drag(drag); | ||||||
|  |         currentDragIcon.set_child(dragWidget); | ||||||
|  |         drag.set_hotspot(this._drag_starting_point_x, this._drag_starting_point_y); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     onDragEnd() { | ||||||
|  |         // Stop all scrolling, which is due to this DND operation.
 | ||||||
|  |         scrollManager.stopScrollAll(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Handle a new drop on `this` properly.
 | ||||||
|  |     // `value` is the thing getting dropped.
 | ||||||
|  |     onDrop(_target, value, _x, _y) { | ||||||
|  |         // If `this` got dropped onto itself, do nothing.
 | ||||||
|  |         if (value === this) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Get the GtkListBoxes of `this` and the drop value.
 | ||||||
|  |         const ownListBox = this.get_parent(); | ||||||
|  |         const valueListBox = value.get_parent(); | ||||||
|  | 
 | ||||||
|  |         // Get the position of `this` and the drop value.
 | ||||||
|  |         const ownPosition = this.get_index(); | ||||||
|  |         const valuePosition = value.get_index(); | ||||||
|  | 
 | ||||||
|  |         // Remove the drop value from its list box.
 | ||||||
|  |         valueListBox.remove(value); | ||||||
|  | 
 | ||||||
|  |         // Since an element got potentially removed from the list of `this`,
 | ||||||
|  |         // get the position of `this` again.
 | ||||||
|  |         const updatedOwnPosition = this.get_index(); | ||||||
|  | 
 | ||||||
|  |         if (ownListBox !== valueListBox) { | ||||||
|  |             // First handle the case where `this` and the drop value are in
 | ||||||
|  |             // different list boxes.
 | ||||||
|  |             if ((ownListBox.boxOrder === "right-box-order" && valueListBox.boxOrder === "left-box-order") | ||||||
|  |                 || (ownListBox.boxOrder === "right-box-order" && valueListBox.boxOrder === "center-box-order") | ||||||
|  |                 || (ownListBox.boxOrder === "center-box-order" && valueListBox.boxOrder === "left-box-order")) { | ||||||
|  |                 // If the list box of the drop value comes before the list
 | ||||||
|  |                 // box of `this`, add the drop value after `this`.
 | ||||||
|  |                 ownListBox.insert(value, updatedOwnPosition + 1); | ||||||
|  |             } else { | ||||||
|  |                 // Otherwise, add the drop value where `this` currently is.
 | ||||||
|  |                 ownListBox.insert(value, updatedOwnPosition); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             if (valuePosition < ownPosition) { | ||||||
|  |                 // If the drop value was before `this`, add the drop value
 | ||||||
|  |                 // after `this`.
 | ||||||
|  |                 ownListBox.insert(value, updatedOwnPosition + 1); | ||||||
|  |             } else { | ||||||
|  |                 // Otherwise, add the drop value where `this` currently is.
 | ||||||
|  |                 ownListBox.insert(value, updatedOwnPosition); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// Finally save the box order(/s) to settings.
 | ||||||
|  |         ownListBox.saveBoxOrderToSettings(); | ||||||
|  |         // If the list boxes of `this` and the drop value were different,
 | ||||||
|  |         // save an updated box order for the list were the drop value was in
 | ||||||
|  |         // as well.
 | ||||||
|  |         if (ownListBox !== valueListBox) valueListBox.saveBoxOrderToSettings(); | ||||||
|  |     } | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -14,40 +14,34 @@ var PrefsBoxOrderListEmptyPlaceholder = GObject.registerClass({ | |||||||
| }, class PrefsBoxOrderListEmptyPlaceholder extends Gtk.Box { | }, class PrefsBoxOrderListEmptyPlaceholder extends Gtk.Box { | ||||||
|     constructor(params = {}) { |     constructor(params = {}) { | ||||||
|         super(params); |         super(params); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         /// Make `this` accept drops by creating a drop target and adding it to
 |     // Handle a new drop on `this` properly.
 | ||||||
|         /// `this`.
 |     // `value` is the thing getting dropped.
 | ||||||
|         let dropTarget = new Gtk.DropTarget(); |     onDrop(_target, value, _x, _y) { | ||||||
|         dropTarget.set_gtypes([GObject.type_from_name("PrefsBoxOrderItemRow")]); |         // Get the GtkListBoxes of `this` and the drop value.
 | ||||||
|         dropTarget.set_actions(Gdk.DragAction.MOVE); |         const ownListBox = this.get_parent(); | ||||||
|         // Handle a new drop on `this` properly.
 |         const valueListBox = value.get_parent(); | ||||||
|         // `value` is the thing getting dropped.
 |  | ||||||
|         dropTarget.connect("drop", (target, value) => { |  | ||||||
|             // Get the GtkListBoxes of `this` and the drop value.
 |  | ||||||
|             const ownListBox = this.get_parent(); |  | ||||||
|             const valueListBox = value.get_parent(); |  | ||||||
| 
 | 
 | ||||||
|             // Remove the drop value from its list box.
 |         // Remove the drop value from its list box.
 | ||||||
|             valueListBox.remove(value); |         valueListBox.remove(value); | ||||||
| 
 | 
 | ||||||
|             // Insert the drop value into the list box of `this`.
 |         // Insert the drop value into the list box of `this`.
 | ||||||
|             ownListBox.insert(value, 0); |         ownListBox.insert(value, 0); | ||||||
| 
 | 
 | ||||||
|             /// Finally save the box orders to settings.
 |         /// Finally save the box orders to settings.
 | ||||||
|             settings.set_strv(ownListBox.boxOrder, [value.item]); |         settings.set_strv(ownListBox.boxOrder, [value.item]); | ||||||
| 
 | 
 | ||||||
|             let updatedBoxOrder = [ ]; |         let updatedBoxOrder = [ ]; | ||||||
|             for (let potentialListBoxRow of valueListBox) { |         for (let potentialListBoxRow of valueListBox) { | ||||||
|                 // Only process PrefsBoxOrderItemRows.
 |             // Only process PrefsBoxOrderItemRows.
 | ||||||
|                 if (potentialListBoxRow.constructor.$gtype.name !== "PrefsBoxOrderItemRow") { |             if (potentialListBoxRow.constructor.$gtype.name !== "PrefsBoxOrderItemRow") { | ||||||
|                     continue; |                 continue; | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 const item = potentialListBoxRow.item; |  | ||||||
|                 updatedBoxOrder.push(item); |  | ||||||
|             } |             } | ||||||
|             settings.set_strv(valueListBox.boxOrder, updatedBoxOrder); | 
 | ||||||
|         }); |             const item = potentialListBoxRow.item; | ||||||
|         this.add_controller(dropTarget); |             updatedBoxOrder.push(item); | ||||||
|  |         } | ||||||
|  |         settings.set_strv(valueListBox.boxOrder, updatedBoxOrder); | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user