364 lines
16 KiB
Rexx
Executable File
364 lines
16 KiB
Rexx
Executable File
/*----------------------------------------------------------------------------*/
|
|
/* */
|
|
/* Copyright (c) 2011-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. */
|
|
/* */
|
|
/*----------------------------------------------------------------------------*/
|
|
/* ooDialog User Guide - Support
|
|
Exercise 08: View.rex
|
|
|
|
ViewMixin v01-02 18Jun13
|
|
---------
|
|
A mixin superclass for View components (part of the Model-View Framework).
|
|
|
|
Contains: class: "ViewMixin"
|
|
|
|
Description: A mixin superclass for all xxxView components.
|
|
|
|
Pre-requisites: MVF.
|
|
|
|
Outstanding Problems: None reported.
|
|
|
|
Changes:
|
|
v01-00 12May13: First Version.
|
|
v01-01 06Jun13: Added drag/drop methods. Also store model id as an
|
|
attribute ('myModel') to save subclases having to do it.
|
|
Note - some drag/drop methods are there as catch-alls for
|
|
when a subclass does not implement them. Default action
|
|
still to be verified.
|
|
18Jun13: Changed "drop" method to "dmDrop" and "pickup" to "dmPickup"
|
|
(both sent to DragMgr).
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
::REQUIRES "ooDialog.cls"
|
|
::REQUIRES "support\Component"
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////////
|
|
==============================================================================
|
|
ViewMixin v01-00 13May13
|
|
---------
|
|
A mixin superclass for View classes. the Order Management dialog. Handles interest registration,
|
|
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
|
|
|
--::CLASS View SUBCLASS RcDialog PUBLIC
|
|
::CLASS View PUBLIC MIXINCLASS PlainBaseDialog
|
|
|
|
::ATTRIBUTE viewMgr
|
|
::ATTRIBUTE objectMgr
|
|
::ATTRIBUTE dragMgr
|
|
::ATTRIBUTE myModel
|
|
|
|
/*----------------------------------------------------------------------------
|
|
initView - initialises the mixin instance - invoked from ???
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
--::method init -- Results in hang!
|
|
::METHOD initView
|
|
--say "View-initView-01."
|
|
self~objectMgr = .local~my.ObjectMgr -- Needed to clear up when dialog closed.
|
|
self~viewMgr = .local~myViewMgr
|
|
-- Direct Manipulation:
|
|
self~dragMgr = .local~my.DragMgr
|
|
--say "View-initView-01: dragMgr =" self~dragMgr
|
|
|
|
return
|
|
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/*----------------------------------------------------------------------------
|
|
activate - must be invoked by subclass.
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
::METHOD activate UNGUARDED
|
|
expose viewClass viewInstance -- needed for tidy-up on close.
|
|
use arg modelId
|
|
-- Store model id for use by subclasses:
|
|
self~myModel = modelId
|
|
--say "View-activate-01: self =" self
|
|
-- Get View Instance name and View Class for tidy-up when dialog is closed.
|
|
viewInstance = self~identityHash
|
|
dlgName = self~objectName
|
|
parse var dlgName . viewClass
|
|
modelData = modelId~query
|
|
--say "View-activate-02."
|
|
return modelData
|
|
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/*----------------------------------------------------------------------------
|
|
showModel - forwards to ObjectMgrloadList - for invocation by subclasses.
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
::METHOD showModel
|
|
use strict arg modelClass, modelInstance, parentDlg
|
|
r = self~ObjectMgr~showModel(modelClass, modelInstance, parentDlg)
|
|
if r = .false then say "View-showModel - ObjectMgr returned .false."
|
|
return r
|
|
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/*----------------------------------------------------------------------------
|
|
loadList - must be invoked by subclass.
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
--::METHOD loadList Wait till check out how do ShowModel for List.
|
|
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
leaving - invoked by ooDialog when a dialog closes.
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
::METHOD leaving UNGUARDED
|
|
expose viewClass viewInstance
|
|
--say "View-leaving-01. objectMgr =" objectMgr
|
|
self~objectMgr~removeView(viewClass, viewInstance)
|
|
self~dragMgr~removeDlg(self) -- closing, so tell DragManager
|
|
-- Note - we do not remove the Model. Should we? If so, not from here!
|
|
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
Popup Offsets
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
setOffsetParent - set the parent dialog id for later offsetting of a child
|
|
dialog.
|
|
**** Note: This method not used in Exercise07. **** */
|
|
::METHOD setOffsetParent
|
|
use strict arg parentDlg
|
|
viewMgr = .local~my.ViewMgr
|
|
viewMgr~parentOffsetDlg = self
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
offset - offsets a "child" dialog from its "parent" dialog (i.e. the dialog
|
|
from which the child is "popped up").
|
|
**** Note: This method not used in Exercise07. **** */
|
|
::METHOD offset
|
|
--say "RcView-offset-1."
|
|
offset = .local~my.ViewMgr~dlgOffset
|
|
parentDlg = .local~my.ViewMgr~parentOffsetDlg
|
|
popupPos = parentDlg~getRealPos
|
|
popupPos~incr(offset,offset)
|
|
self~moveTo(popupPos, "SHOWWINDOW")
|
|
self~ensureVisible()
|
|
|
|
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/*----------------------------------------------------------------------------
|
|
initDialog - invokes offset.
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
::METHOD initDialog
|
|
say "ViewMixin-initDialog-01."
|
|
self~offset
|
|
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
Drag/Drop Methods
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/*----------------------------------------------------------------------------
|
|
dmSetAsSource - called by a view component to define itself as a drag source.
|
|
Typically invoked from subclass' initDialog method.
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
::METHOD dmSetAsSource PRIVATE -- DM setup method
|
|
-- Each source dialog should invoke this only once.
|
|
-- Invoking it more than once may well result in errors.
|
|
-- Note: a dialog may be both source and target.
|
|
expose mouse dmSourceControl sourceWin
|
|
use arg dmSourceCursorFile, dmSourceArea, dmSourceControl
|
|
if dmSourceCursorFile = .nil then do
|
|
say "View-dmSetAsSource-00:" .HRS~dmSrcNulCursor
|
|
return .false
|
|
end
|
|
--say "View-dmSetAsSource-01: dmSourceCursorFile, dmSourceArea, dmSourceControl:"
|
|
--say " '"||dmSourceCursorFile||"', "||dmSourceArea", "||dmSourceControl
|
|
|
|
if dmSourceArea = "DMSOURCEAREA" then do -- set default pickup area
|
|
dmSourceArea = self~clientRect()
|
|
dmSourceArea~left += 10; dmSourceArea~top += 10; -
|
|
dmSourceArea~right -= 10; dmSourceArea~bottom -= 10
|
|
--say "View-dmSetAsSource-02 - default pickup client area =" dmSourceArea
|
|
end
|
|
--else say "View-dmSetAsSource-03 - pickup client area =" dmSourceArea
|
|
|
|
if dmSourceControl = "DMSOURCECONTROL" then do -- The source is a dialog.
|
|
--say "View-dmSetAsSource-04: source is a dialog."
|
|
sourceWin = self
|
|
mouse = .Mouse~new(sourceWin)
|
|
mouse~connectEvent('MOUSEMOVE',dmOnMove)
|
|
mouse~connectEvent('LBUTTONDOWN', dmOnLBdown)
|
|
mouse~connectEvent('LBUTTONUP', dmOnLBup)
|
|
--self~dragMgr~setSource(self, mouse, dmSourceCursorFile, dmSourceArea, .nil)
|
|
self~dragMgr~setSource(self, mouse, dmSourceCursorFile, dmSourceArea, self) -- ***
|
|
end
|
|
else do -- The source is a control (such as a ListView).
|
|
--say "View-dmSetAsSource-05: source is a control."
|
|
sourceWin = dmSourceControl
|
|
mouse = .Mouse~new(dmSourceControl)
|
|
mouse~connectEvent('MOUSEMOVE',dmOnMove)
|
|
mouse~connectEvent('LBUTTONDOWN', dmOnLBdown)
|
|
mouse~connectEvent('LBUTTONUP', dmOnLBup)
|
|
--self~dragMgr~setSource(self, mouse, dmSourceCursorFile, dmSourceArea, dmSourceControl)
|
|
self~dragMgr~setSource(sourceWin, mouse, dmSourceCursorFile, dmSourceArea, self) -- ***
|
|
end
|
|
--mouse~connectEvent('MOUSELEAVE', dmLeave)
|
|
--say "View-dmSetAsSource-06: source is:" sourceWin
|
|
|
|
|
|
return .true
|
|
|
|
/*----------------------------------------------------------------------------
|
|
dmSetAsTarget - called by a view component to define itself as a drag target.
|
|
Typically invoked from subclass' initDialog method.
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
::METHOD dmSetAsTarget -- DM setup method
|
|
-- Each target dialog should invoke this only once.
|
|
-- Invoking it more than once may well result in errors.
|
|
-- Note: a dialog may be both source and target.
|
|
expose dmIsTargetDlg
|
|
use arg dmDropArea
|
|
--say "View-dmSetAsTarget-01."
|
|
|
|
if dmDropArea = "DMDROPAREA" then do -- set default. Better is to check the type.
|
|
dmDropArea = self~clientRect()
|
|
dmDropArea~left += 10; dmDropArea~top += 10; dmDropArea~right -= 30; dmDropArea~bottom -= 30
|
|
end
|
|
|
|
self~dragMgr~setTarget(self, self~hwnd, dmDropArea)
|
|
|
|
return .true
|
|
|
|
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
|
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
::METHOD dmOnLBdown
|
|
expose sourceWin
|
|
use arg keyState, mousePos
|
|
--say "View-dmOnLBdown-00; self, keystate, mousePos =" self||"," keystate||"," mousePos
|
|
info = self~dmGetItemInfo -- for listviews
|
|
if info = 0 then nop --say "View-dmOnLBdown-01 - info is zero."
|
|
|
|
else do
|
|
nop --say "View-dmOnLBdown-02; info, sourceWin =" info||"," sourceWin
|
|
-- store the info somewhere - how about "drag data"?.
|
|
-- Drag data = classname, instance name.
|
|
end
|
|
--self~DragMgr~dmPickup(self, keyState, mousePos, dragData) - not right yet
|
|
self~DragMgr~dmPickup(sourceWin, keyState, mousePos) -- pre-listview
|
|
return 0
|
|
|
|
::METHOD dmGetItemInfo -- Dummy method for when sublcass does not
|
|
-- implement it.
|
|
return 0
|
|
|
|
|
|
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
::METHOD dmOnMove
|
|
expose sourceWin
|
|
use arg keyState, mousePos
|
|
--say "View-dmOnMove: self, sourceWin =" self||"," sourceWin
|
|
self~dragMgr~moving(sourceWin, self, keystate, mousePos)
|
|
--say "View-dmOnMove"
|
|
return 0
|
|
|
|
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
::METHOD dmOnLBup
|
|
use arg keyState, mousePos
|
|
--say "View-dmOnLBup-01; self =" self
|
|
self~dragMgr~dmDrop(self, keyState, mousePos)
|
|
--return r -- throws error, as done no return at all.
|
|
return 0
|
|
say 'DMSource-onLButtonUp: the mouse is at ('mousePos~x',' mousePos~y') with these qualifiers:' keyState
|
|
|
|
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
/* ::METHOD dmNeverDrop
|
|
-- Invoked by a target object to prevent any drop (e.g. if a sales order is
|
|
-- complete and should not now be altered). The red/white target icon is
|
|
-- changed to grey.
|
|
expose dmTargetIconImage dmIcons dmTargetInactive
|
|
use arg dmTargetInactive
|
|
if dmTargetInactive then dmTargetIconImage~setImage(dmIcons[dmTgtInactiveIcon])
|
|
else dmTargetIconImage~setImage(dmIcons[dmTgtReadyIcon])
|
|
*/
|
|
|
|
::METHOD dmQueryDrop
|
|
use arg dmSourceDlg, mousePos
|
|
--say "View-dmQueryDrop-01."
|
|
return .true -- Default is to accept the drop.
|
|
|
|
::METHOD dmDrop
|
|
use arg sourceDlg
|
|
--say "View-dmDrop-01."
|
|
return .true
|
|
|
|
/* ::METHOD cancel
|
|
expose dmDragMgr
|
|
say "View-Cancel-01."
|
|
dmDragMgr~removeDlg(self) -- closing, so tell DragManager
|
|
return self~cancel:super
|
|
*/
|
|
/*
|
|
::METHOD ok
|
|
say "View-ok-01."
|
|
self~dragMgr~removeDlg(self) -- closing, so tell DragManager
|
|
return self~ok:super
|
|
*/
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
Event Management Methods. *** INCOMPLETE ***
|
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
--::METHOD triggerEvent
|
|
-- use strict arg event
|
|
-- idEventMgr = .local~my.EventMgr
|
|
|
|
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
::METHOD viewDoIt
|
|
--say "View-viewDoIt-01."
|
|
|
|
|
|
/*============================================================================*/
|
|
|
|
|
|
|
|
/*==============================================================================
|
|
Human-Readable Strings (HRS) v00-01 13Jan12
|
|
--------
|
|
The HRS class provides constant character strings for user-visible messages.
|
|
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
|
|
|
::CLASS HRS PRIVATE -- Human-Readable Strings
|
|
::CONSTANT dmSrcNulCursor "View-dmSetAsSource - Error: Source Cursor is null."
|
|
::CONSTANT dmTgtBadParam "View-dmSetAsTarget - Error: null dlg or null hwnd or both."
|
|
|
|
|