Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[AHK_L][Alpha]CGUI - Object-Oriented GUIS!


  • Please log in to reply
151 replies to this topic
fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
CGUI is a library which brings object-oriented GUIs to AHK_L. The library takes some inspiration from C#, so if you're used to writing C# you should easily get along.

This library isn't finished yet. It's mostly usable but lacks documentation in some places and is still feature-incomplete. There will also be bugs given the size of the library and my limited testing capabilities.

Most controls are implemented and have at least basic if not full support in terms of features.

There are also some additional classes included, most notably the following:
- file open/save and folder browser dialog classes.
- Menu class (with click event notification functions inside the GUI classes)

The library has a couple of cool integrated features that aren't available in vanilla AHK:
Sorting-independent ListView indexing for array synchronization
Easier use of icons in controls (No need for manual ImageList management)
Tooltips for controls
Attaching controls to other controls (list entries, radio buttons etc.) and automatically show/hide/enable/disable them depending on the state of the parent control/item. This is useful for quickly writing dynamic GUIs that update control visibility/states based on other controls.
Event handling is also closer oriented to OOP principles. It is done by simply creating a function with a specific name in the class that extends from CGUI. This allows separation of different events for enhanced controls like ListViews so the values of A_EventInfo, ErrorLevel, etc... don't need to be checked by the programmer.

Long story short: Here it is (requires at least AHK_L 1.1.05.00 beta3):
Download
GitHub project page

Docs are included.

Please let me know about your experience in using it, the bugs you find and possible feature requests. I also welcome anyone who wants to improve it or join my effort.

Here's an example window that demonstrates most basic techniques used to create windows:
SetBatchlines, -1
MyWindow := new CBasicWindow("Demo") ;Create an instance of this window class
return

#include <CGUI>
Class CBasicWindow Extends CGUI
{
	;Controls can be defined as class variables at the top of the class like this:
	btnButton := this.AddControl("Button", "btnButton", "", "button") 
	
	;Another way to define a control is by creating a subclass with some static properties. 
	;The name of the control will be the name of the subclass and it can be accessed by this name through the GUI object.
	Class MyEdit
	{
		;All variables defined in the class need to be static. 
		;They won't be static during runtime though since a shallow copy of this class is created, 
		;so it's possible to use custom variables and modify them in each instance of this window.
		
		;The three variables below define the options that are used to create this control. They correspond to their parameters in CGUI.AddControl()
		static Type := "Edit"
		static Options := ""
		static Text := "hallo"
		
		;A custom property. It also needs to be static but it won't be during runtime.
		static t := 5
		
		;This will be called before the __New constructor of this window class and allows to init the contents of the control
		__New()
		{
			this.Text := "Test"
		}
		
		;If a control is defined in a subclass it can handle its own events inside the subclass, using only the event name.
		;An additional GUI parameter is supplied to access the GUI and other controls.
		TextChanged(GUI)
		{
			this.t := this.t + 1
			GUI.editField.Text := this.t
		}
	}
	
	;This constructor is called when the window is instantiated. It's used to setup window properties and also control properties. It's also common that the window shows itself.
	__New(Title)
	{
		;Set some window properties
		this.Title := Title
		this.Resize := true
		this.MinSize := "200x150"
		this.CloseOnEscape := true
		this.DestroyOnClose := true
		
		;Add a control dynamically
		this.editField := this.AddControl("Edit", "editField", "w100", "Some data")
		
		;Show the window
		this.Show("")
	}
	
	;Called when the button is clicked. Note the naming scheme "ControlName_EventName"
	btnButton_Click()
	{
		;Set text of the edit control
		this.editField.Text := "Button was clicked"
	}
	
	;Called after the window was destroyed
	PostDestroy()
	{
		;Exit when all instances of this window are closed
		if(!this.Instances.MaxIndex())
			ExitApp
	}
}

For an example GUI window and a pretty cool tool check the C# GUI converter thread.

Some examples: Examples

capitalH
  • Members
  • 64 posts
  • Last active: Apr 05 2012 05:18 AM
  • Joined: 23 Apr 2010
Fragman:

I hope I understand your class correctly (I know that you mention documentation is still incomplete - but I am example type of guy), but if this will be able to do what I think it will do this is great!

The way I understand it (and I may be incorrect) is that this will allow you to attach functions to specific controls (as part of the OOP design) which I can use to replace the labels that AHK currently needs to use. This can mean that it will be much easier to mix and much scripts - as there will be less chance for clashes etc (and easier for me to read).

Looking forward to testing this, but will probably take me some time just to figure it out.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Take a look at the C# GUI converter I linked to above. It's only a simple window, but it contains the basic structure that is needed to use this library.
I'm sorry I can't provide any other real examples for now. My time is currently very limited. All controls share some basic properties like x,y,width, height (and some "text"), so it should be easy to get going. Many controls also have an "Items" array containing their list data where appropriate. Controls are accessed by their name in the class (i.e. this.Edit1) or in the Controls array (this.Controls.Edit1).

It's somewhat oriented to C# in its design, so you might get some inspiration there.

Feel free to look into the code of a specific control to find the relevant functions and properties (__Get and __Set are of importance here).

sumon
  • Moderators
  • 1317 posts
  • Last active: Dec 05 2016 10:14 PM
  • Joined: 18 May 2010
Finally! This is gonna be awesome, I will play around with it "when I have time" (as usual), and might be able to provide a step-by-step example. One question, however: Why does the lib need so many files?

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
I separated the controls into single files for better maintainability. You don't need to distribute the unused control classes this way.

I would be very happy if you could provide some examples. I'll add some examples at a later time (that is, in 2-4 weeks maybe).

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
I may have an hour or two before holiday to write some quick examples. Anyone got an idea of what would be a good demo?

infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
A very simple note-taking app.

Never require a file name, kindof like onenote

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Here you go:
Examples
The NoteExample.ahk example demonstrates how to use TreeViews, Edit controls and buttons and how to handle their events.

I also want to check out the AHK source to see if I can submit a patch to add an A_ControlHWND variable for g-labels. This would make it possible to get rid of the labels that are currently required to receive event notifications. This will have to wait for at least two weeks though until I'm back. In the meantime feel free to explore the capabilities of this library and expand it if you like :)

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Anyone tried some stuff yet? I'm back for a week and will be gone for another then. Not sure how productive I'll be this week though but I suppose I could fix some bugs if they were reported.

Edit: The library can now be found on GitHub:
<!-- m -->https://github.com/ChrisS85/CGUI<!-- m -->

Edit2: I changed TreeView controls and the note example to store the content directly in the control object. Still need to change a few minor things then I will publish the updated version.

Edit3: Icons are now supported for ListView, TreeView, StatusBar and Tab controls and can be used by simply specifying their path/icon number. No need for ImageLists (except internally)!
I also created a CFolderDialog class.

Edit4: Documentation is mostly finished. I will probably write some real GUIs with this library to make sure it works as expected.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Enough edits!
Now working on a feature to assign controls to list items (Tree nodes, ListView/ComboBox/DropDownList/ListBox entries and radio buttons). Controls will be shown dynamically if their assigned item is selected (or radio button is checked). This can be used for scenarios like settings pages where controls are assigned to a page or topic and when different controls should appear depending on radio button selection.

sumon
  • Moderators
  • 1317 posts
  • Last active: Dec 05 2016 10:14 PM
  • Joined: 18 May 2010

Enough edits!
Now working on a feature to assign controls to list items (Tree nodes, ListView/ComboBox/DropDownList/ListBox entries and radio buttons). Controls will be shown dynamically if their assigned item is selected (or radio button is checked). This can be used for scenarios like settings pages where controls are assigned to a page or topic and when different controls should appear depending on radio button selection.


... or pseudo-tabs, with pictures (with mouseover, onclick etc. colorchange)? :D I suppose controls would have to be assignable not only to list items, but other controls aswell.

By the way, check out the source code of bitlyButler and you will see why this is a welcome change. I simulated alot of "If x is selected, show y" manually. Much else was done poorly due to lack of skills, but I like the idea.

Fragman, sorry that I haven't come around to try much of this yet, I still think it's a great idea and I'll try using it asap.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Right now I plan to make it possible to assign them to checkboxes/radio buttons and most or all controls which contain some sort of list. If you need special handling that isn't included it won't be too difficult either. Just add all control objects to an array (which you can even add to a control object) and simply call Show()/Hide() on each of the objects in the array when desired.

I'm adding support for the cases mentioned above because I believe those are most common.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
I'm back and can hopefully do some work on this library. I implemented adding controls to listview rows right now. I think there are only Check/Radio boxes left to do now.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Dynamic showing/hiding/enabling/disabling of sub-controls (which are assigned to list items/selections of other controls) is now fully implemented and working. This will make it very easy to create dynamic GUIs! :)
I have also updated all files linked in the first post.

capitalH
  • Members
  • 64 posts
  • Last active: Apr 05 2012 05:18 AM
  • Joined: 23 Apr 2010
Does not work with AHK_L 1.1.00.00. I do not know which version exactly it requires, but it works perfectly with v1.1.03.00.

It may be helpful to post a version requirement in the top post.