Skip to content

Commit

Permalink
Enable re-order of sessions via DND, Fix #264
Browse files Browse the repository at this point in the history
  • Loading branch information
gnunn1 committed May 13, 2017
1 parent 27b2563 commit 202a64c
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 2 deletions.
16 changes: 16 additions & 0 deletions source/gx/tilix/appwindow.d
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ private:
sb = new SideBar();
sb.onSelected.connect(&onSessionSelected);
sb.onClose.connect(&onUserSessionClose);
sb.onReorder.connect(&onSessionReorder);

ss = new SessionSwitcher();
ss.onFileSelected.connect(&onFileSelected);
Expand Down Expand Up @@ -827,6 +828,21 @@ private:
}
}

void onSessionReorder(string sourceUUID, string targetUUID, CumulativeResult!bool result) {
Session sourceSession = getSession(sourceUUID);
Session targetSession = getSession(targetUUID);
if (sourceSession is null || targetSession is null) {
errorf("Unexpected error for DND, source or target page is null %s, %s", sourceUUID, targetUUID);
result.addResult(false);
return;
}
nb.reorderChild(sourceSession, nb.pageNum(targetSession));
result.addResult(true);
}

/**
* Invoked by sidebar when user selects a session.
*/
void onSessionSelected(string sessionUUID) {
trace("Session selected " ~ sessionUUID);
saViewSideBar.activate(null);
Expand Down
101 changes: 99 additions & 2 deletions source/gx/tilix/sidebar.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@ import std.conv;
import std.format;
import std.experimental.logger;

import gdk.Atom;
import gdk.DragContext;
import gdk.Event;
import gdk.Keysyms;
import gdk.Window: GdkWindow = Window;

import gio.Settings : GSettings = Settings;

import gtk.Adjustment;
import gtk.AspectFrame;
import gtk.Box;
import gtk.Button;
import gtk.DragAndDrop;
import gtk.EventBox;
import gtk.Frame;
import gtk.Grid;
Expand All @@ -28,7 +32,10 @@ import gtk.Main;
import gtk.Overlay;
import gtk.Revealer;
import gtk.ScrolledWindow;
import gtk.SelectionData;
import gtk.TargetEntry;
import gtk.Widget;
import gtk.Window;

import gx.gtk.cairo;
import gx.gtk.util;
Expand Down Expand Up @@ -67,12 +74,29 @@ private:

bool onButtonPress(Event event, Widget w) {
trace("** Sidebar button press");
//If button press happened outside of sidebar close it
// If button press happened outside of sidebar close it
// Modified since DND uses eventbox so additional windows in play
if (event.getWindow() !is null && lbSessions.getWindow() !is null) {
if (event.getWindow().getWindowStruct() == getWindow().getWindowStruct() || event.getWindow().getWindowStruct() == lbSessions.getWindow().getWindowStruct()) {
return false;
}
GdkWindow[] windows = lbSessions.getWindow().getChildren().toArray!GdkWindow();
foreach(window; windows) {
if (event.getWindow().getWindowStruct() == window.getWindowStruct()) {
return false;
}
}
}
trace("Close on button press");
notifySessionSelected(null);

/*
if (event.getWindow() !is null && lbSessions.getWindow() !is null) {
if (event.getWindow().getWindowStruct() != getWindow().getWindowStruct() && event.getWindow().getWindowStruct() != lbSessions.getWindow().getWindowStruct()) {
notifySessionSelected(null);
}
}
*/
return false;
}

Expand All @@ -99,6 +123,25 @@ private:
}
}

void reorderSessions(string sourceUUID, string targetUUID) {
if (sourceUUID == targetUUID) return;
trace("Re-order sessions source=%s, target=%s", sourceUUID, targetUUID);
CumulativeResult!bool result = new CumulativeResult!bool();
onReorder.emit(sourceUUID, targetUUID, result);
if (result.isAnyResult(false)) return;

SideBarRow source = getRow(sourceUUID);
SideBarRow target = getRow(targetUUID);
if (source is null || target is null) {
errorf("Unexpected error for DND, source or target row is null %s, %s", sourceUUID, targetUUID);
return;
}
int index = target.getIndex();
lbSessions.remove(source);
lbSessions.insert(source, index);
reindexSessions();
}

bool onKeyRelease(Event event, Widget w) {
uint keyval;
if (event.getKeyval(keyval)) {
Expand Down Expand Up @@ -294,15 +337,28 @@ public:
* result = Whether the session was closed or not
*/
GenericEvent!(string, CumulativeResult!bool) onClose;

/**
* Event that requests that two sessions be re-ordered, returns
* true if the re-order was successful, false if not.
*
* Params:
* sourceUUID = The session that needs to be moved
* targetUUID = The target session to move in front of
*/
GenericEvent!(string, string, CumulativeResult!bool) onReorder;
}

private:

enum SIDEBAR_DND = "sidebar";

class SideBarRow : ListBoxRow {
private:
string _sessionUUID;
Label lblIndex;
SideBar sidebar;
Window dragImage;

AspectFrame wrapWidget(Widget widget, string cssClass) {
AspectFrame af = new AspectFrame(null, 0.5, 0.5, 1.0, false);
Expand Down Expand Up @@ -382,13 +438,54 @@ private:
grid.attach(btnClose, 2, 0, 1, 1);

overlay.addOverlay(grid);
add(overlay);

//Setup drag and drop
EventBox eb = new EventBox();
eb.add(overlay);
// Drag and Drop
TargetEntry[] targets = [new TargetEntry(SIDEBAR_DND, TargetFlags.SAME_APP, 0)];
eb.dragSourceSet(ModifierType.BUTTON1_MASK, targets, DragAction.MOVE);
eb.dragDestSet(DestDefaults.ALL, targets, DragAction.MOVE);
eb.addOnDragDataGet(&onRowDragDataGet);
eb.addOnDragDataReceived(&onRowDragDataReceived);
eb.addOnDragBegin(&onRowDragBegin);
eb.addOnDragEnd(&onRowDragEnd);

add(eb);

btnClose.addOnClicked(delegate(Button) {
sidebar.removeSession(_sessionUUID);
});
}

void onRowDragBegin(DragContext dc, Widget widget) {
Image image = new Image(getWidgetImage(this, 1.00));
image.show();
dragImage = new Window(GtkWindowType.POPUP);
dragImage.add(image);
DragAndDrop.dragSetIconWidget(dc, dragImage, 0, 0);
}

void onRowDragEnd(DragContext dc, Widget widget) {
dragImage.destroy();
dragImage = null;

// Under Wayland needed to fix cursor sticking due to
// GtkD holding reference to GTK DragReference
dc.destroy();
}

void onRowDragDataGet(DragContext dc, SelectionData data, uint info, uint time, Widget widget) {
char[] buffer = (sessionUUID ~ '\0').dup;
data.set(intern(SIDEBAR_DND, false), 8, buffer);
}

void onRowDragDataReceived(DragContext dc, int x, int y, SelectionData data, uint info, uint time, Widget widget) {
string targetUUID = to!string(data.getDataWithLength()[0 .. $ - 1]);
tracef("Session UUID %s dropped", targetUUID);
sidebar.reorderSessions(sessionUUID, targetUUID);
}

public:
this(SideBar sidebar, Session session, SessionNotification[string] notifications, int width, int height) {
super();
Expand Down

0 comments on commit 202a64c

Please sign in to comment.