;+ ; NAME: ; AdjustPosition ; ; PURPOSE: ; ; This is a program for interactively adjusting the plot position ; coordinates. The result of the function is a four-element floating ; point array of normalized coordinates, suitable for passing to the ; POSITION keyword of most IDL graphics commands. ; ; AUTHOR: ; ; FANNING SOFTWARE CONSULTING ; David Fanning, Ph.D. ; 1645 Sheely Drive ; Fort Collins, CO 80526 USA ; Phone: 970-221-0438 ; E-mail: david@idlcoyote.com ; Coyote's Guide to IDL Programming: http://www.idlcoyote.com ; ; CATEGORY: ; ; Graphics ; ; CALLING SEQUENCE: ; ; position = AdjustPosition(startingPosition) ; ; OPTIONAL INPUTS: ; ; startingPosition - A four-element array of normalized coordinates ; of the form [x0, y0, x1, y1]. ; ; OUTPUTS: ; ; position - The adjusted plot position. A four-element array of normalized coordinates. ; ; INPUT KEYWORDS: ; ; GROUP_LEADER - The group leader of this program. This keyword ; is required to ensure modal operation when calling from ; another widget program. ; ; TITLE - The title of the window. "Adjust Plot Position in Window..." by default. ; ; XOFFSET - The X offset of the program on the display. Calculated from the ; upper left-hand corner of the display. ; ; YOFFSET - The Y offset of the program on the display. Calculated from the ; upper left-hand corner of the display. ; ; OUTPUT KEYWORDS: ; ; CANCEL - Returns a 1 if the user selects the Cancel button. Returns 0 otherwise. ; Note that if the use cancels, the "position" parameter is set to the value of ; the "startingPosition" parameter. ; ; DEPENDENCIES: ; ; Reqires FSC_FIELD and FSC_PLOTWINDOW from the Coyote Library: ; ; http://www.idlcoyote.com/programs/fsc_field.pro ; http://www.idlcoyote.com/programs/fsc_plotwindow.pro ; ; MODIFICATION HISTORY: ; ; Written by David Fanning, March 2001. ;- ; ;******************************************************************************************; ; Copyright (c) 2008, by Fanning Software Consulting, Inc. ; ; All rights reserved. ; ; ; ; Redistribution and use in source and binary forms, with or without ; ; modification, are permitted provided that the following conditions are met: ; ; ; ; * Redistributions of source code must retain the above copyright ; ; notice, this list of conditions and the following disclaimer. ; ; * Redistributions in binary form must reproduce the above copyright ; ; notice, this list of conditions and the following disclaimer in the ; ; documentation and/or other materials provided with the distribution. ; ; * Neither the name of Fanning Software Consulting, Inc. nor the names of its ; ; contributors may be used to endorse or promote products derived from this ; ; software without specific prior written permission. ; ; ; ; THIS SOFTWARE IS PROVIDED BY FANNING SOFTWARE CONSULTING, INC. ''AS IS'' AND ANY ; ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ; ; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ; ; SHALL FANNING SOFTWARE CONSULTING, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, ; ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ; ; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ; ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ; ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ;******************************************************************************************; PRO AdjustPosition_PlotEvents, event ; This event handler responds to events generated by manipulating ; the plot position interactively with the mouse. Widget_Control, event.top, Get_UValue=info, /No_Copy ; Get the current position from the window. position = info.plotWindow->GetPosition() ; Update the text widgets. info.p0->Set_Value, position[0] info.p1->Set_Value, position[1] info.p2->Set_Value, position[2] info.p3->Set_Value, position[3] Widget_Control, event.top, Set_UValue=info, /No_Copy END ;------------------------------------------------------------------------------------------ PRO AdjustPosition_FieldEvents, event ; The event handler responds to events from the text widgets. Widget_Control, event.top, Get_UValue=info, /No_Copy ; Get the values from the text widgets. x0 = info.p0->Get_Value() y0 = info.p1->Get_Value() x1 = info.p2->Get_Value() y1 = info.p3->Get_Value() ; Make sure the values are ordered properly. There must ; be at least 0.05 unit between values. IF x0 GT x1 THEN BEGIN temp = x0 x0 = x1 x1 = temp ENDIF IF x1-x0 LT 0.05 THEN x0 = 0 > (x1 - 0.05) info.p0->Set_Value, x0 info.p2->Set_Value, x1 IF y0 GT y1 THEN BEGIN temp = y0 y0 = y1 y1 = temp ENDIF IF y1-y0 LT 0.05 THEN y0 = 0 > (y1 - 0.05) info.p1->Set_Value, y0 info.p3->Set_Value, y1 ; Set the position in the display. position = [x0, y0, x1, y1] info.plotWindow->SetWindowSize, position ; Update the form info pointer. *(info.ptr) = {cancel:0, position:position} Widget_Control, event.top, Set_UValue=info, /No_Copy END ;------------------------------------------------------------------------------------------ PRO AdjustPosition_ButtonEvents, event ; This event handler responds to Cancel and Accept buttons. Widget_Control, event.top, Get_UValue=info, /No_Copy ; Get the latest plot position. position = info.plotWindow->GetPosition() ; Which button is it? Load the pointer with the correct ; information. Widget_Control, event.id, Get_Value=buttonValue CASE buttonValue OF 'Cancel': *(info.ptr) = {cancel:1, position:position} 'Accept': *(info.ptr) = {cancel:0, position:position} ENDCASE Widget_Control, event.top, /Destroy END ;------------------------------------------------------------------------------------------ FUNCTION AdjustPosition, currentPosition, Group_Leader=group_leader, $ Title=title, Cancel=cancelled, XOffset=xoffset, YOffset=yoffset ; Check keywords. IF N_Elements(currentPosition) EQ 0 THEN currentPosition = [0.15, 0.15, 0.9, 0.9] IF N_Elements(title) EQ 0 THEN title = "Adjust Plot Position in Window..." ; Create TLB as modal, if possible. Otherwise, will have to ; rely on command line blocking. IF N_Elements(group_leader) NE 0 THEN BEGIN tlb = Widget_Base(Title=title, Modal=1, Group_Leader=group_leader, $ Column=1, Base_Align_Center=1) ENDIF ELSE BEGIN tlb = Widget_Base(Title=title, Column=1, Base_Align_Center=1) ENDELSE ; Create the plot window widget. plotwindow = FSC_PlotWindow(tlb, PageSize='DISPLAY', WindowSize=currentPosition, $ Event_Pro='AdjustPosition_PlotEvents', /Color) ; Other widgets. label = Widget_Label(tlb, Value='Adjust plot position with MOUSE. Use middle button to CENTER.') rowbaseID = Widget_Base(tlb, Row=2) f = FSC_Field(rowbaseID, Title='x0: ', Value=currentPosition[0], Decimal=3, Object=p0, $ /CR_Only, Event_Pro='AdjustPosition_FieldEvents') f = FSC_Field(rowbaseID, Title='y0: ', Value=currentPosition[1], Decimal=3, Object=p1, $ /CR_Only, Event_Pro='AdjustPosition_FieldEvents') f = FSC_Field(rowbaseID, Title='x1: ', Value=currentPosition[2], Decimal=3, Object=p2, $ /CR_Only, Event_Pro='AdjustPosition_FieldEvents') f = FSC_Field(rowbaseID, Title='y1: ', Value=currentPosition[3], Decimal=3, Object=p3, $ /CR_Only, Event_Pro='AdjustPosition_FieldEvents') buttonBaseID = Widget_Base(tlb, Row=1, Event_Pro='AdjustPosition_ButtonEvents') b = Widget_Button(buttonBaseID, Value='Cancel') b = Widget_Button(buttonBaseID, Value='Accept') ; Create a pointer to collect position information. Set for CANCEL. ptr = Ptr_New({Cancel:1}) ; Position the widget on the display. IF (N_Elements(xoffset) EQ 0) AND (N_Elements(yoffset) EQ 0) THEN cgCenterTLB, tlb ELSE BEGIN IF N_Elements(xoffset) EQ 0 THEN xoffset = 100 IF N_Elements(yoffset) EQ 0 THEN yoffset = 100 Widget_Control, tlb, XOffset=xoffset, YOffset=yoffset ENDELSE Widget_Control, tlb, /Realize ; Create and store info structure. info = {p1:p1, p2:p2, p3:p3, p0:p0, ptr:ptr, plotWindow:plotWindow} Widget_Control, tlb, Set_UValue=info, /No_Copy ; Block here until the widget is destroyed. XManager, 'adjustposition', tlb ; Set the cancel flag. Return starting position. cancelled = (*ptr).cancel IF cancelled THEN BEGIN Ptr_Free, ptr RETURN, currentPosition ENDIF ; Free pointer and return the new position. thisPosition = (*ptr).position Ptr_Free, ptr RETURN, thisPosition END