#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access #pragma DefaultTab={3,20,4} // Set default tab width in Igor Pro 9 and later static Constant panelMinSize = 100 static Constant edgeDetRange = 15 function buildMainGraph(wave plotThis) Display plotThis SetWindow kwTopWin hook(update)=HookFunction end function buildSubGraph(string gName, wave plotThis) GetWindow $gName, expand variable gExpand = V_value; gExpand = gExpand == 0 ? 1 : gExpand // pixel conversion and expansion factor variable pixConv = ScreenResolution/72*gExpand GetWindow $gName psizeDC variable size = max(min((V_bottom-V_top)/4,(V_right-V_left)/5),panelMinSize)/pixConv variable wL = (V_left+20)/pixConv, wT = (V_top+20)/pixConv, wR = wL+size*1.2, wB = wT+size NewPanel/HOST=$gName/N=floatPanel/W=(wL,wT,wR,wB) Display/HOST=$(gName+"#floatPanel")/FG=(FL,FT,FR,FB)/N=subPlot plotThis ModifyGraph/W=$(gName+"#floatPanel#subPlot") frameStyle=1 SetActiveSubwindow $gName end function HookFunction(STRUCT WMWinHookStruct &s) string gName = StringFromList(0,s.winName,"#") string sName = gname+"#floatPanel#subPlot", floatStruct = "" int hookTakeOver = 0 GetWindow $gName, expand variable gExpand = V_value; gExpand = gExpand == 0 ? 1 : gExpand // pixel conversion and expansion factor variable pixConv = ScreenResolution/72*gExpand variable wEdge = 0, dragEdge = 0, edgeDist = 15 STRUCT DragStruct d STRUCT rect tempRect if (WhichListItem(s.eventName, "mousedown;mousemoved;mouseup;")>-1 && !CmpStr(s.winName, sName)) // mouse events on the sub-graph GetWindow $sName psizeDC tempRect.top = v_top tempRect.left = v_left tempRect.right = v_right tempRect.bottom = v_bottom if (!CheckPointInRect(s.mouseLoc,tempRect)) // mouse is not in plot area GetWindow $sName gsizeDC; wEdge = 1 // encode sub-window mouse edge detection into wEdge wEdge = abs(s.mouseloc.h-v_left) maybe we missed a mouse-up event? SetWindow $gName userdata(floatDrag)="0" dragEdge = 0 endif else break endif StructGet/S d, GetUserData(gName, "", "dragStruct") variable deltah = s.mouseloc.h - d.mouse_init.h variable deltav = s.mouseloc.v - d.mouse_init.v tempRect = d.subwinRect tempRect.top += deltav * (dragEdge == 1 || dragEdge == 2 || dragEdge == 3) tempRect.left += deltah * (dragEdge == 1 || dragEdge == 2 || dragEdge == 4) tempRect.right += deltah * (dragEdge == 1 || dragEdge == 5 || dragEdge == 3) tempRect.bottom += deltav * (dragEdge == 1 || dragEdge == 5 || dragEdge == 4) if (CheckRectPosAndSize(tempRect, d.graphRect)) MoveSubwindow/W=$(gname+"#floatPanel") fnum=(tempRect.left/pixConv, tempRect.top/pixConv, tempRect.right/pixConv, tempRect.bottom/pixConv) d.subwinRect = tempRect endif d.mouse_init = s.mouseloc StructPut/S d, floatStruct SetWindow $gName userdata(dragStruct)=floatStruct break case "resize": if (!WinType(sName)) break endif GetWindow $gName wsizeDC int isHostMinW = abs(v_right-v_left) <= panelMinSize int isHostMinH = abs(v_bottom-v_top) <= panelMinSize GetWindow $sName wsizeDC variable subW = abs(v_right-v_left) variable subH = abs(v_bottom-v_top) variable dW = isHostMinW ? 0 : panelMinSize - subW // check if the panel width is smaller than the minimum variable dH = isHostMinH ? 0 : panelMinSize - subH if (dW <= 0 && dH <= 0) break endif string dragInfo = GetUserData(gName, "", "dragStruct") if (strlen(dragInfo)) StructGet/S d, dragInfo subW = abs(d.subwinRect.right -d.subwinRect.left) subH = abs(d.subwinRect.bottom-d.subwinRect.top) endif tempRect.top = v_top - dH*(dH>0) tempRect.bottom = v_top - dH*(dH>0) + subH tempRect.left = v_left - dW*(dW>0) tempRect.right = v_left - dW*(dW>0) + subW MoveSubwindow/W=$(gname+"#floatPanel") fnum=(tempRect.left/pixConv, tempRect.top/pixConv, tempRect.right/pixConv, tempRect.bottom/pixConv) break endswitch return hookTakeOver end // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ static structure DragStruct STRUCT point mouse_init STRUCT Rect subwinRect STRUCT Rect graphRect endstructure static function CheckRectPosAndSize(STRUCT rect &in, STRUCT rect &ref) int isInside = (in.left>ref.left && in.top>ref.top && in.right= panelMinSize && abs(in.bottom-in.top) >= panelMinSize return isInside && isMinSize end static function CheckPointInRect(STRUCT point &pnt, STRUCT rect &ref) return ( pnt.h>ref.left && pnt.href.top && pnt.v