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