1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2025-07-17 14:29:52 +02:00

39 Commits

Author SHA1 Message Date
f10ad2449c Update Jenkinsfile
All checks were successful
gitea-sync/Diya-API/pipeline/head This commit looks good
2022-09-26 10:57:19 +02:00
0faefcae12 Update Jenkinsfile
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-09-26 10:55:46 +02:00
85968f7b6a Update Jenkinsfile 2022-09-26 10:55:04 +02:00
b393432256 Update Jenkinsfile
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-09-26 10:53:41 +02:00
8639bc4d65 Update Jenkinsfile
Some checks are pending
gitea-sync/Diya-API/pipeline/head Build queued...
2022-09-26 10:53:34 +02:00
79e42786e8 Update Jenkinsfile
Some checks failed
gitea-sync/Diya-API/pipeline/head There was a failure building this commit
2022-09-26 10:52:20 +02:00
cf89a8ca59 Update Jenkinsfile
Some checks failed
gitea-sync/Diya-API/pipeline/head There was a failure building this commit
2022-09-26 10:44:52 +02:00
f61e17de9c rendering improvement
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-08-16 00:59:35 +02:00
3c00e1d181 refactory code, support inline style, improve text rendering 2022-08-15 12:28:09 +02:00
0b7396242a Refactor code on System clock 2022-08-14 22:49:36 +02:00
681d8951b7 remove unused selectors 2022-08-14 22:38:06 +02:00
0e78e6769d Meta node should not visible 2022-08-14 22:22:39 +02:00
8978c06efa Initialize global vars 2022-08-14 18:33:19 +02:00
74ce2b0f37 Supporting read system settings from file 2022-08-14 18:13:23 +02:00
2d09a8501a Refactory code 2022-08-14 16:52:22 +02:00
142f14e936 Rendering context now use multiple texture units to boost performance (on RPI zero, the performance gain is more than 10 FPS ) 2022-08-14 15:42:59 +02:00
677145f1a1 Add missing code of the previous commit 2022-08-14 01:39:09 +02:00
26368c37ab Rendering improvement: render a limited number of nodes (based on FPS setting) on the back buffer each iterration.
The back buffer is only swapped when all nodes are rendered
2022-08-14 01:38:22 +02:00
c7af75550f code refactory on rendering context 2022-08-13 23:48:23 +02:00
c1f2de2896 refactory code 2022-08-13 15:55:51 +02:00
766ae23f8e fix: incorrect line rendering 2022-08-13 01:47:15 +02:00
f3ef0c1aa0 fix: tf global to local problem on 2D node, add LoadingBar widget, and refactor code 2022-08-13 01:37:42 +02:00
2e4c73f8cf API improvements:
- fix: TF update bug on scale
- fix: Use local coordiate for Polygon points
- Add timer node for basic animation
- Dirty processing nodes are monitored by rootnode
- refactory code
2022-08-12 22:19:54 +02:00
2ee103191c OPENGL Rendering Performance improvement 2022-08-12 16:37:53 +02:00
a3d00d52ef Allow to fallback to VM plugins for image handling if SDL_image lib doesnt exist 2022-08-12 12:02:49 +02:00
133ddb0380 Fix: incorrect index in buffer converting 2022-08-10 23:05:25 +02:00
598e252b9e fix: add missing extension 2022-08-10 23:00:30 +02:00
664e2169f3 Refactor code + use primitive for 2D matrix transformation 2022-08-10 22:53:14 +02:00
9442050825 API improvement
- Refactor code
- Texture performance improvement
2022-08-10 19:55:49 +02:00
6f5c6b8551 allow get texture from screen, VM bug on device 2022-08-09 03:14:23 +02:00
141bf2e226 use SDL2_image for texture loading 2022-08-09 00:22:18 +02:00
676113a697 Add global display object that refers to current SDL display 2022-08-08 16:35:04 +02:00
4a95c7d6df remove dependecy on OSSDL2Driver 2022-08-08 13:11:25 +02:00
7a7665430d Remove dependencies on OSSDLDriver 2022-08-08 13:03:46 +02:00
8b6a7927f4 Correct openGL transparent color display problem, stylesheet now allows style inheritance 2022-08-08 00:12:54 +02:00
007d99804f Cache current stylesheet object in each node to gain FPS 2022-08-07 21:08:29 +02:00
c249c2e381 Rework on Graphic styling 2022-08-07 20:43:16 +02:00
6d7ab2dcd6 Merge b8257f7011 2022-08-07 18:17:07 +02:00
b8257f7011 refactory code 2022-08-07 18:15:57 +02:00
64 changed files with 1846 additions and 752 deletions

View File

@ -1,5 +1,15 @@
Extension { #name : #Array } Extension { #name : #Array }
{ #category : #'*Diya' }
Array >> asDiyaStyle [
|style|
style := DiyaStyle new.
self do:[:v |
style at: v key put: v value
].
^style
]
{ #category : #'*Diya' } { #category : #'*Diya' }
Array >> asPoint [ Array >> asPoint [
^ (self at: 1 ifAbsent:[0]) @ (self at: 2 ifAbsent:[0]) ^ (self at: 1 ifAbsent:[0]) @ (self at: 2 ifAbsent:[0])

View File

@ -1,41 +0,0 @@
Extension { #name : #Array2D }
{ #category : #'*Diya' }
Array2D >> asGLBuffer [
|buffer i|
i := 1.
buffer := FFIExternalArray externalNewType: #float size: self size.
self asArray do:[:e|
buffer at:i put:e.
i := i+1
].
buffer autoRelease.
^buffer
]
{ #category : #'*Diya' }
Array2D class >> rotationMatrix2D: rotation [
^Array2D rows: 3 columns: 3 contents:{
rotation cos. (rotation sin) negated. 0.0.
rotation sin. rotation cos. 0.0.
0.0. 0.0. 1.0
}
]
{ #category : #'*Diya' }
Array2D class >> scaleMatrix2D: scale [
^Array2D rows: 3 columns: 3 contents:{
scale x. 0.0. 0.0.
0.0. scale y. 0.0.
0.0. 0.0. 1.0
}
]
{ #category : #'*Diya' }
Array2D class >> translateMatrix2D: translation [
^Array2D rows: 3 columns: 3 contents: {
1.0. 0.0. translation x.
0.0. 1.0. translation y.
0.0. 0.0. 1.0
}
]

View File

@ -8,18 +8,24 @@ Class {
#category : #'Diya-Core' #category : #'Diya-Core'
} }
{ #category : #'instance creation' }
AssetManager class >> defaultAssetLocation [
^Smalltalk imageDirectory / 'assets'
]
{ #category : #'instance creation' } { #category : #'instance creation' }
AssetManager class >> fromLocation: loc [ AssetManager class >> fromLocation: loc [
^self new from: loc; yourself ^self new from: loc; yourself
] ]
{ #category : #'as yet unclassified' } { #category : #adding }
AssetManager >> addAsset: value [
assets at: value name put: value.
^ value
]
{ #category : #adding }
AssetManager >> addAssetName: name value: value [
assets at: name put: value.
^ value
]
{ #category : #'instance creation' }
AssetManager >> from: location [ AssetManager >> from: location [
base := location base := location
] ]
@ -28,15 +34,21 @@ AssetManager >> from: location [
AssetManager >> initialize [ AssetManager >> initialize [
super initialize. super initialize.
assets := Dictionary new. assets := Dictionary new.
base := self class defaultAssetLocation base := DiyaSystemSettings assetPath
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
AssetManager >> name: fileName of: type [ AssetManager >> name: name [
^assets at: fileName ifAbsentPut: [(type fromFile: (base / fileName))]. ^assets at: name.
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
AssetManager >> name: name of: type [
^assets at: name ifAbsentPut: [
(type fromFile: (base / name))].
]
{ #category : #accessing }
AssetManager >> texture: name [ AssetManager >> texture: name [
^self name: name of: DiyaImageTex ^self name: name of: DiyaImageTex
] ]

View File

@ -0,0 +1,6 @@
Extension { #name : #DiskStore }
{ #category : #'*Diya' }
DiskStore class >> inform: string [
Transcript show: string; cr.
]

View File

@ -40,24 +40,23 @@ Diya2DNode >> initialize [
translation := 0@0. translation := 0@0.
scale := 1@1. scale := 1@1.
rotation := 0. rotation := 0.
tf := Array2D identity: 3. tf := MatrixTransform2x3 identity .
shader := Diya2DShader uniqueInstance. shader := Diya2DShader uniqueInstance.
vbuffer := nil. vbuffer := nil.
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
Diya2DNode >> inner: aPoint [ Diya2DNode >> inner: aPoint [
^ self boundingBox containsPoint: (self local: aPoint) ^ self boundingBox containsPoint: (self local: aPoint)
] ]
{ #category : #accessing } { #category : #accessing }
Diya2DNode >> local: aPoint [ Diya2DNode >> local: aPoint [
^((aPoint - (0@0 applyTf: self tf) )/ scale) ^ self tf globalPointToLocal: aPoint
rotateBy: rotation about: 0@0.
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
Diya2DNode >> recFromBuffer [ Diya2DNode >> recFromBuffer [
|maxX maxY minX minY x y| |maxX maxY minX minY x y|
maxX := minX := vbuffer at: 1. maxX := minX := vbuffer at: 1.
@ -75,18 +74,26 @@ Diya2DNode >> recFromBuffer [
{ #category : #accessing } { #category : #accessing }
Diya2DNode >> updateTF [ Diya2DNode >> updateTF [
tf := Array2D identity:3. tf := MatrixTransform2x3 identity.
"translation" "translation"
translation = (0@0) ifFalse:[ tf setOffset: translation + pivot.
tf := tf +* (Array2D translateMatrix2D: translation)].
"rotation" "rotation"
rotation = 0 ifFalse:[ rotation = 0 ifFalse:[tf setAngle: rotation ].
tf := tf +* (Array2D rotationMatrix2D: rotation )]. "translate back to pivot"
"scale" pivot isZero ifFalse:[
scale = (1@1) ifFalse:[ tf := tf composedWithLocal:
tf := tf +* (Array2D scaleMatrix2D: scale)]. (MatrixTransform2x3 identity
setOffset: pivot negated;
yourself)
].
scale isZero ifFalse: [
tf := tf composedWithLocal:
(MatrixTransform2x3 identity
setScale: scale;
yourself)
].
self parent ifNil: [ ^self ]. self parent ifNil: [ ^self ].
self parent isRoot ifFalse: [tf := self parent tf +* tf ]. self parent isRoot ifFalse: [tf := self parent tf composedWithLocal: tf ].
children ifNotNil: [children do:[:c| c updateTF ]]. children ifNotNil: [children do:[:c| c updateTF ]].
] ]

View File

@ -9,74 +9,42 @@ Class {
#category : #'Diya-Graphics' #category : #'Diya-Graphics'
} }
{ #category : #accessing }
Diya2DPrimShape >> bgColor [
^style get: #bgcolor
]
{ #category : #accessing }
Diya2DPrimShape >> bgColor: c [
^style set: #bgcolor value: c
]
{ #category : #accessing }
Diya2DPrimShape >> borderColor [
^style get: #borderColor
]
{ #category : #accessing }
Diya2DPrimShape >> borderColor: c [
style set: #borderColor value: c.
]
{ #category : #accessing } { #category : #accessing }
Diya2DPrimShape >> borderWidth [ Diya2DPrimShape >> borderWidth [
^style get: #border ^ self ? #border
]
{ #category : #accessing }
Diya2DPrimShape >> borderWidth: w [
style set: #border value: w.
] ]
{ #category : #accessing } { #category : #accessing }
Diya2DPrimShape >> boundingBox [ Diya2DPrimShape >> boundingBox [
^ bbox applyTf: self tf. ^ self tf localBoundsToGlobal: bbox.
]
{ #category : #accessing }
Diya2DPrimShape >> color [
^ self style get: #color.
]
{ #category : #accessing }
Diya2DPrimShape >> color: value [
^ self style set: #color value: value
] ]
{ #category : #initialization } { #category : #initialization }
Diya2DPrimShape >> draw [ Diya2DPrimShape >> draw [
vbuffer ifNil: [ ^self ]. vbuffer ifNil: [ ^self ].
OpenGL
enable: GL_CULL_FACE;
enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA.
"configure vao vbo for texture QUAD" "configure vao vbo for texture QUAD"
self texture ifNotNil: [ self texture ifNotNil: [
self texture setup. self texture setup.
context texture0 setImage2D: self texture. context useTexture: self texture.
context texture0 active.
]. ].
context vao enableAttribute: 0. context submitData: vbuffer.
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil .
context vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_STATIC_DRAW.
OpenGL drawArrays: type first:0 count:((vbuffer size )>> 2 ). OpenGL drawArrays: type first:0 count:((vbuffer size )>> 2 ).
"reset value" "reset value"
self texture ifNotNil: [self texture drop.]. self texture ifNotNil: [self texture drop.].
self borderWidth > 0 ifTrue: [ self drawBorder ]. self borderWidth > 0 ifTrue: [ self drawBorder ].
context vao disableAttribute: 0. OpenGL
disable: GL_CULL_FACE;
disable: GL_BLEND.
] ]
{ #category : #initialization } { #category : #initialization }
Diya2DPrimShape >> drawBorder [ Diya2DPrimShape >> drawBorder [
"Diya2DShader uniqueInstance use." "Diya2DShader uniqueInstance use."
shader setUniform: #u_color value: self borderColor asGL4FArray; shader setUniform: #u_color value: (self ? #borderColor) asGL4FArray;
setUniform: #u_texture_type value: 1. setUniform: #u_texture_type value: 1.
OpenGL OpenGL
lineWidth: self borderWidth. lineWidth: self borderWidth.
@ -103,12 +71,11 @@ Diya2DPrimShape >> extent [
Diya2DPrimShape >> initialize [ Diya2DPrimShape >> initialize [
super initialize. super initialize.
texture := nil. texture := nil.
children := nil.
type := GL_TRIANGLES. type := GL_TRIANGLES.
bbox := Rectangle origin: 0@0 corner: 0@0. bbox := Rectangle origin: 0@0 corner: 0@0.
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
Diya2DPrimShape >> inner: aPoint [ Diya2DPrimShape >> inner: aPoint [
bbox ifNil: [ ^false ]. bbox ifNil: [ ^false ].
^ bbox containsPoint: (self local: aPoint) ^ bbox containsPoint: (self local: aPoint)
@ -118,10 +85,17 @@ Diya2DPrimShape >> inner: aPoint [
Diya2DPrimShape >> setUpShader [ Diya2DPrimShape >> setUpShader [
super setUpShader. super setUpShader.
self shader self shader
setUniform: #u_color value: self color asGL4FArray; setUniform: #u_color value: (self ? #color) asGL4FArray;
setUniform: #u_bg_color value: self bgColor asGL4FArray; setUniform: #u_bg_color value: (self ? #bgColor) asGL4FArray.
setUniform: #u_texture_type value: self texture ifNotNil: [
(self texture ifNil: [ 0 ] ifNotNil:[self texture format]). self shader
setUniform: #u_texture value: self texture unit;
setUniform: #u_texture_type value: self texture format.
]
ifNil:
[
self shader setUniform: #u_texture_type value: 0.
].
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -20,7 +20,13 @@ uniform vec4 u_bg_color;
uniform sampler2D u_texture; uniform sampler2D u_texture;
varying vec2 texcoord; varying vec2 texcoord;
void main(void) { void main(void) {
vec4 texcolor = vec4(0,0,0,0); if(u_texture_type == 1)
{
// draw border
gl_FragColor = u_color;
return;
}
vec4 texcolor = u_bg_color;
// alpha // alpha
if(u_texture_type == 0x1906) { if(u_texture_type == 0x1906) {
texcolor = vec4(1, 1, 1, texture2D(u_texture, texcoord).a); texcolor = vec4(1, 1, 1, texture2D(u_texture, texcoord).a);
@ -28,19 +34,15 @@ void main(void) {
// rgba // rgba
else if (u_texture_type == 0x1908){ else if (u_texture_type == 0x1908){
texcolor = texture2D(u_texture, texcoord); texcolor = texture2D(u_texture, texcoord);
} }
else if(u_texture_type == 1)
{
texcolor = vec4(1,1,1,1);
}
vec4 pxcolor = texcolor * u_color; vec4 pxcolor = texcolor * u_color;
if(pxcolor.a > 0.0) if(pxcolor.a > 0.0)
{ {
gl_FragColor = pxcolor; gl_FragColor = pxcolor;
} }
else else
{ {
gl_FragColor = u_bg_color; gl_FragColor = u_bg_color;
} }
}' }'
] ]

View File

@ -4,7 +4,6 @@ Class {
#instVars : [ #instVars : [
'currapp', 'currapp',
'txtFPS', 'txtFPS',
'event',
'running' 'running'
], ],
#category : #'Diya-Applications' #category : #'Diya-Applications'
@ -12,22 +11,19 @@ Class {
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> appNode [ DiyaApplicationLauncher >> appNode [
^root children first ^node children first
] ]
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> bindGlobalEvent [ DiyaApplicationLauncher >> bindGlobalEvent [
|pointer | |pointer |
pointer := root addNode: (DiyaCircle r: 10) at: 200@200. pointer := node addNode: (DiyaCircle r: 10) at: 200@200.
pointer color: Color orange. pointer styleName: #pointer.
pointer borderColor: Color red. target on: #keydown do:[:e| self stdlog: 'keydown...'. running := false.].
pointer borderWidth: 2. target on: #quit do: [:e| running := false].
root on: #keydown do:[:e| Transcript show: 'keydown...';cr. running := false.]. target on: #(fingerdown fingermotion mousemotion) do:[:e|
root on: #quit do: [:e| running := false].
root on: #(fingerdown fingermotion mousemotion) do:[:e|
pointer position: e mapped worldPosition. pointer position: e mapped worldPosition.
"Transcript show: e mapped worldPosition asString;cr." DiyaRenderer mouse: (e mapped x) @ (e mapped y).
DiyaRendererContext uniqueInstance mouse: (e mapped x) @ (e mapped y).
]. ].
] ]
@ -36,18 +32,32 @@ DiyaApplicationLauncher >> defaultApplication [
^DiyaExampleApp ^DiyaExampleApp
] ]
{ #category : #'as yet unclassified' } { #category : #initialization }
DiyaApplicationLauncher >> delta: delta [ DiyaApplicationLauncher >> defineLayout [
|fps| DiyaUIThemesManager uniqueInstance currentTheme
delta = 0 ifTrue:[^self]. define: #fps_text styles: {
fps := ((1000/delta) asInteger). #color -> Color red.
txtFPS data: ('FPS:', fps asString). #fontSize -> 18.
#bgColor -> Color transparent.
};
define: #pointer styles: {
#borderColor -> Color red.
#bgColor -> Color orange.
#border -> 3
}.
node addNode: (DiyaCompositeNode new) at: 0@0.
txtFPS := node addNode:(DiyaText data: '') at: ( self context resolution x - 80)@(self context resolution y - 40).
node addNode: (DiyaTimerNode timeout: 0 do: [:n| self updateFPS ] ).
txtFPS extent: 80@40.
txtFPS styleName: #fps_text.
self bindGlobalEvent.
self loadNode.
] ]
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> initialize [ DiyaApplicationLauncher >> initialize [
super initialize. super initialize.
root := DiyaRootNode new. node := DiyaCompositeNode new.
currapp := nil. currapp := nil.
] ]
@ -55,21 +65,28 @@ DiyaApplicationLauncher >> initialize [
DiyaApplicationLauncher >> launch: app [ DiyaApplicationLauncher >> launch: app [
currapp ifNotNil: [ currapp ifNotNil: [
currapp quit. currapp quit.
root empty.
]. ].
currapp := app uniqueInstance. currapp := app uniqueInstance.
self appNode addNode: currapp root.
self context assets: currapp am. self context assets: currapp am.
currapp setup. currapp target: self appNode.
currapp onloaded:[
self stdlog: 'Application LOADED'.
].
] ]
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> main [ DiyaApplicationLauncher >> onloaded: aBlock [
[(SDL2 pollEvent: event) > 0] whileTrue: [ |loader|
root trigger: (DiyaEvent from: event mapped). running := true.
]. loader := DiyaDefaultSystemLoader on: target.
currapp ifNotNil: [currapp main.]. loader job: [ DiyaFontManager uniqueInstance loadFonts. ] name: 'Loading fonts...'.
root render. loader job: [ self defineLayout ] name: 'Define layout...'.
loader onloaded: [
node children do:[:c| target addNode: c at: c position].
node := target.
aBlock value.
self launch: self defaultApplication.
]
] ]
{ #category : #accessing } { #category : #accessing }
@ -78,14 +95,10 @@ DiyaApplicationLauncher >> running [
] ]
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> setup [ DiyaApplicationLauncher >> updateFPS [
event := SDL_Event new. | fps delta|
root addNode: (Diya2DNode new) at: 0@0. delta := DiyaSystemClock delta.
txtFPS := root addNode:(DiyaText data: '') at: ( self context resolution x - 80)@(self context resolution y - 40). fps := DiyaSystemSettings maxFPS.
txtFPS extent: 80@40. delta = 0 ifFalse:[ fps := (1000/ delta) asInteger].
txtFPS fontSize: 18. txtFPS data: ('FPS:', fps asString).
txtFPS color: Color red.
self bindGlobalEvent.
running := true.
self launch: self defaultApplication.
] ]

View File

@ -2,8 +2,10 @@ Class {
#name : #DiyaApplicationModel, #name : #DiyaApplicationModel,
#superclass : #DiyaSingleton, #superclass : #DiyaSingleton,
#instVars : [ #instVars : [
'root', 'node',
'am' 'am',
'target',
'context'
], ],
#category : #'Diya-Applications' #category : #'Diya-Applications'
} }
@ -20,30 +22,42 @@ DiyaApplicationModel >> cleanup [
{ #category : #accessing } { #category : #accessing }
DiyaApplicationModel >> context [ DiyaApplicationModel >> context [
^DiyaRendererContext uniqueInstance ^DiyaRenderer
] ]
{ #category : #initialization } { #category : #initialization }
DiyaApplicationModel >> initialize [ DiyaApplicationModel >> initialize [
super initialize. super initialize.
context := DiyaRenderer
]
{ #category : #'as yet unclassified' }
DiyaApplicationModel >> loadNode [
|pseudoRoot|
pseudoRoot := DiyaRootNode new.
pseudoRoot addNode: node.
pseudoRoot processQueue do:[:el|
el process
].
] ]
{ #category : #accessing } { #category : #accessing }
DiyaApplicationModel >> main [ DiyaApplicationModel >> node [
^ node
]
{ #category : #accessing }
DiyaApplicationModel >> onloaded: aBlock [
self subclassResponsibility self subclassResponsibility
] ]
{ #category : #accessing } { #category : #accessing }
DiyaApplicationModel >> quit [ DiyaApplicationModel >> quit [
node empty.
self cleanup self cleanup
] ]
{ #category : #accessing } { #category : #initialization }
DiyaApplicationModel >> root [ DiyaApplicationModel >> target: aNode [
^ root target := aNode.
]
{ #category : #accessing }
DiyaApplicationModel >> setup [
self subclassResponsibility
] ]

View File

@ -7,6 +7,7 @@ Class {
{ #category : #initialization } { #category : #initialization }
DiyaBaseApplication >> initialize [ DiyaBaseApplication >> initialize [
super initialize. super initialize.
root := Diya2DNode new. node := DiyaCompositeNode new.
node styleName: #global.
am := AssetManager new. am := AssetManager new.
] ]

View File

@ -13,11 +13,6 @@ DiyaBaseObject >> checkGLError: mark [
]. ].
] ]
{ #category : #accessing }
DiyaBaseObject >> logError: string [
self stderr nextPutAll: string; cr
]
{ #category : #asserting } { #category : #asserting }
DiyaBaseObject >> shouldNotBeCalled [ DiyaBaseObject >> shouldNotBeCalled [
^DiyaCoreAPIError signal: 'Should not be called' ^DiyaCoreAPIError signal: 'Should not be called'
@ -30,12 +25,19 @@ DiyaBaseObject >> stderr [
{ #category : #accessing } { #category : #accessing }
DiyaBaseObject >> stderror: string [ DiyaBaseObject >> stderror: string [
self stderr nextPutAll: string; nextPutAll: Character cr asString. self stderr
nextPutAll: DateAndTime now asString;
nextPutAll: ': ';
nextPutAll: string;
nextPutAll: Character cr asString.
] ]
{ #category : #accessing } { #category : #accessing }
DiyaBaseObject >> stdlog: string [ DiyaBaseObject >> stdlog: string [
self stdout nextPutAll: string; self stdout
nextPutAll: DateAndTime now asString;
nextPutAll: ': ';
nextPutAll: string;
nextPutAll: Character cr asString. nextPutAll: Character cr asString.
] ]

View File

@ -16,9 +16,12 @@ Class {
#category : #'Diya-Runtime' #category : #'Diya-Runtime'
} }
{ #category : #'instance creation' } { #category : #'class initialization' }
DiyaBoot class >> maxFPS [ DiyaBoot class >> initialize [
^60 Smalltalk globals at: #DiyaDisplay put: nil.
Smalltalk globals at: #DiyaSystemClock put: nil.
Smalltalk globals at: #DiyaRenderer put: nil.
Smalltalk globals at: #DiyaSystemSettings put: nil.
] ]
{ #category : #'instance creation' } { #category : #'instance creation' }
@ -31,12 +34,6 @@ DiyaBoot class >> startx [
self uniqueInstance run self uniqueInstance run
] ]
{ #category : #events }
DiyaBoot >> GLinit. [
OpenGL viewportX: 0 Y:0 W: display w H: display h.
OpenGL enable: GL_TEXTURE_2D.
]
{ #category : #events } { #category : #events }
DiyaBoot >> createGLContext [ DiyaBoot >> createGLContext [
context := SDL2 glCreateContext: window. context := SDL2 glCreateContext: window.
@ -82,7 +79,10 @@ DiyaBoot >> init [
SDL2 SDLGetCurrentDisplayMode: display from:0. SDL2 SDLGetCurrentDisplayMode: display from:0.
SDL2 showCursor: 0. SDL2 showCursor: 0.
DiyaSingleton resetAll. DiyaSingleton resetAll.
DiyaFontManager uniqueInstance loadFonts. Smalltalk globals at: #Display ifAbsentPut:display.
Smalltalk globals at: #DiyaDisplay put:display.
Smalltalk globals at: #DiyaSystemSettings put: DiyaSettings uniqueInstance.
Smalltalk globals at: #DiyaSystemClock put: DiyaClock uniqueInstance.
] ]
{ #category : #events } { #category : #events }
@ -90,24 +90,28 @@ DiyaBoot >> initialize [
display := nil. display := nil.
window := nil. window := nil.
context := nil. context := nil.
clock := DiyaClock uniqueInstance. clock := DiyaSystemClock.
] ]
{ #category : #events } { #category : #events }
DiyaBoot >> render [ DiyaBoot >> render [
|delta launcher| |launcher event|
DiyaRendererContext uniqueInstance. event := SDL_Event new.
launcher := DiyaApplicationLauncher uniqueInstance. launcher := DiyaApplicationLauncher uniqueInstance.
launcher setup. "Init the Open GL view port and enable 2D texture"
self GLinit. OpenGL viewportX: 0 Y:0 W: display w H: display h.
OpenGL enable: GL_TEXTURE_2D.
launcher target: DiyaRenderer root.
launcher onloaded: [self stdlog: 'Launcher loaded'].
[ launcher running ] whileTrue: [ [ launcher running ] whileTrue: [
delta := DiyaClock uniqueInstance delta asMilliSeconds. DiyaSystemClock tick.
launcher delta: delta. [(SDL2 pollEvent: event) > 0] whileTrue: [
DiyaClock uniqueInstance tick. DiyaRenderer root trigger: (DiyaEvent from: event mapped).
launcher main. ].
SDL2 glSwapWindow: window. DiyaRenderer render.
delta := DiyaClock uniqueInstance delta asMilliSeconds. SDL2 delay:
SDL2 delay: (0 max: (1000/ self class maxFPS) asInteger - delta). (0 max:
(1000/ DiyaSystemSettings maxFPS) asInteger - (DiyaSystemClock lapDelta)).
]. ].
] ]
@ -181,10 +185,8 @@ DiyaBoot >> showSystemInfo [
stream nextPutAll: rinfo name readString; nextPutAll:' '. stream nextPutAll: rinfo name readString; nextPutAll:' '.
]. ].
stream cr. stream cr.
stream nextPutAll:'Display resolution: '; stream nextPutAll: DiyaDisplay asString; cr.
nextPutAll:display w asString; stream cr.
nextPutAll: 'x';
nextPutAll: display h asString; cr.
self stdout nextPutAll: stream contents self stdout nextPutAll: stream contents
] ]
@ -197,8 +199,11 @@ DiyaBoot >> startx [
"SDL2 glMakeCurrent: window context: context." "SDL2 glMakeCurrent: window context: context."
self showSystemInfo. self showSystemInfo.
DiyaRendererContext DiyaRendererContext
uniqueInstance display: display; uniqueInstance
useProjection: OrthoProjectionMatrix. display: display;
window: window;
useProjection: OrthoProjectionMatrix.
Smalltalk globals at: #DiyaRenderer put: DiyaRendererContext uniqueInstance.
self render. self render.
context delete. context delete.
window destroy. window destroy.

View File

@ -14,9 +14,9 @@ DiyaButton class >> text: string [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaButton >> icon: id [ DiyaButton >> icon: ico [
label icon: id. label icon: ico.
label updateLayout. label setDirty.
] ]
{ #category : #accessing } { #category : #accessing }
@ -27,10 +27,6 @@ DiyaButton >> iconSize: size [
{ #category : #initialization } { #category : #initialization }
DiyaButton >> initialize [ DiyaButton >> initialize [
super initialize. super initialize.
style
set:#textAlign value: #center;
set:#textVAlign value: #middle;
set:#border value: 1.
rec := self addNode: (DiyaRectangle new). rec := self addNode: (DiyaRectangle new).
label := self addNode: (DiyaLabel new). label := self addNode: (DiyaLabel new).
label txt label txt
@ -43,13 +39,13 @@ DiyaButton >> label [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaButton >> text: string [ DiyaButton >> process [
label txt: string. rec extent: self extent.
label extent: self extent.
^true
] ]
{ #category : #accessing } { #category : #accessing }
DiyaButton >> updateLayout [ DiyaButton >> text: string [
rec extent: self extent. label txt: string.
label position: 0@0.
label extent: self extent.
] ]

View File

@ -3,14 +3,15 @@ Class {
#superclass : #DiyaSingleton, #superclass : #DiyaSingleton,
#instVars : [ #instVars : [
'monotonic', 'monotonic',
'lastTick' 'lastTick',
'lapTime'
], ],
#category : #'Diya-Runtime' #category : #'Diya-Runtime'
} }
{ #category : #initialization } { #category : #initialization }
DiyaClock >> delta [ DiyaClock >> delta [
^(DateAndTime now) - lastTick ^ self lapDelta + self lapTime
] ]
{ #category : #initialization } { #category : #initialization }
@ -22,9 +23,21 @@ DiyaClock >> elapsedTime [
DiyaClock >> initialize [ DiyaClock >> initialize [
monotonic := DateAndTime now. monotonic := DateAndTime now.
lastTick := monotonic. lastTick := monotonic.
lapTime := 0.
]
{ #category : #initialization }
DiyaClock >> lapDelta [
^ ((DateAndTime now) - lastTick) asMilliSeconds
]
{ #category : #initialization }
DiyaClock >> lapTime [
^ lapTime
] ]
{ #category : #initialization } { #category : #initialization }
DiyaClock >> tick [ DiyaClock >> tick [
lapTime := self lapDelta.
lastTick := DateAndTime now. lastTick := DateAndTime now.
] ]

View File

@ -0,0 +1,22 @@
Class {
#name : #DiyaCompositeNode,
#superclass : #Diya2DNode,
#category : #'Diya-Graphics'
}
{ #category : #accessing }
DiyaCompositeNode >> process [
]
{ #category : #accessing }
DiyaCompositeNode >> setClean [
]
{ #category : #accessing }
DiyaCompositeNode >> setDirty [
]

View File

@ -0,0 +1,24 @@
Class {
#name : #DiyaDefaultAppLoader,
#superclass : #DiyaDefaultSystemLoader,
#instVars : [
'label'
],
#category : #'Diya-Applications'
}
{ #category : #initialization }
DiyaDefaultAppLoader >> updateLayout [
super updateLayout.
label ifNil:[
label := node addNode: (DiyaText new) at: (progress position + (0@25)).
label inlineStyle: #xAlign value: #center
].
label extent: (progress extent x) @ 40.
]
{ #category : #scheduling }
DiyaDefaultAppLoader >> updateProgress: name percent: p [
label data: name.
progress percent: p
]

View File

@ -1,20 +0,0 @@
Class {
#name : #DiyaDefaultStyle,
#superclass : #DiyaNodeStyle,
#category : #'Diya-Graphics'
}
{ #category : #initialization }
DiyaDefaultStyle >> initialize [
super initialize.
self set: #bgcolor value:(Color r: 0.2118 g: 0.2118 b: 0.2118).
self set: #color value: Color white.
self set: #border value: 0.
self set: #fontSize value: 18.
self set: #fontFamily value: DiyaFontManager uniqueInstance defaultFamily.
self set: #fontStyle value: DiyaFontManager uniqueInstance defaultStyle.
self set: #borderColor value: (Color r: 0.051 g: 0.051 b: 0.051).
self set: #bgcolor2 value: (Color r: 0.1529 g: 0.1529 b: 0.1529).
self set: #textAlign value: #left.
self set: #textVAlign value: #top
]

View File

@ -0,0 +1,21 @@
Class {
#name : #DiyaDefaultSystemLoader,
#superclass : #DiyaLoader,
#instVars : [
'progress'
],
#category : #'Diya-Applications'
}
{ #category : #initialization }
DiyaDefaultSystemLoader >> updateLayout [
|xtent|
xtent := DiyaRenderer resolution.
progress ifNil:[progress := node addNode: (DiyaLoadingBar new) at: 20@((xtent y >> 1) - 50)].
progress extent: (xtent x - 40) @ 20.
]
{ #category : #scheduling }
DiyaDefaultSystemLoader >> updateProgress: name percent: p [
progress percent: p
]

View File

@ -0,0 +1,41 @@
Class {
#name : #DiyaDefaultTheme,
#superclass : #DiyaStyleSheet,
#category : #'Diya-UIThemes'
}
{ #category : #define }
DiyaDefaultTheme >> defineGlobal [
self define: #global styles: {
#bgColor -> (Color r: 0.2118 g: 0.2118 b: 0.2118).
#color -> Color white.
#border -> 0.
#fontSize -> 18.
#fontFamily -> DiyaFontManager uniqueInstance defaultFamily.
#textIconFamily -> 'bootstrap-icons'.
#fontStyle -> DiyaFontManager uniqueInstance defaultStyle.
#borderColor -> Color transparent.
#xAlign -> #left.
#yAlign -> #middle.
#iconSize -> 24.
}
]
{ #category : #define }
DiyaDefaultTheme >> defineLoadingBar [
self define: #loadingBar styles: {
#bgColor -> Color red.
#border -> 1.
#borderColor -> Color white.
};
define: #loadingProgress styles: {
#bgColor -> Color white.
}
]
{ #category : #initialization }
DiyaDefaultTheme >> initialize [
super initialize.
self defineGlobal.
self defineLoadingBar.
]

View File

@ -23,16 +23,6 @@ DiyaEllipse class >> rx: rx ry: ry shader: s [
yourself yourself
] ]
{ #category : #initialization }
DiyaEllipse >> draw [
OpenGL
enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA.
super draw.
OpenGL
disable: GL_BLEND
]
{ #category : #initialization } { #category : #initialization }
DiyaEllipse >> drawBorder [ DiyaEllipse >> drawBorder [
"do nothing" "do nothing"
@ -60,39 +50,7 @@ DiyaEllipse >> inner: aPoint [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaEllipse >> rx [ DiyaEllipse >> process [
^ rx
]
{ #category : #accessing }
DiyaEllipse >> rx: anObject [
rx := anObject.
dirty := true.
]
{ #category : #accessing }
DiyaEllipse >> ry [
^ ry
]
{ #category : #accessing }
DiyaEllipse >> ry: anObject [
ry := anObject.
dirty := true
]
{ #category : #initialization }
DiyaEllipse >> setUpShader [
super setUpShader.
self shader
setUniform: #u_border value: (style get: #border);
setUniform: #u_border_color value: (style get:#borderColor) asGL4FArray;
setUniform: #u_rx value: rx;
setUniform: #u_ry value: ry.
]
{ #category : #accessing }
DiyaEllipse >> update [
bbox := Rectangle origin: ((rx negated) @ (ry negated)) corner: (rx @ ry). bbox := Rectangle origin: ((rx negated) @ (ry negated)) corner: (rx @ ry).
{ {
bbox origin x. bbox origin y. 0.0. 0.0. bbox origin x. bbox origin y. 0.0. 0.0.
@ -105,3 +63,35 @@ DiyaEllipse >> update [
} doWithIndex: [:e :i| vbuffer at: i put: e]. } doWithIndex: [:e :i| vbuffer at: i put: e].
^true ^true
] ]
{ #category : #accessing }
DiyaEllipse >> rx [
^ rx
]
{ #category : #accessing }
DiyaEllipse >> rx: anObject [
rx := anObject.
self setDirty
]
{ #category : #accessing }
DiyaEllipse >> ry [
^ ry
]
{ #category : #accessing }
DiyaEllipse >> ry: anObject [
ry := anObject.
self setDirty
]
{ #category : #initialization }
DiyaEllipse >> setUpShader [
super setUpShader.
self shader
setUniform: #u_border value: (self ? #border);
setUniform: #u_border_color value: ( self ? #borderColor) asGL4FArray;
setUniform: #u_rx value: (rx * (scale x)) ;
setUniform: #u_ry value: (ry * (scale y)) .
]

View File

@ -3,7 +3,8 @@ Class {
#superclass : #DiyaBaseObject, #superclass : #DiyaBaseObject,
#instVars : [ #instVars : [
'enable', 'enable',
'mapped' 'mapped',
'target'
], ],
#category : #'Diya-Events' #category : #'Diya-Events'
} }
@ -38,3 +39,13 @@ DiyaEvent >> mapped: anObject [
DiyaEvent >> preventDefault [ DiyaEvent >> preventDefault [
enable := false enable := false
] ]
{ #category : #accessing }
DiyaEvent >> target [
^ target
]
{ #category : #accessing }
DiyaEvent >> target: anObject [
target := anObject
]

View File

@ -1,6 +1,9 @@
Class { Class {
#name : #DiyaExampleApp, #name : #DiyaExampleApp,
#superclass : #DiyaBaseApplication, #superclass : #DiyaBaseApplication,
#instVars : [
'loader'
],
#category : #'Diya-Applications' #category : #'Diya-Applications'
} }
@ -10,74 +13,177 @@ DiyaExampleApp >> cleanup [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaExampleApp >> main [ DiyaExampleApp >> defineNodes [
|node2 node1 img ell label icon button texture loading|
node := DiyaCompositeNode new.
texture := DiyaImageTex new.
label := node addNode: (DiyaLabel new) at: 10@40.
label extent: 250@24.
label styleName:#text_icon_1.
label icon: 16rF254.
node1 := node addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 300 @ 40.
node1 rotation: 45.
node1 scale: 2.0@2.0.
node1 on: #(mousebuttondown fingerdown) do:[:e|
label txt: 'RECT ', (node1 local: e mapped worldPosition) asIntegerPoint asString].
img := node addNode: (DiyaImageView from:'mrsang.png') at: 10 @ 400.
img styleName: #image_view.
img extent:200@200.
node on: #(mousebuttondown fingerdown) do:[:e|
"change texture"
|p|
p := e mapped worldPosition.
label txt: 'Mouse ', p asIntegerPoint asString.
DiyaRenderer assets
addAsset:(texture fromDisplay: (Rectangle origin: ((p x - 100) @ (p y - 100)) extent: 200@200 ) as: 'capture').
img textureNamed: 'capture'.
].
node2 := node addNode: (DiyaRectangle new) at: 10@80.
node2 styleName: #rect_view.
node2 extent: 240@320.
node2 := node addNode: (DiyaText data: String loremIpsum) at: 10@80.
node2 extent: 240@320.
node2 wordWrap: true.
node2 styleName: #text_view.
node2 := node addNode: (DiyaLine from: 10@10 to: 200@200).
node2 styleName: #line_view.
ell := node addNode: (DiyaEllipse rx:100 ry: 70) at: 120@300.
ell scale: 1.2 @ 1.2.
ell styleName: #ell_view.
"ell rotation: 30."
ell textureNamed:'mrsang.png'.
ell addNode: (DiyaTimerNode timeout: 1000 / 6 do:[:n |
n parent rotation: n parent rotation + 10.
] ).
ell on: #(mousebuttondown fingerdown) do:[:e|
label txt: 'Ellipse clicked', (ell local:e mapped worldPosition) asIntegerPoint asString].
node2 := node addNode: (DiyaConvexPolygon points:{0@40. 150@190. 200@20. 100@0}) at: 250@60.
node2 textureNamed: 'mrsang.png'.
node2 styleName: #poly_view.
icon := node addNode: (DiyaFontIcon data: #(16rF101 16rF155 16rF185 16rF21B 16rF298 16rF254)) at: 240@500.
icon styleName: #text_icon_2.
button := node addNode: (DiyaButton text: 'Click me !') at: 240@460.
icon := DiyaFontIcon data: 16rF130.
"icon := DiyaImageIcon from: 'mrsang.png'."
icon addNode:(DiyaTimerNode timeout: 1000 / 12 do:[:n |
n parent rotation: n parent rotation + 10 pivot: n parent extent / 2.
] ).
button extent: 200@40.
button icon: icon "'mrsang.png'".
"button rotation: Float pi / 2.0."
button styleName: #button_view.
loading := node addNode: (DiyaLoadingBar new) at: 240@550.
loading extent: 200 @ 20.
loading addNode: (DiyaTimerNode timeout: 2000 do:[:n |
|p|
p := (n parent percent + 10).
p > 100 ifTrue:[ p := 0].
n parent percent: p.
] ).
loading := node addNode: (DiyaLoadingBar new) at: 240@580.
loading extent: 200 @ 20.
loading addNode: (DiyaTimerNode timeout: 1000 do:[:n |
|p|
p := (n parent percent + 10).
p > 100 ifTrue:[ p := 0].
n parent percent: p.
] ).
]
{ #category : #accessing }
DiyaExampleApp >> defineStyleSheet [
|fmgr style|
fmgr := DiyaFontManager uniqueInstance.
#(16 18 24) do:[:fontSize|
self stdlog: 'Init font size ', fontSize asString, ' of ', fmgr defaultFamily.
style := fmgr style: fmgr defaultStyle from: fmgr defaultFamily.
(style textureOf: fontSize)" genPrintableASCII" .
].
DiyaUIThemesManager uniqueInstance currentTheme
define: #text_icon_1 styles: {
#color -> Color orange.
#fontSize -> 24.
#bgColor -> Color transparent.
};
define: #text_icon_2 extend:#text_icon_1 styles: {
#fontSize -> 16.
};
define: #image_view styles: {
#color -> Color white.
#border -> 1.
#bgColor -> Color cyan.
#borderColor -> Color red
};
define: #rect_view extend: #image_view styles: {
#bgColor -> Color transparent.
};
define: #text_view styles: {
#color -> Color orange.
#fontSize -> 16.
#bgColor -> Color transparent.
#xAlign -> #center
};
define: #line_view styles: {
#color -> Color red.
#border -> 4
};
define: #ell_view styles: {
#borderColor -> Color red.
#color -> Color white.
#border -> 2.
};
define: #poly_view styles: {
#borderColor -> Color red.
#color -> Color green.
#border -> 1.
#bgColor -> Color transparent.
};
define: #button_view styles: {
#borderColor -> (Color r: 0.051 g: 0.051 b: 0.051).
#color -> Color white.
#bgColor -> (Color r: 0.1529 g: 0.1529 b: 0.1529).
#border -> 1.
#yAlign -> #middle.
#xAlign -> #center
}
]
{ #category : #accessing }
DiyaExampleApp >> initialize [
super initialize.
loader := nil
] ]
{ #category : #accessing } { #category : #accessing }
DiyaExampleApp >> setup [ DiyaExampleApp >> onloaded: aBlock [
|node node1 ell label icon button| loader ifNil: [ loader := DiyaDefaultAppLoader on: target ].
label := root addNode: (DiyaLabel new) at: 10@40. loader job: [ self defineStyleSheet ] name: 'Initializing themes...'.
label extent: 250@24. loader job: [
label color: Color orange. self defineNodes.
label iconSize: 24. self loadNode.
label icon: 16rF254. ] name: 'Initializing UI elements...'.
loader onloaded: [
node1 := root addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 300 @ 40. node children do:[:e|
"node1 rotation: (Float pi / 8.0)." target addNode: e at: e position.
node1 scale: 1.2@1.2. node := target.
node1 on: #(mousebuttondown fingerdown) do:[:e| ].
label txt: 'Mouse ', (node1 local: e mapped worldPosition) asIntegerPoint asString]. aBlock value
].
node := root addNode: (DiyaImageView from:'mrsang.png') at: 10 @ 400.
node color: (Color r: 1.0 g:1.0 b:1.0 alpha:1.0 ).
node borderWidth:1.
node bgColor: Color cyan.
node borderColor: Color red.
node borderWidth: 3.0.
node extent:200@200.
node := root addNode: (DiyaRectangle new) at: 10@80.
node borderWidth: 1.
node extent: 240@320.
node := root addNode: (DiyaText data: String loremIpsum) at: 10@80.
node extent: 240@320.
node wordWrap: true.
node fontSize: 16.
node bgColor: Color transparent.
node align: #center.
node := root addNode: (DiyaLine from: 10@10 to: 200@200).
node color: (Color red).
node borderWidth: 2.0.
ell := root addNode: (DiyaEllipse rx:100 ry: 70) at: 100@300.
ell borderColor: Color red.
ell color: Color white.
ell bgColor: Color cyan.
ell rotation: Float pi / 6.0.
ell borderWidth: 3.0.
"node rotation: Float pi / 2.0."
ell textureNamed:'mrsang.png'.
ell on: #(mousebuttondown fingerdown) do:[:e|
label txt: 'Ellipse clicked', (ell local:e mapped worldPosition) asIntegerPoint asString].
node := root addNode: (DiyaConvexPolygon points:{250@100. 400@250. 450@80. 350@60}).
node color: Color green.
node borderColor: Color red.
node textureNamed: 'mrsang.png'.
node borderWidth: 3.0.
icon := root addNode: (DiyaFontIcon data: #(16rF101 16rF155 16rF185 16rF21B 16rF298 16rF254)) at: 240@500.
icon fontSize: 24.
icon bgColor: Color transparent.
icon color: (Color r: 209/255 g: 66/255 b:245/255 ).
button := root addNode: (DiyaButton text: 'Click me !') at: 240@460.
button extent: 200@40.
button icon:16rF185"'mrsang.png'".
button iconSize: 24.
^ root
] ]

View File

@ -22,11 +22,13 @@ DiyaFFIBase class >> libNames [
{ #category : #accessing } { #category : #accessing }
DiyaFFIBase class >> moduleName [ DiyaFFIBase class >> moduleName [
self libNames do:[:aName| self libNames do:[:aName|
(ExternalAddress loadSymbol: self checkSymbol from: aName) ifNotNil: [ [
^ aName (ExternalAddress loadSymbol: self checkSymbol from: aName) ifNotNil: [
]. ^ aName
]
] on: Error do: [ ]
]. ].
DiyaCoreAPIError signal: 'Unable to find FFI library (', self checkSymbol, ')'. DiyaFFILibNotFound signal: 'Unable to find FFI library (', self checkSymbol, ')'.
] ]
{ #category : #'library path' } { #category : #'library path' }

View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaFFILibNotFound,
#superclass : #DiyaError,
#category : #'Diya-Events'
}

View File

@ -10,7 +10,6 @@ Class {
{ #category : #initialization } { #category : #initialization }
DiyaFontIcon >> data: code [ DiyaFontIcon >> data: code [
super data:(code isArray ifTrue: [ code ] ifFalse:[{code}]). super data:(code isArray ifTrue: [ code ] ifFalse:[{code}]).
bbox := Rectangle origin: 0@0 corner: ((data size) * (self fontSize) ) @ self fontSize.
] ]
{ #category : #initialization } { #category : #initialization }
@ -31,11 +30,9 @@ DiyaFontIcon >> drawText [
] ]
{ #category : #initialization } { #category : #accessing }
DiyaFontIcon >> fontName: name style: face size: size [ DiyaFontIcon >> fontName [
super fontName: name style:face size: size. ^ self ? #textIconFamily
data ifNil: [ ^ self ].
bbox := Rectangle origin: 0@0 corner: ((data size) * size ) @ size.
] ]
{ #category : #initialization } { #category : #initialization }
@ -48,17 +45,10 @@ DiyaFontIcon >> iconSize [
^ self fontSize ^ self fontSize
] ]
{ #category : #accessing }
DiyaFontIcon >> iconSize: v [
"self extent: "
^ self fontSize: v
]
{ #category : #initialization } { #category : #initialization }
DiyaFontIcon >> initialize [ DiyaFontIcon >> initialize [
super initialize. super initialize.
data := { }. data := { }.
self fontName: 'bootstrap-icons' style: 'Regular' size: 16.
vbuffer := FFIExternalArray externalNewType: GLfloat size:24. vbuffer := FFIExternalArray externalNewType: GLfloat size:24.
vbuffer autoRelease. vbuffer autoRelease.
] ]
@ -67,3 +57,10 @@ DiyaFontIcon >> initialize [
DiyaFontIcon >> lastSeparatorFrom: i [ DiyaFontIcon >> lastSeparatorFrom: i [
self shouldNotBeCalled self shouldNotBeCalled
] ]
{ #category : #initialization }
DiyaFontIcon >> process [
data ifNil: [ ^self ].
bbox := Rectangle origin: 0@0 corner: ((data size) * (self fontSize) ) @ self fontSize.
^ super process.
]

View File

@ -13,13 +13,6 @@ DiyaFontManager class >> cleanUpInstance: singleton [
singleton reset. singleton reset.
] ]
{ #category : #'as yet unclassified' }
DiyaFontManager class >> searchPaths [
^ {
Smalltalk imageDirectory / 'fonts'
}
]
{ #category : #initialization } { #category : #initialization }
DiyaFontManager >> defaultFamily [ DiyaFontManager >> defaultFamily [
^'Ubuntu' ^'Ubuntu'
@ -66,7 +59,7 @@ DiyaFontManager >> loadFace: face [
DiyaFontManager >> loadFile: aFile [ DiyaFontManager >> loadFile: aFile [
| path face i numfaces | | path face i numfaces |
path := aFile fullName convertToWithConverter: UTF8TextConverter new. path := aFile fullName convertToWithConverter: UTF8TextConverter new.
Transcript show: 'Loading font file ', path;cr. self stdlog: 'Loading font file ', path.
i := 0. i := 0.
numfaces := nil. numfaces := nil.
[ face := FreeTypeFace basicNew [ face := FreeTypeFace basicNew
@ -74,7 +67,7 @@ DiyaFontManager >> loadFile: aFile [
index: i. index: i.
face newFaceFromFile: path index: i. face newFaceFromFile: path index: i.
face loadFields. face loadFields.
Transcript show: 'Loaded font face ', face styleName;cr. self stdlog: 'Loaded font face ', face styleName.
numfaces ifNil: [ numfaces := face numFaces ]. numfaces ifNil: [ numfaces := face numFaces ].
self loadFace: face. self loadFace: face.
i := i + 1. i := i + 1.
@ -90,7 +83,9 @@ DiyaFontManager >> loadFonts [
{ #category : #initialization } { #category : #initialization }
DiyaFontManager >> loadFonts: force [ DiyaFontManager >> loadFonts: force [
force ifTrue:[self reset]. force ifTrue:[self reset].
self class searchPaths do:[:path| self loadPath: path]. DiyaSystemSettings fontPaths
select:[:p| p asFileReference exists]
thenDo:[:path| self loadPath: path].
] ]

View File

@ -5,17 +5,24 @@ Class {
} }
{ #category : #accessing } { #category : #accessing }
DiyaImageIcon >> iconSize [ DiyaImageIcon >> borderWidth [
^ self extent x ^0
] ]
{ #category : #accessing } { #category : #accessing }
DiyaImageIcon >> iconSize:v [ DiyaImageIcon >> iconSize [
^ self extent: v@v ^ self ? #iconSize
] ]
{ #category : #accessing } { #category : #accessing }
DiyaImageIcon >> initialize [ DiyaImageIcon >> initialize [
super initialize. super initialize.
style set: #border value: 0 ]
{ #category : #accessing }
DiyaImageIcon >> process [
|v|
v := self iconSize.
self extent: (v@v).
^super process
] ]

View File

@ -1,9 +1,6 @@
Class { Class {
#name : #DiyaImageTex, #name : #DiyaImageTex,
#superclass : #OpenGLTexImage2D, #superclass : #OpenGLTexImage2D,
#instVars : [
'path'
],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
'OpenGLTypes' 'OpenGLTypes'
@ -11,6 +8,16 @@ Class {
#category : #'Diya-Graphics' #category : #'Diya-Graphics'
} }
{ #category : #'instance creation' }
DiyaImageTex class >> fromDisplay: aRect as: assetName [
^ self new fromDisplay: aRect as: assetName; yourself
]
{ #category : #'instance creation' }
DiyaImageTex class >> fromDisplayAs: assetName [
^ self new fromDisplayAs: assetName; yourself
]
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaImageTex class >> fromFile: path [ DiyaImageTex class >> fromFile: path [
^ self new fromFile: path; yourself ^ self new fromFile: path; yourself
@ -18,35 +25,87 @@ DiyaImageTex class >> fromFile: path [
{ #category : #accessing } { #category : #accessing }
DiyaImageTex >> drop [ DiyaImageTex >> drop [
OpenGL "OpenGL
disable: GL_CULL_FACE; disable: GL_CULL_FACE;
disable: GL_BLEND. disable: GL_BLEND."
]
{ #category : #conversion }
DiyaImageTex >> flipY [
|buffer size linesize top bottom|
size := self bytesSize.
linesize := width << 2.
buffer := FFIExternalArray externalNewType: GLubyte size: linesize.
LibC memset: buffer getHandle value: 0 size: buffer size.
0 to: (height >> 1) -1 do: [ :line|
top := line * linesize.
bottom := (size - (linesize * (line + 1))).
LibC memCopy: (data getHandle) + top to: buffer getHandle size: linesize.
LibC memCopy: (data getHandle) + bottom to: (data getHandle) + top size: linesize.
LibC memCopy: buffer getHandle to: (data getHandle) + bottom size: linesize.
].
buffer free
]
{ #category : #'instance creation' }
DiyaImageTex >> fromDisplay: aRect as: assetName [
data ifNotNil: [data free].
width := aRect extent x asInteger.
height := aRect extent y asInteger.
commited := false.
data := FFIExternalArray externalNewType: GLubyte size: self bytesSize.
LibC memset: data getHandle value: 0 size: data size.
data autoRelease.
OpenGL readPixelsOn: data getHandle
x: aRect origin x
y: (DiyaDisplay height) - (aRect origin y) - (aRect extent y)
w: aRect extent x
h: aRect extent y
format:GL_RGBA
type: GL_UNSIGNED_BYTE.
name := assetName.
self flipY.
]
{ #category : #'instance creation' }
DiyaImageTex >> fromDisplayAs: assetName [
self fromDisplay: (Rectangle origin: 0@0 extent: DiyaDisplay extent ) as: assetName
] ]
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaImageTex >> fromFile: aPath [ DiyaImageTex >> fromFile: aPath [
|form color index| |surface|
path := aPath. self stdlog: 'Loading texture from ', aPath fullName.
Transcript show: 'Loading texture from ', path fullName;cr. data ifNotNil: [ data free ].
form := ImageReadWriter formFromFileNamed: path. name := aPath fullName.
data := FFIExternalArray externalNewType: GLubyte size:(form width) * (form height) * 4. surface := self surfaceFromFile: aPath.
width := surface w.
height := surface h.
data := FFIExternalArray externalNewType: GLubyte size: self bytesSize.
LibC memset: data getHandle value: 0 size: data size. LibC memset: data getHandle value: 0 size: data size.
data autoRelease. data autoRelease.
width := form width. LibC memCopy: surface pixels getHandle to: data getHandle size: data size.
height := form height. SDL2
index := 1. freeSurface: surface.
0 to: height -1 do:[:y| commited := false.
0 to: width - 1 do:[:x| self stdlog: 'Loaded ', aPath fullName.
color := (form colorAt: x@y) as4bytesRGB. ]
data
at: index put: color first; { #category : #'instance creation' }
at: index + 1 put: (color at: 2); DiyaImageTex >> fromForm: aForm name: aName [
at: index +2 put: (color at: 3); |surface|
at: index + 3 put: color last. name := aName.
index := index + 4. data ifNotNil: [ data free ].
] surface := self surfaceFromForm: aForm.
]. width := surface w.
height := surface h.
commited := false.
data := FFIExternalArray externalNewType: GLubyte size: self bytesSize.
LibC memset: data getHandle value: 0 size: data size.
data autoRelease.
LibC memCopy: surface pixels getHandle to: data getHandle size: data size.
SDL2
freeSurface: surface.
] ]
{ #category : #'instance creation' } { #category : #'instance creation' }
@ -65,20 +124,45 @@ DiyaImageTex >> mipmap [
^false ^false
] ]
{ #category : #accessing }
DiyaImageTex >> path [
^ path
]
{ #category : #accessing } { #category : #accessing }
DiyaImageTex >> setup [ DiyaImageTex >> setup [
OpenGL
enable: GL_CULL_FACE;
enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA.
OpenGLTexture OpenGLTexture
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE; parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_T param: GL_CLAMP_TO_EDGE; parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_T param: GL_CLAMP_TO_EDGE;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MIN_FILTER param: GL_LINEAR; parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MIN_FILTER param: GL_LINEAR;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MAG_FILTER param: GL_LINEAR. parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MAG_FILTER param: GL_LINEAR.
] ]
{ #category : #conversion }
DiyaImageTex >> surfaceFromFile: aPath [
aPath exists ifFalse: [ ^DiyaCoreAPIError signal:'File not found ', aPath fullName ].
[^ SDL2Image SDLImgLoad: aPath fullName] on: Error do: [
^ self surfaceFromForm: (ImageReadWriter formFromFileNamed: aPath)
].
]
{ #category : #conversion }
DiyaImageTex >> surfaceFromForm: aForm [
|srcSurface destSurface form|
form := aForm asFormOfDepth: 32.
srcSurface :=
SDL2 createRGBSurfaceFromPixels: form bits
width: form width height: form height
depth: 32 pitch: (form width << 2)
rmask: 16r00ff0000
gmask: 16r000ff00
bmask: 16r00000ff
amask: 16rff000000.
destSurface :=
SDL2 createRGBSurfaceFromPixels: srcSurface pixels getHandle
width: form width height: form height
depth: 32 pitch: (form width << 2)
rmask: 16r000000ff
gmask: 16r0000ff00
bmask: 16r00ff0000
amask: 16rff000000.
SDL2 SDLBlitSurface: srcSurface srcRect: nil dest: destSurface dstRect: nil.
SDL2
freeSurface: srcSurface.
^ destSurface
]

View File

@ -14,14 +14,6 @@ DiyaLabel >> fontSize [
] ]
{ #category : #accessing }
DiyaLabel >> fontSize: value [
txt fontSize: value.
"icon ifNotNil: [ icon fontSize: value ]."
"dirty := true."
]
{ #category : #accessing } { #category : #accessing }
DiyaLabel >> getHAlign: offset [ DiyaLabel >> getHAlign: offset [
^ 0 max: (txt alignLine: ( txt maxLineWidth)). ^ 0 max: (txt alignLine: ( txt maxLineWidth)).
@ -36,13 +28,12 @@ DiyaLabel >> icon [
DiyaLabel >> icon: anObject [ DiyaLabel >> icon: anObject [
icon := nil. icon := nil.
anObject isNumber ifTrue: [ anObject isNumber ifTrue: [
icon := self addNode: (DiyaFontIcon data: anObject). icon := self addNode: (DiyaFontIcon data: anObject).].
icon align: #left].
anObject isString ifTrue: [ anObject isString ifTrue: [
icon := self addNode: (DiyaImageIcon from: anObject). icon := self addNode: (DiyaImageIcon from: anObject).
]. ].
icon ifNil: [ ^ DiyaCoreAPIError signal: 'Invalid icon identification']. icon ifNil: [ icon := self addNode: anObject ].
dirty := true. self setDirty
] ]
{ #category : #accessing } { #category : #accessing }
@ -52,13 +43,6 @@ DiyaLabel >> iconSize [
] ]
{ #category : #accessing }
DiyaLabel >> iconSize: v [
icon ifNil: [ ^self ].
icon iconSize: v
]
{ #category : #initialization } { #category : #initialization }
DiyaLabel >> initialize [ DiyaLabel >> initialize [
super initialize. super initialize.
@ -68,18 +52,7 @@ DiyaLabel >> initialize [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaLabel >> txt [ DiyaLabel >> process [
^ txt
]
{ #category : #accessing }
DiyaLabel >> txt: anObject [
txt data: anObject.
dirty := true
]
{ #category : #accessing }
DiyaLabel >> updateLayout [
|offset isize align| |offset isize align|
offset := 0. offset := 0.
icon ifNotNil: [ icon ifNotNil: [
@ -89,12 +62,24 @@ DiyaLabel >> updateLayout [
]. ].
txt extent: (extent x - offset) @ (extent y). txt extent: (extent x - offset) @ (extent y).
"lookahead update" "lookahead update"
txt update. txt process.
align := self getHAlign: offset. align := self getHAlign: offset.
txt position: offset @ ( (self extent y - txt extent y ) >> 1). txt position: offset @ ( (self extent y - txt extent y ) >> 1).
icon ifNil: [ ^self ]. icon ifNil: [ ^self ].
"{ offset. txt extent. txt maxLineWidth. align } inspect." "{ offset. txt extent. txt maxLineWidth. align } inspect."
icon position: (align @( (self extent y - self iconSize ) >> 1)). icon position: (align @( (self extent y - self iconSize ) >> 1)).
^ true
] ]
{ #category : #accessing }
DiyaLabel >> txt [
^ txt
]
{ #category : #accessing }
DiyaLabel >> txt: anObject [
txt data: anObject.
self setDirty
]

View File

@ -62,7 +62,7 @@ DiyaLine >> from [
{ #category : #accessing } { #category : #accessing }
DiyaLine >> from: anObject [ DiyaLine >> from: anObject [
from := anObject. from := anObject.
dirty := true. self setDirty
] ]
{ #category : #initialization } { #category : #initialization }
@ -74,14 +74,33 @@ DiyaLine >> initialize [
vbuffer := FFIExternalArray externalNewType: GLfloat size:8. vbuffer := FFIExternalArray externalNewType: GLfloat size:8.
vbuffer autoRelease. vbuffer autoRelease.
type := GL_LINES. type := GL_LINES.
style set: #border value: 0
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
DiyaLine >> inner: aPoint [ DiyaLine >> inner: aPoint [
^false ^false
] ]
{ #category : #accessing }
DiyaLine >> process [
|extent|
bbox := (Rectangle origin: from corner: to ).
self position: bbox origin.
extent := bbox extent.
bbox := (Rectangle origin: 0@0 corner: extent ).
vbuffer
at: 1 put: 0.0;
at: 2 put: 0.0;
at: 3 put: 0.0;
at: 4 put: 0.0;
at: 5 put: extent x asFloat;
at: 6 put: extent y asFloat;
at: 7 put: 0.0;
at: 8 put: 0.0.
^true
]
{ #category : #accessing } { #category : #accessing }
DiyaLine >> to [ DiyaLine >> to [
^ to ^ to
@ -90,22 +109,5 @@ DiyaLine >> to [
{ #category : #accessing } { #category : #accessing }
DiyaLine >> to: anObject [ DiyaLine >> to: anObject [
to := anObject. to := anObject.
dirty := true. self setDirty
]
{ #category : #accessing }
DiyaLine >> update [
|extent|
bbox := (Rectangle origin: from corner: to ).
bbox origin = translation ifFalse:[self position: bbox origin].
from := from - bbox origin.
to := to - bbox origin.
extent := bbox extent.
bbox := (Rectangle origin: 0@0 corner: extent ).
{
0.0. 0.0. 0.0. 0.0.
extent x. extent y. 0.0. 0.0.
} doWithIndex: [:e :i| vbuffer at: i put: e].
^true
] ]

81
Diya/DiyaLoader.class.st Normal file
View File

@ -0,0 +1,81 @@
Class {
#name : #DiyaLoader,
#superclass : #DiyaBaseObject,
#instVars : [
'node',
'jobs',
'target'
],
#category : #'Diya-Applications'
}
{ #category : #'instance creation' }
DiyaLoader class >> on: target [
^ self new target: target; yourself
]
{ #category : #scheduling }
DiyaLoader >> executeJobs: callback [
"target visibility: false."
target empty.
target addNode: node.
"target visibility: true".
node visibility: true.
self updateLayout.
500 milliSeconds wait.
self job: [ 500 milliSeconds wait. ] name: 'finishing' .
jobs withIndexDo: [ :job :i|
self updateProgress: job key percent: ((i - 1) * 100 / (jobs size)) asInteger.
job value value.
].
jobs := OrderedCollection new.
self updateProgress: 'Finishing...' percent: 100.
node visibility: false.
target empty.
callback value.
target visibility: true.
]
{ #category : #initialization }
DiyaLoader >> initialize [
super initialize.
node := DiyaCompositeNode new.
jobs := OrderedCollection new.
target := nil.
]
{ #category : #scheduling }
DiyaLoader >> job: aBlock name: aName [
jobs add: (aName -> aBlock)
]
{ #category : #accessing }
DiyaLoader >> node [
^ node
]
{ #category : #scheduling }
DiyaLoader >> onloaded: aBlock [
[ self executeJobs: aBlock ] fork"At: Processor userBackgroundPriority".
]
{ #category : #accessing }
DiyaLoader >> target [
^ target
]
{ #category : #accessing }
DiyaLoader >> target: anObject [
target := anObject
]
{ #category : #initialization }
DiyaLoader >> updateLayout [
self subclassResponsibility
]
{ #category : #scheduling }
DiyaLoader >> updateProgress: name percent: p [
self subclassResponsibility
]

View File

@ -0,0 +1,55 @@
Class {
#name : #DiyaLoadingBar,
#superclass : #DiyaWidget,
#instVars : [
'label',
'bar',
'progress',
'percent'
],
#category : #'Diya-Widgets'
}
{ #category : #accessing }
DiyaLoadingBar >> bar [
^ bar
]
{ #category : #initialization }
DiyaLoadingBar >> initialize [
super initialize.
bar := self addNode: (DiyaRectangle new).
progress := self addNode: (DiyaRectangle new).
bar styleName: #loadingBar.
progress styleName: #loadingProgress.
"label := self addNode: (DiyaLabel new).
label wordWrap: false."
percent := 0.
]
{ #category : #accessing }
DiyaLoadingBar >> label [
^ label
]
{ #category : #accessing }
DiyaLoadingBar >> percent [
^ percent
]
{ #category : #accessing }
DiyaLoadingBar >> percent: anObject [
percent := anObject.
self setDirty.
]
{ #category : #processing }
DiyaLoadingBar >> process [
bar extent: self extent.
progress extent: ((self percent) * (self extent x) / 100) @ (self extent y).
]
{ #category : #accessing }
DiyaLoadingBar >> progress [
^ progress
]

View File

@ -0,0 +1,45 @@
Class {
#name : #DiyaMetaNode,
#superclass : #DiyaNode,
#category : #'Diya-Graphics'
}
{ #category : #accessing }
DiyaMetaNode >> addNode: node at: pos [
self shouldNotBeCalled
]
{ #category : #accessing }
DiyaMetaNode >> boundingBox [
^ Rectangle origin: 0@0 extent: 0@0
]
{ #category : #rendering }
DiyaMetaNode >> draw [
]
{ #category : #accessing }
DiyaMetaNode >> extent [
^ 0@0
]
{ #category : #initialization }
DiyaMetaNode >> initialize [
visibility := false.
]
{ #category : #testing }
DiyaMetaNode >> inner: aPoint [
^ false
]
{ #category : #processing }
DiyaMetaNode >> process [
]
{ #category : #processing }
DiyaMetaNode >> updateTF [
]

View File

@ -10,11 +10,14 @@ Class {
'tf', 'tf',
'shader', 'shader',
'context', 'context',
'dirty',
'ehandlers', 'ehandlers',
'root', 'root',
'styleName',
'style', 'style',
'id' 'inlineStyle',
'id',
'visibility',
'pivot'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -29,20 +32,37 @@ DiyaNode class >> with: shader [
^self new shader: shader; yourself ^self new shader: shader; yourself
] ]
{ #category : #accessing } { #category : #styling }
DiyaNode >> ? styleAttr [
| value|
value := inlineStyle at: styleAttr ifAbsent:[nil].
value ifNotNil: [ ^value ].
styleName ifNotNil: [
style ifNil: [
style := DiyaUIThemesManager uniqueInstance currentTheme ? (self styleName).
].
value := style at: styleAttr ifAbsent:[nil].
value ifNotNil: [ ^value ].
].
"try to look at parent style"
parent ifNil:[self styleNotFound: styleAttr].
^ parent ? styleAttr
]
{ #category : #'add/remove' }
DiyaNode >> addNode: node [ DiyaNode >> addNode: node [
^self addNode: node at: 0@0 ^self addNode: node at: 0@0
] ]
{ #category : #accessing } { #category : #'add/remove' }
DiyaNode >> addNode: node at: pos [ DiyaNode >> addNode: node at: pos [
children ifNil: [ ^self ]. children ifNil: [ ^self ].
node parent: self. node parent: self.
node position: pos.
children add: node. children add: node.
node position: pos.
node root: self root. node root: self root.
node style parent: style. node setDirtyAll.
^ node ^ node
] ]
{ #category : #accessing } { #category : #accessing }
@ -55,13 +75,20 @@ DiyaNode >> children [
^children ^children
] ]
{ #category : #accessing } { #category : #rendering }
DiyaNode >> draw [ DiyaNode >> draw [
self subclassResponsibility self subclassResponsibility
] ]
{ #category : #requirements } { #category : #requirements }
DiyaNode >> empty [ DiyaNode >> empty [
children ifNotNil: [
children do:[:c|
c root: nil.
c setClean.
c visibility: false.
]
].
children := OrderedCollection new. children := OrderedCollection new.
] ]
@ -80,16 +107,24 @@ DiyaNode >> initialize [
super initialize. super initialize.
parent := nil. parent := nil.
shader := nil. shader := nil.
context := DiyaRendererContext uniqueInstance. context := DiyaRenderer.
children := OrderedCollection new. children := OrderedCollection new.
dirty := false.
ehandlers := Dictionary new. ehandlers := Dictionary new.
style := DiyaNodeStyle new. styleName := nil.
style := nil.
root := nil. root := nil.
id := Random new nextInt: 1e6 inlineStyle := Dictionary new.
visibility := true.
pivot := 0@0.
id := self className,'#',(Random new nextInt: 1e6) asString.
] ]
{ #category : #'as yet unclassified' } { #category : #styling }
DiyaNode >> inlineStyle: name value: value [
inlineStyle at: name put: value
]
{ #category : #testing }
DiyaNode >> inner: aPoint [ DiyaNode >> inner: aPoint [
^ self subclassResponsibility ^ self subclassResponsibility
] ]
@ -116,6 +151,11 @@ DiyaNode >> parent: anObject [
parent := anObject parent := anObject
] ]
{ #category : #accessing }
DiyaNode >> pivot [
^ pivot
]
{ #category : #accessing } { #category : #accessing }
DiyaNode >> position [ DiyaNode >> position [
^ translation ^ translation
@ -127,23 +167,54 @@ DiyaNode >> position: anObject [
self updateTF. self updateTF.
] ]
{ #category : #processing }
DiyaNode >> process [
^self subclassResponsibility
]
{ #category : #convenience } { #category : #convenience }
DiyaNode >> register: aBlock to: eventName [ DiyaNode >> register: aBlock to: eventName [
|evtCode| |evtCode|
evtCode := SDL2Constants bindingOf: ('SDL_', eventName asUppercase). evtCode := SDL2Constants bindingOf: ('SDL_', eventName asUppercase).
evtCode ifNil: [ ^DiyaCoreAPIError signal: 'Unknow event ', eventName ]. evtCode ifNil: [ evtCode := eventName ].
ehandlers at: evtCode value put: aBlock. ehandlers at: evtCode value put: aBlock.
] ]
{ #category : #accessing } { #category : #'add/remove' }
DiyaNode >> remove [
parent ifNotNil: [ parent removeChild: self ]
]
{ #category : #'add/remove' }
DiyaNode >> removeChild: c [
c setClean.
c root: nil.
c visibility: false.
children ifNotNil: [ children remove: c ifAbsent:[ ]]
]
{ #category : #rendering }
DiyaNode >> render [ DiyaNode >> render [
dirty ifTrue:[ visibility ifFalse:[^self].
dirty := self update not]. shader ifNotNil: [self setUpShader].
shader ifNotNil: [ self setUpShader ].
self draw. self draw.
children ifNil: [ ^self ]. children ifNil: [ ^self ].
children do: [:c | c render ]. root ifNil: [ ^self ].
root renderNext: children
]
{ #category : #'add/remove' }
DiyaNode >> replaceChild: aNode with: anotherNode [
|index|
children ifNil: [ ^ self ].
index := children indexOf: aNode.
index = 0 ifTrue:[^ self].
children at: index put: anotherNode.
anotherNode parent: self.
anotherNode root: self root.
anotherNode setDirtyAll.
aNode root: nil.
] ]
{ #category : #accessing } { #category : #accessing }
@ -153,7 +224,11 @@ DiyaNode >> root [
{ #category : #accessing } { #category : #accessing }
DiyaNode >> root: anObject [ DiyaNode >> root: anObject [
root := anObject root = anObject ifTrue:[^self].
root := anObject.
children ifNotNil: [
children do:[:c | c root: root]
]
] ]
{ #category : #accessing } { #category : #accessing }
@ -167,6 +242,13 @@ DiyaNode >> rotation: anObject [
self updateTF. self updateTF.
] ]
{ #category : #accessing }
DiyaNode >> rotation: anObject pivot: p [
rotation := anObject.
pivot := p.
self updateTF.
]
{ #category : #accessing } { #category : #accessing }
DiyaNode >> scale [ DiyaNode >> scale [
^ scale ^ scale
@ -178,15 +260,33 @@ DiyaNode >> scale: anObject [
self updateTF. self updateTF.
] ]
{ #category : #accessing } { #category : #'changing state' }
DiyaNode >> setClean [
root ifNil: [ ^self ].
root cleanDirtyNode: self.
]
{ #category : #'changing state' }
DiyaNode >> setDirty [
root ifNil: [ ^self ].
self root enqueueDirtyNode: self.
]
{ #category : #'changing state' }
DiyaNode >> setDirtyAll [
self setDirty.
children ifNotNil: [
children do:[:c| c setDirtyAll] ]
]
{ #category : #rendering }
DiyaNode >> setUpShader [ DiyaNode >> setUpShader [
|mem| |mem|
mem := self tf asGLBuffer. mem := self tf asGLBuffer.
shader use; shader use;
setUniform: #u_time value: DiyaClock uniqueInstance elapsedTime asFloat; setUniform: #u_time value: DiyaSystemClock elapsedTime asFloat;
setUniform: #u_projection value: {GL_FALSE. context projection buffer}; setUniform: #u_projection value: {GL_FALSE. context projection buffer};
setUniform: #u_resolution value: { context resolution x. context resolution y }; setUniform: #u_resolution value: { context resolution x. context resolution y };
setUniform: #u_texture value: 0;
setUniform: #u_transform value: {GL_TRUE. mem}. setUniform: #u_transform value: {GL_TRUE. mem}.
context mouse ifNotNil: [ context mouse ifNotNil: [
"in shader, window origin is bottom left conor of the window "in shader, window origin is bottom left conor of the window
@ -210,16 +310,31 @@ DiyaNode >> shader: anObject [
shader := anObject shader := anObject
] ]
{ #category : #accessing } { #category : #stepping }
DiyaNode >> style [ DiyaNode >> step [
^style ]
{ #category : #stepping }
DiyaNode >> stepDown [
self step.
children ifNotNil: [ children do:[:c | c stepDown ] ]
] ]
{ #category : #accessing } { #category : #accessing }
DiyaNode >> style: aStyle [ DiyaNode >> styleName [
style := aStyle. ^ styleName
dirty := true. ]
parent ifNotNil: [ style parent: parent style ]
{ #category : #accessing }
DiyaNode >> styleName: anObject [
styleName := anObject.
style := nil.
self setDirty
]
{ #category : #'event handling' }
DiyaNode >> styleNotFound: styleAttr [
DiyaCoreAPIError signal: 'Query undefined style ', styleAttr, ' in', styleName.
] ]
{ #category : #accessing } { #category : #accessing }
@ -227,23 +342,31 @@ DiyaNode >> tf [
^ tf ^ tf
] ]
{ #category : #'as yet unclassified' } { #category : #'event handling' }
DiyaNode >> trigger: evt [ DiyaNode >> trigger: evt [
evt enable ifFalse:[^self]. evt enable ifFalse:[^self].
ehandlers at: evt mapped type ifPresent:[:handler| handler value: evt]. ehandlers at: evt mapped type ifPresent:[:handler|
evt target: self.
handler value: evt].
children ifNil: [^self]. children ifNil: [^self].
evt enable ifTrue: [ evt enable ifTrue: [
"evt mapped triggableOn: children first."
children select: [:node | evt mapped triggableOn: node ] thenDo:[:node| node trigger: evt] children select: [:node | evt mapped triggableOn: node ] thenDo:[:node| node trigger: evt]
]. ].
] ]
{ #category : #accessing } { #category : #processing }
DiyaNode >> update [
^self subclassResponsibility
]
{ #category : #accessing }
DiyaNode >> updateTF [ DiyaNode >> updateTF [
self subclassResponsibility self subclassResponsibility
] ]
{ #category : #accessing }
DiyaNode >> visibility [
^ visibility
]
{ #category : #accessing }
DiyaNode >> visibility: anObject [
visibility := anObject.
children ifNotNil: [
children do:[:c| c visibility: anObject ] ]
]

View File

@ -1,45 +0,0 @@
Class {
#name : #DiyaNodeStyle,
#superclass : #DiyaBaseObject,
#instVars : [
'styles',
'parent'
],
#category : #'Diya-Graphics'
}
{ #category : #'as yet unclassified' }
DiyaNodeStyle class >> inherit: parent [
^self new parent: parent; yourself
]
{ #category : #initialization }
DiyaNodeStyle >> get: styleName [
^ styles at: styleName ifAbsent: [ parent ifNotNil: [ parent get: styleName ] ifNil: nil]
]
{ #category : #initialization }
DiyaNodeStyle >> initialize [
super initialize.
styles := Dictionary new.
parent := nil.
"self set: #bgcolor value: Color transparent.
self set: #color value:Color white.
self set: #border value: 0.
self set: #borderColor value: Color transparent."
]
{ #category : #accessing }
DiyaNodeStyle >> parent [
^ parent
]
{ #category : #accessing }
DiyaNodeStyle >> parent: anObject [
parent := anObject
]
{ #category : #initialization }
DiyaNodeStyle >> set: styleName value: value [
styles at: styleName put: value
]

View File

@ -37,31 +37,12 @@ DiyaPolygon >> points [
{ #category : #accessing } { #category : #accessing }
DiyaPolygon >> points: anObject [ DiyaPolygon >> points: anObject [
points := anObject. points := anObject.
dirty := true self setDirty
] ]
{ #category : #accessing } { #category : #accessing }
DiyaPolygon >> recFromPoints [ DiyaPolygon >> process [
|maxX maxY minX minY x y| bbox := Rectangle encompassing: points.
maxX := minX := (points at: 1) x.
maxY := minY := (points at: 1) y.
points do: [ :p|
x := p x.
y := p y.
maxX := maxX max: x.
maxY := maxY max: y.
minX := minX min: x.
minY := minY min: y.
].
^ Rectangle origin: minX@minY corner: maxX @ maxY
]
{ #category : #accessing }
DiyaPolygon >> update [
bbox := self recFromPoints.
translation = bbox origin ifFalse:[ self position: bbox origin].
points := points collect:[:e | e - bbox origin].
bbox := self recFromPoints.
self calculateVertices. self calculateVertices.
^true ^true
] ]

View File

@ -23,7 +23,7 @@ DiyaRectangle >> drawLines [
{ #category : #accessing } { #category : #accessing }
DiyaRectangle >> extent: v [ DiyaRectangle >> extent: v [
bbox := Rectangle origin:0@0 corner: v. bbox := Rectangle origin:0@0 corner: v.
dirty := true self setDirty
] ]
{ #category : #accessing } { #category : #accessing }
@ -37,14 +37,28 @@ DiyaRectangle >> initialize [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaRectangle >> update [ DiyaRectangle >> process [
|extent| |extent|
extent := self extent. extent := self extent.
{ vbuffer
0. 0. 0.0. 0.0. at: 1 put: 0.0;
0. extent y. 0.0. 1.0. at: 2 put: 0.0;
extent x. extent y. 1.0. 1.0. at: 3 put: 0.0;
extent x. 0. 1.0. 0.0. at: 4 put: 0.0;
} doWithIndex: [:e :i| vbuffer at: i put: e].
at: 5 put: 0.0;
at: 6 put: extent y asFloat;
at: 7 put: 0.0;
at: 8 put: 1.0;
at: 9 put: extent x asFloat;
at: 10 put: extent y asFloat;
at: 11 put: 1.0;
at: 12 put: 1.0;
at: 13 put: extent x asFloat;
at: 14 put: 0.0;
at: 15 put: 1.0;
at: 16 put: 0.0.
^true ^true
] ]

View File

@ -6,9 +6,12 @@ Class {
'display', 'display',
'vbo', 'vbo',
'vao', 'vao',
'texture0', 'textures',
'projection', 'projection',
'assets' 'assets',
'window',
'root',
'lock'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -28,6 +31,11 @@ DiyaRendererContext class >> maxFloatBufferSize [
^4096 ^4096
] ]
{ #category : #accessing }
DiyaRendererContext class >> maxTextureNumber [
^ 32
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> assets [ DiyaRendererContext >> assets [
^ assets ^ assets
@ -40,9 +48,11 @@ DiyaRendererContext >> assets: anObject [
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> destroy [ DiyaRendererContext >> destroy [
vao disableAttribute: 0.
vao delete. vao delete.
vbo delete. vbo delete.
texture0 delete. textures do: [:e | e key delete ].
textures := OrderedCollection new.
] ]
{ #category : #accessing } { #category : #accessing }
@ -55,16 +65,42 @@ DiyaRendererContext >> display: anObject [
display := anObject display := anObject
] ]
{ #category : #rendering }
DiyaRendererContext >> findTextureUnit [
textures withIndexDo: [ :e :i|
e value ifNil: [ ^ i - 1]
].
"random unit value"
^ (Random new nextInt: self class maxTextureNumber) - 1
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> initialize [ DiyaRendererContext >> initialize [
super initialize. super initialize.
vbo := OpenGLVertexBuffer new. vbo := OpenGLVertexBuffer new.
vao := OpenGLVertexArray new. vao := OpenGLVertexArray new.
texture0 := OpenGLTexture fromUnit: 0. textures := Dictionary new.
lock := Mutex new.
vao bind. vao bind.
vbo bind: GL_ARRAY_BUFFER. vbo bind: GL_ARRAY_BUFFER.
projection := Array2D identity: 4. projection := Array2D identity: 4.
assets := AssetManager new. assets := AssetManager new.
vao enableAttribute: 0.
OpenGLVertexArray
vertexAttributePointerIndex: 0
size:4
type: GL_FLOAT
normalized: GL_FALSE
stride: 16
pointer: nil.
textures :=
(1 to: self class maxTextureNumber ) collect:[:i|
(OpenGLTexture fromUnit: i - 1) -> nil] .
]
{ #category : #accessing }
DiyaRendererContext >> lock [
^ lock
] ]
{ #category : #accessing } { #category : #accessing }
@ -82,27 +118,62 @@ DiyaRendererContext >> projection [
^ projection ^ projection
] ]
{ #category : #'as yet unclassified' } { #category : #rendering }
DiyaRendererContext >> render [
root render.
root readyForSwap ifTrue: [
SDL2 glSwapWindow: window.
]
]
{ #category : #accessing }
DiyaRendererContext >> resolution [ DiyaRendererContext >> resolution [
^ (display w) @ (display h) ^ (display w) @ (display h)
] ]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> texture0 [ DiyaRendererContext >> root [
^ texture0 root ifNil: [ root := DiyaRootNode new ].
^ root
] ]
{ #category : #'as yet unclassified' } { #category : #rendering }
DiyaRendererContext >> submitData: vbuffer [
vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_STATIC_DRAW.
]
{ #category : #'transformation matrices' }
DiyaRendererContext >> useProjection: aClass [ DiyaRendererContext >> useProjection: aClass [
projection := aClass fromDisplay: self display projection := aClass fromDisplay: self display
] ]
{ #category : #accessing } { #category : #rendering }
DiyaRendererContext >> vao [ DiyaRendererContext >> useTexture: aTexture [
^ vao |assoc|
aTexture unit == -1 ifTrue:[ aTexture unit: self findTextureUnit].
assoc := textures at: aTexture unit + 1.
assoc value = aTexture ifFalse:[
"unregister current texture"
assoc value ifNotNil: [ assoc value commited: false ].
aTexture commited: false.
assoc value: aTexture.
].
assoc key active.
aTexture commited ifTrue:[ ^ self ].
"self stdlog: 'Commit data data to texture ', aTexture name, ' on Unit ', aTexture unit asString."
assoc key setImage2D: aTexture.
aTexture commited: true.
] ]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> vbo [ DiyaRendererContext >> window [
^ vbo ^ window
]
{ #category : #accessing }
DiyaRendererContext >> window: anObject [
window := anObject
] ]

View File

@ -1,6 +1,10 @@
Class { Class {
#name : #DiyaRootNode, #name : #DiyaRootNode,
#superclass : #DiyaNode, #superclass : #DiyaNode,
#instVars : [
'Q',
'R'
],
#category : #'Diya-Graphics' #category : #'Diya-Graphics'
} }
@ -9,13 +13,22 @@ DiyaRootNode >> boundingBox [
^ Rectangle origin: 0@0 corner: context resolution ^ Rectangle origin: 0@0 corner: context resolution
] ]
{ #category : #'add/remove' }
DiyaRootNode >> cleanDirtyNode: aNode [
Q remove: aNode ifAbsent:[]
]
{ #category : #accessing } { #category : #accessing }
DiyaRootNode >> draw [ DiyaRootNode >> draw [
|c| |c|
c := style get: #bgcolor. c := self ? #bgColor.
OpenGL clearColorR: c red G: c green B: c blue A: c alpha. OpenGL clearColorR: c red G: c green B: c blue A: c alpha.
OpenGL clear: GL_COLOR_BUFFER_BIT. OpenGL clear: GL_COLOR_BUFFER_BIT.
context vbo bind: GL_ARRAY_BUFFER. ]
{ #category : #'add/remove' }
DiyaRootNode >> enqueueDirtyNode: aNode [
Q addIfNotPresent: aNode
] ]
{ #category : #accessing } { #category : #accessing }
@ -29,10 +42,12 @@ DiyaRootNode >> initialize [
parent := self. parent := self.
shader := nil. shader := nil.
root := self. root := self.
style := DiyaDefaultStyle new styleName := #global.
Q := OrderedCollection new.
R := OrderedCollection new.
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
DiyaRootNode >> inner: aPoint [ DiyaRootNode >> inner: aPoint [
^true ^true
] ]
@ -43,8 +58,68 @@ DiyaRootNode >> isRoot [
] ]
{ #category : #initialization } { #category : #initialization }
DiyaRootNode >> update [ DiyaRootNode >> process [
^true
]
{ #category : #controlling }
DiyaRootNode >> processQueue [
^ Q
]
{ #category : #testing }
DiyaRootNode >> readyForSwap [
^ R isEmpty
]
{ #category : #rendering }
DiyaRootNode >> render [
| maxProcessingTime|
self stepDown.
R ifEmpty: [
self draw.
self renderNext: children
].
maxProcessingTime := (1000 / DiyaSystemSettings maxFPS) asInteger.
[
self spinOnce: maxProcessingTime
] whileTrue
]
{ #category : #rendering }
DiyaRootNode >> renderNext: nodes [
R addAllFirstUnlessAlreadyPresent: nodes.
]
{ #category : #initialization }
DiyaRootNode >> setClean [
]
{ #category : #initialization }
DiyaRootNode >> setDirty [
]
{ #category : #rendering }
DiyaRootNode >> spinOnce: maxProcessingTime [
|node|
Q ifNotEmpty: [
node := Q removeFirst.
node process.
"context lock critical: [node process]."
].
R ifNotEmpty: [
node := R removeFirst.
node render.
"context lock critical: [node render]. "
].
(Q isEmpty and: R isEmpty) ifTrue: [ ^false ].
DiyaSystemSettings renderAtOnce ifTrue: [ ^ true ].
^(DiyaSystemClock lapDelta < maxProcessingTime)
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -0,0 +1,90 @@
Class {
#name : #DiyaSettings,
#superclass : #DiyaSingleton,
#instVars : [
'maxFPS',
'fontPaths',
'assetPath',
'renderAtOnce'
],
#category : #'Diya-Core'
}
{ #category : #'as yet unclassified' }
DiyaSettings class >> defaultSettingFile [
^ Smalltalk imageDirectory / 'settings.json'
]
{ #category : #accessing }
DiyaSettings >> assetPath [
^ assetPath
]
{ #category : #accessing }
DiyaSettings >> assetPath: anObject [
assetPath := anObject
]
{ #category : #accessing }
DiyaSettings >> fontPaths [
^ fontPaths
]
{ #category : #accessing }
DiyaSettings >> fontPaths: anObject [
fontPaths := anObject
]
{ #category : #initialization }
DiyaSettings >> initialize [
super initialize.
maxFPS := 60.
renderAtOnce := false.
fontPaths := { Smalltalk imageDirectory / 'fonts' }.
assetPath := Smalltalk imageDirectory / 'assets'.
self loadFromFile.
self logSettings
]
{ #category : #initialization }
DiyaSettings >> loadFromFile [
|d v|
self class defaultSettingFile exists ifFalse: [
self stderror: 'Setting file not found. Using default settings'.
^self
].
d := STON fromStream: self class defaultSettingFile readStream.
maxFPS := d at:'max_fps' ifAbsent:[maxFPS].
v := d at:'asset_dir' ifAbsent:[nil].
v ifNotNil: [ assetPath := v ].
renderAtOnce := d at: 'render_all_at_once' ifAbsent:[renderAtOnce ].
fontPaths := fontPaths , (d at:'font_dirs' ifAbsent:[#()]).
]
{ #category : #initialization }
DiyaSettings >> logSettings [
self stdlog: 'max_fps = ', maxFPS asString.
self stdlog: 'font_dirs = ', fontPaths asString.
self stdlog: 'asset_dir = ', assetPath asString.
self stdlog: 'render_all_at_once = ', renderAtOnce asString.
]
{ #category : #accessing }
DiyaSettings >> maxFPS [
^ maxFPS
]
{ #category : #accessing }
DiyaSettings >> maxFPS: anObject [
maxFPS := anObject
]
{ #category : #accessing }
DiyaSettings >> renderAtOnce [
^ renderAtOnce
]
{ #category : #accessing }
DiyaSettings >> renderAtOnce: anObject [
renderAtOnce := anObject
]

View File

@ -25,7 +25,7 @@ DiyaSingleton class >> new [
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaSingleton class >> reset [ DiyaSingleton class >> reset [
|singleton key| |singleton key|
key := self class asString asSymbol. key := self class.
singleton := singletons at: key ifAbsent: [ ^ self ]. singleton := singletons at: key ifAbsent: [ ^ self ].
self cleanUpInstance: singleton. self cleanUpInstance: singleton.
singletons removeKey: key singletons removeKey: key
@ -38,11 +38,11 @@ DiyaSingleton class >> resetAll [
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaSingleton class >> uniqueInstance [ DiyaSingleton class >> uniqueInstance [
^singletons at: self class asString asSymbol ifAbsentPut: [ super new ]. ^singletons at: self class ifAbsentPut: [ super new ].
] ]
{ #category : #initialization } { #category : #initialization }
DiyaSingleton >> initialize [ DiyaSingleton >> initialize [
super initialize. super initialize.
Transcript show: 'Initialise unique instance of ', self className; cr. self stdlog: 'Initialise unique instance of ', self className.
] ]

41
Diya/DiyaStyle.class.st Normal file
View File

@ -0,0 +1,41 @@
Class {
#name : #DiyaStyle,
#superclass : #DiyaBaseObject,
#instVars : [
'parent',
'style'
],
#category : #'Diya-UIThemes'
}
{ #category : #accessing }
DiyaStyle >> at: name ifAbsent: aBlock [
|value|
value := style at: name ifAbsent:[nil].
value ifNotNil: [ ^value ].
parent ifNil: [ ^aBlock value ].
^ parent at:name ifAbsent: aBlock.
]
{ #category : #accessing }
DiyaStyle >> at: name put: value [
style at: name put: value
]
{ #category : #initialization }
DiyaStyle >> initialize [
super initialize.
style := Dictionary new.
parent := nil
]
{ #category : #accessing }
DiyaStyle >> parent [
^ parent
]
{ #category : #accessing }
DiyaStyle >> parent: anObject [
parent := anObject
]

View File

@ -0,0 +1,45 @@
Class {
#name : #DiyaStyleSheet,
#superclass : #DiyaBaseObject,
#instVars : [
'stylesheet'
],
#category : #'Diya-UIThemes'
}
{ #category : #convenience }
DiyaStyleSheet >> ? styleName [
^stylesheet at: styleName ifAbsent:[
DiyaCoreAPIError signal: 'Unable to query stylesheet ', styleName
].
]
{ #category : #initialization }
DiyaStyleSheet >> define: styName extend: parentStyName styles: rules [
|parentSheet style|
parentSheet := self ? parentStyName.
style := self define: styName styles: rules.
style parent: parentSheet.
^style
]
{ #category : #initialization }
DiyaStyleSheet >> define: name styles: rules [
|style|
style := rules asDiyaStyle.
stylesheet at: name put: style.
^style
]
{ #category : #initialization }
DiyaStyleSheet >> initialize [
super initialize.
stylesheet := Dictionary new.
]
{ #category : #accessing }
DiyaStyleSheet >> stylesheet [
^ stylesheet
]

View File

@ -1,5 +1,5 @@
Class { Class {
#name : #DiyaTableLayout, #name : #DiyaTableLayout,
#superclass : #DiyaWidget, #superclass : #DiyaLayout,
#category : #'Diya-Widgets' #category : #'Diya-Widgets'
} }

View File

@ -27,13 +27,7 @@ DiyaText class >> data: string shader: s [
{ #category : #'menu messages' } { #category : #'menu messages' }
DiyaText >> align [ DiyaText >> align [
^ self style get: #textAlign ^ self ? #xAlign
]
{ #category : #'menu messages' }
DiyaText >> align: v [
self style set: #textAlign value: v.
self formatText
] ]
{ #category : #accessing } { #category : #accessing }
@ -54,6 +48,11 @@ DiyaText >> allocMemory [
vbuffer autoRelease. vbuffer autoRelease.
] ]
{ #category : #accessing }
DiyaText >> borderWidth [
^0
]
{ #category : #accessing } { #category : #accessing }
DiyaText >> data [ DiyaText >> data [
^ data ^ data
@ -62,7 +61,7 @@ DiyaText >> data [
{ #category : #accessing } { #category : #accessing }
DiyaText >> data: anObject [ DiyaText >> data: anObject [
data := anObject. data := anObject.
dirty := true self setDirty
] ]
{ #category : #initialization } { #category : #initialization }
@ -84,39 +83,25 @@ DiyaText >> drawText [
{ #category : #accessing } { #category : #accessing }
DiyaText >> extent: v [ DiyaText >> extent: v [
bbox := Rectangle origin: 0@0 corner: (v x) @ (v y negated ). bbox := Rectangle origin: 0@0 corner: (v x) @ (v y negated ).
dirty := true self setDirty
] ]
{ #category : #accessing } { #category : #accessing }
DiyaText >> fontName [ DiyaText >> fontName [
^ self style get: #fontFamily ^ self ? #fontFamily
]
{ #category : #initialization }
DiyaText >> fontName: name style: face size: size [
name ifNotNil: [style set:#fontFamily value: name].
face ifNotNil: [style set: #fontStyle value:face].
style set: #fontSize value: size.
dirty := true.
self initTexture
] ]
{ #category : #accessing } { #category : #accessing }
DiyaText >> fontSize [ DiyaText >> fontSize [
^ self style get:#fontSize ^ self ? #fontSize
]
{ #category : #initialization }
DiyaText >> fontSize: size [
self fontName: nil style:nil size: size
] ]
{ #category : #accessing } { #category : #accessing }
DiyaText >> fontStyle [ DiyaText >> fontStyle [
^ self style get: #fontStyle ^ self ? #fontStyle
] ]
{ #category : #accessing } { #category : #'text-processing' }
DiyaText >> formatText [ DiyaText >> formatText [
|offset index line| |offset index line|
lines ifNil: [^self]. lines ifNil: [^self].
@ -187,13 +172,11 @@ DiyaText >> initialize [
data := nil. data := nil.
wrap := false. wrap := false.
texheight := 0. texheight := 0.
style set: #border value: 0.
"style set: #bgcolor value: Color red."
type := GL_QUADS. type := GL_QUADS.
maxLineWidth := 0. maxLineWidth := 0.
] ]
{ #category : #'as yet unclassified' } { #category : #'text-processing' }
DiyaText >> lastSeparatorFrom: index [ DiyaText >> lastSeparatorFrom: index [
index to: 1 by: -1 do: [:i| index to: 1 by: -1 do: [:i|
(data at: i) isSeparator ifTrue:[^i]. (data at: i) isSeparator ifTrue:[^i].
@ -217,6 +200,19 @@ DiyaText >> maxLineWidth [
^ maxLineWidth ^ maxLineWidth
] ]
{ #category : #initialization }
DiyaText >> process [
bbox ifNil: [ ^true ].
data ifNil:[^true].
data ifEmpty:[^true].
texture ifNil: [ self initTexture ].
vbuffer ifNotNil: [vbuffer free].
vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 16.
vbuffer autoRelease.
self drawText.
^true
]
{ #category : #accessing } { #category : #accessing }
DiyaText >> splitLines [ DiyaText >> splitLines [
|line ret tex2D| |line ret tex2D|
@ -231,39 +227,28 @@ DiyaText >> splitLines [
] whileTrue. ] whileTrue.
] ]
{ #category : #accessing } { #category : #stepping }
DiyaText >> texture [ DiyaText >> step [
texture ifNil: [ self initTexture ]. texture ifNil: [ ^self ].
texheight = texture height ifFalse: [ texheight = texture height ifTrue: [ ^self].
texheight := texture height. texheight := texture height.
self update. self setDirty
dirty := false.
].
^texture
] ]
{ #category : #initialization } { #category : #accessing }
DiyaText >> update [ DiyaText >> styleName: aName [
bbox ifNil: [ ^true ]. super styleName: aName.
data ifNil:[^true]. texture := nil.
data ifEmpty:[^true]. ]
vbuffer ifNotNil: [vbuffer free].
vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 16. { #category : #accessing }
vbuffer autoRelease. DiyaText >> texture [
self drawText. ^texture
dirty := false.
^true
] ]
{ #category : #'menu messages' } { #category : #'menu messages' }
DiyaText >> valign [ DiyaText >> valign [
^ self style get: #textVAlign ^ self ? #yAlign
]
{ #category : #'menu messages' }
DiyaText >> valign: v [
self style set: #textVAlign value: v.
self formatText.
] ]
{ #category : #accessing } { #category : #accessing }
@ -276,5 +261,5 @@ DiyaText >> valignText:h [
{ #category : #initialization } { #category : #initialization }
DiyaText >> wordWrap: aBool [ DiyaText >> wordWrap: aBool [
wrap := aBool. wrap := aBool.
dirty := true self setDirty
] ]

View File

@ -0,0 +1,68 @@
Class {
#name : #DiyaTimerNode,
#superclass : #DiyaMetaNode,
#instVars : [
'timeout',
'elapsedTime',
'handlers'
],
#category : #'Diya-Graphics'
}
{ #category : #accessing }
DiyaTimerNode class >> timeout: ms [
^ self new timeout: ms; yourself
]
{ #category : #accessing }
DiyaTimerNode class >> timeout: ms do: aBlock [
^ (self timeout: ms) onTimeout: aBlock;yourself
]
{ #category : #accessing }
DiyaTimerNode class >> timeout: ms doOnce: aBlock [
^ (self timeout: ms) onceTimeout: aBlock;yourself
]
{ #category : #accessing }
DiyaTimerNode >> delta [
^ DiyaSystemClock delta
]
{ #category : #accessing }
DiyaTimerNode >> initialize [
super initialize.
elapsedTime := 0.
handlers := OrderedCollection new.
]
{ #category : #'as yet unclassified' }
DiyaTimerNode >> onTimeout: aBlock [
handlers add: aBlock
]
{ #category : #'as yet unclassified' }
DiyaTimerNode >> onceTimeout: aBlock [
|newBlock|
handlers := OrderedCollection new.
newBlock := [ :node | aBlock value: node. self remove ].
handlers add: newBlock
]
{ #category : #stepping }
DiyaTimerNode >> step [
elapsedTime := elapsedTime + self delta.
elapsedTime >= timeout ifFalse:[^ self].
handlers do:[:e| e value: self ].
elapsedTime := 0
]
{ #category : #accessing }
DiyaTimerNode >> timeout [
^ timeout
]
{ #category : #accessing }
DiyaTimerNode >> timeout: anObject [
timeout := anObject
]

View File

@ -0,0 +1,54 @@
Class {
#name : #DiyaUIThemesManager,
#superclass : #DiyaSingleton,
#instVars : [
'themes',
'currentThemeName'
],
#category : #'Diya-UIThemes'
}
{ #category : #adding }
DiyaUIThemesManager >> addTheme:name stylesheet:sheet [
themes at:name put: sheet
]
{ #category : #accessing }
DiyaUIThemesManager >> currentTheme [
^ themes at: self currentThemeName ifAbsent: [
DiyaCoreAPIError signal: 'Undefined theme named', self currentThemeName
]
]
{ #category : #accessing }
DiyaUIThemesManager >> currentThemeName [
^ currentThemeName
]
{ #category : #accessing }
DiyaUIThemesManager >> currentThemeName: anObject [
currentThemeName := anObject
]
{ #category : #initialization }
DiyaUIThemesManager >> defaultTheme [
^ themes at: #default
]
{ #category : #initialization }
DiyaUIThemesManager >> defineDefaultTheme [
self addTheme: #default stylesheet: DiyaDefaultTheme new.
]
{ #category : #initialization }
DiyaUIThemesManager >> initialize [
super initialize.
themes := Dictionary new.
self defineDefaultTheme.
self currentThemeName: #default.
]
{ #category : #accessing }
DiyaUIThemesManager >> themes [
^ themes
]

View File

@ -12,22 +12,6 @@ DiyaWidget class >> fromStyle: aStyle [
^self new style: aStyle; yourself ^self new style: aStyle; yourself
] ]
{ #category : #accessing }
DiyaWidget >> bgColor:v [
^style set: #bgcolor value: v
]
{ #category : #accessing }
DiyaWidget >> color [
^style get: #color
]
{ #category : #accessing }
DiyaWidget >> color: value [
style set: #color value: value
]
{ #category : #geometry } { #category : #geometry }
DiyaWidget >> extent [ DiyaWidget >> extent [
^extent ^extent
@ -36,21 +20,10 @@ DiyaWidget >> extent [
{ #category : #geometry } { #category : #geometry }
DiyaWidget >> extent: size [ DiyaWidget >> extent: size [
extent := size. extent := size.
dirty := true. self setDirty.
] ]
{ #category : #initialization } { #category : #initialization }
DiyaWidget >> initialize [ DiyaWidget >> initialize [
super initialize. super initialize.
] ]
{ #category : #accessing }
DiyaWidget >> update [
self updateLayout.
^ true
]
{ #category : #accessing }
DiyaWidget >> updateLayout [
self subclassResponsibility
]

View File

@ -51,18 +51,16 @@ ImageInitializer >> initializeImage [
do: [ :c | do: [ :c |
[ c initialize ] [ c initialize ]
on: Error on: Error
do: [ c = Cursor do: [ retryList add: c ] ].
ifFalse: [ retryList add: c ] ] ].
retryList retryList
do: [ :c | do: [ :c |
Transcript self stdlog: 'CLASS: ' , c asString , ' is not initialized, retry'.
show: 'CLASS: ' , c asString , ' is not initialized';
cr.
c initialize ]. c initialize ].
DiyaSingleton resetAll. DiyaSingleton resetAll.
FFIMethodRegistry resetAll. FFIMethodRegistry resetAll.
Smalltalk garbageCollect. Smalltalk garbageCollect.
SourceFiles := SourceFileArray new. SourceFiles := SourceFileArray new.
"Smalltalk vm parameterAt: 45 put: (Smalltalk vm parameterAt: 44) * 2."
Transcript show: 'Image initialized'; cr. Transcript show: 'Image initialized'; cr.
] ]

View File

@ -1,5 +1,16 @@
Extension { #name : #LibC } Extension { #name : #LibC }
{ #category : #'*Diya' }
LibC class >> alloc: size [
^self uniqueInstance alloc: size
]
{ #category : #'*Diya' }
LibC >> alloc:size [
^self ffiCall: #(void *malloc(size_t size))
]
{ #category : #'*Diya' } { #category : #'*Diya' }
LibC >> memset:pointer value: value size: size [ LibC >> memset:pointer value: value size: size [
^self ffiCall: #(void *memset(void *pointer, int value, size_t size)) ^self ffiCall: #(void *memset(void *pointer, int value, size_t size))

View File

@ -0,0 +1,15 @@
Extension { #name : #MatrixTransform2x3 }
{ #category : #'*Diya' }
MatrixTransform2x3 >> asGLBuffer [
|buffer|
buffer := FFIExternalArray externalNewType: #float size: 9.
1 to: 6 do:[:i|
buffer at:i put: (self at:i)].
buffer
at: 7 put: 0;
at: 8 put: 0;
at: 9 put: 1.
buffer autoRelease.
^buffer
]

View File

@ -93,6 +93,11 @@ OpenGL class >> pixelstorei: pname param: param [
^self ffiCall: #(void glPixelStorei( GLenum pname,GLint param)) ^self ffiCall: #(void glPixelStorei( GLenum pname,GLint param))
] ]
{ #category : #geometry }
OpenGL class >> readPixelsOn: buffer x:x y: y w:w h:h format: fmt type: type [
^ self ffiCall: #(void glReadPixels( GLint x,GLint y,GLsizei w,GLsizei h,GLenum fmt,GLenum type,void * buffer))
]
{ #category : #accessing } { #category : #accessing }
OpenGL class >> vertex3fX:x Y:y Z:z [ OpenGL class >> vertex3fX:x Y:y Z:z [
^self ffiCall: #(void glVertex3f( GLfloat x,GLfloat y,GLfloat z)) ^self ffiCall: #(void glVertex3f( GLfloat x,GLfloat y,GLfloat z))

View File

@ -11,6 +11,8 @@ Class {
'GL_ARRAY_BUFFER', 'GL_ARRAY_BUFFER',
'GL_ARRAY_BUFFER_BINDING', 'GL_ARRAY_BUFFER_BINDING',
'GL_ATTACHED_SHADERS', 'GL_ATTACHED_SHADERS',
'GL_BGR',
'GL_BGRA',
'GL_BLEND', 'GL_BLEND',
'GL_BLUE', 'GL_BLUE',
'GL_BYTE', 'GL_BYTE',
@ -115,6 +117,8 @@ OpenGLConstants class >> initCommonConstants [
GL_ALPHA := 16r1906. GL_ALPHA := 16r1906.
GL_RGB := 16r1907. GL_RGB := 16r1907.
GL_RGBA := 16r1908. GL_RGBA := 16r1908.
GL_BGR := 16r80E0.
GL_BGRA := 16r80E1.
GL_LINE_SMOOTH := 16r0B20. GL_LINE_SMOOTH := 16r0B20.
GL_LINE_SMOOTH_HINT := 16r0C52 GL_LINE_SMOOTH_HINT := 16r0C52
] ]

View File

@ -26,7 +26,7 @@ OpenGLFontTex class >> fromFace: face ofSize: size [
^self new fromFace: face ofSize: size; yourself ^self new fromFace: face ofSize: size; yourself
] ]
{ #category : #'instance creation' } { #category : #processing }
OpenGLFontTex >> blitPixel8: bitmap at: offset size: size [ OpenGLFontTex >> blitPixel8: bitmap at: offset size: size [
size = (0@0) ifTrue:[^self]. size = (0@0) ifTrue:[^self].
0 to: size y - 1 do: [ :i| 0 to: size y - 1 do: [ :i|
@ -52,9 +52,9 @@ OpenGLFontTex >> charmap [
{ #category : #accessing } { #category : #accessing }
OpenGLFontTex >> drop [ OpenGLFontTex >> drop [
OpenGL OpenGL
pixelstorei: GL_UNPACK_ALIGNMENT param: 4; pixelstorei: GL_UNPACK_ALIGNMENT param: 4";
disable: GL_CULL_FACE; disable: GL_CULL_FACE;
disable: GL_BLEND. disable: GL_BLEND".
] ]
{ #category : #accessing } { #category : #accessing }
@ -67,6 +67,8 @@ OpenGLFontTex >> fromFace: aFace ofSize: size [
|minhang rec iptr charcode w numw| |minhang rec iptr charcode w numw|
fontSize := size. fontSize := size.
face := aFace. face := aFace.
commited := false.
name := aFace familyName, '@', aFace styleName,'@', size asString.
charmap := Dictionary new. charmap := Dictionary new.
face setPixelWidth:0 height: self fontSize. face setPixelWidth:0 height: self fontSize.
cellw := cellh := minhang := maxbearing := 0. cellw := cellh := minhang := maxbearing := 0.
@ -100,7 +102,7 @@ OpenGLFontTex >> fromFace: aFace ofSize: size [
iptr free. iptr free.
] ]
{ #category : #accessing } { #category : #processing }
OpenGLFontTex >> genGlyph:c [ OpenGLFontTex >> genGlyph:c [
|rec offset glyph gsize| |rec offset glyph gsize|
face setPixelWidth:0 height: self fontSize. face setPixelWidth:0 height: self fontSize.
@ -122,13 +124,20 @@ OpenGLFontTex >> genGlyph:c [
self reallocateBuffer. self reallocateBuffer.
]. ].
]. ].
commited := false.
^glyph ^glyph
] ]
{ #category : #processing }
OpenGLFontTex >> genPrintableASCII [
33 to: 126 do: [ :c| self genGlyph: c ]
]
{ #category : #accessing } { #category : #accessing }
OpenGLFontTex >> getGlyph: c [ OpenGLFontTex >> getGlyph: c [
^(self charmap at: c ifAbsentPut:[self genGlyph:c]) ^(self charmap at: c ifAbsentPut:[
self genGlyph:c])
] ]
{ #category : #initialization } { #category : #initialization }
@ -156,7 +165,7 @@ OpenGLFontTex >> meanww [
^ meanww ^ meanww
] ]
{ #category : #accessing } { #category : #processing }
OpenGLFontTex >> reallocateBuffer [ OpenGLFontTex >> reallocateBuffer [
|newbuffer| |newbuffer|
maxrows := maxrows + 4. maxrows := maxrows + 4.
@ -169,12 +178,12 @@ OpenGLFontTex >> reallocateBuffer [
] ]
{ #category : #accessing } { #category : #initialization }
OpenGLFontTex >> setup [ OpenGLFontTex >> setup [
OpenGL OpenGL
enable: GL_CULL_FACE; "enable: GL_CULL_FACE;
enable: GL_BLEND; enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA; blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA;"
pixelstorei: GL_UNPACK_ALIGNMENT param: 1. pixelstorei: GL_UNPACK_ALIGNMENT param: 1.
OpenGLTexture OpenGLTexture
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE; parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE;

View File

@ -10,7 +10,10 @@ Class {
'border', 'border',
'format', 'format',
'type', 'type',
'data' 'data',
'unit',
'commited',
'name'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -29,6 +32,21 @@ OpenGLTexImage2D >> border: anObject [
border := anObject border := anObject
] ]
{ #category : #accessing }
OpenGLTexImage2D >> bytesSize [
^(width * height) << 2
]
{ #category : #accessing }
OpenGLTexImage2D >> commited [
^ commited
]
{ #category : #accessing }
OpenGLTexImage2D >> commited: anObject [
commited := anObject
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> data [ OpenGLTexImage2D >> data [
^ data ^ data
@ -59,7 +77,7 @@ OpenGLTexImage2D >> drop [
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> extent [ OpenGLTexImage2D >> extent [
^ width @ height ^ self width @ self height
] ]
{ #category : #accessing } { #category : #accessing }
@ -82,6 +100,13 @@ OpenGLTexImage2D >> height: anObject [
height := anObject height := anObject
] ]
{ #category : #initialization }
OpenGLTexImage2D >> initialize [
super initialize.
unit := -1.
commited := false
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> internalFormat [ OpenGLTexImage2D >> internalFormat [
^ internalFormat ^ internalFormat
@ -107,6 +132,11 @@ OpenGLTexImage2D >> mipmap [
^false ^false
] ]
{ #category : #accessing }
OpenGLTexImage2D >> name [
^ name
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> setup [ OpenGLTexImage2D >> setup [
^self subclassResponsibility ^self subclassResponsibility
@ -132,6 +162,16 @@ OpenGLTexImage2D >> type: anObject [
type := anObject type := anObject
] ]
{ #category : #accessing }
OpenGLTexImage2D >> unit [
^ unit
]
{ #category : #accessing }
OpenGLTexImage2D >> unit: anObject [
unit := anObject
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> width [ OpenGLTexImage2D >> width [
^ width ^ width

View File

@ -51,24 +51,24 @@ OpenGLVertexBuffer class >> subData:target offset: offset size: size data: data
^self ffiCall: #(void glBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const void * data)) ^self ffiCall: #(void glBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const void * data))
] ]
{ #category : #'as yet unclassified' } { #category : #initialization }
OpenGLVertexBuffer >> bind: target [ OpenGLVertexBuffer >> bind: target [
^OpenGLVertexBuffer bind:target buffer: self vertexBufferID ^OpenGLVertexBuffer bind:target buffer: self vertexBufferID
] ]
{ #category : #'as yet unclassified' } { #category : #'accessing - data' }
OpenGLVertexBuffer >> data:target data: data size: size usage: usage [ OpenGLVertexBuffer >> data:target data: data size: size usage: usage [
self bind: target. "self bind: target."
^OpenGLVertexBuffer bufferData: target size: size data:(data ifNil:[data] ifNotNil: [data getHandle]) usage: usage ^OpenGLVertexBuffer bufferData: target size: size data:(data ifNil:[data] ifNotNil: [data getHandle]) usage: usage
] ]
{ #category : #'as yet unclassified' } { #category : #'accessing - data' }
OpenGLVertexBuffer >> data:target data: data usage: usage [ OpenGLVertexBuffer >> data:target data: data usage: usage [
self bind: target. "self bind: target."
^OpenGLVertexBuffer bufferData: target size: (data size) << 2 data:data getHandle usage: usage ^OpenGLVertexBuffer bufferData: target size: (data size) << 2 data:data getHandle usage: usage
] ]
{ #category : #'as yet unclassified' } { #category : #'add/remove' }
OpenGLVertexBuffer >> delete [ OpenGLVertexBuffer >> delete [
OpenGLVertexBuffer deleteBuffersSize: 1 buffers: vertexBufferID getHandle. OpenGLVertexBuffer deleteBuffersSize: 1 buffers: vertexBufferID getHandle.
] ]
@ -81,15 +81,15 @@ OpenGLVertexBuffer >> initialize [
OpenGLVertexBuffer genVertexBuffersSize: 1 buffers: vertexBufferID getHandle OpenGLVertexBuffer genVertexBuffersSize: 1 buffers: vertexBufferID getHandle
] ]
{ #category : #'as yet unclassified' } { #category : #'accessing - data' }
OpenGLVertexBuffer >> subData:target offset: offset data:data [ OpenGLVertexBuffer >> subData:target offset: offset data:data [
self bind: target. "self bind: target."
^OpenGLVertexBuffer subData: target offset: offset size: (data size) << 2 data: data getHandle ^OpenGLVertexBuffer subData: target offset: offset size: (data size) << 2 data: data getHandle
] ]
{ #category : #'as yet unclassified' } { #category : #'accessing - data' }
OpenGLVertexBuffer >> subData:target offset: offset data:data size: size [ OpenGLVertexBuffer >> subData:target offset: offset data:data size: size [
self bind: target. "self bind: target."
^OpenGLVertexBuffer subData: target offset: offset size: size data: data getHandle ^OpenGLVertexBuffer subData: target offset: offset size: size data: data getHandle
] ]

View File

@ -1,10 +1,5 @@
Extension { #name : #Point } Extension { #name : #Point }
{ #category : #'*Diya' }
Point >> applyTf: tf [
^(tf +* (self asArray3F)) asPoint
]
{ #category : #'*Diya' } { #category : #'*Diya' }
Point >> asArray3F [ Point >> asArray3F [
^ self asArray3F: 1.0 ^ self asArray3F: 1.0
@ -14,18 +9,3 @@ Point >> asArray3F [
Point >> asArray3F: z [ Point >> asArray3F: z [
^ { self x. self y. z } ^ { self x. self y. z }
] ]
{ #category : #'*Diya' }
Point >> asGLCoord [
|res|
res := DiyaRendererContext uniqueInstance resolution.
^(self / ( res / 2.0)) + (-1.0@ -1.0).
]
{ #category : #'*Diya' }
Point >> glNormalise [
|res p|
res := DiyaRendererContext uniqueInstance resolution.
p := self / (res/ 2).
^ (p x asFloat) @ (p y asFloat)
]

View File

@ -1,8 +0,0 @@
Extension { #name : #Rectangle }
{ #category : #'*Diya' }
Rectangle >> applyTf: tf [
^ Rectangle
origin: (self origin applyTf: tf)
corner: (self corner applyTf: tf)
]

View File

@ -1,11 +1,28 @@
Extension { #name : #SDL2 } Extension { #name : #SDL2 }
{ #category : #'*Diya' }
SDL2 class >> SDLAllocFormat: pixel_format [
^ self ffiCall: #(SDL_PixelFormat * SDL_AllocFormat(Uint32 pixel_format))
]
{ #category : #'*Diya' }
SDL2 class >> SDLBlitSurface: src srcRect: srcrect dest: dst dstRect: dstrect [
^ self ffiCall: #(int SDL_UpperBlit(SDL_Surface* src,SDL_Rect* srcrect,SDL_Surface* dst,SDL_Rect* dstrect))
]
{ #category : #'*Diya' } { #category : #'*Diya' }
SDL2 class >> SDLClearError [ SDL2 class >> SDLClearError [
^ self ffiCall: #(void SDL_ClearError(void)) ^ self ffiCall: #(void SDL_ClearError(void))
] ]
{ #category : #'*Diya' }
SDL2 class >> SDLFreeFormat: handle [
^ self ffiCall: #(void SDL_FreeFormat(SDL_PixelFormat *handle))
]
{ #category : #'*Diya' } { #category : #'*Diya' }
SDL2 class >> SDLGetCurrentDisplayMode: mode from:index [ SDL2 class >> SDLGetCurrentDisplayMode: mode from:index [
^ self ffiCall: #(int SDL_GetCurrentDisplayMode(int index, SDL_DisplayMode* mode)) ^ self ffiCall: #(int SDL_GetCurrentDisplayMode(int index, SDL_DisplayMode* mode))

30
Diya/SDL2Image.class.st Normal file
View File

@ -0,0 +1,30 @@
Class {
#name : #SDL2Image,
#superclass : #DiyaFFIBase,
#pools : [
'SDL2Constants',
'SDL2ConstantsHint',
'SDL2Types'
],
#category : #'Diya-SDL2'
}
{ #category : #'as yet unclassified' }
SDL2Image class >> SDLImgLoad: file [
^ self ffiCall: #(SDL_Surface * IMG_Load(const char *file))
]
{ #category : #accessing }
SDL2Image class >> checkSymbol [
^'IMG_Load'
]
{ #category : #accessing }
SDL2Image class >> libNames [
^#(
'libSDL2_image.so'
'libSDL2_image-2.0.so.0'
'libSDL2_image-2.0.so'
'libSDL2_image-2.0.so.0.2.3'
)
]

View File

@ -25,6 +25,25 @@ SDL_DisplayMode class >> fieldsDesc [
) )
] ]
{ #category : #converting }
SDL_DisplayMode >> asString [
^ 'SDL display: ', self width asString, 'x', self height asString, ' - ', self depth asString, ' bits depth'.
]
{ #category : #'color mapping' }
SDL_DisplayMode >> colormapIfNeededFor: dest [
^ Color colorMapIfNeededFrom: self depth to: dest depth
]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> depth [
|format depth|
format := SDL2 SDLAllocFormat: self format.
depth := format BitsPerPixel.
SDL2 SDLFreeFormat: format.
^depth
]
{ #category : #'accessing structure variables' } { #category : #'accessing structure variables' }
SDL_DisplayMode >> driverdata [ SDL_DisplayMode >> driverdata [
"This method was automatically generated" "This method was automatically generated"
@ -37,6 +56,16 @@ SDL_DisplayMode >> driverdata: anObject [
handle pointerAt: OFFSET_DRIVERDATA put: anObject getHandle. handle pointerAt: OFFSET_DRIVERDATA put: anObject getHandle.
] ]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> extent [
^ self w @ self height
]
{ #category : #other }
SDL_DisplayMode >> forceDisplayUpdate [
]
{ #category : #'accessing structure variables' } { #category : #'accessing structure variables' }
SDL_DisplayMode >> format [ SDL_DisplayMode >> format [
"This method was automatically generated" "This method was automatically generated"
@ -61,6 +90,11 @@ SDL_DisplayMode >> h: anObject [
handle signedLongAt: OFFSET_H put: anObject handle signedLongAt: OFFSET_H put: anObject
] ]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> height [
^ self h
]
{ #category : #'accessing structure variables' } { #category : #'accessing structure variables' }
SDL_DisplayMode >> refresh_rate [ SDL_DisplayMode >> refresh_rate [
"This method was automatically generated" "This method was automatically generated"
@ -84,3 +118,8 @@ SDL_DisplayMode >> w: anObject [
"This method was automatically generated" "This method was automatically generated"
handle signedLongAt: OFFSET_W put: anObject handle signedLongAt: OFFSET_W put: anObject
] ]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> width [
^ self w
]

View File

@ -8,6 +8,6 @@ SDL_TouchFingerEvent >> triggableOn: aNode [
{ #category : #'*Diya' } { #category : #'*Diya' }
SDL_TouchFingerEvent >> worldPosition [ SDL_TouchFingerEvent >> worldPosition [
|resolution| |resolution|
resolution := DiyaRendererContext uniqueInstance resolution. resolution := DiyaRenderer resolution.
^((self x)* (resolution x) ) @ ((self y)* (resolution y)). ^((self x)* (resolution x) ) @ ((self y)* (resolution y)).
] ]

View File

@ -6,6 +6,17 @@ SDL_Window >> destroy [
handle beNull handle beNull
] ]
{ #category : #'*Diya' }
SDL_Window class >> finalizeResourceData: aTuple [
| handle |
handle := aTuple first.
handle isNull ifTrue: [ ^ self ].
self destroyWindow: handle.
handle beNull
]
{ #category : #'*Diya' } { #category : #'*Diya' }
SDL_Window >> warpMouseX:x Y:y [ SDL_Window >> warpMouseX:x Y:y [
^self ffiCall: #(void SDL_WarpMouseInWindow(self,int x, int y)) ^self ffiCall: #(void SDL_WarpMouseInWindow(self,int x, int y))

3
Jenkinsfile vendored
View File

@ -20,7 +20,8 @@ pipeline{
{ {
stage('Build image from SDK') { stage('Build image from SDK') {
steps { steps {
build job: 'Diya-image', propagate: true, wait: true // build specific multi-branch job on master branch
build job: 'gitea-sync/DiyaSDK/master', propagate: true, wait: true
} }
} }
} }