'encoding UTF-8 Do not remove or change this line!
'**************************************************************
'
' Licensed to the Apache Software Foundation (ASF) under one
' or more contributor license agreements. See the NOTICE file
' distributed with this work for additional information
' regarding copyright ownership. The ASF licenses this file
' to you under the Apache License, Version 2.0 (the
' "License"); you may not use this file except in compliance
' with the License. You may obtain a copy of the License at
'
' http://www.apache.org/licenses/LICENSE-2.0
'
' Unless required by applicable law or agreed to in writing,
' software distributed under the License is distributed on an
' "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
' KIND, either express or implied. See the License for the
' specific language governing permissions and limitations
' under the License.
'
'**************************************************************
' **
' ** short description : Tools to draw and select form controls in basic-ide
' **
'\******************************************************************************
private const ICONTROLCOUNT = 22
'*******************************************************************************
function hGetControlParams( cParam as string ) as integer
'///
Retrieve basic parameters to draw formcontrols to a dialog
'///All values are in percent relative to the window size.
'///+ All values are optimized for 1024x768 pixels screen resolution but
'///+ have been tested successfully with 1280x1024 and 800x600
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Name of the coordinate (string). Valid options are:
'///
'///+- "XOREGO" (Upper left corner)
'///+- "YOREGO" (Upper left corner)
'///+- "XDIST" (Distance between the upper left corners of neighbor controls)
'///+- "YDIST" (Distance between the upper left corners of neighbor controls)
'///+- "XSIZE" (Width of control)
'///+- "YSIZE" (Heighth of the control)
'///
'///
'///Returns:
'///
'///+- Coordinate/Distance/Size in percent of window size (integer)
'///
'///+- A number between 1 and 100
'///+- 0 on error (invalid function parameter)
'///
'///
'///Description:
'///
cParam = ucase( cParam )
'///+- Currently following values are defined:
'///
select case ( cParam )
'///+- XOREGO = 31
case "XOREGO" : hGetControlParams() = 31
'///+- XDIST = 8
case "XDIST" : hGetControlParams() = 8
'///+- XSIZE = 6
case "XSIZE" : hGetControlParams() = 6
'///+- YOREGO = 30
case "YOREGO" : hGetControlParams() = 30
'///+- YDIST = 7
case "YDIST" : hGetControlParams() = 7
'///+- YSIZE = 5
case "YSIZE" : hGetControlParams() = 5
'///+- Incorrect function parameter = 0
case else : hGetControlParams() = 0
'///
end select
'///
end function
'*******************************************************************************
function hGetControlName( iControl as integer ) as string
'///A function to deliver a speaking name for all form controls
'///Note that the numbers of the controls are unique
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 22, see description below
'///
'///
'///Returns:
'///
'///+- Name for a control (string)
'///
'///+- Name for a control (may contain whitespaces)
'///+- An empty string in case of an invalid function parameter
'///
'///
'///Description:
'///
'///+- Currently following control are defined:
'///
select case iControl
'///+- Push Button
case 1 : hGetControlName() = "Push Button"
'///+- Image Control
case 2 : hGetControlName() = "Image Control"
'///+- Check Box
case 3 : hGetControlName() = "Check Box"
'///+- Radio Button
case 4 : hGetControlName() = "Radio Button"
'///+- Fixed Text
case 5 : hGetControlName() = "Fixed Text"
'///+- Edit Field
case 6 : hGetControlName() = "Edit Field"
'///+- List Box
case 7 : hGetControlName() = "List Box"
'///+- Combo Box
case 8 : hGetControlName() = "Combo Box"
'///+- Vertical ScrollBar
case 9 : hGetControlName() = "Vertical ScrollBar"
'///+- Horizontal ScrollBar
case 10 : hGetControlName() = "Horizontal ScrollBar"
'///+- Frame
case 11 : hGetControlName() = "Frame"
'///+- Progress Bar
case 12 : hGetControlName() = "Progress Bar"
'///+- Vertical Fixed Line
case 13 : hGetControlName() = "Vertical Fixed Line"
'///+- Horizontal Fixed Line
case 14 : hGetControlName() = "Horizontal Fixed Line"
'///+- Date Field
case 15 : hGetControlName() = "Date Field"
'///+- Time Field
case 16 : hGetControlName() = "Time Field"
'///+- Numeric Field
case 17 : hGetControlName() = "Numeric Field"
'///+- Currency Field
case 18 : hGetControlName() = "Currency Field"
'///+- Form Field
case 19 : hGetControlName() = "Form Field"
'///+- Pattern Field
case 20 : hGetControlName() = "Pattern Field"
'///+- File Control
case 21 : hGetControlName() = "File Control"
'///+- Tree Control
case 22 : hGetControlName() = "Tree Control"
'///
'///+- "" for function parameter < 1 or > 22
case else : sControl = ""
end select
'///
end function
'*******************************************************************************
function hInsertControl( iControl as integer ) as string
'///Function to insert one of the BASIC formcontrols by index
'///Note that the numbers of the controls are unique
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 22, see description below
'///
'///
'///Returns:
'///
'///+- Name for a control (string)
'///
'///+- Name for a control (may contain whitespaces)
'///+- An empty string in case of an invalid function parameter
'///
'///
'///Description:
'///
const CFN = "hInsertControl::"
Kontext "ToolsCollectionBar"
'///+- Click on the requested button on the ToolsCollectionBar:
'///
select case iControl
'///+- Push Button
case 1 : InsPushButton.click()
'///+- Image Control
case 2 : InsImgCtrl.click()
'///+- Check Box
case 3 : InsCheckbox.click()
'///+- Radio Button
case 4 : InsRadioButton.click()
'///+- Fixed Text
case 5 : InsFixedText.click()
'///+- Edit Field
case 6 : InsEditField.click()
'///+- List Box
case 7 : InsListbox.click()
'///+- Combo Box
case 8 : InsComboBox.click()
'///+- Vertical ScrollBar
case 9 : InsScrollBarV.click()
'///+- Horizontal ScrollBar
case 10 : InsScrollBarH.click()
'///+- Frame
case 11 : InsFrame.click()
'///+- Progress Bar
case 12 : InsProgressbar.click()
'///+- Vertical Fixed Line
case 13 : InsFixedLineV.click()
'///+- Horizontal Fixed Line
case 14 : InsFixedLineH.click()
'///+- Date Field
case 15 : InsDateField.click()
'///+- Time Field
case 16 : InsTimeField.click()
'///+- Numeric Field
case 17 : InsNumField.click()
'///+- Currency Field
case 18 : InsCurrencyField.click()
'///+- Form Field
case 19 : InsFormField.click()
'///+- Pattern Field
case 20 : InsPatternField.click()
'///+- File Control
case 22 : InsFileCtrl.click()
'///+- Tree Control
case 22 : InsTreeControl.click()
end select
'///
'///+- "" for function parameter < 1 or > 22
hInsertControl() = hGetControlName( iControl )
'///
end function
'*******************************************************************************
function hDrawControlOnDialog( iControl as integer ) as string
'///Draw a control on a dialog at a fixed position
'///Note that the numbers of the controls are unique
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 22, see description for hInsertControl()
'///
'///
'///Returns:
'///
'///+- Name for a control (string)
'///
'///+- Name for a control (may contain whitespaces)
'///+- An empty string in case of an invalid function parameter
'///
'///
'///Description:
'///
const CFN = "hDrawControlOnDialog::"
dim sControl as string ' The name of the current control
dim brc as boolean ' some returnvalue
' coordinates of the controls on the dialog in the dialog-editor
dim iXO as integer
dim iYO as integer
dim iXE as integer
dim iYE as integer
'///+- determine where the control is to be painted (hGetControlPos...)
iXO = hGetControlPosXO( iControl )
iYO = hGetControlPosYO( iControl )
iXE = hGetControlPosXE( iControl )
iYE = hGetControlPosYE( iControl )
'///+- click the desired control
sControl = hInsertControl( iControl )
printlog( CFN & " Index=" & iControl & _
" at XO=" & iXO & _
" XE=" & iXE & _
" YO=" & iYO & _
" YE=" & iYE & _
" : " & sControl )
'///+- Draw the control (using hDrawControl(...))
brc = hDrawControl( iXO, iYO, iXE, iYE )
hDrawControlOnDialog() = sControl
'///
end function
'*******************************************************************************
function hDrawControl( xPos as integer, _
yPos as integer, _
xEnd as integer, _
yEnd as integer ) as boolean
'///Draw a control on the dialog pane in the dialog editor
'///Starting point: Basic IDE/Dialog editor
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Note: All units are in percent of the relative to the current window size
'///Input:
'///
'///+- X-Orego (Upper left corner) (integer)
'///
'///+- Min = 0
'///+- Max = 100 (allowed but not useful)
'///
'///+- Y-Orego (Upper left corner) (integer)
'///
'///+- Min = 0
'///+- Max = 100 (allowed but not useful)
'///
'///+- X-End (Lower right corner) (integer)
'///
'///+- Min = 0
'///+- Max = 100 (allowed but not useful)
'///
'///+- Y-End (Lower right corner) (integer)
'///
'///+- Min = 0
'///+- Max = 100 (allowed but not useful)
'///
'///
'///Returns:
'///
'///+- Errorstatus (boolean)
'///
'///+- TRUE on success
'///+- FALSE on failure
'///
'///
'///Description:
'///
const CFN = "hDrawControl::"
'///+- Set context to Basic IDE
Kontext "BasicIDE"
'///+- Draw the control using mouse actions
'///
'///+- Mouse down on pos X/Y-Orego
'///+- Mouse move to pos X/Y-End
'///+- Mouse up on pos X/Y-End
'///
'///
autoexecute = false
DialogWindow.MouseUp( 20 , 20 ) : wait 100
try
DialogWindow.MouseMove ( xPos, yPos ) : wait 100
DialogWindow.MouseDown ( xPos, yPos ) : wait 100
DialogWindow.MouseMove ( xEnd, yEnd ) : wait 100
DialogWindow.MouseUp ( xEnd, yEnd ) : wait 100
hDrawControl() = true
catch
warnlog( "#i39852# " & CFN & "Unable to complete mouseactions on dialog" )
hDrawControl() = false
endcatch
autoexecute = true
end function
'*******************************************************************************
function hGetControlPosXO( iControl as integer ) as integer
'///Retrieve the upper left X-coordinate for a control
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 22, see description for hInsertControl()
'///
'///
'///Returns:
'///
'///+- X-Orego in percent of window size (integer)
'///
'///Description:
'///
dim xOffset as integer
xOffset = hGetControlParams( "xorego" )
dim xDistance as integer
xDistance = hGetControlParams( "xdist" )
'///+- Define an offset for the control depending on its ID
'///
'///+- < 7 : Column one
'///+- 7 ... 12 : Column two
'///+- 13 ... 18 : Column three
'///+- > 18 : Column four
'///
'///
select case ( iControl )
case 1, 2, 3, 4, 5, 6 : hGetControlPosXO() = xOffset
case 7, 8, 9, 10, 11, 12 : hGetControlPosXO() = xOffset + 1 * xDistance
case 13, 14, 15, 16, 17, 18 : hGetControlPosXO() = xOffset + 2 * xDistance
case 19, 20, 21, 22, 23, 24 : hGetControlPosXO() = xOffset + 3 * xDistance
end select
end function
'*******************************************************************************
function hGetControlPosYO( iControl as integer ) as integer
'///Retrieve the upper left Y-coordinate for a control
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 21, see description for hInsertControl()
'///
'///
'///Returns:
'///
'///+- Y-Orego in percent of window size (integer)
'///
'///Description:
'///
dim yOffset as integer
yOffset = hGetControlParams( "yorego" )
dim yDistance as integer
yDistance = hGetControlParams( "ydist" )
'///+- Define an offset for the control depending on its ID
'///
'///+- 1 , 7 , 13 , 19 : Row one
'///+- 2 , 8 , 14 , 20 : Row two
'///+- 3 , 9 , 15 , 21 : Row three
'///+- 4 , 10 , 16 , 22 : Row four
'///+- 5 , 11 , 17 : Row five
'///+- 6 , 12 , 18 : Row six
'///
'///
select case ( iControl )
case 1, 7, 13, 19 : hGetControlPosYO() = yOffset
case 2, 8, 14, 20 : hGetControlPosYO() = yOffset + 1 * yDistance
case 3, 9, 15, 21 : hGetControlPosYO() = yOffset + 2 * yDistance
case 4, 10, 16, 22 : hGetControlPosYO() = yOffset + 3 * yDistance
case 5, 11, 17, 23 : hGetControlPosYO() = yOffset + 4 * yDistance
case 6, 12, 18, 24 : hGetControlPosYO() = yOffset + 5 * yDistance
end select
end function
'*******************************************************************************
function hGetControlPosXE( iControl as integer ) as integer
'///Retrieve the lower right X-coordinate for a control
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 22, see description for hInsertControl()
'///
'///
'///Returns:
'///
'///+- X-End in percent of window size (integer)
'///
'///Description:
'///
'///+- Get pos for X-Orego, add "XSIZE"
hGetControlPosXE() = hGetControlPosXO( iControl ) + _
hGetControlParams( "xsize" )
'///
end function
'*******************************************************************************
function hGetControlPosYE( iControl as integer ) as integer
'///Retrieve the lower right Y-coordinate for a control
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 22, see description for hInsertControl()
'///
'///
'///Returns:
'///
'///+- Y-End in percent of window size (integer)
'///
'///Description:
'///
'///+- Get pos for Y-Orego, add "YSIZE"
hGetControlPosYE() = hGetControlPosYO( iControl ) + _
hGetControlParams( "ysize" )
'///
end function
'*******************************************************************************
function hGetControlPosXM( iControl as integer ) as integer
'///Retrieve the center (X) of a control
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 22, see description for hInsertControl()
'///
'///
'///Returns:
'///
'///+- X-Center in percent of window size (integer)
'///
'///Description:
'///
dim XO as integer
dim XE as integer
'///+- Find X-Orego
XO = hGetControlPosXO( iControl )
'///+- Find X-End
XE = hGetControlPosXE( iControl )
'///+- Calculate the distance, find the middle between the two
hGetControlPosXM() = XO + 0.5 * ( XE - XO )
'///
end function
'*******************************************************************************
function hGetControlPosYM( iControl as integer ) as integer
'///Retrieve the center (Y) of a control
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...). The coordinates
'///+ returned by this function can be used to draw and to select a control.
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 22, see description for hInsertControl()
'///
'///
'///Returns:
'///
'///+- Y-Center in percent of window size (integer)
'///
'///Description:
'///
dim YO as integer
dim YE as integer
'///+- Find Y-Orego
YO = hGetControlPosYO( iControl )
'///+- Find Y-End
YE = hGetControlPosYE( iControl )
'///+- Calculate the distance, find the middle between the two
hGetControlPosYM() = YO + 0.5 * ( YE - YO )
'///
end function
'*******************************************************************************
function hSelectControl( iControl as integer ) as boolean
'///Function to select one of the BASIC formcontrols by index
'///Note: Refer to the inline documentation for implementation details
'///In most cases it is desired to place multiple controls on a single
'///+ dialog pane. To prevent the controls from overlapping each other
'///+ they are arranged in rows and columns. Each control is identified
'///+ by a unique number (see description for hInsertControl(...)). The
'///+ dimensions are defined in hGetControlParams(...).
'///Input:
'///
'///+- Number of the control (integer)
'///
'///+- Any number between 1 and 22, see description for hInsertControl()
'///
'///
'///Returns:
'///
'///+- Errorstatus (boolean)
'///
'///+- TRUE if the properties-button on ToolsCollectionBar is enabled
'///+- FALSE in any other case
'///
'///
'///Description:
'///
dim xPos as integer
dim yPos as integer
dim iCurrentSelectionMethod as integer
const SELECT_MIDDLE = 1 ' click into the middle of the control
const SELECT_UPPER_LEFT = 2 ' click the upper left corner of the control
const SELECT_LOWER_RIGHT = 3 ' click the lower right corner of the control
const SELECT_FRAME_AROUND = 4 ' select by drawing a frame around the control
const EXTRA_FRAME_SIZE = 1 ' one percent in-/outside the border of the control
const SELECTION_METHODS = 4 ' this function sports four ways of seleting a control
const REPEAT_COUNT = 5 ' number of times to send a keystroke to the dialog window
hSelectControl() = false
'///+- Verify that the ToolsCollectionBar is visible. if not: Abort
kontext "ToolsCollectionBar"
if ( not ToolsCollectionBar.exists() ) then
warnlog( "The ToolsCollectionBar is not visible, open it first" )
exit function
endif
'///+- Enable the selection mode on ToolsCollectionBar
SelectMode.click()
' Note: The controls have areas where they ignore a mouseclick. E.g. the
' framecontrol can only be grabbed at the border, you won't be able to
' select it by clicking in the middle. Furthermore - even if the Dialog-
' editor-window is maximized - we might still miss the upper left corner.
' So what happens in this loop is that we try to click in the middle of the
' control. This works in 21 out of 22 cases. If it fails, we try to grab the
' border, first upper left corner then lower right. If this still fails,
' we try to select the control by using a rectangle selection around the
' control. If this last resort fails, the function exits gracefully but
' with a warnlog (causing some other functions to fail with warnings
' as well). Beware of possible problems with screen resolutions.
' This function has been tested for 1024x768 and 1280x1024 pixels.
' Method 4 is dangerous because it might accidentially select the
' background window which is the reason why this is not the default.
'///+- Try four different ways of selecting the control before giving up
'///
'///+- Mouse-Click in the middle
'///+- Mouse-Click on upper left corner
'///+- Mouse-Click on lower right corner
'///+- Rubberband around the control (Mouse movement)
'///+- Deselct everything and use to activate the control
'///
autoexecute = false
for iCurrentSelectionMethod = 1 to SELECTION_METHODS
Kontext "BasicIDE"
DialogWindow.typeKeys( "" , REPEAT_COUNT )
select case ( iCurrentSelectionMethod )
case SELECT_MIDDLE
xPos = hGetControlPosXM( iControl )
yPos = hGetControlPosYM( iControl )
DialogWindow.MouseMove( xPos, yPos )
DialogWindow.MouseDown( xPos, yPos )
DialogWindow.MouseUp ( xPos, yPos )
case SELECT_UPPER_LEFT
xPos = hGetControlPosXO( iControl ) + EXTRA_FRAME_SIZE
yPos = hGetControlPosYO( iControl ) + EXTRA_FRAME_SIZE
DialogWindow.MouseMove( xPos, yPos )
DialogWindow.MouseDown( xPos, yPos )
DialogWindow.MouseUp ( xPos, yPos )
case SELECT_LOWER_RIGHT
xPos = hGetControlPosXE( iControl ) - EXTRA_FRAME_SIZE
yPos = hGetControlPosYE( iControl ) - EXTRA_FRAME_SIZE
DialogWindow.MouseMove( xPos, yPos )
DialogWindow.MouseDown( xPos, yPos )
DialogWindow.MouseUp ( xPos, yPos )
case SELECT_FRAME_AROUND
xPos = hGetControlPosXO( iControl ) - EXTRA_FRAME_SIZE
yPos = hGetControlPosYO( iControl ) - EXTRA_FRAME_SIZE
DialogWindow.MouseMove( xPos, yPos )
DialogWindow.MouseDown( xPos, yPos )
xPos = hGetControlPosXE( iControl ) + EXTRA_FRAME_SIZE
yPos = hGetControlPosYE( iControl ) + EXTRA_FRAME_SIZE
DialogWindow.MouseMove( xPos, yPos )
DialogWindow.MouseUp ( xPos, yPos )
end select
try
if ( iControl = 11 ) then
wait( 100 )
printlog( "tried method: " & iCurrentSelectionMethod )
endif
ContextProperties
hSelectControl() = true
exit for
catch
endcatch
next iCurrentSelectionMethod
autoexecute = true
'///
end function