/*----------------------------------------------------------------------------*/ /* */ /* Copyright (c) 2013-2014 Rexx Language Association. All rights reserved. */ /* */ /* This program and the accompanying materials are made available under */ /* the terms of the Common Public License v1.0 which accompanies this */ /* distribution. A copy is also available at the following address: */ /* https://www.oorexx.org/license.html */ /* */ /* 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 Rexx Language Association 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "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 THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS 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; 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. */ /* */ /*----------------------------------------------------------------------------*/ /** * The augmentedResize.rex example has the same initial dialog layout as the * basicResize.rex example. However, to give a better appearance to the dialog * as it is enlarged or shrunk, the precise way each dialog control is to be * changed is defined in the program code. * * All code that defines the sizing of the resizable dialog has to be defined * in the defineSizing() method. This method is invoked automatically by the * ooDialog framework. The default implementation of the method does nothing. * The method is meant to be over-ridden by the programmer to change the * default sizing parameters of the ResizingAdmin class. The method is invoked * before the underlying dialog is created. The programmer can not inovke any * method that requires the underlying dialog to exist from the defineSizing() * method. */ -- Get the directory our source code files are located in. sd = locate() -- Use the global .constDir, only, for symbolic IDs, load the symbols from -- the basicResize.h file. .application~setDefaults('O', sd'rc\basicResize.h', .false) dlg = .ResizableDlg~new(sd"rc\basicResize.rc", IDD_RESIZABLE) dlg~execute("SHOWTOP", IDI_DLG_OOREXX) return 0 -- End of entry point. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*\ Directives, Classes, or Routines. \* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ ::requires "ooDialog.cls" -- Inherit the ResizingAdmin class to make resizing available. ::class 'ResizableDlg' subclass RcDialog inherit ResizingAdmin /** defineSizing() * * This method is invoked automatically by the ooDialog framework. A default * implmentation is provided. That implmentation does not do anything. To * change how the default implmentation works, the program must over-ride the * defineSizing() method and invoke ResizingAdmin methods to change the * defaults. * * Each dialog control must be referenced by its resource ID. The ID can be * numeric or symbolic. This is no different than any other use of ooDialog. * * The basic premise of the resizing admin is that each side, left, top, right, * etc., of every control window can be "pinned" to the side of another window. * By default each side is pinned to a side of the dialog window itself. But, * any side of a dialog control window can be pinned to a side of any other * dialog control in the dialog. * * There are several different "types" of pins. The programmer defines the * "sizing" of any dialog control by defining how each "edge" of the control * should be sized. The definition consists of: the id of the control, which * side of the control is to be pined, which side of another window the control * edge is pinned to, the type of the pin, and the ID of the other window. For * instance: * * The left side of a button control could be "pinned" to the left side of the * dialog window using a 'proportional' pin. * * or * * The right side of a list-view control could be "pinned" the left side of an * edit control using a 'stationary' pin. * * The control windows are identified by the resource ID of the control. The * dialog window is identified by a special constant provided by the * ResizingAdmin class, the IDC_DEFAULT_PINTO_WINDOW constant. * * The edges (sides) of windows are identified by the keywords: LEFT, TOP, * RIGHT, and BOTTOM. In addition there are two other edge keywords: XCENTER * and YCENTER. * * XCENTER specifies that the edge is pinned to the horizontal center of the * pinned to edge. YCENTER specifies that the edge is pinned to the vertical * center of the pinned to edge. * * The types of pins are identified by the kewords: PROPORTIONAL, STATIONARY, * MYTOP, and MYLEFT. * * PROPORTIONAL : The distance between the edge and the pinned to edge grows, * (or shrinks,) proportionally to the size of the pinned to * window. * * STATIONARY : The distance between the edge and the pinned to edge remains * equal to what it was when the dialog was initially created. * * MYLEFT : A special keyword, can only be used for the right edge of a * control. Pins the right edge of the control to its left * edge. This has the effect of keeping the width of the * control constant. * * MYTOP : A special keyword, can only be used for the bottom edge of a * control. Pins the bottom edge of the control to its top * edge. This has the effect of keeping the height of the * control constant. * * The ooDialog framework uses an algorithm to resize / reposition the dialog * control windows that virtually eliminates flicker. This code requires that * the sizing for every control in the dialog be specified. When the underlying * dialog is first created, the framework enumerates every dialog control. If a * a control did not have its sizing defined by the programmer, the framework * assigns the default sizing to the control and adds the sizing definition to * the end of the sizing definitions list. * * When the sizing event notification is received, the ooDialog framework * resizes and repositions every dialog control in the order of the sizing * defintions in the list. * * Because of this, any "pinned to" window must come before the window that pins * to it in the list. I.e., if a side of a list-view control is to be "pinned" * to the left side of an edit control, the sizing definition for the edit * control must be specified before the sizing definition for the list-view is * specified. Sizing definitions are placed in the list in the order the * programmer defines the control sizing. The sizing definitions for all * controls not defined by the programmer are appended to the end of the list, * in the order they are enumerated by the operating system. * * The code in the following defineSizing() method shows how to apply the above * explanation. The ooDialog reference manual should be consulted for the * complete documentation on the ResizingAdmin class. */ ::method defineSizing -- Assign the IDC_DEFAULT_PINTO_WINDOW constant to a short variable name. -- This is just done here to keep the code a little more readable. In -- addition, IDC_DEFAULT_PINTO_WINDOW is the default. In almost all cases, -- IDC_DEFAULT_PINTO_WINDOW can simply be omitted. ID_DLG = self~IDC_DEFAULT_PINTO_WINDOW -- The sizing for each edge of a dialog control can be specified -- individually. Here we define the sizing for the list-view. It is pinned -- to the left top corner and right bottom corner of the dialog. This means -- the pixel distance between the edges of the list-view and the edges of -- the dialog will remain constant. self~controlLeft(IDC_LV_MAIN, 'STATIONARY', 'LEFT', ID_DLG) self~controlTop(IDC_LV_MAIN, 'STATIONARY', 'TOP', ID_DLG) self~controlRight(IDC_LV_MAIN, 'STATIONARY', 'RIGHT', ID_DLG) self~controlBottom(IDC_LV_MAIN, 'STATIONARY', 'BOTTOM', ID_DLG) -- The complete sizing for a single control can be specified at one time. -- The first argument must be the resource ID of the control. Following -- that are four arguments defining the sizing for the 4 edges of the -- control. The must be in order: left top right bottom. However, each -- argument is optional. If it is omitted, the default sizing for that edge -- is used. -- -- Each of the 4 arguments must be an array. The fist item in the array is -- required and is the type of pin. The second item in the array is also -- required. It is the edge of the other window that the edge of the -- control is pinned to. The third item in the array is the id of the -- window that the control's edge is pinned to. This item can be omitted, -- it defaults to the dialog window. -- -- This definition pins the Test push button to the right top corner of the -- dialog. Since it is a 'stationary' pin the push button will 'stay' in -- place. The right side of the button is pinned to its own left side. -- This makes the width of the button constant, it will not change as the -- dialog is sized. The bottom edge of the button is pinned to its top. -- This makes the height of the button constant. -- -- Note that when the pin type is MYLEFT or MYRIGHT, the other 2 -- specifications, the edge and window, are always ignored. However, the -- controlSizing() method requires that the first 2 items in the array not -- be omitted. self~controlSizing(IDC_PB_TEST, - .array~of('STATIONARY', 'RIGHT', IDC_LV_MAIN), - .array~of('STATIONARY', 'TOP'), - .array~of('MYLEFT', 'LEFT'), - .array~of('MYTOP', 'TOP') - ) -- The following just defines the sizing for all of the rest of the -- controls. self~controlSizing(IDC_GB_TEST, - .array~of('STATIONARY', 'LEFT'), - .array~of('STATIONARY', 'BOTTOM', IDC_LV_MAIN), - .array~of('STATIONARY', 'RIGHT'), - .array~of('MYTOP', 'TOP') - ) self~controlSizing(IDC_EDIT_LABELS, - .array~of('PROPORTIONAL', 'LEFT', IDC_GB_TEST), - .array~of('STATIONARY', 'TOP', IDC_GB_TEST), - .array~of('STATIONARY', 'RIGHT', IDC_GB_TEST), - .array~of('MYTOP', 'TOP') - ) self~controlSizing(IDC_ST_LABELS, - .array~of('STATIONARY', 'LEFT', IDC_EDIT_LABELS), - .array~of('STATIONARY', 'TOP', IDC_GB_TEST), - .array~of('MYLEFT', 'LEFT'), - .array~of('MYTOP', 'TOP') - ) self~controlSizing(IDC_ST_NAMES, - .array~of('STATIONARY', 'LEFT', IDC_GB_TEST), - .array~of('STATIONARY', 'TOP', IDC_GB_TEST), - .array~of('MYLEFT', 'LEFT'), - .array~of('MYTOP', 'TOP') - ) self~controlSizing(IDC_EDIT_NAMES, - .array~of('STATIONARY', 'LEFT', IDC_ST_NAMES), - .array~of('STATIONARY', 'TOP', IDC_GB_TEST), - .array~of('STATIONARY', 'LEFT', IDC_ST_LABELS), - .array~of('MYTOP', 'TOP') - ) self~controlSizing(IDC_ST_PLACES, - .array~of('STATIONARY', 'LEFT', IDC_GB_TEST), - .array~of('STATIONARY', 'TOP', IDC_GB_TEST), - .array~of('MYLEFT', 'LEFT'), - .array~of('MYTOP', 'TOP') - ) self~controlSizing(IDC_EDIT_PLACES, - .array~of('STATIONARY', 'LEFT', IDC_ST_PLACES), - .array~of('STATIONARY', 'TOP', IDC_GB_TEST), - .array~of('STATIONARY', 'LEFT', IDC_EDIT_NAMES), - .array~of('MYTOP', 'TOP') - ) self~controlSizing(IDOK, - .array~of('STATIONARY', 'RIGHT'), - .array~of('STATIONARY', 'BOTTOM'), - .array~of('MYLEFT', 'LEFT'), - .array~of('MYTOP', 'TOP') - ) self~controlSizing(IDCANCEL, - .array~of('STATIONARY', 'RIGHT'), - .array~of('STATIONARY', 'BOTTOM'), - .array~of('MYLEFT', 'LEFT'), - .array~of('MYTOP', 'TOP') - ) return 0 /** initDialog() * * This is just a typical initDialog() method. We merely put some items into * the list-view to give the dialog some texture. */ ::method initDialog self~newGroupBox(IDC_GB_TEST)~setText('Group Box Stationary Left / Right') list = self~newListView(IDC_LV_MAIN) list~setView('REPORT') columnNames = .array~of("Line", "Number") list~addExtendedStyle("FULLROWSELECT GRIDLINES CHECKBOXES HEADERDRAGDROP") list~InsertColumn(0, "Row (Column 1)", 95) list~InsertColumn(1, "Column 2", 95) list~InsertColumn(2, "Column 3", 95) do i = 1 to 200 list~addRow(i, , "Line" i, "Column" 2, "Column" 3) end