360 likes | 517 Views
Resize of Progress Windows . Brynjar Hasle, Chemistry as www.chemistry.no Chairman Progress Usergroup Norway www.pugnorway.no. Consept. Independent layer (library) separated from application objects (only consideration is the screen objects). Simple setup at window level
E N D
Resize of Progress Windows Brynjar Hasle, Chemistry as www.chemistry.no Chairman Progress Usergroup Norway www.pugnorway.no
Consept Independent layer (library) separated from application objects (only consideration is the screen objects) Simple setup at window level + overrides pr combination of window and frame Work with absolute positions (pixels)
Basic window setup pos>x: follow right edge Cust.no: Name: Cust.no: 1234 Search >Y: Details Excel
Basic window setup PROCEDURE InitializeObject: DYNAMIC-FUNCTION(”setOrgWinSize”:U, THIS-PROCEDURE:CURRENT-WINDOW, 600,400,0,0). /* limit X, limit Y, min X, min Y */ (0,0) sets design size as minimum for window. ON WINDOW-RESIZED: DYNAMIC-FUNCTION(”setWidgetResize”:U, THIS-PROCEDURE:CURRENT-WINDOW, THIS-PROCEDURE:CURRENT-WINDOW, ”Resize”:U,””).
DemoPicsPro, PartSrc For Progress to allow window-size to increase the virtual-width/height setting must be adjusted (to 1600 by 1200, f.ex). Window settings are stored in temp-tables. It’s a good habit to free up memory: ON CLOSE OF THIS-PROCEDURE DYNAMIC-FUNCTION("setCleanUpResize”:U, THIS-PROCEDURE:CURRENT-WINDOW).
Override of basic setup Cust.no: Name: Cust.no: 1234 Search Details Excel
Override of basic setup DYNAMIC-FUNCTION("setNoResizeY”:U, THIS-PROCEDURE:CURRENT-WINDOW, FRAME {&FRAME-NAME}:HANDLE, "RECT-1”:U). ------- Optionally make the search button stay with the fill-ins: DYNAMIC-FUNCTION("setNoMoveX”:U, THIS-PROCEDURE:CURRENT-WINDOW, FRAME {&FRAME-NAME}:HANDLE, ”btnSearch”:U). /* can be comma-separated list of widgets */ DYNAMIC-FUNCTION("setNoResizeX”:U, THIS-PROCEDURE:CURRENT-WINDOW, FRAME {&FRAME-NAME}:HANDLE, "RECT-1”:U).
Working with tab-folders(suppressed windows / smart objects) When a (new) frame is realized it has to be adjusted to the current window-size: PROCEDURE InitializeObject: DYNAMIC-FUNCTION(”setWidgetResize”:U, FRAME {&FRAME-NAME}:FIRST-CHILD, THIS-PROCEDURE:CURRENT-WINDOW, ”Adjust”:U,””). NB: Overrides are set pr window/frame, default behaviour is set at window-level
DemoFeste, Obje (By the way, this is how the library is initialized: DEF VAR hResizeLib AS HANDLE NO-UNDO. RUN ResizeLib.p PERSIST SET hResizeLib. SESSION:ADD-SUPER-PROC(hResizeLib). - f.ex in the login routine)
Handling multiple resizeable objects Cust.no: Name: Cust.no: 1234 Search Customers: Orders: Details Confirm
Handling multiple resizeable objects Resizeable objects are (here) frames, rectangles, browsers, control-frames, etc. When two or more objects must share the same delta x/y only one of the objects can be resized: DYNAMIC-FUNCTION("setNoResizeY”:U, THIS-PROCEDURE:CURRENT-WINDOW, FRAME {&FRAME-NAME}:HANDLE, "RECT-1,brwOrders”:U).
Handling multiple resizeable objects In this example, since we didn’t bother to adjust the y-limit up to make the order browser and it’s label follow the bottom-edge of the window we must add an extra override: DYNAMIC-FUNCTION("setAddMoveY”:U, THIS-PROCEDURE:CURRENT-WINDOW, FRAME {&FRAME-NAME}:HANDLE, ”fill-in_OrderLabel,brwOrders”:U). Note that in this case the label must be a fill-in (view-as text, maybe) cause a TEXT widget cannot have a name.
DemoFrontier This demo is using the downloadable version of ResizeLib
Splitbars Cust.no: Name: Cust.no: 1234 Search Customers: Orders: Details Confirm
Splitbars The splitbar is a moveable button. The move can be limited either by a designated frame or by minimum required space from top and bottom window-edge (as in this example). It also needs to be initiated: Procedure InitializeObject: DYNAMIC-FUNCTION("setSplitBarY", THIS-PROCEDURE:CURRENT-WINDOW, btnSplitBarY:HANDLE IN FRAME {&FRAME-NAME}, NO). /* */ The same call applies to END-MOVE of splitbar button /* YES: Extra option to limit splitbar move to 1st half of window - does not apply here */
Splitbars Also we must give all handles to the widgets that should follow the move: DYNAMIC-FUNCTION("setFollowSplitBarY", THIS-PROCEDURE:CURRENT-WINDOW, btnSplitBarY:HANDLE IN FRAME {&FRAME-NAME}, STRING(brwCustomer:HANDLE) + "," + STRING(fill-in_OrderLabel:HANDLE) + "," + STRING(brwOrders:HANDLE)). And then set limits to the moveability: DYNAMIC-FUNCTION("setSplitBarYlimits", btnSplitBarY:HANDLE IN FRAME {&FRAME-NAME}, 150,100). /* Min from top and bottom */
DemoTimereg Only one vertical and one horizontal splitbar can exist in the same window. To make it easier to obtain widget-handles (from ADM1 objects) there’s a special function available that returns a comma-separated list: DYNAMIC-FUNCTION("getWidgetHandles", FRAME {&FRAME-NAME}:HANDLE, 0). /* Initial level, should always be 0 */
Splitbars and tab-folders When a suppressed window is run (typically on change of tab-folder) it now needs to adjust both to window-size and to current position of the splitbar(s). This requires a few additional steps. • Before the suppressed window is run, pull the splitbar(s) back to the original (design) position: • DYNAMIC-FUNCTION("resetSplitBarPos”:U, • THIS-PROCEDURE:CURRENT-WINDOW,0). 2. Run the suppressed window At this time all the handles to widgets that should follow the splitbar move are available.. (to be obtained from current procedure and the suppressed window)
Splitbars and tab-folders 3. ..so we can re-initiate widgets to follow splitbar move: DYNAMIC-FUNCTION("setFollowSplitBarX”:U, THIS-PROCEDURE:CURRENT-WINDOW, btnSplitBarX:HANDLE IN FRAME frSplitBarX, cFollowXbar). /* the list of handles */ 4. And finally adjust the new frame to current window size: DYNAMIC-FUNCTION("setWidgetResize”:U, hSuppressedFrame:FIRST-CHILD, THIS-PROCEDURE:CURRENT-WINDOW, "Adjust”:U,""). /* hSuppressedFrame is obtained from the suppressed window. The function also repositions the splitbar to it’s previous position */
DemoLast Frontier In this example with double layer of tab-folders we must adjust the size of the splitbar (and it’s frame) to current window-size when the splitbar is re-created: FRAME frSplitBarX:HEIGHT-PIXELS = FRAME frSplitBarX:HEIGHT-PIXELS + DYNAMIC-FUNCTION("getCurrentDeltaY”:U). btnSplitBarX:HEIGHT-PIXELS IN FRAME frSplitBarX = FRAME frSplitBarX:HEIGHT-PIXELS - 2. Also to enable the re-created splitbar to be set to it’s previous position we use a special cleanup procedure when the window containing the splitbar is closed: DYNAMIC-FUNCTION("setCleanUpSplitBar”:U, THIS-PROCEDURE:CURRENT-WINDOW, btnSplitBarX:HANDLE IN FRAME frSplitBarX).
ADM ADM toolbars and tab-folders are handled by the library – no extra overrides. Sometimes you need the handle to a smart-object frameto set overrides. For ADM1 you can add this function to smart.i: &IF DEFINED (getFrameHandleDefined) = 0 &THEN &SCOPED-DEFINE getFrameHandleDefined FUNCTION getFrameHandle RETURNS WIDGET-HANDLE (): &IF "{&FRAME-NAME}" NE "" &THEN RETURN FRAME {&FRAME-NAME}:HANDLE. &ELSE RETURN ?. &ENDIF END FUNCTION. &ENDIF ADM2 has a built in function, ”getContainerHandle”
Dynamics Dynamics has built-in methods for resize. For dynamic objects that’s fine but for static objects it’s hard to follow the Dynamics approach (sample code from the Toolbar and Menu Designer): PROCEDURE repositionSplitBar: DEFINE VARIABLE dMinWidth AS DECIMAL NO-UNDO. DEFINE VARIABLE dMinHeight AS DECIMAL NO-UNDO. DEFINE VARIABLE hFolder AS HANDLE NO-UNDO. DEFINE VARIABLE hPanel AS HANDLE NO-UNDO. DEFINE VARIABLE iPage AS INTEGER NO-UNDO. &SCOPED-DEFINE PANEL_WIDTH 58 {fnarg lockWindow TRUE}. {get MinWidth dMinWidth h_dyntreeview} . ASSIGN btnSplitBar:COL IN FRAME {&FRAME-NAME} = MAX(btnSplitBar:COL ,dMinWidth) btnSplitBar:COL = MIN(btnSplitBar:COL, {&WINDOW-NAME}:WIDTH * 4 / 5) btnSplitBar:ROW = 1 btnSplitBar:HEIGHT = FRAME {&FRAME-NAME}:HEIGHT coModule:WIDTH = MAX(1,btnSplitBar:COL - coModule:COL + .3) coObjType:WIDTH = coModule:WIDTH NO-ERROR. .. To be continued..
Dynamics RUN resizeObject IN h_dyntreeview (INPUT {&WINDOW-NAME}:HEIGHT - FRAME {&FRAME-NAME}:ROW - 1.25, INPUT btnSplitBar:COL). /* Check whether the folder width needs to be increased or decreased */ {get ContainerHandle hFolder h_folder}. {get ContainerHandle hpanel h_pupdsav}. IF hFolder:column <= btnSplitBar:COL + btnSplitBar:WIDTH THEN /* SplitBar is being moved to the right */ DO: RUN resizeObject IN h_folder (INPUT {&WINDOW-NAME}:HEIGHT - FRAME {&FRAME-NAME}:ROW + .9, INPUT {&WINDOW-NAME}:WIDTH - btnSplitBar:COL - btnSplitBar:WIDTH ). RUN repositionObject IN h_folder (INPUT 1.00, btnSplitBar:COL + btnSplitBar:WIDTH). RUN resizeObject IN h_pupdsav (hPanel:HEIGHT, IF {&WINDOW-NAME}:WIDTH - btnSplitBar:COL - 1 < {&PANEL_WIDTH} THEN {&WINDOW-NAME}:WIDTH - btnSplitBar:COL - 2 ELSE {&PANEL_WIDTH}). RUN repositionObject IN h_pupdsav (hPanel:ROW, btnSplitBar:COL + 1 + ({&WINDOW-NAME}:WIDTH - btnSplitBar:COL - hPanel:WIDTH - 1) / 2 ). IF VALID-HANDLE(h_gscicview) THEN RUN centerObject(INPUT h_gscicview, INPUT 1). IF VALID-HANDLE(h_gsmmsview) THEN RUN centerObject(INPUT h_gsmmsview, INPUT 1). IF VALID-HANDLE(h_gsmmiview) THEN RUN centerObject(INPUT h_gsmmiview, INPUT 1). IF VALID-HANDLE(h_gsmitview) THEN RUN centerObject(INPUT h_gsmitview, INPUT 1). IF VALID-HANDLE(h_gscobviewt) THEN RUN centerObject(INPUT h_gscobviewt, INPUT 1). ....
Dynamics IF VALID-HANDLE(h_gsmomviewt) THEN RUN centerObject(INPUT h_gsmomviewt, INPUT 1). IF VALID-HANDLE(h_gsmtmview) THEN RUN centerObject(INPUT h_gsmtmview, INPUT 1). IF VALID-HANDLE(h_gsmombrow) THEN DO: RUN resizeObject IN h_gsmombrow(6.91,{&WINDOW-NAME}:WIDTH - btnSplitBar:COL - 7). RUN repositionObject IN h_gsmombrow(2.67, btnSplitBar:COL + 4). END. END. /* End splitbar being moved to right */ ELSE DO: /* Splitbar being moved to left */ RUN repositionObject IN h_folder (INPUT 1.00, btnSplitBar:COL + btnSplitBar:WIDTH ). RUN resizeObject IN h_folder (INPUT {&WINDOW-NAME}:HEIGHT - FRAME {&FRAME-NAME}:ROW + .9, INPUT {&WINDOW-NAME}:WIDTH - btnSplitBar:COL - btnSplitBar:WIDTH ). RUN repositionObject IN h_pupdsav (hPanel:ROW, IF {&WINDOW-NAME}:WIDTH - btnSplitBar:COL - 1 > {&PANEL_WIDTH} THEN btnSplitBar:COL + 1 + ({&WINDOW-NAME}:WIDTH - btnSplitBar:COL - {&PANEL_WIDTH} - 1) / 2 ELSE btnSplitBar:COL + 2). RUN resizeObject IN h_pupdsav (hPanel:HEIGHT, IF {&WINDOW-NAME}:WIDTH - btnSplitBar:COL - 1 < {&PANEL_WIDTH} THEN {&WINDOW-NAME}:WIDTH - btnSplitBar:COL - 3 ELSE {&PANEL_WIDTH}). IF VALID-HANDLE(h_gscicview) THEN RUN centerObject(INPUT h_gscicview, INPUT 2). IF VALID-HANDLE(h_gsmmsview) THEN RUN centerObject(INPUT h_gsmmsview, INPUT 2). IF VALID-HANDLE(h_gsmmiview) THEN RUN centerObject(INPUT h_gsmmiview, INPUT 2). ....
Dynamics IF VALID-HANDLE(h_gsmitview) THEN RUN centerObject(INPUT h_gsmitview, INPUT 2). IF VALID-HANDLE(h_gscobviewt) THEN RUN centerObject(INPUT h_gscobviewt, INPUT 2). IF VALID-HANDLE(h_gsmomviewt) THEN RUN centerObject(INPUT h_gsmomviewt, INPUT 2). IF VALID-HANDLE(h_gsmombrow) THEN DO: RUN repositionObject IN h_gsmombrow(2.67, btnSplitBar:COL + 4). RUN resizeObject IN h_gsmombrow(6.91,{&WINDOW-NAME}:WIDTH - btnSplitBar:COL - 7). END. IF VALID-HANDLE(h_gsmtmview) THEN RUN centerObject(INPUT h_gsmtmview, INPUT 2). END. /* End splitbar being moved to left */ /* the calls to the folder is untabbing the tab folders. Reset tabs */ {get CurrentPage iPage}. IF iPage > 2 THEN DO: {set CurrentPage 1}. END. RUN ShowCurrentPage IN h_folder (IF giLastTabPage = 2 THEN 2 ELSE 1). /* Select the first tab folder */ {set CurrentPage iPage}. {fnarg lockWindow FALSE}. END PROCEDURE.
Other Fill-ins are not resized by default. To resize: DYNAMIC-FUNCTION("setAddResizeX”:U, THIS-PROCEDURE:CURRENT-WINDOW, FRAME {&FRAME-NAME}:HANDLE, "fi-cTotal”:U). Function to lock window update: DYNAMIC-FUNCTION("setLockWindowUpdate”:U,TRUE). Function to display all widgets with names and types: DYNAMIC-FUNCTION (”ShowMeTheWidgets”:U, hWidget, /* handle to window, frame.. */ 0, /* level, always 0 */ ””, /* try ”bottom-up” */ ”c:\temp\widgetlist.txt” /* result */ ).