Results 11 to 15 of 15

Thread: JUI - Another GUI

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Location
    England
    Posts
    524

    Arrow JUI - Another GUI

    Hi peeps, bit of an update for you, I've now started work on the visual side of the window/widget manager JUI. This is a re-design/re-write of my old VFA Window manager.

    I've included screen shots of both the old VFA (craft2y.jpg) and the new JUI (CC_EARLY.JPG) so you can see where it currently stands in terms of matching the features of VFA.

    VFA was a single threaded, immediate mode GUI with no message sub system (everything was triggered in events filtering down through the windows/widgets). This worked but was quite slow and the design was around 20 years out of date.

    JUI is a multi-threaded, soon to be non-immediate, message driven window manager. Every single window and widget runs in it's own thread, able to deploy messages directly to any other component, including it's parent, in a lock free manner.

    Because each widget runs in it's own thread as opposed to only a window having a thread in conventional desktop OS's, it allows for a nice trick: E.g. you can write some code that looped to infinity and place it in the onclick event of a button. The button will lock but every other widget and window is still functional.

    The only issue with this design is thread overhead. if you have 100 widgets, you have 100 threads. This can become a problem as you move to several hundred widgets due to the memory allocation of each thread within the OS, basically your limited to around 2000 threads under posix systems, around 600 on Windows systems.

    Here is an example unit for creating a window, widgets assigning callbacks etc

    (Initialization of the Window manager and various other supporting functions is trivial so I won't display here)

    Code:
    unit cc_guimain;
    
    {$mode objfpc}{$H+}
    {$i jui.inc}
    {$i pin.inc}
    {$i cc.inc}
    
    interface
    
    uses
      Classes, sysutils, sdl, u_gl,
    
      j2d, j2d_poly, j2d_polygroup, j2d_tspline,
    
      jui_const, jui_log,  jui_screen, jui_textureman, jui_font,
      jui_mouse, jui_cursor,
    
      jui_global, jui_message, jui_messenger, jui_keyboard,
      jui_lockable, jui_theme, jui_element, jui_window,
      jui_windowman, jui_widget, jui_basetypes, jui_titlebar, jui_button,
      jui_colourwheel, jui_editbox, jui_listview, jui_scrollbar,
    
      pin_log, pin_lockable, pin_message, pin_messenger, pin_tcp,
    
      cc_global, cc_gamestate;
    
    
    type
        TCCGUIMain = class
        private
              WindowMan : TJUIWindowMan;
        public
              Window : TJUIWindow;
              TitleBar : TJUITitleBar;
              StartServerButton : TJUIButton;
              StartClientButton : TJUIButton;
              EditBox : TJUIEditBox;
              ListView : TJUIListView;
    
              constructor create(AWindowMan : TJUIWindowMan);
              destructor destroy;override;
              procedure StartServerClick(ButtonMessage : TMsgMouseButton);
              procedure StartClientClick(ButtonMessage : TMsgMouseButton);
    
    
        end;
    
    
    implementation
    
    
    constructor TCCGUIMain.create(AWindowMan : TJUIWindowMan);
    var
       TempButton : TJUIButton;
    begin
         WindowMan := AWindowMan;
         
         Window := WindowMan.CreateWindow;
         Window.LocalRect := J2DRect(10,10,360,360);
         Window.Caption := 'GUIMain - Testing Widgets';
         TJUIWidget(TitleBar) := Window.CreateWidget(TJUITitleBar);
         TitleBar.LocalRect := J2DRect(0,0,window.width,19);
         Titlebar.Caption := 'GUIMain';
    
         TJUIWidget(StartServerButton) := Window.CreateWidget(TJUIButton);
         StartServerButton.LocalRect := J2DRect(5,25,80,45);
         StartServerButton.Caption := 'Start Server';
         StartServerButton.OnMouseClick := @StartServerClick;
    
         TJUIWidget(StartClientButton) := Window.CreateWidget(TJUIButton);
         StartClientButton.LocalRect := J2DRect(95,25,170,45);
         StartClientButton.Caption := 'Start Client';
         StartClientButton.OnMouseClick := @StartClientClick;
    
         TJUIWidget(EditBox) := Window.CreateWidget(TJUIEditBox);
         EditBox.LocalRect := J2DRect(180,25,290,41);
    
    
         TJUIWidget(ListView) := Window.CreateWidget(TJUIListView);
         ListView.LocalRect := J2DRect(5,55,290,305);
         ListView.Anchor.Right := true;
         listview.anchor.bottom := true;
    
         listview.Columns[0].Caption := 'I love';
         listview.AddColumn('Fish');
         listview.AddColumn('Fingers');
    
    
         listview.AddItem('It''s all good');
         listview.Items[ListView.NumItems-1].SubItems[0].caption := 'This Is A SubItem';
    
    
    end;
    
    destructor TCCGUIMain.destroy;
    begin
         inherited;
    end;
    
    procedure TCCGUIMain.StartServerClick(ButtonMessage : TMsgMouseButton);
    begin
         if assigned(CCGlobal.PINServer) then
         begin
              CCGlobal.PINServer.OutBoundRelay := nil;
              freeandnil(CCGlobal.ServerState);
              freeandnil(CCGlobal.PINServer);
    
         end else
         begin
              CCGlobal.PINServer := TPINServer.Create('0.0.0.0',6969);
              CCGlobal.ServerState := TCCServerState.create;
    
              CCGlobal.ServerState.OutBoundRelay := CCGlobal.PINServer;
              CCGlobal.PINServer.OutBoundRelay := CCGlobal.ServerState;
    
              CCGlobal.PINServer.Listen;
         end;
    
    end;
    
    procedure TCCGUIMain.StartClientClick(ButtonMessage : TMsgMouseButton);
    begin
         if assigned(CCGlobal.PINClient) then
         begin
              CCGlobal.PINClient.OutBoundRelay := nil;
              freeandnil(CCGlobal.ClientState);
              freeandnil(CCGlobal.PINClient);
         end else
         begin
              CCGlobal.PINClient := TPINClient.Create('192.168.0.1',6969);
              CCGlobal.ClientState := TCCClientState.create;
    
              CCGlobal.ClientState.OutBoundRelay := CCGlobal.PINClient;
              CCGlobal.PINClient.OutBoundRelay := CCGlobal.ClientState;
    
              CCGlobal.PINClient.Connect;
         end;
    end;
    
    end.
    So yes, I shall be releasing this at some point but I'm looking for another developer to help me with the workload. There's still a number of widgets I need to re-code and I may need help on moving to a faster VBO rendering method (need new font units, is GLViewPort depreciated? EDIT : GLViewPort is *not* depreciated )

    The old VFA is usable in much the same manner, but the design stinks. if you really want it, let me know.

    and on a side note I've nearly finished PIN and I'm going to wrap up my hardware skinning lib from P3D, in my opinion the most modern skinning implementation in delphi (EDIT:FreePascal/Lazarus for me personally, all the way ) that I've seen so far, hence why I want to give it to the community.

    Peace.
    Attached Images Attached Images
    Last edited by phibermon; 13-10-2010 at 10:24 PM.
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •