Posts

Showing posts from October, 2023

How to build this without writing Code

I'm not sure if I should do this now, because I have not explained a number of additional aspects to the code, but for those of you who are interested.  The foundation of what I shown you here, IS the foundation of code my PBXClassBuilder-Standard generates for you.  And I truly mean generates  for you. You can have all this code generated for you without writing a single line of it yourself. Now PBXClassBuilder-Standard is not perfect, it is approximately 90=95% accurate. And I am constantly tweaking it edging this number ever higher. To use PBXClassBuilder-Standard, You should start with Forms already laid out and built.  Within PBXClassBuilder-Standard you use intuitive screens to define your table structure, while linking the Table Fields to their intended form Fields.  Then link the Tables together as Parent Child, and finally you simply click buttons to generate the code, Including the SQL Code to create the tables. The Whole development process, post Forms, is only a few mi

Connecting the Forms to the Data-Layer (part 9)

Here is the whole View Code Sheet Define quitfrmSolarSystem Declare SolarSystemCustom() Declare SolarSystemSetScreen() Declare SolarSystemCreate() Declare SolarSystemModify() Declare SolarSystemDelete() Declare SolarSystemSetData() Declare SolarSystemSave() Declare SolarSystemClose() Procedure SolarSystemSetScreen() Protected String$, x, y, w, h, i, ID Shared WorkSolarSystem Protected EventID, MenuID, GadgetID, WindowID, Index Shared quitfrmSolarSystem quitfrmSolarSystem = #False If Window_frmSolarSystem() SolarSystemCustom() SetActiveWindow(#Window_frmSolarSystem) ;Set Screen Data SetGadgetText(#Gadget_frmSolarSystem_txtName, WorkSolarSystem\Name) SetGadgetText(#Gadget_frmSolarSystem_txtGrow, Str(WorkSolarSystem\GRow)) SetGadgetText(#Gadget_frmSolarSystem_txtGCol, Str(WorkSolarSystem\GCol)) SetActiveGadget(#Gadget_frmSolarSystem_txtName) Repeat EventID =WaitWindowEvent() MenuID =EventMenu() GadgetID =EventG

Connecting the Forms to the Data-Layer (part 8)

 So now we are down to just the SolarSystem Code Sheet. This is NOT a rubberstamp of the Galaxy. The MAIN reason is that the Galaxy Records are Sourced directly from the Database, As you will recall our SolarSystem is Sourced from the Galaxy Record's Solar System Collection NOT the Database. This makes for a VERY Significant difference between in the code. Our Procedure are the save ALL the Steps are the same, the differences are in the details. Starting once again at the top, we have our declares: Define quitfrmSolarSystem Declare SolarSystemCustom() Declare SolarSystemSetScreen() Declare SolarSystemCreate() Declare SolarSystemModify() Declare SolarSystemDelete() Declare SolarSystemSetData() Declare SolarSystemSave() Declare SolarSystemClose() And then, as before the SetScreen Procedure, and Control-Loop. Procedure SolarSystemSetScreen() Protected String$, x, y, w, h, i, ID Shared WorkSolarSystem Protected EventID, MenuID, GadgetID, WindowID, Index Shared quitfrm

Connecting the Forms to the Data-Layer (part 7)

 Here is the entire Galaxy Code Sheet: Define quitfrmGalaxy Declare GalaxyCustom() Declare GalaxySetScreen() Declare GalaxyCreate() Declare GalaxyModify(GalaxyID.i) Declare GalaxyDelete(GalaxyID.i) Declare GalaxySetData() Declare GalaxySave() Declare GalaxyClose() Procedure GalaxySetScreen() Protected String$, x, y, w, h, ID Shared WorkGalaxy Protected EventID, MenuID, GadgetID, WindowID, Index Shared quitfrmGalaxy quitfrmGalaxy = #False If Window_frmGalaxy() DisableWindow(#Window_frmMain, #True) SetActiveWindow(#Window_frmGalaxy) GalaxyCustom() SetGadgetText(#Gadget_frmGalaxy_txtName, WorkGalaxy\Name) SetActiveGadget(#Gadget_frmGalaxy_txtName) ;Set Screen Data GALAXY::LoadListIcon(#Gadget_frmGalaxy_liSolarsystems) If ListEx::CountItems(#Gadget_frmGalaxy_liSolarsystems) > 0 ListEx::SetState(#Gadget_frmGalaxy_liSolarsystems, 0) EndIf Repeat EventID =WaitWindowEvent() MenuID =EventMenu() GadgetI

Connecting the Forms to the Data-Layer (part 6)

 Now Let's look at The Galaxy View Code. I'll take it from the Top Down. the the next post will be it in its entirety. Beginning at the top we Have: Define quitfrmGalaxy Declare GalaxyCustom() Declare GalaxySetScreen() Declare GalaxyCreate() Declare GalaxyModify(GalaxyID.i) Declare GalaxyDelete(GalaxyID.i) Declare GalaxySetData() Declare GalaxySave() Declare GalaxyClose() These are nothing more than the declaration of the aforementioned Procedures. First Procedure is the "SetScreen", as I always put the Form Custom at the bottom. You will remember this Procedure's job is to Display the Form, and load information from the DataLayer to the Screen. After this the procedure contains the Control-Loop for the form.  Procedure GalaxySetScreen() Protected String$, Index, ID Shared WorkGalaxy Protected EventID, MenuID, GadgetID, WindowID, Index Shared quitfrmGalaxy quitfrmGalaxy = #False If Window_frmList() DisableWindow(#Window_frmMain, #True)

Connecting the Forms to the Data-Layer (part 5)

 This is the whole Desktop Code Sheet ;/ Created with PureVision64 v6.01 x64 ;/ Thu, 05 Oct 2023 18:19:52 ;/ by Peter Hollyer XIncludeFile "Blog_Constants.pb" XIncludeFile "Blog_Windows.pb" XIncludeFile "Utils/ComboBoxExModule.pbi" XIncludeFile "Utils/ListExModule.pbi" XIncludeFile "Models/DB.pbi" XIncludeFile "Models/SolarSystem.pbi" XIncludeFile "Models/Galaxy.pbi" Global WorkGalaxy.GALAXY::Galaxy Global WorkSolarSystem.SOLARSYSTEM::SolarSystem XIncludeFile "Views/frmSolarSystem.pbi" XIncludeFile "Views/frmGalaxy.pbi" Declare frmMainCustom() ;- Main Loop If Window_frmMain() frmMainCustom() Define Index, ID ;This Loads the ListIcon with all Galaxies in the Database GALAXY::LoadListIcon(#Gadget_frmMain_liList) ;If there ARE Records select the First If ListEx::CountItems(#Gadget_frmMain_liList) > 0 ListEx::SetState(#Gadget_frmMain_liList, 0) EndI

Connecting Forms to Data-Layer (part 4)

 Now we will finish out our frmMain or our Application Desk Top  Scrolling down our Control loop we get to the section with out List of Galaxies, and our Create, Modify, Delete Buttons. Our first change will be to the List, specifically we want the default behavior of Double-Clicking an Item in our list to be "Modify". To accomplish this, we insert a PostEvent command which will Left-Click the the Modify Button for us. Case #Gadget_frmMain_liList Select EventType() Case #PB_EventType_LeftDoubleClick PostEvent(#PB_Event_Gadget, #Window_frmMain, #Gadget_frmMain_btModify, #PB_EventType_LeftClick) Default EndSelect Next we Come to the Create Button, Here we want to call our GalaxyCreate Method. Case #Gadget_frmMain_btCreate Select EventType() Case #PB_EventType_LeftClick GalaxyCreate() Default EndSelect Here is our FIRST

Connecting the Forms to the Data-Layer (part 3)

I apologize if I am a bit brisk today, I slipped and fell getting out of my wheelchair today, messed up my Right Knee and left foot. Any Way Picking up where I left off, our next step to create our database tables. Here is the Solarsystem Table SQL: DROP Table IF EXISTS SolarSystem ; Create Table SolarSystem ( ID INTEGER Not NULL PRIMARY KEY AUTOINCREMENT, GalaxyID INTEGER , Name VarChar(100) NOT NULL , GRow INTEGER , GCol INTEGER , FOREIGN KEY (GalaxyID) REFERENCES Galaxy(ID) );    And the Galaxy Table SQL: DROP Table IF EXISTS Galaxy ; Create Table Galaxy ( ID INTEGER Not NULL PRIMARY KEY AUTOINCREMENT, Name VarChar(100) NOT NULL ); I've decided the BEST way to show all this to you will simply be to Start at the top and Explain each Procedure as it's called, rather then explain them first and hook them up.    We have our Data-Layer, Screens, and SQL Tables. Next Step I'll connect our Application Desktop to the Galaxy Data-Layer table.  Firts
Image
 I've spent my day working on StoryBook, it's almost ready for release, but I'm putting it aside to continue my blog post. Picking up where I left off, everyone has a good grasp on what I'm building I now will list the Procedures which Control the linkage between our Data-layer and our GUI layer.  Each form will have its own Control-Loop. SetScreen() - Displays  Form, and loads form from Data-layer object. Create()      - Creates a NEW Data-layer object and calls SetScreen() Modify()    - Modify Find/Loads Data-Layer Object and calls SetScreen() Delete()      - Delete Confirms, then Deletes Data-layer object. SetData()    - SetData() Loads Form User Input into Data-Layer Object Save()         - Save Calls SetData() the attempts to Save Data-Layer Object Close()        - Cleare any used Images, etc. and Set Close Form Variable. These are the suffixes that append to the table or form names, so these would translate to being GalaxyCreate() or SolarSystemSetScreen(). Now de

Connecting the Forms to the Data-Layer (part 1)

Image
Completing this series of Entries can not be complete until we connect the data-Layer with the Forms, and the is the goal of these next few entries. As methodical as my approch was with the Data-Layer, will be my approach to Forms. Now regardless, of what tool, if any, you use to develop your forms; Forms serve only Two Purposes. The first being, to present data, from the database, to the users, and Secondly to input all changes the user makes back into the Database. I will pick up where we left off, and build out our Galaxy/SolarSystem Example with the following Forms: Galaxy Form: Solar System Form: And here is the Code that generates these forms. Procedure.i Window_frmSolarSystem() If OpenWindow(#Window_frmSolarSystem,0,0,430,186,"Solar System",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible,WindowID(#Window_frmMain)) TextGadget(#Gadget_frmSolarSystem_lbName,40,10,150,25,"Name: ",#PB_Text_Right) SetGadgetFont(#Gadget_

Parent Child Table (part 6)

 So, as before, here is the whole Solar System Module, or Child Module: XIncludeFile "../Utils/ThemedMessage.pbi" XIncludeFile "DB.pbi" DeclareModule SOLARSYSTEM Structure SolarSystem ID.i ; Table Primary Key GalaxyID.i ; Foreign Key to Table Galaxy Name.s ; Name of SolarSystem GRow.i ; Galactic Row GCol.i ; Galactic Column State.i EndStructure Declare LoadComboName(cbData.i) Declare LoadListViewName(lvData.i) Declare LoadListIcon(liData.i) Declare CreateTable() Declare.i Init(*Class.SolarSystem) Declare.i Find(SolarSystemID.i, *Class.SolarSystem) Declare.i FindByName(Name$, *Class.SolarSystem) Declare.i Save(*Class.SolarSystem) Declare.i Delete(*Class.SolarSystem) Declare.i Validate(*Class.SolarSystem) Declare.i DeleteValidate(*Class.SolarSystem) EndDeclareModule Module SOLARSYSTEM EnableExplicit Declare Dispose(*Class.S

Parent Child Table (part 7)

 And here is the entire Galaxy Module, or Parent Module: XIncludeFile "../Utils/ThemedMessage.pbi" XIncludeFile "DB.pbi" XIncludeFile "SolarSystem.pbi" DeclareModule GALAXY Structure Galaxy ID.i ; Table Primary Key Name.s ; Name of Galaxy List SolarSystemCollection.SOLARSYSTEM::SolarSystem() List DeleteSolarSystemCollection.SOLARSYSTEM::SolarSystem() State.i EndStructure Declare LoadComboName(cbData.i) Declare LoadListViewName(lvData.i) Declare LoadListIcon(liData.i) ;----------------------------------------------- Declare.i LoadComboBoxSolarSystemCollectionName(liData.i, *Class.Galaxy) Declare.i LoadListViewSolarSystemCollectionName(liData.i, *Class.Galaxy) Declare.i ListIconSolarSystemCollection(liData.i, *Class.Galaxy) Declare.s ListIconItemSolarSystem(*Class.SOLARSYSTEM::SolarSystem) ;----------------------------------------------- Declare CreateTable() Declare.i

Parent Child Table (part 5)

 This brings us to the Delete. The changes needed in the delete are very straight forward. As you probably expect we must iterate the child collection, and call it's Delete Procedure on each record.  When that is complete, we are free to delete the Parent Record. If DeleteValidate(*Class) = #False ProcedureReturn #False Else ;======================================================= ForEach *Class\SolarSystemCollection() SOLARSYSTEM::Delete(*Class\SolarSystemCollection()) Next ;======================================================= DBID = DB::Open(DBTYPE::#Sqlite) SetDatabaseLong(DBID, 0, *Class\ID) Sql$ = " DELETE " Sql$ = Sql$ + "FROM " As there are NO changes to the Validate and DeleteValidate steps, you might be thinking we are done but there are several more NEW Procedures we will need to add to the Module. These are hybrid List Procedures, only these lists will pull from our Collection and NOT