rexx-things/modules/windows/oodialog/userGuide/exercises/Exercise08/Support/View.rex
2025-03-12 20:50:48 +00:00

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."