
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
Describe what you're looking for in as much detail as you'd like.
Our AI reads your request and finds the best matching books for you.
Popular searches:
Join 2 million readers and get unlimited free ebooks