Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado
Hi, I'm setting up a system to draw annotation in data space on an image and I've encountered (another!) problem with fg. So here is the (relatively) short story: I draw a square on an image in data space and I handle events a "graphic event handler class". Say I have an object selected, then I want to move this by clicking anywhere on the image and dragging the mouse and releasing. So what I do is: - catch the position of the click in the mouse down event - calculate the difference between current position in the mouse motion event with respect to the last position (eventually given by mouse down event or updated after processing) - translate the object in one of either methods: [Translation method] delta = newPos-PreviousPos self.myObj->tranlsate, delta[0], delta[1] [getData/setData method] delta = newPos-PreviousPos self.myObj->getData, xx, yy xx += delta[0] yy += delta[1] self.myObj->setData, xx, yy Now here are the problems with these two approaches: [Translation method] This works, as long as one does not try to translate in data space. This proved to be tricky because if the object was scaled before, also the translations where scaled. I could not find a consistent pattern to reproduce, so forgive me for just throwing this out like this. However, using the translate method with normal coordinates works well. [getData/setData method] This proved to generate a clear error. The highlighted corners of the square are place elsewhere. Yeah, can't describe this any better, but the good thing, is that it's reproducible and the code is below. After a couple of hours spent trying to figure out what was happening with data coordinates and with the get/set method, I resorted to using normal coordinates with the translation method. However, there is a bug hidden somewhere with the get/set. Below is the code to test. Cheers, Helder Instructions: Run the code below, then click on the edge of the square and move it with the mouse. In my case the result is terrible and obvious to see... function SqObjEvent::MouseMotion, oWin, x, y, KeyMods if self.isCorner then return, 1 if self.lbPressed then begin pos = oWin->ConvertCoord(x, y, /device, /to_data) delta = pos[0:1]-[self.x0,self.y0] self.sq->getData, xx, yy xx += delta[0] yy += delta[1] self.sq->setData, xx, yy self.x0 = pos[0] self.y0 = pos[1] endif return, 1 end function SqObjEvent::MouseDown, oWin, x, y, button, keyMods, clicks if button ne 1 then return, 1 if clicks gt 1 then return,1 pos = oWin->ConvertCoord(x, y, /device, /to_data) self.x0 = pos[0] self.y0 = pos[1] self.lbPressed = 1b self.sq->getData, xx, yy nPos = oWin->ConvertCoord( x, y, /device, /to_norm) nData = oWin->ConvertCoord(xx, yy, /device, /to_norm) self.isCorner = min(sqrt((nPos[0]-nData[0,0:3])^2+(nPos[1]-nData[1,0:3])^2)) lt 0.03 return, 1 end function SqObjEvent::MouseUp, oWin, x, y, button self.lbPressed = 0b self.isCorner = 0b return, 1 end function SqObjEvent::Init, io, sq self.io=io self.sq=sq self.x0 = 0d self.y0 = 0d self.isCorner = 0b self.lbPressed = 0b return, 1 end pro SqObjEvent__define void = {SqObjEvent, $ inherits GraphicsEventAdapter, $ io:obj_new(),$ sq:obj_new(),$ x0:0d,$ y0:0d,$ isCorner:0b,$ lbPressed:0b} end pro testMoveSquare tlb = widget_base(/column) wWindow = widget_window(tlb, xsize=500, ysize=500);,$ widget_control, tlb, /realize widget_control, wWindow, get_value=oWin io = image(dist(1000), image_dimensions=[500,500], current=oWin, margin=0) sq = polygon([0.4,0.6,0.6,0.4]*500.0,[0.4,0.4,0.6,0.6]*500.0, '-b2', fill_background=0, /data, target=io) oWin.event_handler = obj_new('SqObjEvent', io, sq) xmanager, 'testMoveObjects', tlb, event_handler = 'testMoveObjects_event', /no_block end