1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2024-12-27 20:08:22 +01:00
Diya-API/Diya/DiyaNode.class.st

260 lines
4.8 KiB
Smalltalk
Raw Normal View History

2022-03-01 22:58:58 +01:00
Class {
#name : #DiyaNode,
#superclass : #DiyaBaseObject,
#instVars : [
'translation',
'parent',
2022-03-03 19:19:40 +01:00
'children',
2022-03-01 22:58:58 +01:00
'scale',
'rotation',
'tf',
'shader',
2022-03-04 20:28:38 +01:00
'context',
2022-03-19 02:18:29 +01:00
'dirty',
'ehandlers',
2022-03-23 00:52:15 +01:00
'root',
'style',
'id'
2022-03-01 22:58:58 +01:00
],
#pools : [
'OpenGLConstants',
2022-03-19 02:18:29 +01:00
'OpenGLTypes',
'SDL2Constants'
2022-03-01 22:58:58 +01:00
],
#category : #'Diya-Graphics'
}
{ #category : #'instance creation' }
DiyaNode class >> with: shader [
^self new shader: shader; yourself
]
2022-03-03 19:19:40 +01:00
{ #category : #accessing }
DiyaNode >> addNode: node [
^self addNode: node at: 0@0
]
{ #category : #accessing }
DiyaNode >> addNode: node at: pos [
children ifNil: [ ^self ].
node parent: self.
node position: pos.
children add: node.
2022-03-19 02:18:29 +01:00
node root: self root.
2022-03-23 00:52:15 +01:00
node style parent: style.
2022-03-03 19:19:40 +01:00
^ node
]
{ #category : #accessing }
DiyaNode >> boundingBox [
^ self subclassResponsibility
]
{ #category : #accessing }
DiyaNode >> children [
^children
]
{ #category : #accessing }
DiyaNode >> draw [
self subclassResponsibility
]
{ #category : #requirements }
DiyaNode >> empty [
children := OrderedCollection new.
]
2022-03-04 20:28:38 +01:00
{ #category : #accessing }
DiyaNode >> extent [
2022-03-16 01:32:01 +01:00
^ self subclassResponsibility
2022-03-04 20:28:38 +01:00
]
{ #category : #accessing }
DiyaNode >> id [
^ id
]
2022-03-01 22:58:58 +01:00
{ #category : #initialization }
DiyaNode >> initialize [
super initialize.
parent := nil.
2022-03-03 19:19:40 +01:00
shader := nil.
context := DiyaRendererContext uniqueInstance.
2022-03-03 19:19:40 +01:00
children := OrderedCollection new.
2022-03-19 02:18:29 +01:00
dirty := false.
ehandlers := Dictionary new.
2022-03-23 00:52:15 +01:00
style := DiyaNodeStyle new.
2022-03-19 02:18:29 +01:00
root := nil.
id := Random new nextInt: 1e6
2022-03-19 02:18:29 +01:00
]
2022-08-07 18:15:57 +02:00
{ #category : #accessing }
2022-03-19 02:18:29 +01:00
DiyaNode >> inner: aPoint [
^ self subclassResponsibility
]
{ #category : #testing }
DiyaNode >> isRoot [
2022-03-19 02:18:29 +01:00
^ false
]
{ #category : #convenience }
DiyaNode >> on: eventName do: aBlock [
2022-03-21 01:45:21 +01:00
eventName isArray ifFalse:[ ^ self register: aBlock to: eventName ].
eventName do:[:e| self register: aBlock to:e ].
2022-03-19 02:18:29 +01:00
2022-03-01 22:58:58 +01:00
]
{ #category : #accessing }
DiyaNode >> parent [
^ parent
]
{ #category : #accessing }
DiyaNode >> parent: anObject [
parent := anObject
]
2022-03-01 22:58:58 +01:00
{ #category : #accessing }
DiyaNode >> position [
^ translation
]
{ #category : #accessing }
DiyaNode >> position: anObject [
translation := anObject.
self updateTF.
2022-03-01 22:58:58 +01:00
]
2022-03-21 01:45:21 +01:00
{ #category : #convenience }
DiyaNode >> register: aBlock to: eventName [
|evtCode|
evtCode := SDL2Constants bindingOf: ('SDL_', eventName asUppercase).
evtCode ifNil: [ ^DiyaCoreAPIError signal: 'Unknow event ', eventName ].
ehandlers at: evtCode value put: aBlock.
]
2022-03-01 22:58:58 +01:00
{ #category : #accessing }
DiyaNode >> render [
2022-03-23 00:52:15 +01:00
dirty ifTrue:[
dirty := self update not].
2022-08-07 18:15:57 +02:00
shader ifNotNil: [self setUpShader].
2022-03-03 19:19:40 +01:00
self draw.
children ifNil: [ ^self ].
children do: [:c | c render ].
2022-03-01 22:58:58 +01:00
]
2022-03-19 02:18:29 +01:00
{ #category : #accessing }
DiyaNode >> root [
^ root
]
{ #category : #accessing }
DiyaNode >> root: anObject [
root := anObject
]
2022-03-01 22:58:58 +01:00
{ #category : #accessing }
DiyaNode >> rotation [
^ rotation
]
{ #category : #accessing }
DiyaNode >> rotation: anObject [
rotation := anObject.
self updateTF.
2022-03-01 22:58:58 +01:00
]
{ #category : #accessing }
DiyaNode >> scale [
^ scale
]
{ #category : #accessing }
DiyaNode >> scale: anObject [
scale := anObject.
self updateTF.
2022-03-01 22:58:58 +01:00
]
2022-08-07 18:15:57 +02:00
{ #category : #initialization }
DiyaNode >> setClean [
dirty := false
]
{ #category : #initialization }
DiyaNode >> setDirty [
dirty := true
]
2022-03-06 18:33:10 +01:00
{ #category : #accessing }
DiyaNode >> setUpShader [
2022-03-15 19:11:19 +01:00
|mem|
mem := self tf asGLBuffer.
2022-03-06 18:33:10 +01:00
shader use;
setUniform: #u_time value: DiyaClock uniqueInstance elapsedTime asFloat;
setUniform: #u_projection value: {GL_FALSE. context projection buffer};
setUniform: #u_resolution value: { context resolution x. context resolution y };
setUniform: #u_texture value: 0;
2022-03-15 19:11:19 +01:00
setUniform: #u_transform value: {GL_TRUE. mem}.
2022-03-06 18:33:10 +01:00
context mouse ifNotNil: [
"in shader, window origin is bottom left conor of the window
the mouse position should be transformed to this coodinate"
shader setUniform: #u_mouse value:
{ context mouse x. context mouse y }.
2022-03-06 18:33:10 +01:00
].
2022-03-15 19:11:19 +01:00
mem free.
2022-03-06 18:33:10 +01:00
]
2022-03-01 22:58:58 +01:00
{ #category : #accessing }
DiyaNode >> shader [
2022-03-03 19:19:40 +01:00
shader ifNil: [
parent ifNil: [ ^nil ].
^parent shader ].
2022-03-01 22:58:58 +01:00
^ shader
]
{ #category : #accessing }
DiyaNode >> shader: anObject [
shader := anObject
]
2022-03-23 00:52:15 +01:00
{ #category : #accessing }
DiyaNode >> style [
^style
]
{ #category : #accessing }
DiyaNode >> style: aStyle [
style := aStyle.
dirty := true.
parent ifNotNil: [ style parent: parent style ]
]
2022-03-01 22:58:58 +01:00
{ #category : #accessing }
DiyaNode >> tf [
^ tf
]
2022-08-07 18:15:57 +02:00
{ #category : #'event handling' }
2022-03-19 02:18:29 +01:00
DiyaNode >> trigger: evt [
evt enable ifFalse:[^self].
ehandlers at: evt mapped type ifPresent:[:handler| handler value: evt].
children ifNil: [^self].
evt enable ifTrue: [
"evt mapped triggableOn: children first."
children select: [:node | evt mapped triggableOn: node ] thenDo:[:node| node trigger: evt]
].
]
{ #category : #accessing }
DiyaNode >> update [
^self subclassResponsibility
]
2022-03-01 22:58:58 +01:00
{ #category : #accessing }
DiyaNode >> updateTF [
self subclassResponsibility
]