The example in this section demonstrates techniques and features that are useful with ESL drag and drop support.
ESL classes are used to group similar source and target objects together. This reduces the number of drag and drop responses that need to be written.
Icons similar to those that appear in the Windows Program Manager are simulated using graphical and image regions. The include files DDICON.HDR and DDICON.INC contain the code that creates these pseudo-icons.
Two dragtypes are used for Person application objects – "Person" and "PersonIcon". When the source object is a pseudo-icon, the "PersonIcon" dragtype is used; this dragtype is accepted by both Primary_GR and by the Printer pseudo-icon. When the source object is the list box (or, more precisely, a line in the list box), the "Person" dragtype is used; this dragtype is only accepted by the printer. If the same dragtype were used for both, you could drag from the list box and drop on Primary_GR, which would cause the corresponding Person pseudo-icon to be moved to that position. This would be counter-intuitive in this application.
Some extensions that could be made:
The printer could be made into a source object that could be dropped anywhere in Primary_GR, allowing the user to reposition it in the same way the Person pseudo-icons can be moved.
A template object for creating new Person application objects could be added to Primary_GR. Dragging from this object to Primary_GR would cause a new Person application object to be created, and would create a new pseudo-icon to represent that application object. The new pseudo-icon could be added to the People_CL class, and would then behave like the rest of the People pseudo-icons. A dialog box could be brought up to allow the user to enter information about the new person.
#################################################
#
# DRAG AND DROP SAMPLE APPLICATION
#
# Drag and drop design
#----------------------
#
# Objects:
# Pseudo-icons, created for each name
# in the array Names[]. These are
# called 'person' icons.
# The Primary window, which acts like a
# folder containing the people icons.
# A printer icon.
# A list box, containing the names from the
# Names[] array.
#
# Drag and Drop operations:
# The user can drag any person icon and drop
# it somewhere else in the Primary window
# to move that icon.
# Source = person icon
# Target = Primary window
# Dragtype = "PersonIcon"
# Dragdata = name of the person
# The user can drag any person icon onto the
# printer icon. This does not move the
# person icon, but causes a message box
# containing the name of the person to
# be displayed.
# Source = person icon
# Target = printer icon
# Dragtype = "PersonIcon"
# Dragdata = name of the person
# The user can drag the name of a person from
# the list box onto the printer. To prevent
# the user from being able to drop on the
# Primary window, a different dragtype is
# used.
# Source = list box
# Target = printer icon
# Dragtype = "Person"
# Dragdata = name of the person
#################################################
#include "ddicon.hdr"
#################################################
#
# DDICON.HDR
#
# Used for creating pseudo-icons in ESL
#
#################################################
#
# Icon size constants. For OS/2 and Windows VGA,
# icons are 32x32. For XGA, use 40x40. The
# bitmaps passed to NewIcon() must be the size
# specified here.
#
integer constant IconXSize_IC is 32
integer constant IconYSize_IC is 32
#
# Icon spacing constants - specify the spacing
# in between two icons. 0 would make the edges
# of two adjacent icons barely touch.
# These can be customized for your application
#
integer variable IconXSpacing_IV is (IconXSize_IC / 2)
integer variable IconYSpacing_IV is (IconYSize_IC / 2)
#integer variable IconXSpacing_IV is 1
#integer variable IconYSpacing_IV is 1
#
# Font use for the caption text under each
# pseudo-icon. Can be set to any font that ESL
# supports.
#
#font CaptionFont is facename "Helv" 8 point
string variable CaptionFont_SV is "CaptionFont"
# Create a pseudo-icon
subroutine NewIcon (string: ObjName_SV, # input
string: Parent_SV, # input
string: Caption_SV, # input
string: Parameter_SV, # input
integer: XPos_IV, # input
integer: YPos_IV, # input
string: Bitmap_SV) # input
# Get the x and y size of a text string
subroutine GetTextSize (string: String_SV, # input
string: Font_SV, # input
integer: XSize_IV, # output
integer: YSize_IV) # output
include "message.inc"
##
## Application Data
##
integer constant NumPeople_IC is 4
string Names[4] is "Tom", "Dick", "Harry", " Moe"
#
# DRAG AND DROP
# Definitions for dragtypes and classes
#
string variable PersonType_SV is "Person"
string variable PersonIconType_SV is "PersonIcon"
class People_CL # contains person objects
class Printer_CL # contains printer object
# other variables used in responses
integer CaptionHeight_IV
string ObjName_SV
string Temp_SV
subroutine ResponseToStart()
subroutine PrintReport(string: Name_SV)
# Get the x and y size of a text string
subroutine GetTextSize(
string: String_SV, # input
string: Font_SV, # input
integer: XSize_IV, # output
integer: YSize_IV) # output
##
## Object Definitions
##
color 26 primary graphical region Primary_GR
size 400 300 at 10 10 in desktop
title bar "Drag and Drop Sample Application"
size border
system menu
minimize button
vertical scroll bar
no scale
invisible dialog region Dialog_DR
size 80 80 at 100 30 in desktop
title bar "List of People"
border
minimize button
list box People_LB
size (xsize of Dialog_DR) (ysize of
Dialog_DR)
at 0 0 in Dialog_DR
#include "ddicon.inc"
#################################################
#
# DDICON.INC
#
# Used for creating pseudo-icons in ESL
#
#################################################
#################################################
#
# GetTextSize_GR
# Used in GetTextSize() subroutine to calculate
# the width and height of a text string.
#
# Assumptions:
# The program is not a fullscreen application
# (this uses 'in desktop').
# This file is included after the primary region
# has been defined.
# Note:
# This region must have a non-zero size.
#
invisible graphical region GetTextSize_GR
size 1 1 at 0 0 in desktop
#################################################
#
# NewIcon
# Draws a simulated icon using a graphical
# region and an image region. Caller can
# specify name of regions, caption, parameter,
# parent object, position, and bitmap to
# display.
#
# To create a bitmap from an icon, you can bring
# the icon into the appropriate Windows or OS/2
# icon editor, copy the entire image, then
# create a new bitmap, paste the icon image into
# the bitmap, and save the bitmap. The bitmaps
# must be the size specified by IconXSize_IC and
# IconYSize_IC (see below).
#
# Uses the following global configuration
# variables:
# IconXSize_IC - x size of a standard icon
# IconYSize_IC - y size of a standard icon
# CaptionFont_SV - font used for caption text
# (see ddicon.hdr for the definitions of these
# values)
#
subroutine NewIcon( string: ObjName_SV,
string: Parent_SV,
string: Caption_SV,
string: Parameter_SV,
integer: XPos_IV,
integer: YPos_IV,
string: Bitmap_SV ) is
string EmpKeyName
string EmpKeyName2
integer TextX
integer TextY
integer ParentColor_IV
call GetTextSize( Caption_SV, CaptionFont_SV, TextX, TextY )
copy (TextX + 4) to TextX # space on
# sides...
if (TextX < IconXSize_IC) then
copy IconXSize_IC to TextX
end if
copy (background of Parent_SV) to ParentColor_IV
add color ParentColor_IV graphical region ObjName_SV
size TextX (TextY + IconYSize_IC)
at XPos_IV YPos_IV in Parent_SV
parameter is Parameter_SV
no scale
move to (TextX / 2) (TextY / 2)
black font CaptionFont_SV text center Caption_SV
add image region ObjName_SV
size IconXSize_IC IconYSize_IC
at (2 + (TextX - IconXSize_IC) / 2) TextY
in ObjName_SV in Parent_SV
parameter is Parameter_SV
file Bitmap_SV
#################################################
#
# GetTextSize
# Calculate the height and width of some text,
# in pixels
#
# Algorithm:
# Create a key with nothing but the text in it.
# Then query the extent of the key to get the
# width and height of the text.
#
subroutine GetTextSize (string: String_SV, # input
string: Font_SV, # input
integer: XSize_IV, # output
integer: YSize_IV ) is # output
string variable TempName_SV
copy "TempCaption_KEY" to TempName_SV
add invisible key TempName_SV
at 0 0 in GetTextSize_GR
font Font_SV text String_SV
copy (right of TempName_SV) to XSize_IV
copy (top of TempName_SV) to YSize_IV
delete TempName_SV
##
## Responses
##
#
# Response to start sets up icons for each name
# in the Names[] array, creates a Printer icon,
# and fills the list box with the names in
# Names[].
#
response to start
call ResponseToStart()
# DRAG AND DROP
# All objects in the People_CL class can be dragged,
# so each is a drag source. The dragdata is taken
# from the object's parameter, which was set earlier
# to be one of the names in the Names[] array.
#
response to People_CL
on drag
drag parameter type PersonIconType_SV
using icon "fred.ico"
# DRAG AND DROP
# Primary_GR acts like a folder containing people.
# It is a drag target. A person object can be
# dropped onto Primary_GR to place that person
# object at that position.
#
response to Primary_GR
on dragover
if (dragtype = PersonIconType_SV) then
allow drop
end if
on drop
if (dragtype = PersonIconType_SV) then
copy dragdata "_GR" to ObjName_SV
change ObjName_SV in Primary_GR position to xcoord (ycoord - CaptionHeight_IV)
end if
# DRAG AND DROP
# The Printer_GR object can have a either a
# person icon or the name of a person from the
# list box dropped on it. It is a drag target.
# A message box is displayed in this sample, but
# a real application would print a report about
# the person object.
#
response to Printer_CL
on dragover
if ((dragtype = PersonType_SV) or
(dragtype = PersonIconType_SV)) then
allow drop end if
on drop
if ((dragtype = PersonType_SV) or
(dragtype = PersonIconType_SV)) then
copy dragdata to Temp_SV
call PrintReport( Temp_SV )
end if
# DRAG AND DROP
# The list box containing names can be used as
# a drag source also. The dragdata is the
# text of the line from which the user began
# the drag - it is one of the names from the
# Names[] array.
#
response to People_LB
on drag
copy (textual line ycoord from People_LB) to Temp_SV
if (Temp_SV != "") then
drag Temp_SV type PersonType_SV
using icon "fred.ico"
end if
##
## Subroutines
##
subroutine ResponseToStart() is
string ObjName_SV
string Parent_SV
string Caption_SV
string Parameter_SV
string Bitmap_SV
string Temp_SV
integer XPos_IV
integer YPos_IV
integer I
integer Temp_IV
# make the dialog visible
make Dialog_DR permanent
make Dialog_DR visible
# loop and create icons for the people in the
# Names[]array
copy Primary_GR to Parent_SV
copy 20 to XPos_IV
copy 20 to YPos_IV
copy "fred.bmp" to Bitmap_SV
for I = 1 to NumPeople_IC loop
copy Names[I] "_GR" to ObjName_SV
copy Names[I] to Caption_SV
copy Names[I] to Parameter_SV
call NewIcon( ObjName_SV, Parent_SV, Caption_SV, Parameter_SV, XPos_IV, YPos_IV, Bitmap_SV )
# NewIcon() creates two regions - add both to
# People_CL
add ObjName_SV in Parent_SV to class People_CL
add ObjName_SV in ObjName_SV in Parent_SV to class People_CL
# move to the next icon position
copy (XPos_IV + xsize of ObjName_SV in Parent_SV + IconXSpacing_IV) to XPos_IV
# add the name to the list box
add to People_LB
insert Names[I]
end loop
# create printer icon
copy 20 to XPos_IV
copy (YPos_IV + ysize of ObjName_SV in Parent_SV + 20) to YPos_IV
copy "Printer_GR" to ObjName_SV
copy "Printer" to Caption_SV
copy "printer.bmp" to Bitmap_SV
copy "" to Parameter_SV
call NewIcon( ObjName_SV, Parent_SV, Caption_SV, Parameter_SV, XPos_IV, YPos_IV, Bitmap_SV )
# NewIcon() creates two regions - add both to
# Printer_CL
add ObjName_SV in Parent_SV to class Printer_CL
add ObjName_SV in ObjName_SV in Parent_SV to class Printer_CL
# get the height of the caption text, to
# offset drops properly
copy "ABC" to Temp_SV
call GetTextSize( Temp_SV, CaptionFont_SV, Temp_IV, CaptionHeight_IV )
subroutine PrintReport(string: Name_SV) is
string Temp_SV
string Message_SV
copy "Would you like to print a report about " Name_SV "?"
to Message_SV
copy ReplyToMessage("Sample Drag and Drop Application", Message_SV, MessageOKCancel,1,MessageQuery )
to Temp_SV