Core

BlitzMax Forums/BlitzMax Programming/Core

JoshK(Posted 2015) [#1]
Core is a low-level foundation for desktop applications for Windows, Mac, and Linux PCs, for BlitzMax and BlitzMaxNG.
https://github.com/Leadwerks/Core

Core handles window creation, keyboard and mouse input, direct 2D rendering, and can be used to create OpenGL contexts. Core uses GDI, Quartz, and X for 2D rendering on each supported platform. This provides fast 2D rendering without the glitches and slow speed of trying to render a GUI in a 3D context. It also provides better support for text, including clear type rendering and text wrapping. All of this is done without the existing MaxGUI drivers.

Core is not a GUI, but a GUI layer based on Core is planned. This will provide a high-performance cross-platform GUI without the glitches associated with 2D-in-3D interfaces, and without the gotchas and inconsistencies of the various native GUI drivers. It's going to be written as a MaxGUI driver, so all your existing code will just work with the new GUI.

Basically, this is how interfaces like Steam and Photoshop work.

The image in the center is a working 3D viewport with Leadwerks.







Example usage:
SuperStrict

Import "Core.bmx"

Local win:TCoreWindow=CoreCreateWindow("Core Window Test",200,100,800,600,Null,0)

Local subwin:TCoreWindow=CoreCreateSubWindow("Subwindow",0,0,CoreWindowClientWidth(win),CoreWindowClientHeight(win),win,0)
CoreWindowSetColor subwin,64,64,64,True

Local subwin2:TCoreWindow=CoreCreateSubWindow("Subwindow 2",50,50,CoreWindowClientWidth(subwin)-100,CoreWindowClientHeight(subwin)-100,subwin,0)
CoreWindowSetColor subwin2,35,35,35,True

Repeat
	WaitEvent()
Forever

End



xlsior(Posted 2015) [#2]
Nice one!


markcw(Posted 2015) [#3]
Well done!


JoshK(Posted 2015) [#4]
The Windows implementation is done, except for image drawing. I'm going to attempt an implementation with X on Linux now.

One of the big problems with X, and the reason why Linux GUIs are so bad, is its asynchronous design. it was originally created in order to run a program on one computer and output a display on another networked computer! This causes huge problems because you can do things like set the size of a window, then query it immediately and get a different result than what you just set! With this approach, all the controls within the window will be "virtualized" so X has no control over anything except the main window.

The SubWindow class should probably only be used for creating an OpenGL rendering context. I think separate gadgets within the window should be implemented by the GUI, as if the window was just a blank canvas for drawing. The more stuff that's written in BMX code, the less opportunities there are for bad OS code to screw up your program.

The commands are quite repetitive and verbose. This isn't meant to be used directly by the application developer, but to be the basis of a GUI.

	Function CoreWindowSetShape(win:TCoreWindow,x:Int,y:Int,width:Int,height:Int)
	Function CoreWindowSetClipRegion(win:TCoreWindow,x:Int,y:Int,width:Int,height:Int,clip:Int)
	Function CoreImageGetWidth:Int(img:TCoreImage)
	Function CoreImageGetHeight:Int(img:TCoreImage)
	Function CoreDeleteObject(o:Byte Ptr)
	Function CoreImageCreate:TCoreImage(width:Int,height:Int,format:Int,pixels:Byte Ptr)
	Function CoreWindowDrawImage(img:TCoreImage,x:Int,y:Int,width:Int,height:Int)
	Function CoreWindowDrawRect(win:TCoreWindow,x:Int,y:Int,width:Int,height:Int)	
	Function CoreWindowDrawText(win:TCoreWindow,text$z,x:Int,y:Int,width:Int,height:Int,style:Int)
	Function CoreWindowClear(win:TCoreWindow)
	Function CoreWindowSetText(win:TCoreWindow,text$z)
	Function CoreWindowSetCallback(win:TCoreWindow,Callback(win:TCoreWindow, event_id:Int, x:Int, y:Int ))
	Function CoreWindowGetHandle:Byte Ptr(win:TCoreWindow)
	Function CoreWindowSetColor(win:TCoreWindow,r%,g%,b%,bg%)
	Function CoreCreateWindow:TCoreWindow(title$z,x:Int,y:Int,width:Int,height:Int,parent:TCoreWindow,style:Int)
	Function CoreCreateSubWindow:TCoreWindow(title$z,x:Int,y:Int,width:Int,height:Int,parent:TCoreWindow,style:Int)
	Function CoreWindowClientWidth:Int(win:TCoreWindow)
	Function CoreWindowClientHeight:Int(win:TCoreWindow)
	Function CoreWindowGetX:Int(win:TCoreWindow)
	Function CoreWindowGetY:Int(win:TCoreWindow)
	Function CoreWindowGetWidth:Int(win:TCoreWindow)
	Function CoreWindowGetHeight:Int(win:TCoreWindow)


Example:
SuperStrict

Framework brl.systemdefault
Import brl.eventqueue
Import "Core.bmx"

Global win:TCoreWindow=CoreCreateWindow("Core Window Test",200,100,800,600,Null,CORE_WINDOW_DEFAULT)
CoreWindowSetColor win,34,34,35,True
CoreWindowSetCallback(win,MainWindowCallback)

Global subwin:TCoreWindow=CoreCreateSubWindow("Subwindow",40,40,CoreWindowClientWidth(win)-200,CoreWindowClientHeight(win)-60,win,0)
CoreWindowSetColor subwin,0,0,0,True

Global subwin2:TCoreWindow=CoreCreateSubWindow("Subwindow 2",50,50,CoreWindowClientWidth(subwin)-100,CoreWindowClientHeight(subwin)-100,subwin,0)
CoreWindowSetColor subwin2,35,35,35,True
CoreWindowSetCallback(subwin2,SubWindowCallback)

Repeat
	WaitEvent()
Forever

End

Function MainWindowCallback(win:TCoreWindow, id:Int, x:Int, y:Int) "C"
	Select id
	Case CORE_EVENT_WINDOW_CLOSE
		End
	Case CORE_EVENT_WINDOW_PAINT
		CoreWindowClear(win)
	Case CORE_EVENT_WINDOW_SIZE
		CoreWindowSetShape subwin,40,40,CoreWindowClientWidth(win)-200,CoreWindowClientHeight(win)-60
		CoreWindowSetShape subwin2,50,50,CoreWindowClientWidth(subwin)-100,CoreWindowClientHeight(subwin)-100
	EndSelect
EndFunction
 
Function SubWindowCallback(win:TCoreWindow, id:Int, x:Int, y:Int) "C"
	Select id
	Case CORE_EVENT_WINDOW_PAINT
		Local s:String="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
		s=s+"~n~n"+s+"~n~n"+s
		CoreWindowSetClipRegion(win,50,50,200,200,False)
		CoreWindowClear(win)
		CoreWindowSetClipRegion(win,50,50,200,200,True)
		CoreWindowSetColor(win,0,0,128,False)
		CoreWindowDrawRect(win,0,0,CoreWindowClientWidth(win)/2,CoreWindowClientHeight(win))
		CoreWindowSetColor(win,255,255,255,False)
		CoreWindowDrawText(win,s,0,0,CoreWindowClientWidth(win),CoreWindowClientHeight(win),CORE_TEXT_CENTER|CORE_TEXT_wrap)
	EndSelect
EndFunction



dmaz(Posted 2015) [#5]
very nice... I have to ask though... why linux before os x?


JoshK(Posted 2015) [#6]
The Skn3.PainPanel mod, which helped me learn a lot of this, shows that OSX basically works. Linux has the most uncertainty and the worst potential for problems, so I want to research it first.


JoshK(Posted 2015) [#7]
Github project added:
https://github.com/Leadwerks/Core

If you would like to start on the Mac implementation I will add it to the repo. This code will help figure it out:
https://github.com/skn3/paintpanel


Dabhand(Posted 2015) [#8]
Excellent work!

Dabz


JoshK(Posted 2015) [#9]
I've got a very basic implementation of X. Enough that I am pretty sure it will work. I'm pretty surprised there isn't already a simple open-source lib like this.




kmac(Posted 2015) [#10]
I suspect that I'm misunderstanding the final objective of Core. That said, perhaps imGUI ( https://github.com/ocornut/imgui ) overlaps.


Mithril(Posted 2015) [#11]
@JoshK : Actually there is... SDL being the first that comes to mind. What are you trying to achieve, that SDL doesn't already do? Because it isn't that clear to me. Because I am of course assuming you know about SDL :)


JoshK(Posted 2015) [#12]
I don't think SDL even supports child windows. It's more for creating a rendering context that fills a window. Not sure how well it combines native 2D drawing with OpenGL.


JoshK(Posted 2015) [#13]
To my surprise, GDI rendering works just fine on a window that is the child of an OpenGL viewport. At least on Windows:



Mithril(Posted 2015) [#14]
@JoshK: Actually it can. .. but don't get me wrong.. not trying to put your idea down.. it might be better than SDL, I don't know. I'm just more interested in what you are trying to achieve.

Yeah.. discovered that too when I was into OpenGL things :) I even managed to mix OpenGL and DirectX. (Still have the source on one of my old cd's) but it (windows) cried bloody h--l :) as well. But that is just what I like to do sometimes... push the limits.

Anyway, if you make this easy to use, it is definitely interesting.. will be watching your progress :)


JoshK(Posted 2015) [#15]
Seriously, show me where:
https://wiki.libsdl.org/SDL_CreateWindow
https://wiki.libsdl.org/SDL_CreateWindow?action=fullsearch&context=180&value=parent&titlesearch=Titles
https://wiki.libsdl.org/SDL_CreateWindow?action=fullsearch&context=180&value=child&titlesearch=Titles


degac(Posted 2015) [#16]
@JoshK

nice idea to have a replacement/new GUI system for BMX(ng) - based on the MaxGUI philosophy
The bad thing I have no skill in C/C++ to help in the development...