UI Architecture

Introduction

The CodeSmithy IDE code is split into backend and UI parts. This page describes the architecture of the UI part.

The App Class

wxWidgets applications must provide a class derived from wxApp that will be the entry point of the application. The CodeSmithy::App class fulfills this role. The class diagram for this class is shown below.

{ "classdiagram": [ { "class": { "name": "wxApp", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "App", "attributes": [ { "name": "m_singleInstanceChecker", "visibility": "private" } ], "operations": [ ] } }, { "class": { "name": "wxSingleInstanceChecker", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "wxServer", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "AppServer", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "DocumentTypes", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "ProjectTypes", "attributes": [ ], "operations": [ ] } }, { "relationship": { "type": "inheritance", "baseclass": "wxApp", "derivedclass": "App" } }, { "relationship": { "type": "composition", "containingclass": "App", "containedclass": "wxSingleInstanceChecker" } }, { "relationship": { "type": "inheritance", "baseclass": "wxServer", "derivedclass": "AppServer" } }, { "relationship": { "type": "composition", "containingclass": "App", "containedclass": "AppServer" } }, { "relationship": { "type": "composition", "containingclass": "App", "containedclass": "DocumentTypes" } }, { "relationship": { "type": "composition", "containingclass": "App", "containedclass": "ProjectTypes" } } ] }

Document types and Project types

The code is meant to be somewhat re-usable in case someone wants to produce a custom IDE based on the CodeSmithy code. For that reason the list of document and project types that are supported are created in the App class and passed to the rest of the code.

Singleton behavior

The wxSingleInstanceChecker and AppServer classes are used to implement singleton behavior when launching a new instance of CodeSmithy. The exact behavior is configurable by the user but by default when launching the application:

  • If CodeSmithy is launched without specifying a document to load a new instance will be created.
  • If CodeSmithy is launched with a document that should be loaded then if there is an instance of CodeSmithy already running the document will be loaded in the existing instance. If there is no existing instance a new CodeSmithy instance will be launched.

Note that from an implementation point of view an instance is always launched but in some cases it just instructs the existing one to load the document and exits immediately without ever displaying a UI to the user.

The Frame Class

As is typical for wxWidgets applications CodeSmithy implements a main frame by providing a class derived from the wxFrame class: the Frame class.

The Frame class also acts as the coordinator between the various UI elements, the loaded workspaces, the projects and documents, etc. As a result it is a complex and somewhat monolithic class. When CodeSmithy is bit more mature ways to improve this may emerge but for the time being this class is probably going to remain a bit of a monster class.

{ "classdiagram": [ { "class": { "name": "wxFrame", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "Frame", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "AppSettings", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "AppState", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "UILog", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "DocumentIdGenerator", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "Documents", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "ActiveWorkspace", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "ActiveDocument", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "MenuBar", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "WorkspacePanel", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "wxFileHistory", "attributes": [ ], "operations": [ ] } }, { "relationship": { "type": "inheritance", "baseclass": "wxFrame", "derivedclass": "Frame" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "AppSettings" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "AppState" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "UILog" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "DocumentIdGenerator" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "Documents" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "ActiveWorkspace" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "ActiveDocument" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "MenuBar" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "WorkspacePanel" } }, { "relationship": { "type": "composition", "containingclass": "Frame", "containedclass": "wxFileHistory" } } ] }

Menu bar

The MenuBar class implements the menu bar displayed in the frame.

Workspace panel

The WorkspacePanel class contains the UI elements that are displayed in the content area of the frame. Almost all the CodeSmithy UI is part of the workspace panel.

Documents

The list of all documents managed by the CodeSmithy application is stored in the Documents class. Note that this list may include documents currently not visible in the UI but that the application need to keep track of regardless (they may have unsaved changes for instance).

Active workspace and active document

The currently selected workspace and document are important factors in deciding things like what options should be presented to the user, what exact actions menu items will perform and so forth.

The ActiveWorkspace and ActiveDocument classes hold a reference to the currenly selected workspace and document and allow other objects to register observer so they are notified when the selection changes.

Application Settings

{ "classdiagram": [ { "class": { "name": "AppSettings", "attributes": [ ], "operations": [ ] } } ] }

Application State

{ "classdiagram": [ { "class": { "name": "AppState", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "RecentDocuments", "attributes": [ ], "operations": [ ] } }, { "class": { "name": "RecentWorkspaces", "attributes": [ ], "operations": [ ] } } ] }