Atomic Web Server Module

Share your advanced PureBasic knowledge/code with the community.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Atomic Web Server Module

Post by eddy »

other versions:
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
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Re: Atomic Web Server Module

Post by Poshu »

mmmmh, seems like you messed up with your copy pasta! This is some nice exemple of node-webkit, not atomic :p
Post Reply