Atomic Web Server Module
Posted: Wed Dec 03, 2014 3:20 am
other versions:
http://www.purebasic.fr/english/viewtop ... 13&t=29487
http://www.purebasic.fr/english/viewtop ... 12&t=36954
http://www.purebasic.fr/english/viewtop ... 13&t=29487
http://www.purebasic.fr/english/viewtop ... 12&t=36954
Code: Select all
EnableExplicit
Macro POW2
(#PB_Compiler_EnumerationValue - 1) << 1
EndMacro
CompilerIf Not Defined(PB_DEBUGGER_SendError, #PB_Function)
CompilerIf #PB_Compiler_Debugger
Import ""
PB_DEBUGGER_SendError(Message.p-ascii)
PB_DEBUGGER_SendWarning(Message.p-ascii)
EndImport
CompilerElse
Macro PB_DEBUGGER_SendError(Message) : EndMacro
Macro PB_DEBUGGER_SendWarning(Message) : EndMacro
CompilerEndIf
Macro SendDebuggerError(ErrorMessage) : PB_DEBUGGER_SendError(ErrorMessage) : EndMacro
Macro SendDebuggerWarning(WarningMessage) : PB_DEBUGGER_SendWarning(WarningMessage) : EndMacro
CompilerEndIf
Structure NW_WINDOW
id.i
*json
EndStructure
Structure NW_PAGE
id.i
file$
html$
*file
EndStructure
Structure NW_APPLICATION
*json
EndStructure
Structure NW_ENGINE
engine$
isInitialized.b
app.NW_APPLICATION
Map windows.NW_WINDOW()
Map pages.NW_PAGE()
EndStructure
Global nw.NW_ENGINE
Enumeration
#nw_Window_HasToolbar=1
#nw_Window_CenteredPosition=POW2
#nw_Window_MousePosition=POW2
#nw_Window_Resizable=POW2
#nw_Window_AlwaysOnTop=POW2
#nw_Window_HideFrame=POW2
#nw_Window_HideTaskbarButton=POW2
#nw_Window_Invisible=POW2
#nw_Window_Transparent=POW2
#nw_Window_FullScreen=POW2
#nw_Window_FullScreenKioskMode=POW2
#nw_Window_Default=0
EndEnumeration
Procedure.i InitNodeWebkit(EnginePath$)
With nw
ClearStructure(@nw, NW_ENGINE)
InitializeStructure(@nw, NW_ENGINE)
If FileSize(EnginePath$)>0
\engine$=EnginePath$
\isInitialized=#True
ProcedureReturn \isInitialized
EndIf
\isInitialized=#False
SendDebuggerError("Node-webkit initialization has failed!")
EndWith
EndProcedure
Procedure.i CreateAppPackage(Name$="node-webkit-demo", Description$="My Node Webkit Demo", Version$="1.0.0", Keywords$="node-webkit,demo")
With nw
If \isInitialized
\app\json=CreateJSON(#PB_Any)
If IsJSON(\app\json)
Protected appJson=SetJSONObject(JSONValue(\app\json))
SetJSONString(AddJSONMember(appJson, "name"), LCase(Name$))
SetJSONString(AddJSONMember(appJson, "description"), Description$)
SetJSONString(AddJSONMember(appJson, "version"), Version$)
SetJSONString(AddJSONMember(appJson, "window"), "[MAIN_WINDOW_JSON]")
If Keywords$
Protected keywordsJson=SetJSONArray(AddJSONMember(appJson, "keywords"))
Protected keyword$, keywordIndex
For keywordIndex=1 To CountString(Keywords$, ",") + 1
keyword$=Trim(StringField(Keywords$, keywordIndex, ","))
SetJSONString(AddJSONElement(keywordsJson), keyword$)
Next
EndIf
ProcedureReturn \app
EndIf
Else
SendDebuggerError("Node-webkit engine is not initialized!")
EndIf
EndWith
EndProcedure
Procedure SetAppSingleInstance(SingleInstance=#True)
With nw
If IsJSON(\app\json)
Protected appJson=JSONValue(\app\json)
SetJSONBoolean(AddJSONMember(appJson, "single-instance"), SingleInstance)
Else
SendDebuggerError("Node-webkit app package is not configured!")
EndIf
EndWith
EndProcedure
Procedure SetAppContributors(name$, email$="", web$="")
With nw
If IsJSON(\app\json)
Protected appJson=JSONValue(\app\json)
Protected contributorsJson=GetJSONMember(appJson, "contributors")
If Not contributorsJson
contributorsJson=SetJSONArray(AddJSONMember(appJson, "contributors"))
EndIf
Protected contributorJson=SetJSONObject(AddJSONElement(contributorsJson))
SetJSONString(AddJSONMember(contributorJson, "name"), name$)
If web$ : SetJSONString(AddJSONMember(contributorJson, "web"), web$) : EndIf
If email$ : SetJSONString(AddJSONMember(contributorJson, "email"), email$) : EndIf
Else
SendDebuggerError("Node-webkit app package is not configured!")
EndIf
EndWith
EndProcedure
Procedure SetAppMaintainers(name$, email$="", web$="")
With nw
If IsJSON(\app\json)
Protected appJson=JSONValue(\app\json)
Protected maintainersJson=GetJSONMember(appJson, "maintainers")
If Not maintainersJson
maintainersJson=SetJSONArray(AddJSONMember(appJson, "maintainers"))
EndIf
Protected maintainerJson=SetJSONObject(AddJSONElement(maintainersJson))
SetJSONString(AddJSONMember(maintainerJson, "name"), name$)
If web$ : SetJSONString(AddJSONMember(maintainerJson, "web"), web$) : EndIf
If email$ : SetJSONString(AddJSONMember(maintainerJson, "email"), email$) : EndIf
Else
SendDebuggerError("Node-webkit app package is not configured!")
EndIf
EndWith
EndProcedure
Procedure.i CreatePage(File$, Content$)
With nw
If IsJSON(\app\json)
Static Id : Id + 1
Protected *page.NW_PAGE=AddMapElement(\pages(), "" + Id)
*page\id=Id
*page\file$=File$
*page\html$="<!DOCTYPE html>" +
"<html>" +
" <head>" +
" </head>" +
" <body>" +
Content$ +
" </body>" +
"</html>"
*page\file=CreateFile(#PB_Any, File$)
If IsFile(*page\file)
WriteString(*page\file, *page\html$)
ProcedureReturn *page
EndIf
Else
SendDebuggerError("Node-webkit app package is not configured!")
EndIf
EndWith
EndProcedure
Procedure.i CreateWindow(x, y, Width, Height, Title$="", Flags=#nw_Window_Default, Page$="index.html", Icon$="default-icon.png")
With nw
If IsJSON(\app\json)
Static Id : Id + 1
Protected *win.NW_WINDOW=AddMapElement(\windows(), "" + Id)
*win\id=Id
*win\json=CreateJSON(#PB_Any)
If IsJSON(*win\json)
Protected winJson=SetJSONObject(JSONValue(*win\json))
SetJSONString(AddJSONMember(winJson, "title"), Title$)
SetJSONInteger(AddJSONMember(winJson, "width"), Width)
SetJSONInteger(AddJSONMember(winJson, "height"), Height)
SetJSONBoolean(AddJSONMember(winJson, "toolbar"), Bool(Flags & #nw_Window_HasToolbar))
SetJSONBoolean(AddJSONMember(winJson, "resizable"), Bool(Flags & #nw_Window_Resizable))
SetJSONBoolean(AddJSONMember(winJson, "show"), Bool(Not (Flags & #nw_Window_Invisible)))
SetJSONBoolean(AddJSONMember(winJson, "frame"), Bool(Not (Flags & #nw_Window_HideFrame)))
SetJSONBoolean(AddJSONMember(winJson, "show_in_taskbar"), Bool(Not (Flags & #nw_Window_HideTaskbarButton)))
SetJSONBoolean(AddJSONMember(winJson, "always-on-top"), Bool(Flags & #nw_Window_AlwaysOnTop))
SetJSONBoolean(AddJSONMember(winJson, "transparent"), Bool(Flags & #nw_Window_Transparent))
SetJSONBoolean(AddJSONMember(winJson, "fullscreen"), Bool(Flags & #nw_Window_FullScreen))
SetJSONBoolean(AddJSONMember(winJson, "kiosk"), Bool(Flags & #nw_Window_FullScreenKioskMode)) ; Caution, this mode will lock your desktop.
Protected position$=""
If Bool(Flags & #nw_Window_CenteredPosition) : position$="center" : EndIf
If Bool(Flags & #nw_Window_MousePosition) : position$="mouse" : EndIf
If position$
SetJSONString(AddJSONMember(winJson, "position"), position$)
Else
SetJSONInteger(AddJSONMember(winJson, "x"), x)
SetJSONInteger(AddJSONMember(winJson, "y"), y)
EndIf
If Icon$ : SetJSONString(AddJSONMember(winJson, "icon"), Icon$) : EndIf
SetJSONString(AddJSONMember(winJson, "open-page-url"), Page$)
ProcedureReturn *win
EndIf
Else
SendDebuggerError("Node-webkit app package is not configured!")
EndIf
EndWith
EndProcedure
Procedure SetWindowBounds(Window, MinWidth=#PB_Ignore, MinHeight=#PB_Ignore, MaxWidth=#PB_Ignore, MaxHeight=#PB_Ignore)
With nw
Protected *win.NW_WINDOW=Window
If *win And IsJSON(*win\json)
Protected winJson=(JSONValue(*win\json))
RemoveJSONMember(winJson, "min_width")
RemoveJSONMember(winJson, "min_height")
RemoveJSONMember(winJson, "max_width")
RemoveJSONMember(winJson, "max_height")
If MinWidth<>#PB_Ignore : SetJSONInteger(AddJSONMember(winJson, "min_width"), MinWidth) : EndIf
If MinHeight<>#PB_Ignore : SetJSONInteger(AddJSONMember(winJson, "min_height"), MinHeight) : EndIf
If MaxWidth<>#PB_Ignore : SetJSONInteger(AddJSONMember(winJson, "max_width"), MaxWidth) : EndIf
If MaxHeight<>#PB_Ignore : SetJSONInteger(AddJSONMember(winJson, "max_height"), MaxHeight) : EndIf
Else
SendDebuggerError("Node-webkit window '" + Window + "' is not configured!")
EndIf
EndWith
EndProcedure
Procedure SetWindowIcon(Window, Icon$="default-icon.png")
With nw
Protected *win.NW_WINDOW=Window
If *win And IsJSON(*win\json)
Protected winJson=(JSONValue(*win\json))
RemoveJSONMember(winJson, "icon")
If Icon$ : SetJSONString(AddJSONMember(winJson, "icon"), Icon$) : EndIf
Else
SendDebuggerError("Node-webkit window '" + Window + "' is not configured!")
EndIf
EndWith
EndProcedure
Procedure SetWindowPage(Window, Page$="index.html")
With nw
Protected *win.NW_WINDOW=Window
If *win And IsJSON(*win\json)
Protected winJson=(JSONValue(*win\json))
RemoveJSONMember(winJson, "open-page-url")
If Page$ : SetJSONString(AddJSONMember(winJson, "open-page-url"), Page$) : EndIf
Else
SendDebuggerError("Node-webkit window '" + Window + "' is not configured!")
EndIf
EndWith
EndProcedure
Procedure.i BuildAppPackage(Run=#False, MainWindow=#PB_Default)
With nw
If MainWindow=#PB_Default And MapSize(\windows())>0
;use last created window as Principal Window
MainWindow=\windows()
EndIf
Protected *win.NW_WINDOW=MainWindow
If *win And IsJSON(*win\json) And IsJSON(\app\json)
Protected winJson=(JSONValue(*win\json))
Protected appJson=(JSONValue(\app\json))
SetJSONString(AddJSONMember(appJson, "main"), GetJSONString(GetJSONMember(winJson, "open-page-url")))
Protected winJson$=ComposeJSON(*win\json)
Protected appJson$=ComposeJSON(\app\json)
Protected packageJson$=ReplaceString(appJson$, #DQUOTE$ + "[MAIN_WINDOW_JSON]" + #DQUOTE$, winJson$)
Protected packageJson=ParseJSON(#PB_Any, packageJson$)
If SaveJSON(packageJson, "package.json", #PB_JSON_PrettyPrint)
FreeJSON(packageJson)
If Run
RunProgram(nw\engine$, GetCurrentDirectory(), "")
EndIf
ProcedureReturn
EndIf
EndIf
SendDebuggerError("Node-webkit app package building has failed! You must create and select the main window.")
EndWith
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
DisableExplicit
; ********************
; EXAMPLE 1
; ********************
;create default icon (if not exists)
UsePNGImageEncoder()
If FileSize("default-icon.png")<0 And CreateImage(0, 32, 32, 32, RGB(60, 100, 255))
SaveImage(0, "default-icon.png", #PB_ImagePlugin_PNG)
EndIf
;specify location of node-webkit application
If InitNodeWebkit("node-webkit-v0.11.5-win-x64\nw.exe")
;create app
If CreateAppPackage()
;create window
If CreateWindow(20, 20, 200, 150)
;build application and show main window
BuildAppPackage(#True)
EndIf
EndIf
EndIf
Delay(100)
; ********************
; EXAMPLE 2
; ********************
;specify location of node-webkit application
If InitNodeWebkit("node-webkit-v0.11.5-win-x64\nw.exe")
;create app
If CreateAppPackage("hello-world", "Hello World App", "0.1", "node-webkit, tutorial, purebasic")
SetAppSingleInstance(#True)
SetAppContributors("Eddy R.")
SetAppContributors("Bill M.", "bill@pb-interest.com")
SetAppMaintainers("Eddy R.")
SetAppMaintainers("John Doe", "john-doe@purebasic-community.com", "http://www.purebasic-community.com")
;create custom icon (if not exists)
UsePNGImageEncoder()
If FileSize("face_icon.png")<0 And CreateImage(0, 32, 32, 32, #PB_Image_Transparent)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Gradient)
BackColor(RGBA(255, 0, 0, 255))
GradientColor(0.8, RGBA(255, 0, 0, 255))
FrontColor(RGBA(100, 0, 0, 255))
LinearGradient(0, 0, 0, 32)
RoundBox(0, 0, 32, 32, 6, 6)
DrawingMode(#PB_2DDrawing_Gradient)
ResetGradientColors()
BackColor(RGB(255, 255, 255))
FrontColor(RGB(131, 190, 255))
CircularGradient(10, 10, 10)
Circle(10, 10, 10)
CircularGradient(25, 15, 5)
Circle(25, 15, 5)
DrawingMode(#PB_2DDrawing_Default)
Circle(12, 12, 4, RGB(0, 0, 0))
Circle(27, 17, 2, RGB(0, 0, 0))
StopDrawing()
SaveImage(0, "face_icon.png", #PB_ImagePlugin_PNG)
EndIf
;create custom page
If CreatePage("home_page.html",
"<h1>Hello World ! </h1>" +
"We are using node.js<script>document.write(process.version)</script>.")
EndIf
;create window
mainWin=CreateWindow(0, 0, 350, 300, "Main Window", #nw_Window_CenteredPosition | #nw_Window_Resizable | #nw_Window_AlwaysOnTop | #nw_Window_HideTaskbarButton)
If mainWin
SetWindowBounds(mainWin, 300, 200)
SetWindowIcon(mainWin, "face_icon.png")
SetWindowPage(mainWin, "home_page.html")
;build / run application then show home
BuildAppPackage(#True, mainWin)
EndIf
EndIf
EndIf
CompilerEndIf