![Free-eBooks.net](/resources/img/logo-nfe.png)
![All New Design](/resources/img/allnew.png)
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