| 
 | 
 | 
 
Home » U++ Library support » ArrayCtrl, HeaderCtrl & GridCtrl » Problem with Drag&Drop in ArrayCtrl 
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	
		
		
			| Re: Problem with Drag&Drop in ArrayCtrl [message #22556 is a reply to message #22552] | 
			Sun, 26 July 2009 23:50    | 
		 
		
			
				
				
				  | 
					
						  
						koldo
						 Messages: 3453 Registered: August 2008 
						
					 | 
					Senior Veteran  | 
					 | 
		 
		 
	 | 
 
	
		| luzr wrote on Sun, 26 July 2009 17:28 |  
 | koldo wrote on Sat, 18 July 2009 07:51 |   More simple:  
 
Is it possible to update/refresh only one row in an ArrayCtrl ? 
 
Best regards 
Koldo
  |  
  
 
	void       ArrayCtrl::RefreshRow(int i); 
  |  
  
 
Hello Mirek 
 
Unfortunately RefreshRow() does not repaint the row. 
 
To force the repaint I have to scroll up and down and then I see the row repainted. 
 
Using instead UpdateRefresh() repaints the rows properly, but it seems it cancels the Drag & Drop possibility.  
 
It is difficult to prepare a sample case as the application is rather big. Here I put some details: 
 
The variable is declared under the TopWindow class as 
 
 
The layout is in: 
	filesList.AddColumn("Thumbnail").SetDisplay(Single<DisplayThumbnail>()).HeaderTab().Min(50);
	filesList.AddColumn("Properties").HeaderTab().Min(50);
	filesList.MultiSelect().HeaderObject().Absolute().Clipboard();
	filesList.HeaderTab(0).SetRatio(10);
	filesList.ColumnWidths("100 100");
	filesList.WhenDropInsert = 	THISBACK(DropInsertFilelist);
	filesList.WhenDrag = 		THISBACK(DragFilelist);
	filesList.WhenDrop = 		THISBACK(DropFilelist);
 
 
DisplayThumbnail declaration: 
struct DisplayThumbnail : public Display {
    virtual void Paint(Draw& w, const Rect& r, const Value& val, Color ink, Color paper, dword style) const; 
};
 
 
And Drag & Drop functions 
	void DropFilelist(PasteClip& d)
	{
		if(AcceptText(d)) {
			filesList.Add(GetString(d), GetString(d));
			filesList.SetFocus();
		}
	}
	void DropInsertFilelist(int line, PasteClip& d)
	{
		if(AcceptInternal<ArrayCtrl>(d, "array")) {
			filesList.InsertDrop(line, d);
			filesList.SetFocus();
			filesList.SetLineCy(70);
		}
	}
	void DragFilelist()
	{
		filesList.DoDragAndDrop(InternalClip(filesList, "array"));
	}
 
 
Best regards 
Koldo 
		
		
  Best regards 
Iñaki
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	| 
		
 |  
	
		
		
			| Re: Problem with Drag&Drop in ArrayCtrl [message #22571 is a reply to message #22559] | 
			Mon, 27 July 2009 17:20    | 
		 
		
			
				
				
				  | 
					
						  
						mirek
						 Messages: 14271 Registered: November 2005 
						
					 | 
					Ultimate Member  | 
					 | 
		 
		 
	 | 
 
	
		| koldo wrote on Mon, 27 July 2009 03:03 |   Hello Mirek 
 
This is: 
 
void MainWindow::Timer()
{
	if (timerOn)
		return;
	timerOn = true;
	
	for (int i = 0; i < thumbnails.GetCount(); ++i) {
		if (!thumbnails[i].loaded) {
			if (thumbnails[i].type == TYPE_IMAGE) 
				LoadThumbnail(i);
			else if (thumbnails[i].type == TYPE_VIDEO) 
				LoadThumbnailVideo(i);
			filesList.UpdateRefresh();		
			//filesList.RefreshRow(FindThumbnail(thumbnails[i].fileName));
			break;
		}
	}	
	timerOn = false;
} 
 
thumbnails array has all the thumbnailed images. This loops opens the first not opened yet. 
 
With this when you open a folder all file names are viewed and every 200ms a thumbnail is loaded and viewed, similar to Nautilus in Gnome. 
 
Best regards 
Koldo
  |  
  
 
And LoadThumbnail* ? (I need to see commands that you use to alter ArrayCtrl content...). 
 
BTW, I believe RefreshRow works as it should. Any chance the problem is in FindThumbnail? 
 
(In fact, using normal "Set", you do not even need RefreshRow - it is called implicitly). 
 
Mirek
		
		
		[Updated on: Mon, 27 July 2009 17:23] Report message to a moderator  
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	
		
		
			| Re: Problem with Drag&Drop in ArrayCtrl [message #22577 is a reply to message #22574] | 
			Tue, 28 July 2009 03:06    | 
		 
		
			
				
				
				  | 
					
						  
						mirek
						 Messages: 14271 Registered: November 2005 
						
					 | 
					Ultimate Member  | 
					 | 
		 
		 
	 | 
 
	
		I have tried to create a testcase: 
 
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
struct TestDisplay : Display {
	virtual void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
	{
		Display::Paint(w, r, AsString(q) + " " + AsString(GetTickCount()),
		               ink, paper, style);
	}
};
struct App : TopWindow {
	ArrayCtrl a, b;
	Splitter  s;
	TimeCallback tb;
	
	void Timer()
	{
		a.UpdateRefresh();
	}
	void DnD(PasteClip& d)
	{
		if(AcceptText(d)) {
			a.Add(GetString(d), GetString(d));
			a.SetFocus();
		}
	}
	void DnDInsert(int line, PasteClip& d)
	{
		if(AcceptInternal<ArrayCtrl>(d, "array")) {
			a.InsertDrop(line, d);
			a.SetFocus();
		}
		if(AcceptText(d)) {
			a.Insert(line);
			a.Set(line, 0, GetString(d));
			a.SetCursor(line);
			a.SetFocus();
		}
	}
	void DnDInsertB(int line, PasteClip& d)
	{
		if(AcceptInternal<ArrayCtrl>(d, "array")) {
			const ArrayCtrl& src = GetInternal<ArrayCtrl>(d);
			bool self = &src == &b;
			Vector< Vector<Value> > data;
			for(int i = 0; i < src.GetCount(); i++)
				if(src.IsSel(i)) {
					Value v = src.Get(i, 0);
					data.Add().Add(IsNumber(v) ? FormatIntRoman((int)src.Get(i, 0)) : String(v));
				}
			b.InsertDrop(line, data, d, self);
			b.SetFocus();
		}
	}
	void Drag()
	{
		if(a.DoDragAndDrop(InternalClip(a, "array")) == DND_MOVE)
			a.RemoveSelection();
	}
	void DragB()
	{
		if(b.DoDragAndDrop(InternalClip(b, "array"), b.GetDragSample()) == DND_MOVE)
			b.RemoveSelection();
	}
	typedef App CLASSNAME;
	App() {
		a.AddColumn("You can paste the text here too").SetDisplay(Single<TestDisplay>());
		a.MultiSelect();
		a.WhenDropInsert = THISBACK(DnDInsert);
		a.WhenDrop = THISBACK(DnD);
		a.WhenDrag = THISBACK(Drag);
		b.AddColumn("Roman numbers");
		b.MultiSelect();
		b.WhenDropInsert = THISBACK(DnDInsertB);
		b.WhenDrag = THISBACK(DragB);
		Add(s.Horz(a, b));
		for(int i = 0; i < 200; i++) {
			a.Add(i);
			b.Add(FormatIntRoman(i, true));
		}
		Sizeable();
		
		tb.Set(-200, THISBACK(Timer));
	}
};
GUI_APP_MAIN
{
	App().Run();
}
 
 
I believe this is as close as possible to your app - and it seems to work quite fine both in linux and win32. 
 
Mirek
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	
		
		
			| Re: Problem with Drag&Drop in ArrayCtrl [message #22580 is a reply to message #22577] | 
			Tue, 28 July 2009 09:49    | 
		 
		
			
				
				
				  | 
					
						  
						koldo
						 Messages: 3453 Registered: August 2008 
						
					 | 
					Senior Veteran  | 
					 | 
		 
		 
	 | 
 
	
		Hello Mirek 
 
Thank you for the testcase. I have changed it to show the problem. 
 
RefreshRow works well but Drag & Drop does not work while there are thumbnails to be loaded. 
 
To run it put the file "c:\\demo.jpg" that will be the thumbnail to be loaded. 
 
Perhaps to do this right would I have to use multitasking ? 
 
Best regards 
Koldo 
 
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
Array <Image> imgLst;
	
struct TestDisplay : Display {
	virtual void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
	{
		w.DrawRect(r, paper);
		int id = q.Is<int>() ? q : -1;
		if (id >= 0 && id < imgLst.GetCount()) {
			Rect rect(r.left, r.top, r.left+70, r.top+70);
			if (imgLst[id])
				w.DrawImage(rect, imgLst[id]);
			else
				Display::Paint(w, r, "Image not loaded", ink, paper, style);
		} else
			Display::Paint(w, r, "Image not available", ink, paper, style);
	}
};
struct App : TopWindow {
	ArrayCtrl a, b;
	Splitter  s;
	TimeCallback tb;
	
	void Timer()
	{
		for (int i = 0; i < imgLst.GetCount(); ++i) {
			if (!imgLst[i]) {
				imgLst[i] = StreamRaster::LoadFileAny("c:\\demo.jpg");
				a.RefreshRow(i);
				return;
			}
		}
	}
	void DnD(PasteClip& d)
	{
		if(AcceptText(d)) {
			a.Add(GetString(d), GetString(d));
			a.SetFocus();
		}
	}
	void DnDInsert(int line, PasteClip& d)
	{
		if(AcceptInternal<ArrayCtrl>(d, "array")) {
			a.InsertDrop(line, d);
			a.SetFocus();
		}
		if(AcceptText(d)) {
			a.Insert(line);
			a.Set(line, 0, GetString(d));
			a.SetCursor(line);
			a.SetFocus();
		}
	}
	void DnDInsertB(int line, PasteClip& d)
	{
		if(AcceptInternal<ArrayCtrl>(d, "array")) {
			const ArrayCtrl& src = GetInternal<ArrayCtrl>(d);
			bool self = &src == &b;
			Vector< Vector<Value> > data;
			for(int i = 0; i < src.GetCount(); i++)
				if(src.IsSel(i)) {
					Value v = src.Get(i, 0);
					data.Add().Add(IsNumber(v) ? FormatIntRoman((int)src.Get(i, 0)) : String(v));
				}
			b.InsertDrop(line, data, d, self);
			b.SetFocus();
		}
	}
	void Drag()
	{
		if(a.DoDragAndDrop(InternalClip(a, "array")) == DND_MOVE)
			a.RemoveSelection();
	}
	void DragB()
	{
		if(b.DoDragAndDrop(InternalClip(b, "array"), b.GetDragSample()) == DND_MOVE)
			b.RemoveSelection();
	}
	typedef App CLASSNAME;
	App() {
		a.AddColumn("You can paste the text here too").SetDisplay(Single<TestDisplay>());
		a.MultiSelect();
		a.WhenDropInsert = THISBACK(DnDInsert);
		a.WhenDrop = THISBACK(DnD);
		a.WhenDrag = THISBACK(Drag);
		a.SetLineCy(70);
		
		b.AddColumn("Roman numbers");
		b.MultiSelect();
		b.WhenDropInsert = THISBACK(DnDInsertB);
		b.WhenDrag = THISBACK(DragB);
		Add(s.Horz(a, b));
		for(int i = 0; i < 40; i++) {
			a.Add(i);
			imgLst.Add();
			b.Add(FormatIntRoman(i, true));
		}
		Sizeable();
		
		tb.Set(-200, THISBACK(Timer));
	}
};
GUI_APP_MAIN
{
	App().Run();
} 
		
		
  Best regards 
Iñaki
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	
		
		
			| Re: Problem with Drag&Drop in ArrayCtrl [message #22599 is a reply to message #22596] | 
			Wed, 29 July 2009 13:16    | 
		 
		
			
				
				
				  | 
					
						  
						koldo
						 Messages: 3453 Registered: August 2008 
						
					 | 
					Senior Veteran  | 
					 | 
		 
		 
	 | 
 
	
		Hello Mirek 
 
I have tried both samples GuiMT amd GuiLock. 
 
GuiLock is simpler but I have realized that while moving application window GuiLock gets stucked but GuiMT follows refreshing the window. This is a nice behaviour. What could it be ? 
 
In the same GuiMT changing 
PostCallback(callback2(f.gui, &Divisors::ShowResult, f.line, "working..." + r1 + r2));  
with 
f.gui->table.Set(f.line, 1, "working..." + r1 + r2));  
 
The program works but GuiMT gets stucked. 
 
Best regards 
Koldo 
 
 
Addendum:  
I have tested both in linux and the window is refreshed while it is moved 
 
Addendum 2: 
Compiled with MinGW GUIMT works but GUILock gets hanged with this message "Assertion failed in C:\upp\uppsrc\Draw\DrawLock.cpp, line 28 sGLockLevel > 0". 
 
In post  http://www.ultimatepp.org/forum/index.php?t=msg&th=4145& amp;start=0& Mirek says 
 
| Quote: |   You cannot do MT in mingw.
  |  
  
 
Is this just temporal ?. If not I think it would have to be indicated in the documentation
		
		
  Best regards 
Iñaki
		[Updated on: Fri, 31 July 2009 17:16] Report message to a moderator  
 |  
	| 
		
	 | 
 
 
 |   
Goto Forum:
 
 Current Time: Tue Nov 04 02:39:45 CET 2025 
 Total time taken to generate the page: 0.04868 seconds 
 |   
 |  
  |