[UICore]

Gregor.UICore

Sunday, April 27, 2003

Gregor.UICore namespace

Action Lists

Implements some sort of action pattern, that is, placing common aspects of menu, toolbar buttons, and keyboard shortcuts into a single class (CAction). Then, there is a special toolbar class that allows identifiying buttons by string key; its buttons can be initialized from actions. Also, the owner-drawn menu items often talked about live in this namespace (the menu items can be used without actions, and vice versa, you can hook up actions to regular menu items with using my drawing code).

Image By String Key

Offers a special image list class that quickly picks up all resource icons embedded in an assembly, and makes them accessible by name. It's used with the action and control classes in this project.

Gregor.UICore.Controls namespace

Yet Another Toolbar

Features the XContainerBar class, which is a flexible toolbar that can host any control. It supports actions (from the Actions sub namespace), buttons, separators, and combo boxes by default. Its layout management allows for stretching a given item to make use of excess space, as well as displaying items in a menu if the space is too small. Action items can show text, icon, or both, and of course dropdown and toggle style items are taken care of as well. There is a built-in customization dialog, which lets the user edit item appearance, icons, and keyboard shortcuts. Container bars also support serialization. Both customization and serialization support are available for and extensible by custom bar items (which wrap up other types of controls).

Mixing Lists with Trees

Then, there is the XTreeListView class, an extenstion to WinForms.ListView. It supports displaying hierarchical data in a list view (the user may drill down, for example, into folders that are shown, see the XShellTreeView class in the Gregor.AppCore project). XTreeListView is similiar to the controls found in certain news readers, although the implementation is somewhat hacked (dare I not say "practical"?): icons are not indented, and there are no "+"/"-" icons for expanding and collapsing (but the arrow, plus/minus, and backspace keys as well as double-clicking, work), and the use of certain base class members (in particular, the Items property and the Sort() method) are illegal. XTreeListView also supports grouping in addition to sorting (groups can be shown in two ways: either as seperator items, or in a hierarchical way, using the drill-down functionality; see the NestGroups property).

Gregor.UICore.Dialogs namespace

Dialog Classes

Special form base classes for dialogs with various degree of specialty can be found here.

There are a few ready-to-use dialog classes as well, such as the FCombo class, which is a convenient way of receiving "choice" input using a combo box.

Gregor.UICore.Docking namespace

About Tool Windows

Has a wrapper class (CToolWindow) which adds docking capabilities to any form. The form need not worry about any aspect of it, and can be derived from any other form class. The same goes for hosting main windows. The CToolWindow class wraps a descendent of the class System.Windows.Forms.NativeWindow, hijacking the dockable form's handle. Everything else is managed by the XDockStrip and CDockManager classes, mostly.

Tool window capabilities include:

When docked to an edge, the host form is added a so-called "dock strip" having toggle buttons to show and hide the tool window. The toggle buttons on the dock strip can be rearranged by drag-and-drop (even across edges). They can show an icon and text (with the option of hiding the text when the tool window is hidden). Dock strips and their toggle buttons can be styled in a variety of ways (fonts, colors).

Tool windows have buttons in their title bar for toggling Hover (AutoHide) style like in Visual Studio. When docked, no borders are drawn, given a solid docking appearance.

Drag-and-Drop

The tool windows themselves can be dragged, too, using outline dragging (by painting on the desktop window using bitwise operations on pixels, which is encapsulated in the CDragRectangle class, driven by the CDragManager class).

Here's an overview of drag-and-drop in action, and toolwindows in serveral docking states.

Coding Example

Here's a sample of how to use docking. Note that any content on the hosting form must come through tool windows (the dock manager virtually owns it):

// set LIBS=Gregor.Core.dll,Gregor.UICore.dll,Gregor.AppCore.dll
// csc.exe /debug+ /t:winexe /r:%LIBS% TestDocking.cs

using System;
using System.Drawing;
using System.Windows.Forms;
using Gregor.Core;
using Gregor.UICore;
using Gregor.UICore.Docking;
using Gregor.AppCore;

namespace Gregor {

[Module()]
public class TestDocking {

    [STAThread()]
    public static void Main(string[] args)
    {
        Dev.StopOnExceptions = true;
        Dev.AllowDetails = true;

        // the following line of code will be executed next:
        Application.Run(new FHost());
    }

} // module TestDocking

public class FHost : Form {

    private CDockManager m_DockManager;

    public FHost()
    {
        this.Text = "Gregor.UICore.Docking Sample";
        this.Size = new Size(500, 300);

        m_DockManager = new CDockManager(this, true);
        m_DockManager.FillContainer.FillStrip.StyleSet = CStyleSet.LightTabbed;

        this.AddToolWindow("Hello",      "Property.ico", DockState.Fill);
        this.AddToolWindow("World",      "Library.ico",  DockState.Fill);
        this.AddToolWindow("Goodbye",    "Event.ico",    DockState.Right);
        this.AddToolWindow("Underworld", "Public.ico",   DockState.Right);
    }

    private CToolWindowRestore AddToolWindow(string sText,
                                             string sIcon,
                                             DockState ds)
    {
        CToolWindowRestore twr = m_DockManager.ToolWindowRestores.Add(
            typeof(FTool),               // type of user window
            sText,                       // key
            sText,                       // initial tool window text 
            AppCoreStockIcons.ImageList, // image list (optional)
            sIcon                        // icon key in image list (optional) 
        );

        twr.Tooltip = twr.Text + " tool window";
        twr.DockState = ds;
        twr.SetUserWindowCreateArgs(sText); // will be passed to constructor

        return twr;
    }

    protected override void OnLoad(EventArgs e)
    {
        try{
            foreach(CToolWindowRestore twr in m_DockManager.ToolWindowRestores){
                m_DockManager.ShowToolWindow(twr.Key);
            }
        }catch(Exception ex){
            Dev.ProcessException(ex);
        }finally{
            base.OnLoad(e);
        }
    }

} // class FHost

public class FTool : Form {

    public FTool(string sText) : base()
    {
        TextBox txt = new TextBox();

        txt.Multiline = true;
        txt.Dock = DockStyle.Fill;
        txt.Text = sText;

        this.Controls.Add(txt);
    }

} // class FTool

} // namespace Gregor