DDgui Programmers Reference Guide by Nicholas J. Kingsley - HTML preview

PLEASE NOTE: This is an HTML preview only and some elements such as links or page numbers may be incorrect.
Download the book in PDF, ePub, Kindle for a complete version.

Vector Editor

 

// --------------------------------- //

// Project: VectorEditor

// Start: Saturday, July 17, 2010

// IDE Version: 8.036

 

// Working mode constants

CONSTANT VERSION$  = "1.0.0.2"

 

CONSTANT MODE_ADD%  = 0

CONSTANT MODE_MOVE%  = 1

CONSTANT MODE_REMOVE% = 2

CONSTANT MODE_INSERT% = 3

 

CONSTANT CELL_NODE%  = 0

 

CONSTANT NODE_HANDLE% = -1

CONSTANT NODE_NODE1% = 0

CONSTANT NODE_NODE2% = 1

CONSTANT NODE_NODE3% = 2

CONSTANT NODE_NODE4% = 3

CONSTANT NODE_NODE5% = 4

CONSTANT NODE_NODE6% = 5

CONSTANT NODE_NODE7% = 6

CONSTANT NODE_NODE8% = 7

CONSTANT NODE_NODE9% = 8

CONSTANT NODE_NODE10% = 9

CONSTANT NODE_USER%  = 10

 

CONSTANT INVALID%  = -1

 

CONSTANT SECTION_NAME$ = "OBJECT"

CONSTANT KEY_AUTHOR$ = "AUTHOR"

CONSTANT KEY_OBJECTNAME$= "NAME"

CONSTANT KEY_HANDLE$ = "HANDLE"

CONSTANT KEY_DATA$  = "DATA"

CONSTANT KEY_INUSE$  = "INUSE" // Groups in use

 

CONSTANT SECTION_USER$ = "USER"

CONSTANT KEY_COUNT$  = "COUNT"

 

CONSTANT COLOUR_HANDLE1%= RGB(128,128,128)

CONSTANT COLOUR_HANDLE2%= RGB(64,64,64)

 

CONSTANT MAX_NODEGROUPS%= 10

CONSTANT MAX_USERGROUPS%= 10

 

// Holds X & Y value for a node or user cell

TYPE tNode

x%   // X & Y cell position

y%

currentColour%  // Colour for node not connecting to first/last node

lastColour%

ENDTYPE

 

TYPE tNodeGroup

name$  // Node name

nodes[] AS tNode

ENDTYPE

 

// Holds user cell information when reading in from INI file

TYPE tCellInfo

name$

nodeIndex%  // NODE_NODE1-10 for nodes, > NODE_NODE10 for user cells

currentColour%

lastColour%

maxRange%

ENDTYPE

 

TYPE tFindItem

groupIndex% // < 0, if not in use, 0 - 9 for node group, > 9 for user cell

nodeIndex% // Index into array

ENDTYPE

 

TYPE tUndo

name$

nodeGroup[] AS tNodeGroup

userCells[] AS tNodeGroup

ENDTYPE

 

// Displays the grid

TYPE TGrid

x%

y%

gridSprite%

GRID_WIDTH% = 33

GRID_HEIGHT% = 33

cellWidth%

cellHeight%

halfCellWidth%

halfCellHeight%

totalHeight%

totalWidth%

handleX%

handleY%

showX%

showY%

 

nodeGroup[] AS tNodeGroup

userCells[] AS tNodeGroup

undo[] AS tUndo

 

actionType%    // Whether we're in add, move, remove or insert mode

cellMode AS tCellInfo // Type of cell information to process - add a node or user-defined cell information

 

leftButtonPressed%

findItem AS tFindItem

 

FUNCTION Initialise%:screenWidth%,screenHeight%

LOCAL screen%=0

LOCAL lx%,ly%

 

  self.gridSprite%=GENSPRITE()

IF self.gridSprite%<0 THEN RETURN FALSE

 

  DIM self.userCells[MAX_USERGROUPS%]

FOR ly%=0 TO MAX_USERGROUPS%-1

  self.userCells[ly%].name$="User Cell #"+ly%

NEXT

 

  DIM self.nodeGroup[MAX_NODEGROUPS%]

FOR ly%=0 TO MAX_NODEGROUPS%-1

  self.nodeGroup[ly%].name$="Node Group #"+ly%

NEXT

 

  self.ClearData()

 

  self.cellWidth%=INTEGER((screenWidth%/2)/self.GRID_WIDTH%)

self.cellHeight%=self.cellWidth%

self.halfCellWidth%=INTEGER(self.cellWidth%/2)

self.halfCellHeight%=self.halfCellWidth%

 

  self.totalWidth%=self.cellWidth%*self.GRID_WIDTH%

self.totalHeight%=self.cellHeight%*self.GRID_HEIGHT%

 

  self.x%=((screenWidth%/2)-self.totalWidth%)/2

self.y%=(screenHeight%-self.totalHeight%)/2

 

  self.showX%=(screenWidth%/2)+(((screenWidth%/2)-self.GRID_WIDTH%)/2)

self.showY%=screenHeight%-4-self.GRID_HEIGHT%

 

  CREATESCREEN screen%,self.gridSprite%,self.totalWidth%+2,self.totalHeight%+2

USESCREEN screen%

 

  FOR ly%=1 TO self.GRID_HEIGHT%-1

  DRAWLINE 1,ly%*self.cellHeight%,self.totalWidth%,ly%*self.cellHeight%,RGB(0,0,200)

NEXT

 

  FOR lx%=1 TO self.GRID_WIDTH%-1

  DRAWLINE lx%*self.cellWidth%,1,lx%*self.cellWidth%,self.totalHeight%,RGB(0,0,200)

NEXT

 

  DRAWLINE 0,0,self.totalWidth%,0,RGB(0,0,200)

DRAWLINE self.totalWidth%+1,0,self.totalWidth%+1,self.totalHeight%+1,RGB(0,0,200)

DRAWLINE 0,self.totalHeight%+1,self.totalWidth%+1,self.totalHeight%+1,RGB(0,0,200)

DRAWLINE 0,0,0,self.totalHeight%+1,RGB(0,0,200)

 

  USESCREEN -1

 

  self.handleX%=INTEGER(self.GRID_WIDTH%/2)

self.handleY%=INTEGER(self.GRID_HEIGHT%/2)

 

  self.leftButtonPressed%=FALSE

self.findItem.groupIndex%=INVALID%

self.findItem.nodeIndex%=INVALID%

 

  RETURN TRUE

ENDFUNCTION

 

//! Change action type

FUNCTION SetActionType%:actionType%

self.actionType%=actionType%

ENDFUNCTION

 

FUNCTION SetNodeInfo%:cellInfo AS tCellInfo

self.cellMode=cellInfo

ENDFUNCTION

 

//! Display the grid, nodes and user cells

FUNCTION DisplayGrid%:

LOCAL loop AS tNode

LOCAL loop2%,loop3%,size%,x1%,y1%,x2%,y2%,nextIndex%,colour%

 

  // Display the grid first

ALPHAMODE 0.0

DRAWSPRITE self.gridSprite%,self.x%,self.y%

 

  // Draw the handle

FOR x1%=0 TO self.GRID_WIDTH%-1

  self.Rect(x1%,self.handleY%,COLOUR_HANDLE2%)

NEXT

 

  FOR y1%=0 TO self.GRID_HEIGHT%-1

  self.Rect(self.handleX%,y1%,COLOUR_HANDLE2%)

NEXT

 

  self.Rect(self.handleX%,self.handleY%,COLOUR_HANDLE1%)

 

  // Draw user-defined cells

FOR loop2%=0 TO MAX_NODEGROUPS%-1

  FOREACH loop IN self.userCells[loop2%].nodes[]

   self.Rect(loop.x%,loop.y%,loop.currentColour%)

  NEXT

NEXT

 

  // Draw node cells

FOR loop2%=0 TO MAX_NODEGROUPS%-1

  FOREACH loop IN self.nodeGroup[loop2%].nodes[]

   self.Rect(loop.x%,loop.y%,loop.currentColour%)

  NEXT

NEXT

 

  // Draw node lines

FOR loop2%=0 TO MAX_NODEGROUPS%-1

  size%=BOUNDS(self.nodeGroup[loop2%].nodes[],0)

  IF size%>1

   FOR loop3%=0 TO size%-1

    x1%=self.x%+(self.nodeGroup[loop2%].nodes[loop3%].x%*self.cellWidth%)+1+self.halfCellWidth%

    y1%=self.y%+(self.nodeGroup[loop2%].nodes[loop3%].y%*self.cellHeight%)+1+self.halfCellHeight%

    nextIndex%=loop3%+1

    IF nextIndex%>=size%

     nextIndex%=0

     colour%=RGB(255,255,0)

    ELSE

     colour%=self.nodeGroup[loop2%].nodes[loop3%].currentColour%

    ENDIF

 

     x2%=self.x%+(self.nodeGroup[loop2%].nodes[nextIndex%].x%*self.cellWidth%)+1+self.halfCellWidth%

    y2%=self.y%+(self.nodeGroup[loop2%].nodes[nextIndex%].y%*self.cellHeight%)+1+self.halfCellHeight%

    DRAWLINE x1%,y1%,x2%,y2%,colour%

 

     x1%=self.showX%+self.nodeGroup[loop2%].nodes[loop3%].x%

    y1%=self.showY%+self.nodeGroup[loop2%].nodes[loop3%].y%

    x2%=self.showX%+self.nodeGroup[loop2%].nodes[nextIndex%].x%

    y2%=self.showY%+self.nodeGroup[loop2%].nodes[nextIndex%].y%

    DRAWLINE x1%,y1%,x2%,y2%,RGB(0,0,255)

 

    NEXT

  ENDIF

NEXT

ENDFUNCTION

 

FUNCTION Rect%:x%,y%,colour%

DRAWRECT self.x%+(x%*self.cellWidth%)+1,self.y%+(y%*self.cellHeight%)+1,self.cellWidth%,self.cellHeight%,colour%

ENDFUNCTION

 

FUNCTION Process%:

LOCAL mx%,my%,b1%,b2%

 

  MOUSESTATE mx%,my%,b1%,b2%

 

  IF b1%

  SELECT self.actionType%

   CASE MODE_ADD%

        IF self.leftButtonPressed%=FALSE

         IF self.InGridArea(mx%,my%)

          IF self.cellMode.nodeIndex%>=NODE_NODE1% AND self.cellMode.nodeIndex%<=NODE_NODE10%

           self.AddNodeItem(mx%,my%)

          ELSE

           self.AddUserItem(mx%,my%)

          ENDIF

 

           self.leftButtonPressed%=TRUE

         ENDIF

        ENDIF

 

    CASE MODE_MOVE%

        // Move a node or user-defined cell

        IF self.leftButtonPressed%=FALSE

         IF self.FindNode(mx%,my%,self.findItem)=TRUE

          self.leftButtonPressed%=TRUE

         ENDIF

        ELSE

         IF self.findItem.nodeIndex%<>INVALID%

          self.MoveItem(mx%,my%,self.findItem)

         ENDIF

        ENDIF

 

    CASE MODE_REMOVE%

        // Remove a node or user-defined cell

        IF self.leftButtonPressed%=FALSE

         IF self.FindNode(mx%,my%,self.findItem)=TRUE

          self.leftButtonPressed%=TRUE

         ENDIF

        ELSE

         IF self.findItem.nodeIndex%<>INVALID%

          self.DeleteItem(self.findItem)

          self.findItem.nodeIndex%=INVALID%

         ENDIF

        ENDIF

 

    CASE MODE_INSERT%

        // Insert and sort - only with nodes

        IF self.leftButtonPressed%=FALSE

         IF self.InGridArea(mx%,my%)

          IF self.cellMode.nodeIndex%>=NODE_NODE1% AND self.cellMode.nodeIndex%<=NODE_NODE10%

           self.AddNodeItem(mx%,my%)

 

            FOR mx%=0 TO BOUNDS(self.nodeGroup[self.cellMode.nodeIndex%-NODE_NODE1%].nodes[],0)-1

            DEBUG self.nodeGroup[self.cellMode.nodeIndex%-NODE_NODE1%].nodes[mx%].x%+" "+self.nodeGroup[self.cellMode.nodeIndex%-NODE_NODE1%].nodes[mx%].y%+"\n"

           NEXT

           DEBUG "\n"

//

           // Sort

           SORTARRAY self.nodeGroup[self.cellMode.nodeIndex%-NODE_NODE1%].nodes[],ADDRESSOF(sortRoutine)

 

            FOR mx%=0 TO BOUNDS(self.nodeGroup[self.cellMode.nodeIndex%-NODE_NODE1%].nodes[],0)-1

            DEBUG self.nodeGroup[self.cellMode.nodeIndex%-NODE_NODE1%].nodes[mx%].x%+" "+self.nodeGroup[self.cellMode.nodeIndex%-NODE_NODE1%].nodes[mx%].y%+"\n"

           NEXT

          ELSE

           self.AddUserItem(mx%,my%)

          ENDIF

 

           self.leftButtonPressed%=TRUE

         ENDIF

        ENDIF

 

 

   ENDSELECT

ELSE

  self.leftButtonPressed%=FALSE

  self.findItem.groupIndex%=INVALID%

  self.findItem.nodeIndex%=INVALID%

ENDIF

 

ENDFUNCTION

 

//! Are mouse coordinates withing grid area ?

FUNCTION InGridArea%:mx%,my%

IF (mx%>=self.x% AND mx%<=self.x%+self.totalWidth%) AND _

    (my%>=self.y% AND my%<=self.y%+self.totalHeight%)

  RETURN TRUE

ELSE

  RETURN FALSE

ENDIF

ENDFUNCTION

 

//! Convert mouse coordinates to cell X & Y values

FUNCTION MouseXYToCellXY%:mx%,my%,BYREF cellX%,BYREF cellY%

cellX%=INTEGER((mx%-(self.x%+1))/self.cellWidth%)

cellY%=INTEGER((my%-(self.y%+1))/self.cellHeight%)

ENDFUNCTION

 

//! Delete a node or user cell

FUNCTION DeleteItem%:found AS tFindItem

IF found.groupIndex%>=NODE_NODE1% AND found.groupIndex%<=NODE_NODE10%

  // Deleting a node

  DIMDEL self.nodeGroup[found.groupIndex%-NODE_NODE1%].nodes[],found.nodeIndex%

ELSEIF found.groupIndex%>=NODE_USER%

  // Deleting User cell

  DIMDEL self.userCells[found.groupIndex%-NODE_USER%].nodes[],found.nodeIndex%

ELSE

  DDgui_msg("Invalid group index value : "+found.groupIndex%,FALSE)

ENDIF

ENDFUNCTION

 

//! Add a node to the node list into the current node group

FUNCTION AddNodeItem%:mx%,my%

LOCAL node AS tNode

 

  self.AddToUndo("Adding Node")

self.MouseXYToCellXY(mx%,my%,node.x%,node.y%)

node.currentColour%=self.cellMode.currentColour%

node.lastColour%=self.cellMode.lastColour%

DIMPUSH self.nodeGroup[self.cellMode.nodeIndex%-NODE_NODE1%].nodes[],node

ENDFUNCTION

 

//! Add a user-defined cell to the correct group

FUNCTION AddUserItem%:mx%,my%

LOCAL node AS tNode

 

  IF ((self.cellMode.maxRange%>0) AND (BOUNDS(self.userCells[self.cellMode.nodeIndex%-NODE_USER%].nodes[],0)<self.cellMode.maxRange%)) OR (self.cellMode.maxRange%<0)

  self.AddToUndo("Adding User Cell")

  self.MouseXYToCellXY(mx%,my%,node.x%,node.y%)

  node.lastColour%=self.cellMode.lastColour%

  node.currentColour%=self.cellMode.currentColour%

  DIMPUSH self.userCells[self.cellMode.nodeIndex%-NODE_USER%].nodes[],node

ELSE

  DDgui_msg("You are only allow to use "+self.cellMode.maxRange%+" of the selected cell",FALSE)

ENDIF

ENDFUNCTION

 

FUNCTION FindNode%:mx%,my%,found AS tFindItem

LOCAL loop%

LOCAL cx%,cy%

 

  self.MouseXYToCellXY(mx%,my%,cx%,cy%)

 

  // Look for group node

FOR loop%=0 TO MAX_NODEGROUPS%-1

  FOR loop2%=0 TO BOUNDS(self.nodeGroup[loop%].nodes[],0)-1

   IF self.nodeGroup[loop%].nodes[loop2%].x%=cx% AND self.nodeGroup[loop%].nodes[loop2%].y%=cy%

    found.groupIndex%=loop%+NODE_NODE1%

    found.nodeIndex%=loop2%

    RETURN TRUE

   ENDIF

  NEXT

NEXT

 

  // Now we look for user cells

FOR loop%=0 TO MAX_USERGROUPS%-1

  FOR loop2%=0 TO BOUNDS(self.userCells[loop%].nodes[],0)-1

   IF self.userCells[loop%].nodes[loop2%].x%=cx% AND self.userCells[loop%].nodes[loop2%].y%=cy%

    found.groupIndex%=loop%+NODE_USER%

    found.nodeIndex%=loop2%

    RETURN TRUE

   ENDIF

  NEXT

NEXT

 

  RETURN FALSE

ENDFUNCTION

 

//! Move a node or user cell

FUNCTION MoveItem%:mx%,my%,found AS tFindItem

IF found.groupIndex%>=NODE_NODE1% AND found.groupIndex%<=NODE_NODE10%

  // Moving a node

  self.AddToUndo("Moving Node")

  self.MouseXYToCellXY(mx%,my%,self.nodeGroup[found.groupIndex%-NODE_NODE1%].nodes[found.nodeIndex%].x%,self.nodeGroup[found.groupIndex%-NODE_NODE1%].nodes[found.nodeIndex%].y%)

  self.CheckInRange(self.nodeGroup[found.groupIndex%-NODE_NODE1%].nodes[found.nodeIndex%].x%,self.nodeGroup[found.groupIndex%-NODE_NODE1%].nodes[found.nodeIndex%].y%)

ELSEIF found.groupIndex%>=NODE_USER%

  // User cell

  self.AddToUndo("Movinf User Cell")

  self.MouseXYToCellXY(mx%,my%,self.userCells[found.groupIndex%-NODE_USER%].nodes[found.nodeIndex%].x%,self.userCells[found.groupIndex%-NODE_USER%].nodes[found.nodeIndex%].y%)

  self.CheckInRange(self.userCells[found.groupIndex%-NODE_USER%].nodes[found.nodeIndex%].x%,self.userCells[found.groupIndex%-NODE_USER%].nodes[found.nodeIndex%].y%)

ELSE

  DDgui_msg("Invalid group index value : "+found.groupIndex%,FALSE)

ENDIF

ENDFUNCTION

 

FUNCTION ReturnHandleXYAsString$:

RETURN self.handleX%+","+self.handleY%

ENDFUNCTION

 

//! Convert all the X/Y values to a string, subtracting the handle X & Y positions from it

FUNCTION ReturnNodesAsString$:index%

LOCAL temp$

LOCAL loop AS tNode

 

  temp$=""

FOREACH loop IN self.nodeGroup[index%].nodes[]

  temp$=temp$+(loop.x%-self.handleX%)+","+(loop.y%-self.handleY%)+","

NEXT

 

  RETURN LEFT$(temp$,LEN(temp$)-1)

ENDFUNCTION

 

//! Convert all the X/Y values to a string, subtracting the handle X & Y positions from it.  This is for user cells

FUNCTION ReturnUserCellsAsString$:index%

LOCAL temp$

LOCAL loop AS tNode

 

  temp$=""

FOREACH loop IN self.userCells[index%].nodes[]

  temp$=temp$+(loop.x%-self.handleX%)+","+(loop.y%-self.handleY%)+","

NEXT

 

  RETURN LEFT$(temp$,LEN(temp$)-1)

ENDFUNCTION

 

//! Return a string containing only groups in use

FUNCTION ReturnGroupsInUse$:

LOCAL temp$

LOCAL loop%

 

  temp$=""

FOR loop%=NODE_NODE1% TO NODE_NODE10%

  IF BOUNDS(self.nodeGroup[loop%-NODE_NODE1%].nodes[],0)>0

   temp$=temp$+(loop%-NODE_NODE1%)+","

  ENDIF

NEXT

 

  RETURN LEFT$(temp$,LEN(temp$)-1)

ENDFUNCTION

 

//! Search for any user cells

FUNCTION ReturnUserGroupInUse$:

LOCAL loop%

LOCAL temp$

 

  temp$=""

FOR loop%=0 TO MAX_USERGROUPS%-1

  IF BOUNDS(self.userCells[loop%].nodes[],0)>0

   temp$=temp$+loop%+","

  ENDIF

NEXT

 

  RETURN LEFT$(temp$,LEN(temp$)-1)

ENDFUNCTION

 

FUNCTION SetHandleFromText%:text$

LOCAL val$[]

 

  IF text$=""

  self.handleX%=INTEGER(self.GRID_WIDTH%/2)

  self.handleY%=INTEGER(self.GRID_HEIGHT%/2)

ELSE

  DIM val$[0]

  IF SPLITSTR(text$,val$[],",")>=2

   self.handleX%=INTEGER(val$[0])

   self.handleY%=INTEGER(val$[1])

  ELSE

   DDgui_msg("Invalid handle data - reverting to default",FALSE)

   self.handleX%=INTEGER(self.GRID_WIDTH%/2)

   self.handleY%=INTEGER(self.GRID_HEIGHT%/2)

  ENDIF

ENDIF

 

  RETURN TRUE