| 要約: |
|
| 例: "単純なドラッグ アンド ドロップ関係の作成" | |
![]() | |
{HBox spacing = 5cm, valign = "center",
|| Step 1: this circle is the 'dragee' It can be dragged
|| because the dragee option is set. NOTE: It must be set to
|| ImageDragee.
{EllipseGraphic width = 1cm, height = 1cm, dragee = {ImageDragee}},
{Frame || Step Two: this image is the 'drop target'.
width = 2cm, height = 2cm,
background = {Background {url "../../default/images/shopping-cart.gif"}},
|| The following line handles the DragOver event. You
|| must assign the event to a variable (in this case 'e')
|| so that you can call its will-accept-drop? method.
{on e:DragOver do
{e.will-accept-drop?
|| Returns one of the four DragEffect constants.
|| You must include four positional arguments of
|| the same data types, as shown below.
{proc {type:Type, x:Distance, y:Distance,
effect:#DragEffect}:DragEffect
{return drag-effect-copy}
} } }, || stacked for compactness
|| Step Three: The following line handles the Drop event.
|| You must assign the event to a variable (in this case
|| 'e') so that you can call its accept-drop method.
{on e:Drop do
{e.accept-drop
|| Return one of the four DropResult objects. You
|| must include four positional arguments of the
|| same data types, as shown below.
{proc {a:any, x:Distance, y:Distance,
effect:#DragEffect}:DropResult
{return {DropResultCopy
|| The 'action' argument to a
|| DropResult object specifies what
|| action occurs when the dragee is
|| dropped. Supply a procedure to the
|| 'action' argument.
action = {proc {}:void
{popup-message
"You dropped the ball!",
modal? = true}
} } } } } } } } |
| 例: 目標にドロップできるドラッグ対象の指定 | |
![]() | |
{VBox halign = "center", spacing = 1cm,
|| The four objects in this HBox are dragees. Note that they
|| are of two types, EllipseGraphic and RectangleGraphic.
{HBox spacing = 2cm,
{RectangleGraphic
width = 10mm, height = 14mm, dragee = {ImageDragee}},
{EllipseGraphic
width = 14mm, height = 10mm, dragee = {ImageDragee}},
{RectangleGraphic
width = 4mm, height = 16mm, dragee = {ImageDragee}},
{EllipseGraphic
width = 10mm, height = 14mm, dragee = {ImageDragee}}
},
{TextFlowBox || This TextFlowBox is the drop target.
border-width = 2pt, border-color = "black", margin = 5pt,
{text font-size = 16pt, Please drop round objects on this box.},
{on e:DragOver do
{e.will-accept-drop?
{proc
{type:Type, x:Distance, y:Distance,
effect:#DragEffect}:DragEffect
|| The following code specifies that
|| EllipseGraphics can be dropped on the drop
|| target and other objects cannot.
|| Note that the name of the first argument in
|| the procedure (type) is used to call
|| methods of the dragee.
{if {type.subtype-of? EllipseGraphic} then
{return drag-effect-copy}
else
{return drag-effect-none}
}
}
}
},
|| The rest of code handles the Drop event. Note that
|| only one DropResult is specified. It is the DragEffect
|| that must distinguish between different dragees.
{on e:Drop do
{e.accept-drop
{proc
{a:any,
x:Distance,
y:Distance,
effect:#DragEffect
}:DropResult
{return
{DropResultCopy
action =
{proc {}:void
{popup-message
modal? = true,
"Success!"
} } } } } } } } } |
| 例: の条件に基づいて DropDropResult を指定 | |
![]() | |
{VBox halign = "center", spacing = 1cm,
{HBox spacing = 2cm,
|| The following four objects are dragees, of two
|| different types (EllipseGraphic and RectangleGraphic).
{RectangleGraphic
width = 10mm, height = 14mm, dragee = {ImageDragee}},
{EllipseGraphic
width = 14mm, height = 10mm, dragee = {ImageDragee}},
{RectangleGraphic
width = 4mm, height = 16mm, dragee = {ImageDragee}},
{EllipseGraphic
width = 10mm, height = 14mm, dragee = {ImageDragee}
}
},
{TextFlowBox || The drop target.
border-width = 2pt, border-color = "black", margin = 5pt,
{text font-size = 16pt,
Please drop {bold round} objects on this box},
|| The following code handles the DragOver event.
|| Any dragee can be dropped on this drop target.
{on e:DragOver do
{e.will-accept-drop?
{proc
{type:Type,
x:Distance,
y:Distance,
effect:#DragEffect
}:DragEffect
{return drag-effect-copy}
}
}
},
|| The following code handles the Drop event. The
|| 'action' taken depends on the criteria in this 'if'
|| expression. Note that the name of the first argument
|| in the procedure that returns the DropResult (a) refers
|| to the dragee.
{on e:Drop do
{e.accept-drop
{proc
{a:any,
x:Distance,
y:Distance,
effect:#DragEffect}:DropResult
{return
{DropResultCopy
action =
{proc {}:void
{if a isa EllipseGraphic then
{popup-message
modal? = true,
"Correct. The object is round."}
else
{popup-message
modal? = true,
"Wrong! The object is not round."}
}
}
}
}
}
}
}
}
}
|

| 例: ドラッグ アンド ドロップ操作をコントロールするための CTRL キーの使用 | |
![]() | |
{text Drop the circle on the box while holding down the {bold CTRL}
key. Then drop the circle on the box without holding it down.}
{HBox
valign = "center", width = 9cm,
{EllipseGraphic || the dragee
width = 1cm, height = 1cm, dragee = {ImageDragee}},
{Fill width = {make-elastic preferred-size = 10cm}},
{VBox || the drop target
width = 1.5cm, height = 1.5cm, border-width = 1pt,
border-color = {FillPattern.get-black},
opaque-to-events? = true,
{on e:DragOver do
{e.will-accept-drop?
{proc
{a:Type,
b:Distance,
c:Distance,
d:#DragEffect
}:DragEffect
|| This drop target returns one of two drag
|| effects based on the state of the
|| DropSource. The call to
|| DragEffect.has-effect? reveals this state.
|| The DragEffect object is named "d" in the
|| arguments to this procedure. If the user
|| has pressed CTRL, the state of the
|| DropSource is "copy".
{if {d.has-effect? "copy"} then
{return drag-effect-copy}
else
{return drag-effect-move}
}
}
}
},
{on e:Drop at vb:VBox do
{e.accept-drop
{proc
{w:any,
x:Distance,
y:Distance,
z:#DragEffect
}:DropResult
|| This drop target returns one of two drop
|| results based on the Dragsource's state, as
|| revealed by the call to
|| DragEffect.has-effect? The DragEffect is
|| named "z" in the arguments to this
|| procedure. If the user has pressed CTRL,
|| the state of the DropSource is "copy".
{if {z.has-effect? "copy"} then
{return
{DropResultCopy
action =
{proc {}:void
|| In this case a copy of the
|| dragee (w) is added.
{vb.add {w.clone-appearance}}
}
}
}
else
{return
{DropResultMove
action =
{proc {}:void
|| In this case the dragee (w)
|| itself is added.
{vb.add w}
}
} } } } } } } } |
| 例: DragEnter および DragLeave の使用 | |
![]() | |
|| curler-position-target creates a drop target for dropping a
|| CurlPlayer of a particular type. It takes a position string,
|| which it displays, and a position-type, which is compared
|| against the type being dropped.
{define-class CurlerPositionTarget {inherits VBox}
field position:String
field position-type:Type
|| display holder for adding the name of the player.
field name-holder:TextFlowBox
{constructor {default
position:String,
position-type:Type
}
set self.position = position
set self.position-type = position-type
set self.name-holder = {TextFlowBox}
|| construct a VBox, which is the drop target. Its contents
|| are the position name, a picture, and then the name-holder,
|| which will be modified when the drop occurs.
{construct-super
halign = "center",
{bold {value position}},
{image
source = {url "../../default/images/curler3-transparent.gif"},
width = 0.5in, height = 0.5in, blocking? = true
},
self.name-holder}}
|| DragOver handler compares the type being dragged
|| to the type that we accept.
{method public {on-drag-over e:DragOver}:void
{e.will-accept-drop?
{proc {t:Type, x:Distance,
y:Distance, effect:#DragEffect}:DragEffect
{if {self.right-player-type? t} then
{return drag-effect-copy}
else
{return drag-effect-none}}
{e.consume}
}}}
|| Drop handler makes sure that the right type is dropped. If
|| so, it adds the name in dragee to the display by changing the
|| contents of the name-holder.
{method public {on-drop e:Drop}:void
|| Make sure to remove any background added by
|| the DragEnter handler
{unset self.background}
{e.accept-drop
{proc {a:any, x:Distance,
y:Distance, effect:#DragEffect}:DropResult
{if {self.right-player-type? {type-of a}} then
{return
{DropResultCopy
action = {proc {}:void
let name-holder:TextFlowBox = self.name-holder
{name-holder.clear}
{name-holder.add a.player-name}
{e.consume}
}}}
else
{return {DropResultNone}}}
}
}
}
|| DragEnter handler sets the background if we are over the
|| right type of object
{method public {on-drag-enter e:DragEnter}:void
let right-type?:bool = true
{e.dss.for-each
{proc {ds:DataTransferSource}:void
{unless {self.right-player-type? {ds.get-data-type}}
do set right-type? = false}}}
{if right-type? then
set self.background = "yellow"}
{e.consume}
{super.on-drag-enter e} || Call the superclass implementation
}
{method public {on-drag-leave e:DragLeave}:void
{unset self.background}
{e.consume}
{super.on-drag-leave e} || Call the superclass implementation
}
{method private {right-player-type? t:Type}:bool
{return (self.position-type == t)}
}
}
|| CurlPlayer is an abstract class whose subclass can
|| be dropped on a curler-position-target.
{define-class abstract CurlPlayer {inherits VBox}
|| player name
field player-name:String
{constructor {default player-name:String}
set self.player-name = player-name
{construct-super
{Frame
{image
source = {url "../../default/images/curler4-transparent.gif"},
blocking? = true},
width = 0.5in,
height = 0.5in
},
player-name,
border-width = 1pt,
text-selectable? = false,
|| All you have to do to make it draggable
dragee = {ImageDragee}
}
}
}
|| Derivations for skip, vice-skip, second, and lead.
{define-class CurlSkip {inherits CurlPlayer}
{constructor {default player-name:String}
{construct-super player-name}}}
{define-class CurlViceSkip {inherits CurlPlayer}
{constructor {default player-name:String}
{construct-super player-name}}}
{define-class CurlSecond {inherits CurlPlayer}
{constructor {default player-name:String}
{construct-super player-name}}}
{define-class CurlLead {inherits CurlPlayer}
{constructor {default player-name:String}
{construct-super player-name}}}
|| Main display code
{value
|| create a canvas on which to put the curler-position-target
|| objects.
let c:Canvas = {Canvas
width = 2in,
height = 7in,
border-color = "black",
border-width = 1pt
}
|| background image is the curl playing surface.
{c.add {image
source = {url "../../default/images/sheetofice2.gif"},
blocking? = true},
x = .2in, y = 6.75in}
|| add the curler-position-targets for the positions.
{c.add {CurlerPositionTarget "Skip", CurlSkip},
x = 1in, y = 0.5in}
{c.add {CurlerPositionTarget "Second", CurlSecond},
x = 0.5in, y = 3in}
{c.add {CurlerPositionTarget "Vice-Skip", CurlViceSkip},
x = 1.4in, y = 3in}
{c.add {CurlerPositionTarget "Lead", CurlLead},
x = 1in, y = 6in}
|| Here's what gets displayed:
{HBox
valign = "top",
|| VBox contains instructions and players.
{VBox
spacing = 4pt,
{TextFlowBox
{bold { big Instructions}},
{paragraph Drag player names from the left onto the appropriate
positions to play them at that position. }
},
{bold Leads},
{RasterBox
{CurlLead "Hemmings"},
{CurlLead "Harstone"},
{CurlLead "Schmirler"},
{CurlLead "Harris"},
{CurlLead "Richardson "},
{CurlLead "Jones "}},
{bold Skips},
{RasterBox
{CurlSkip "Werenich"},
{CurlSkip "Gervais"},
{CurlSkip "Mazinke"},
{CurlSkip "Pickering "},
{CurlSkip "Northcotte"}},
{bold Vice-Skips},
{RasterBox
{CurlViceSkip "Richardson"},
{CurlViceSkip "D'Amour"},
{CurlViceSkip "Peterson"},
{CurlViceSkip "Sanders"},
{CurlViceSkip "Sparkes"},
{CurlViceSkip "Tobin"}},
{bold Seconds},
{RasterBox
{CurlSecond "Pezer"},
{CurlSecond "Schoenhals"},
{CurlSecond "Duguid"},
{CurlSecond "Mckee"}
}
}, || VBox
c || instantiate the Canvas object
} || HBox
} || main display code
|
| 例:
ドラッグ対象の | |
![]() | |
|| SimpleEditableCanvas is a drop target
{define-class public SimpleEditableCanvas {inherits Canvas}
{constructor {default ...}
{construct-super ...}
}
{method public {on-drop e:Drop}:void
{e.accept-drop
{proc {a:any,
x:Distance,
y:Distance,
effect:#DragEffect}:DropResult
|| Only support move
{if {effect.has-effect? "move"} then
{return {DropResultMove action =
{proc {}:void
|| get the dragee option from
|| the object being dropped
let dragee:Dragee = a.dragee
|| compute the new position in the drop
|| container
let (real-x:Distance, real-y:Distance) =
{dragee.get-drop-position x, y, self}
{self.add a, x = real-x, y = real-y}
}}}
else
{return {DropResultNone}}
}
}}
{e.consume}
{super.on-drop e}
}
{method public {on-drag-over e:DragOver}:void
{e.will-accept-drop?
{proc {t:Type,
x:Distance,
y:Distance,
effect:#DragEffect}:DragEffect
|| only supports move
{if {effect.has-effect? "move"} then
{return drag-effect-move}
else
{return drag-effect-none}
}
}}
{e.consume}
{super.on-drag-over e}
}
}
{value let simple-canvas =
{SimpleEditableCanvas
width = 3in,
height = 2in,
background = "beige"}
let simple-canvas-obj =
{Frame
width = 0.5in,
height = 0.25in,
background = "blue",
dragee = {ImageDragee}
}
{simple-canvas.add simple-canvas-obj, x = 1.5in, y = 1in}
{value simple-canvas}
}
|
| 例: 複数のオブジェクトのドラッグ | |
![]() | |
|| A frame that is both draggable and selectable
{define-class SimpleDraggableFrame {inherits Frame}
{constructor {default ...}
{construct-super.Frame
dragee = {ImageDragee},
background = "blue",
graphic-selectable = {GraphicSelectable},
...
}
}
}
{define-class SimpleEditableCanvas {inherits Canvas}
{constructor {default ...}
{construct-super ...}
}
{method public {on-drop e:Drop}:void
{e.accept-drop
{proc {a:any,
x:Distance,
y:Distance,
effect:#DragEffect}:DropResult
|| Only support move
{if {effect.has-effect? "move"} then
{return {DropResultMove action =
{proc {}:void
|| get the dragee option from
|| the object being dropped
let dragee:Dragee = a.dragee
|| compute the new position in the drop
|| container
let (real-x:Distance, real-y:Distance) =
{dragee.get-drop-position x, y, self}
{self.add a, x = real-x, y = real-y}
}}
}
else
{return {DropResultNone}}
}
}}
{e.consume}
{super.on-drop e}
}
{method public {on-drag-over e:DragOver}:void
{e.will-accept-drop?
{proc {t:Type,
x:Distance,
y:Distance,
effect:#DragEffect}:DragEffect
|| only supports move
{if {effect.has-effect? "move"} then
{return drag-effect-move}
else
{return drag-effect-none}
}
}}
{e.consume}
{super.on-drag-over e}
}
}
{value
let simple-canvas:SimpleEditableCanvas =
{SimpleEditableCanvas
width = 3in,
height = 2in,
background = "beige"
}
{simple-canvas.add
{SimpleDraggableFrame
width = 0.5in,
height = 0.25in},
x = 1.5in,
y = 1in
}
{simple-canvas.add
{SimpleDraggableFrame
width = 0.5in,
height = 0.25in},
x = 0in,
y = 0in
}
{DiscreteGraphicSelectionFrame
simple-canvas
}
}
|
| 例: ファイルのドラッグ アンド ドロップ | |
![]() | |
{define-proc {process-urls urls:{Array-of Url}}:void
{vb.clear}
{for url in urls do
{vb.add url.filename}
}
}
{let vb:VBox =
{VBox
background = "silver",
{Frame width = 2cm, height = 2cm}, ||give box initial size
{on e:DragOver do
{e.will-accept-drop?
{proc {type:Type, x:Distance, y:Distance,
effect:#DragEffect}:DragEffect
{return
{if type == {Array-of Url} then
drag-effect-copy
else
drag-effect-none
}
}
}
}
},
{on e:Drop do
{e.accept-drop
{proc {a:any, x:Distance, y:Distance,
effect:#DragEffect}:DropResult
{return
{DropResultCopy
action = {proc {}:void
{type-switch a
case urls:{Array-of Url} do
{process-urls urls}
}
}
}
}
}
}
}
}
}
{value vb}
|