From: Good Guy <good1.2guy@gmail.com>
Date: Wed, 28 Oct 2020 22:07:24 +0000 (-0600)
Subject: move grab dragbox to guicast, add tile_mixers region to session/layout, change menu... 
X-Git-Tag: 2020-10~3
X-Git-Url: https://git.cinelerra-gg.org/git/?a=commitdiff_plain;h=b4017f68039ef7e31eedee4a27580a28bee36fc5;p=goodguy%2Fcinelerra.git

move grab dragbox to guicast, add tile_mixers region to session/layout, change menu tile mixers to drag tile mixers
---

diff --git a/cinelerra-5.1/cinelerra/assetpopup.C b/cinelerra-5.1/cinelerra/assetpopup.C
index 9eda28d7..b414455c 100644
--- a/cinelerra-5.1/cinelerra/assetpopup.C
+++ b/cinelerra-5.1/cinelerra/assetpopup.C
@@ -1022,104 +1022,26 @@ int GrabshotMenuItem::handle_event()
 }
 
 GrabshotThread::GrabshotThread(MWindow *mwindow)
- : Thread(1, 0, 0)
+ : BC_DragBox(mwindow->gui)
 {
 	this->mwindow = mwindow;
-	popup = 0;
-	done = -1;
 }
+
 GrabshotThread::~GrabshotThread()
 {
-	delete popup;
 }
 
 void GrabshotThread::start(GrabshotMenuItem *menu_item)
 {
-	popup = new GrabshotPopup(this, menu_item->mode);
-	popup->lock_window("GrabshotThread::start");
-	for( int i=0; i<4; ++i )
-		edge[i] = new BC_Popup(mwindow->gui, 0,0, 1,1, ORANGE, 1);
-	mwindow->gui->grab_buttons();
-	mwindow->gui->grab_cursor();
-	popup->grab(mwindow->gui);
-	popup->create_objects();
-	popup->show_window();
-	popup->unlock_window();
-	done = 0;
-	Thread::start();
-}
-
-void GrabshotThread::run()
-{
-	popup->lock_window("GrabshotThread::run 0");
-	while( !done ) {
-		popup->update();
-		popup->unlock_window();
-		enable_cancel();
-		Timer::delay(200);
-		disable_cancel();
-		popup->lock_window("GrabshotThread::run 1");
-	}
-	mwindow->gui->ungrab_cursor();
-	mwindow->gui->ungrab_buttons();
-	popup->ungrab(mwindow->gui);
-	for( int i=0; i<4; ++i ) delete edge[i];
-	popup->unlock_window();
-	delete popup;  popup = 0;
-}
-
-GrabshotPopup::GrabshotPopup(GrabshotThread *grab_thread, int mode)
- : BC_Popup(grab_thread->mwindow->gui, 0,0, 16,16, -1,1)
-{
-	this->grab_thread = grab_thread;
-	this->mode = mode;
-	dragging = -1;
-	grab_color = ORANGE;
-	x0 = y0 = x1 = y1 = -1;
-	lx0 = ly0 = lx1 = ly1 = -1;
-}
-GrabshotPopup::~GrabshotPopup()
-{
+	mode = menu_item->mode;
+	start_drag();
 }
 
-int GrabshotPopup::grab_event(XEvent *event)
+int GrabshotThread::handle_done_event(int x0, int y0, int x1, int y1)
 {
-	int cur_drag = dragging;
-	switch( event->type ) {
-	case ButtonPress:
-		if( cur_drag > 0 ) return 1;
-		x0 = event->xbutton.x_root;
-		y0 = event->xbutton.y_root;
-		if( !cur_drag ) {
-			draw_selection(-1);
-			if( event->xbutton.button == RIGHT_BUTTON ) break;
-			if( x0>=get_x() && x0<get_x()+get_w() &&
-			    y0>=get_y() && y0<get_y()+get_h() ) break;
-		}
-		x1 = x0;  y1 = y0;
-		draw_selection(1);
-		dragging = 1;
-		return 1;
-	case ButtonRelease:
-		dragging = 0;
-	case MotionNotify:
-		if( cur_drag > 0 ) {
-			x1 = event->xbutton.x_root;
-			y1 = event->xbutton.y_root;
-			draw_selection(0);
-		}
-		return 1;
-	default:
-		return 0;
-	}
-
-	int cx = lx0,     cy = ly0;
-	int cw = lx1-lx0, ch = ly1-ly0;
-	hide_window();
-	sync_display();
-	grab_thread->done = 1;
+	int cx = x0,    cy = y0;
+	int cw = x1-x0, ch = y1-y0;
 
-	MWindow *mwindow = grab_thread->mwindow;
 	Preferences *preferences = mwindow->preferences;
 	char filename[BCTEXTLEN], snapshot_path[BCTEXTLEN];
 	static const char *exts[] = { "png", "jpg", "tif", "ppm" };
@@ -1153,12 +1075,13 @@ int GrabshotPopup::grab_event(XEvent *event)
 	}
 
 // no odd dimensions
-	int rw = get_root_w(0), rh = get_root_h(0);
+	int rw = mwindow->gui->get_root_w(0);
+	int rh = mwindow->gui->get_root_h(0);
 	if( cx < 0 ) { cw += cx;  cx = 0; }
 	if( cy < 0 ) { ch += cy;  cy = 0; }
 	if( cx+cw > rw ) cw = rw-cx;
 	if( cy+ch > rh ) ch = rh-cy;
-	if( !cw || !ch ) return 1;
+	if( !cw || !ch ) return 0;
 
 	VFrame vframe(cw,ch, BC_RGB888);
 	if( cx+cw < rw ) ++cw;
@@ -1201,37 +1124,3 @@ int GrabshotPopup::grab_event(XEvent *event)
 	return 1;
 }
 
-void GrabshotPopup::update()
-{
-	set_color(grab_color ^= GREEN);
-	draw_box(0,0, get_w(),get_h());
-	flash(1);
-}
-
-void GrabshotPopup::draw_selection(int show)
-{
-	if( show < 0 ) {
-		for( int i=0; i<4; ++i ) hide_window(0);
-		flush();
-		return;
-	}
-
-	int nx0 = x0 < x1 ? x0 : x1;
-	int nx1 = x0 < x1 ? x1 : x0;
-	int ny0 = y0 < y1 ? y0 : y1;
-	int ny1 = y0 < y1 ? y1 : y0;
-	lx0 = nx0;  lx1 = nx1;  ly0 = ny0;  ly1 = ny1;
-
-	--nx0;  --ny0;
-	BC_Popup **edge = grab_thread->edge;
-	edge[0]->reposition_window(nx0,ny0, nx1-nx0, 1);
-	edge[1]->reposition_window(nx1,ny0, 1, ny1-ny0);
-	edge[2]->reposition_window(nx0,ny1, nx1-nx0, 1);
-	edge[3]->reposition_window(nx0,ny0, 1, ny1-ny0);
-
-	if( show > 0 ) {
-		for( int i=0; i<4; ++i ) edge[i]->show_window(0);
-	}
-	flush();
-}
-
diff --git a/cinelerra-5.1/cinelerra/assetpopup.h b/cinelerra-5.1/cinelerra/assetpopup.h
index c948e0e1..176174f8 100644
--- a/cinelerra-5.1/cinelerra/assetpopup.h
+++ b/cinelerra-5.1/cinelerra/assetpopup.h
@@ -430,40 +430,20 @@ public:
 
 	int handle_event();
 	GrabshotSubMenu *submenu;
-	int mode;
 	GrabshotThread *grab_thread;
+	int mode;
 };
 
-class GrabshotThread : public Thread
+class GrabshotThread : public BC_DragBox
 {
 public:
 	GrabshotThread(MWindow* mwindow);
 	~GrabshotThread();
-
-	MWindow *mwindow;
-	GrabshotPopup *popup;
-	BC_Popup *edge[4];
-	int done;
-
 	void start(GrabshotMenuItem *menu_item);
-	void run();
-};
+	int handle_done_event(int x0, int y0, int x1, int y1);
 
-class GrabshotPopup : public BC_Popup
-{
-public:
-	GrabshotPopup(GrabshotThread *grab_thread, int mode);
-	~GrabshotPopup();
-	int grab_event(XEvent *event);
-	void draw_selection(int invert);
-	void update();
-
-	GrabshotThread *grab_thread;
+	MWindow *mwindow;
 	int mode;
-	int dragging;
-	int grab_color;
-	int x0, y0, x1, y1;
-	int lx0, ly0, lx1, ly1;
 };
 
 #endif
diff --git a/cinelerra-5.1/cinelerra/mainmenu.C b/cinelerra-5.1/cinelerra/mainmenu.C
index b7b9f358..5735f8c9 100644
--- a/cinelerra-5.1/cinelerra/mainmenu.C
+++ b/cinelerra-5.1/cinelerra/mainmenu.C
@@ -1739,7 +1739,7 @@ void MixerItems::create_objects()
 	BC_SubMenu *mixer_submenu = new BC_SubMenu();
 	add_submenu(mixer_submenu);
 	mixer_submenu->add_submenuitem(new MixerViewer(this));
-	mixer_submenu->add_submenuitem(new TileMixers(this));
+	mixer_submenu->add_submenuitem(new DragTileMixers(this));
 	mixer_submenu->add_submenuitem(new AlignMixers(this));
 	mixer_submenu->add_submenuitem(new MixMasters(this));
 }
@@ -1810,16 +1810,51 @@ int MixerViewer::handle_event()
 	return 1;
 }
 
-TileMixers::TileMixers(MixerItems *mixer_items)
- : MixerItem(mixer_items, _("Tile mixers"), "Alt-t", 't')
+DragTileMixers::DragTileMixers(MixerItems *mixer_items)
+ : MixerItem(mixer_items, _("Drag Tile mixers"), "Alt-t", 't')
 {
 	set_alt();
+	drag_box = 0;
 }
 
-int TileMixers::handle_event()
+DragTileMixers::~DragTileMixers()
 {
-	MWindow *mwindow = mixer_items->mwindow;
-	mwindow->tile_mixers();
+	delete drag_box;
+}
+
+int DragTileMixers::handle_event()
+{
+	if( !drag_box ) {
+		MWindow *mwindow = mixer_items->mwindow;
+		drag_box = new TileMixersDragBox(mwindow->gui);
+	}
+	if( !drag_box->running() )
+		drag_box->start(this);
+	return 1;
+}
+
+TileMixersDragBox::TileMixersDragBox(MWindowGUI *gui)
+ : BC_DragBox(gui)
+{
+	tile_mixers = 0;
+}
+
+void TileMixersDragBox::start(DragTileMixers *tile_mixers)
+{
+	this->tile_mixers = tile_mixers;
+	start_drag();
+}
+
+int TileMixersDragBox::handle_done_event(int x0, int y0, int x1, int y1)
+{
+	MWindow *mwindow = tile_mixers->mixer_items->mwindow;
+	if( x0 >= x1 || y0 >= y1 ) x0 = x1 = y0 = y1 = 0;
+	mwindow->session->tile_mixers_x = x0;
+	mwindow->session->tile_mixers_y = y0;
+	mwindow->session->tile_mixers_w = x1 - x0;
+	mwindow->session->tile_mixers_h = y1 - y0;
+	mwindow->tile_mixers(x0, y0, x1, y1);
+	tile_mixers = 0;
 	return 1;
 }
 
diff --git a/cinelerra-5.1/cinelerra/mainmenu.h b/cinelerra-5.1/cinelerra/mainmenu.h
index 983addcb..0da2c60e 100644
--- a/cinelerra-5.1/cinelerra/mainmenu.h
+++ b/cinelerra-5.1/cinelerra/mainmenu.h
@@ -568,11 +568,23 @@ public:
 	int handle_event();
 };
 
-class TileMixers : public MixerItem
+class DragTileMixers : public MixerItem
 {
 public:
-	TileMixers(MixerItems *mixer_items);
+	DragTileMixers(MixerItems *mixer_items);
+	~DragTileMixers();
 	int handle_event();
+	TileMixersDragBox *drag_box;
+};
+
+class TileMixersDragBox : public BC_DragBox
+{
+public:
+	TileMixersDragBox(MWindowGUI *gui);
+	void start(DragTileMixers *tile_mixers);
+	int handle_done_event(int x0, int y0, int x1, int y1);
+
+	DragTileMixers *tile_mixers;
 };
 
 class AlignMixers : public MixerItem
diff --git a/cinelerra-5.1/cinelerra/mainmenu.inc b/cinelerra-5.1/cinelerra/mainmenu.inc
index 022dce41..f9a5e3d3 100644
--- a/cinelerra-5.1/cinelerra/mainmenu.inc
+++ b/cinelerra-5.1/cinelerra/mainmenu.inc
@@ -73,6 +73,7 @@ class TrimSelection;
 class MixerItems;
 class MixerViewer;
 class TileMixers;
+class TileMixersDragBox;
 class AlignMixers;
 class AlignTimecodes;
 class AddAudioTrack;
diff --git a/cinelerra-5.1/cinelerra/mainsession.C b/cinelerra-5.1/cinelerra/mainsession.C
index 7d582c46..f4e4cc9b 100644
--- a/cinelerra-5.1/cinelerra/mainsession.C
+++ b/cinelerra-5.1/cinelerra/mainsession.C
@@ -98,6 +98,7 @@ MainSession::MainSession(MWindow *mwindow)
 	gwindow_x = gwindow_y = 0;
 	cswindow_x = cswindow_y = cswindow_w = cswindow_h = 0;
 	swindow_x = swindow_y = swindow_w = swindow_h = 0;
+	tile_mixers_x = tile_mixers_y = tile_mixers_w = tile_mixers_h = 0;
 	ewindow_w = ewindow_h = 0;
 	channels_x = channels_y = 0;
 	picture_x = picture_y = 0;
@@ -378,6 +379,11 @@ void MainSession::default_window_positions(int window_config)
 	swindow_w = xS(600);
 	swindow_h = yS(400);
 
+	tile_mixers_x = 1 + mwindow_x;
+	tile_mixers_y = 1;
+	tile_mixers_w = cwindow_x - tile_mixers_x;
+	tile_mixers_h = mwindow_y - tile_mixers_y;
+
 	batchrender_w = xS(750);
 	batchrender_h = yS(400);
 	batchrender_x = root_w / 2 - batchrender_w / 2;
@@ -485,6 +491,11 @@ int MainSession::load_defaults(BC_Hash *defaults)
 	rmonitor_w = defaults->get("RMONITOR_W", rmonitor_w);
 	rmonitor_h = defaults->get("RMONITOR_H", rmonitor_h);
 
+	tile_mixers_x = defaults->get("TILE_MIXERS_X", 0);
+	tile_mixers_y = defaults->get("TILE_MIXERS_Y", 0);
+	tile_mixers_w = defaults->get("TILE_MIXERS_W", 0);
+	tile_mixers_h = defaults->get("TILE_MIXERS_H", 0);
+
 	batchrender_x = defaults->get("BATCHRENDER_X", batchrender_x);
 	batchrender_y = defaults->get("BATCHRENDER_Y", batchrender_y);
 	batchrender_w = defaults->get("BATCHRENDER_W", batchrender_w);
@@ -595,6 +606,11 @@ int MainSession::save_defaults(BC_Hash *defaults)
 	defaults->update("RMONITOR_W", rmonitor_w);
 	defaults->update("RMONITOR_H", rmonitor_h);
 
+	defaults->update("TILE_MIXERS_X", tile_mixers_x);
+	defaults->update("TILE_MIXERS_Y", tile_mixers_y);
+	defaults->update("TILE_MIXERS_W", tile_mixers_w);
+	defaults->update("TILE_MIXERS_H", tile_mixers_h);
+
 	defaults->update("RWINDOW_X", rwindow_x);
 	defaults->update("RWINDOW_Y", rwindow_y);
 	defaults->update("RWINDOW_W", rwindow_w);
diff --git a/cinelerra-5.1/cinelerra/mainsession.h b/cinelerra-5.1/cinelerra/mainsession.h
index e8d31db6..6ea76e3b 100644
--- a/cinelerra-5.1/cinelerra/mainsession.h
+++ b/cinelerra-5.1/cinelerra/mainsession.h
@@ -154,6 +154,8 @@ public:
 	int cswindow_x, cswindow_y, cswindow_w, cswindow_h;
 // subtitle
 	int swindow_x, swindow_y, swindow_w, swindow_h;
+// mixer tile region
+	int tile_mixers_x, tile_mixers_y, tile_mixers_w, tile_mixers_h;
 // binfolder filter window
 	int bwindow_w, bwindow_h;
 // error window
diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C
index f8d4fc4e..c57c2ecf 100644
--- a/cinelerra-5.1/cinelerra/mwindow.C
+++ b/cinelerra-5.1/cinelerra/mwindow.C
@@ -1469,6 +1469,26 @@ int MWindow::select_zwindow(ZWindow *zwindow)
 
 void MWindow::tile_mixers()
 {
+	int x1 = session->tile_mixers_x;
+	int y1 = session->tile_mixers_y;
+	int x2 = x1 + session->tile_mixers_w;
+	int y2 = y1 + session->tile_mixers_h;
+	tile_mixers(x1, y1, x2, y2);
+}
+
+void MWindow::tile_mixers(int x1, int y1, int x2, int y2)
+{
+	if( x1 == x2 || y1 == y2 ) {
+// use top left quadrent
+		int sw = gui->get_screen_w(1, -1);
+		int sh = gui->get_screen_w(1, -1);
+		x1 = 1;     y1 = 1;
+		x2 = sw/2;  y2 = sh/2;
+	}
+	else {
+		if( x1 > x2 ) { int t = x1;  x1 = x2;  x2 = t; }
+		if( y1 > y2 ) { int t = y1;  y1 = y2;  y2 = t; }
+	}
 	int nz = 0;
 	for( int i=0; i<zwindows.size(); ++i ) {
 		ZWindow *zwindow = zwindows[i];
@@ -1477,8 +1497,6 @@ void MWindow::tile_mixers()
 	}
 	if( !nz ) return;
 	int zn = ceil(sqrt(nz));
-	int x1 = 1 + gui->get_x(), x2 = cwindow->gui->get_x();
-	int y1 = 1, y2 = gui->get_y();
 	int rw = gui->get_root_w(0), rh = gui->get_root_h(0);
 	if( x1 < 0 ) x1 = 0;
 	if( y1 < 0 ) y1 = 0;
@@ -3054,6 +3072,7 @@ void MWindow::restore_windows()
 	else if( session->show_lwindow && lwindow->gui->is_hidden() )
 		show_lwindow();
 
+	tile_mixers();
 	gui->lock_window("MWindow::restore_windows");
 	gui->focus();
 }
diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h
index 73cdcfac..6a4e2fb6 100644
--- a/cinelerra-5.1/cinelerra/mwindow.h
+++ b/cinelerra-5.1/cinelerra/mwindow.h
@@ -305,6 +305,7 @@ public:
 	void start_mixer();
 	int select_zwindow(ZWindow *zwindow);
 	void tile_mixers();
+	void tile_mixers(int x1, int x2, int y1, int y2);
 	int masters_to_mixers();
 	void mix_masters();
 	void set_gang_tracks(int v);
diff --git a/cinelerra-5.1/cinelerra/mwindowedit.C b/cinelerra-5.1/cinelerra/mwindowedit.C
index 66910d2a..6744cee8 100644
--- a/cinelerra-5.1/cinelerra/mwindowedit.C
+++ b/cinelerra-5.1/cinelerra/mwindowedit.C
@@ -2869,6 +2869,10 @@ int MWindow::masters_to_mixers()
 		for( ; track && !track->master; track=track->next )
 			mixer_last = track;
 		Track *next_track = track;
+		if( !master_track->armed ) {
+			master_track = next_track;
+			continue;
+		}
 		Mixer *master_mixer = 0;
 		for( int i=0, n=edl->mixers.size(); i<n; ++i ) {
 			if( master_track->index_in(edl->mixers[i]) >= 0 ) {
diff --git a/cinelerra-5.1/cinelerra/mwindowgui.C b/cinelerra-5.1/cinelerra/mwindowgui.C
index a68d4d17..6381fa07 100644
--- a/cinelerra-5.1/cinelerra/mwindowgui.C
+++ b/cinelerra-5.1/cinelerra/mwindowgui.C
@@ -1042,6 +1042,7 @@ void MWindowGUI::default_positions()
 	mwindow->cwindow->gui->unlock_window();
 	mwindow->awindow->gui->unlock_window();
 //printf("MWindowGUI::default_positions 2\n");
+	mwindow->tile_mixers();
 }
 
 
diff --git a/cinelerra-5.1/doc/shortcuts.html b/cinelerra-5.1/doc/shortcuts.html
index 6f3ec8a4..e4800715 100644
--- a/cinelerra-5.1/doc/shortcuts.html
+++ b/cinelerra-5.1/doc/shortcuts.html
@@ -758,7 +758,7 @@
 	</tr>
 	<tr>
 		<td height="26" align="right"><font face="Liberation Serif" size=4><br></font></td>
-		<td align="left"><font face="Liberation Serif" size=4>Tile mixers</font></td>
+		<td align="left"><font face="Liberation Serif" size=4>Drag Tile mixers</font></td>
 		<td align="left"><font face="Liberation Serif" size=4>'Alt-t’</font></td>
 		<td align="left"><font face="Liberation Serif" size=4>Tile mixer windows to original position/size</font></td>
 	</tr>
diff --git a/cinelerra-5.1/guicast/Makefile b/cinelerra-5.1/guicast/Makefile
index 04bc87a0..cf189dea 100644
--- a/cinelerra-5.1/guicast/Makefile
+++ b/cinelerra-5.1/guicast/Makefile
@@ -27,6 +27,7 @@ OBJS = \
 	$(OBJDIR)/bcdialog.o \
 	$(OBJDIR)/bcdisplay.o \
 	$(OBJDIR)/bcdisplayinfo.o \
+	$(OBJDIR)/bcdragbox.o \
 	$(OBJDIR)/bcdragwindow.o \
 	$(OBJDIR)/bcfilebox.o \
 	$(OBJDIR)/bcfontentry.o \
diff --git a/cinelerra-5.1/guicast/bcdragbox.C b/cinelerra-5.1/guicast/bcdragbox.C
new file mode 100644
index 00000000..10a39d96
--- /dev/null
+++ b/cinelerra-5.1/guicast/bcdragbox.C
@@ -0,0 +1,148 @@
+#include "bcdragbox.h"
+#include "bcmenuitem.h"
+#include "bctimer.h"
+#include "bcwindowbase.h"
+#include "colors.h"
+
+BC_DragBox::BC_DragBox(BC_WindowBase *parent)
+ : Thread(1, 0, 0)
+{
+	this->parent = parent;
+	popup = 0;
+	done = -1;
+}
+BC_DragBox::~BC_DragBox()
+{
+	if( running() ) {
+		done = 1;
+		cancel();
+	}
+	join();
+	delete popup;
+}
+
+void BC_DragBox::start_drag()
+{
+	popup = new BC_DragBoxPopup(this);
+	popup->lock_window("BC_DragBox::start");
+	for( int i=0; i<4; ++i )
+		edge[i] = new BC_Popup(parent, 0,0, 1,1, ORANGE, 1);
+	parent->grab_buttons();
+	parent->grab_cursor();
+	popup->grab(parent);
+	popup->create_objects();
+	popup->show_window();
+	popup->unlock_window();
+	done = 0;
+	Thread::start();
+}
+
+void BC_DragBox::run()
+{
+	popup->lock_window("BC_DragBox::run 0");
+	while( !done ) {
+		popup->update();
+		popup->unlock_window();
+		enable_cancel();
+		Timer::delay(200);
+		disable_cancel();
+		popup->lock_window("BC_DragBox::run 1");
+	}
+	int x0 = popup->lx0, y0 = popup->ly0;
+	int x1 = popup->lx1, y1 = popup->ly1;
+	parent->ungrab_cursor();
+	parent->ungrab_buttons();
+	popup->ungrab(parent);
+	for( int i=0; i<4; ++i ) delete edge[i];
+	popup->unlock_window();
+	delete popup;  popup = 0;
+	handle_done_event(x0, y0, x1, y1);
+}
+
+BC_DragBoxPopup::BC_DragBoxPopup(BC_DragBox *grab_thread)
+ : BC_Popup(grab_thread->parent, 0,0, 16,16, -1,1)
+{
+	this->grab_thread = grab_thread;
+	dragging = -1;
+	grab_color = ORANGE;
+	x0 = y0 = x1 = y1 = -1;
+	lx0 = ly0 = lx1 = ly1 = -1;
+}
+
+BC_DragBoxPopup::~BC_DragBoxPopup()
+{
+}
+
+int BC_DragBoxPopup::grab_event(XEvent *event)
+{
+	int cur_drag = dragging;
+	switch( event->type ) {
+	case ButtonPress: {
+		if( cur_drag > 0 ) return 1;
+		int x0 = event->xbutton.x_root;
+		int y0 = event->xbutton.y_root;
+		if( !cur_drag ) {
+			draw_selection(-1);
+			if( event->xbutton.button == RIGHT_BUTTON ) break;
+			if( x0>=get_x() && x0<get_x()+get_w() &&
+			    y0>=get_y() && y0<get_y()+get_h() ) break;
+		}
+		this->x0 = this->x1 = x0;
+		this->y0 = this->y1 = y0;
+		draw_selection(1);
+		dragging = 1;
+		return 1; }
+	case ButtonRelease:
+		dragging = 0;
+	case MotionNotify:
+		if( cur_drag > 0 ) {
+			this->x1 = event->xbutton.x_root;
+			this->y1 = event->xbutton.y_root;
+			draw_selection(0);
+		}
+		return 1;
+	default:
+		return 0;
+	}
+
+	hide_window();
+	sync_display();
+	grab_thread->done = 1;
+	return 1;
+}
+
+void BC_DragBoxPopup::update()
+{
+	set_color(grab_color ^= GREEN);
+	draw_box(0,0, get_w(),get_h());
+	flash(1);
+}
+
+void BC_DragBoxPopup::draw_selection(int show)
+{
+	if( show < 0 ) {
+		for( int i=0; i<4; ++i ) hide_window(0);
+		flush();
+		return;
+	}
+
+	int nx0 = x0 < x1 ? x0 : x1;
+	int nx1 = x0 < x1 ? x1 : x0;
+	int ny0 = y0 < y1 ? y0 : y1;
+	int ny1 = y0 < y1 ? y1 : y0;
+	lx0 = nx0;  lx1 = nx1;
+	ly0 = ny0;  ly1 = ny1;
+
+	--nx0;  --ny0;
+	BC_Popup **edge = grab_thread->edge;
+	edge[0]->reposition_window(nx0,ny0, nx1-nx0, 1);
+	edge[1]->reposition_window(nx1,ny0, 1, ny1-ny0);
+	edge[2]->reposition_window(nx0,ny1, nx1-nx0, 1);
+	edge[3]->reposition_window(nx0,ny0, 1, ny1-ny0);
+
+	if( show > 0 ) {
+		for( int i=0; i<4; ++i ) edge[i]->show_window(0);
+	}
+	flush();
+}
+
diff --git a/cinelerra-5.1/guicast/bcdragbox.h b/cinelerra-5.1/guicast/bcdragbox.h
new file mode 100644
index 00000000..4ecb9264
--- /dev/null
+++ b/cinelerra-5.1/guicast/bcdragbox.h
@@ -0,0 +1,41 @@
+#ifndef __BC_DRAGRECT_H__
+#define __BC_DRAGRECT_H__
+
+#include "bcwindowbase.inc"
+#include "bcdragbox.inc"
+#include "bcpopup.h"
+#include "thread.h"
+
+
+class BC_DragBox : public Thread
+{
+public:
+	BC_DragBox(BC_WindowBase *parent);
+	~BC_DragBox();
+	void start_drag();
+	void run();
+	virtual int handle_done_event(int x0, int y0, int x1, int y1) { return 0; }
+
+	BC_Popup *edge[4];
+	BC_WindowBase *parent;
+	BC_DragBoxPopup *popup;
+	int done;
+};
+
+class BC_DragBoxPopup : public BC_Popup
+{
+public:
+	BC_DragBoxPopup(BC_DragBox *grab_thread);
+	~BC_DragBoxPopup();
+	int grab_event(XEvent *event);
+	void update();
+	void draw_selection(int show);
+
+	BC_DragBox *grab_thread;
+	int dragging;
+	int grab_color;
+	int x0, y0, x1, y1;
+	int lx0, ly0, lx1, ly1;
+};
+
+#endif
diff --git a/cinelerra-5.1/guicast/bcdragbox.inc b/cinelerra-5.1/guicast/bcdragbox.inc
new file mode 100644
index 00000000..ae232b7d
--- /dev/null
+++ b/cinelerra-5.1/guicast/bcdragbox.inc
@@ -0,0 +1,7 @@
+#ifndef __BC_DRAGRECT_INC__
+#define __BC_DRAGRECT_INC__
+
+class BC_DragBox;
+class BC_DragBoxPopup;
+
+#endif
diff --git a/cinelerra-5.1/guicast/bcresources.C b/cinelerra-5.1/guicast/bcresources.C
index 54cef106..cdac6305 100644
--- a/cinelerra-5.1/guicast/bcresources.C
+++ b/cinelerra-5.1/guicast/bcresources.C
@@ -857,14 +857,14 @@ new_vframes(10,default_vscroll_data,
 	filebox_columntype[1] = FILEBOX_SIZE;
 	filebox_columntype[2] = FILEBOX_DATE;
 	filebox_columntype[3] = FILEBOX_EXTENSION;
-	filebox_columnwidth[0] = xS(200);
+	filebox_columnwidth[0] = xS(300);
 	filebox_columnwidth[1] = xS(100);
-	filebox_columnwidth[2] = xS(100);
-	filebox_columnwidth[3] = xS(100);
+	filebox_columnwidth[2] = xS(150);
+	filebox_columnwidth[3] = xS(49);
 	dirbox_columntype[0] = FILEBOX_NAME;
 	dirbox_columntype[1] = FILEBOX_DATE;
-	dirbox_columnwidth[0] = xS(200);
-	dirbox_columnwidth[1] = xS(100);
+	dirbox_columnwidth[0] = xS(400);
+	dirbox_columnwidth[1] = xS(199);
 
 	filebox_text_images = default_filebox_text_images;
 	filebox_icons_images = default_filebox_icons_images;
diff --git a/cinelerra-5.1/guicast/guicast.h b/cinelerra-5.1/guicast/guicast.h
index 62a37d93..6e93b2d7 100644
--- a/cinelerra-5.1/guicast/guicast.h
+++ b/cinelerra-5.1/guicast/guicast.h
@@ -29,6 +29,7 @@
 #include "bcbutton.h"
 #include "bcclipboard.h"
 #include "bcdialog.h"
+#include "bcdragbox.h"
 #include "bcdragwindow.h"
 #include "bclistboxitem.h"
 #include "bcpan.h"