Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » ArrayCtrl, HeaderCtrl & GridCtrl » Problem with Drag&Drop in ArrayCtrl
Re: Problem with Drag&Drop in ArrayCtrl [message #22608 is a reply to message #22599] Fri, 31 July 2009 19:04 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
koldo wrote on Wed, 29 July 2009 07:16

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.



Careful there. The real problem with MT is that some synchronization bugs happen with low probability - that means the app seems to work, but might crash once a hour or week.

Mirek

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; 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[/quote]
Re: Problem with Drag&Drop in ArrayCtrl [message #22774 is a reply to message #22608] Thu, 13 August 2009 13:42 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3358
Registered: August 2008
Senior Veteran
Hello all

I have prepared a MT version using PostCallback that works very well.

Main change is in function LoadImageThread that substitute the timer function.

#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>() ? (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;
	Thread threadPainter;
	
	void RefreshThumb(int row)
	{
		a.RefreshRow(row);	
	}
	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();
};

void LoadImageThread(App *gui, Array <Image> *imgs)
{
	for (int i = 0; i < (*imgs).GetCount(); ++i) {
		for (int j = 0; j < gui->a.GetCount(); ++j) {
			Value ix = gui->a.Get(j, 0);
			if (ix.Is<int>() && i == ix) {
				if (!(*imgs)[ix]) {
					(*imgs)[ix] = StreamRaster::LoadFileAny("/mnt/C/demo.jpg");
					PostCallback(callback1(gui, &App::RefreshThumb, i));
				}
			}
		}
	}
}

App::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 < 25; i++) {
		a.Add(i);
		imgLst.Add();
		b.Add(FormatIntRoman(i, true));
	}
	Sizeable();
	
	threadPainter.Run(callback2(LoadImageThread, this, &imgLst));
}

GUI_APP_MAIN
{
	App().Run();
}


This is the output

index.php?t=getfile&id=1880&private=0

An annoying problem is that RefreshRow(row) works well in general, but if I just drag an image and does not click or roll the mouse, the image refreshing is stopped like in the image. This behavior happens both in Linux and in Windows. If I click or roll the mouse all the loaded images are refreshed immediately.

Just changing RefreshRow(row) with UpdateRefresh() solves the problem.

Best regards
koldo
  • Attachment: dib.PNG
    (Size: 84.33KB, Downloaded 480 times)


Best regards
Iñaki
Re: Problem with Drag&Drop in ArrayCtrl [SOLVED] [message #22902 is a reply to message #22774] Wed, 26 August 2009 09:17 Go to previous message
koldo is currently offline  koldo
Messages: 3358
Registered: August 2008
Senior Veteran
Hello all

Finally I have implemented this in the original program and it works very well.

Thank you Mirek + mrjt for your help.

Best regards
Koldo


Best regards
Iñaki
Previous Topic: Substring formating in ArrayCtrl (SqlCtrl)
Next Topic: Right Click on GridCtrl
Goto Forum:
  


Current Time: Sun Apr 28 23:46:40 CEST 2024

Total time taken to generate the page: 0.03099 seconds