|
I mean a lightweight framework abstracted away from the underlying windowing system ala 'java/swing'
That is where I got some of the original design ideas from ! VCF uses peers to wrap up various OS/windowing services. For example there is a ControlPeer that wraps up the basic windowign control functionality for. Heavyweight vs lightweight is really an issue of whether or not the control uses the raw windowing system resources and "owns" the resources, or shares them with it's parent.
For example when you sub class from a CustomControl to make your own control you tell the CustomControl wether or not you want to be a heavyweight or lightweight control. If you're a heavyweight control, you will have you own HWND (under Win32, on GTK it'd be a GtkWidget, on Mac OSX it'd be an instance of NSView), and corresponding HDC resources. If you are a lightweight control you will not have your own HWND, but instead share it with your parent.
In general it doesn't matter which you choose, as it acts the same pretty much for either one, but there may be cases where you one or the other, and lightweight controls certainly take up fewer resources.
The only cases where *specific* controls are wrapped by extra peers are those that are complex enough that you'd want to take advantage of the common existing controls as opposed to simply reinvent it from scratch.
These are the text control, the tree control, and the list view control. In addition, menus and windows (i.e. popup windows liek dialogs) also have a specific peer. Everything else is written using just the VCF.
In the future I would like to have a Text editing framework and get rid of the TextPeer. I have some experimental code at home, but it would require alot more work, and I don't have teh time at the moment. If the text stuff is soemthing that interestests you I'd be happy to discuss it.
I had a look for #ifdef WIN32 #ifdef LINUX thru the windows codebase and there didn't seem to be that many.
There aren't and it's on purpose. The only place you'll really see it is where the actual concrete toolkits are created. Each toolkit, in turn, is responsible for creating a number of peer instances, appropriate to the toolkit. So for example, the SystemToolkit (an abstract class) defines a series of methods for creating instances of FilePeers, ThreadPeers, MutexPeers, etc. For each platform you must implement a concrete instance of this class and provide concrete classes for the various peers. So on Win32 you'll see a Win32SystemToolkit class, and corresponding Win32Thread, Win32Mutex, etc. For linux you'll see a LinuxSystemToolkit, and LinuxThread, LinuxMutex, etc.
IMHO this makes it alot easier to read the code and not wonder what piece belongs to what, wading through a morass of #ifdefs, which simply do not scale, IMHO.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
Tell me more about the text editing stuff. I have an old tree control written on top of a MFC CWnd that i intend to refurbish one day soon with some of the concepts i have gleaned from swing, which everyone is welcome to.
|
|
|
|
|
Well I played around with it after reading the C++ Patterns book (don't remember the authors) in which for part of the book they discuss architecting a text editor and the various pieces of it and how to design it.
The concept I have at home uses the Glyph as the smallest unit and could paint itself. Then you had a Composition that would hold one or more glyphs. A Composition was itself a Glyph. Compositions could be a vertical or horizontal. There was a LineBreaker class for determing how to break and where, with a concrete impl called the HorizontalLineBreak. It works OK, but the issue of wrapping around things, for example, say you have a HorizontalComposition with a series of CharacterGlyphs and an ImageGlyph in the middle. How do you wrap the caharacter around correctly? I never got that far. If you interested, I'd be more that happy to send you the code and you can play with it - maybe you'll get farther than me!
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
I vaguely remember that. I've had a quick revisit to www.abiword.com www.abisource.com which might be a solution they have certainly come a long way since I last looked at it 2 years ago. Their text engine source is nicely seperated in the codebase. The main problem might be coming to grips with their internal data storage format to drive it.
http://www.sophists.com/Led/LedClassLib/Competitors.asp
http://www.serif.com/technology/serif_text.asp
http://www.merzwaren.com/waste/
http://www.sophists.com/
http://www.abisource.com/
|
|
|
|
|
The real problem with mixed heavyweight / lightweight controls is getting consistent look and feel. Especially if you want to allow the user to choose, programmers to create skinning renderer sets etc.
Getting rid of them would also shrink you codebase considerably and make things more managable. list and tree are not really a problem.
Menus are probably also not too bad. Its the text edit that is going to be the killer, unless we accept mono spaced plain text to start with.
|
|
|
|
|
The real problem with mixed heavyweight / lightweight controls is getting consistent look and feel
Actually this is not a problem with wether they are lightweight or heavy weight, but more an issue of *how* they are rendered/drawn. For example, lets say I want ot build a control that looks like/emulates a checkbox. It doesn't matter much whether the control is lightweight or heavyweight, as it will get all the user events it needs (i.e. mouse, keyboard, etc) either way. It will get the right pain event as well.
What *does* make a difference is how you go about painting the various pieces of it.
In the VCF this is solved in two main ways. First the GraphicsContext has a series of methods for painting various UI elements that are in compliance with the windowing systems UI standards. So to draw the little check box, you can call the GraphicsContext::drawCheckboxRect() and on Win32 you'll get a normal looking chaeckbox, on GTK you'll get a GTK looking check box that takes into account the current GTKL theme etc. To draw the focus rect if the control is focused you call the GraphicsContext::drawSelectionRect(), and so on.
To ensure that you use the right fonts, and sizes for thigns you use the UIMetricManager which gets you this kind of info, like what is the correct font to use for control, for menus, etc, and what is the standard size for a label, for a menu etc.
The other way you can accomplish this is to create different View sub classes that can handle all the painting. For example, we might write our Checkbox control, put all the logic for handling mouse events, setting it's state, etc, and then managee the painting by creating a number of view classes, say XPCheckboxView, Office2000CheckboxView, etc, and then at runtime do something like:
CheckBox* checkbox = new ChekcBox();
checkbox->setView( new Office2000CheckboxView() );
Or something like that
Menus are probably also not too bad
You don't want to emulate Menus. Qt does this and suffers for it on other platfroms (like OSX). Plus you spend all that time writing menu code from scratch when the OS/windowing system already has it doen for you, and you gain very little. The heavyweight/lightweight choice *only* applies to custom controls. Controls for which there are specific peers (like the tree control, list view control, etc) do not get this choice (the fact that some of the UIToolkit factory methods still have this choice is incorrect and needs to be removed - that's my fault for lack of clarity there).
Its the text edit that is going to be the killer
Yes this is a lot of work to do right. Which is precisely why I haven't had time to really dig in and do it!
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
Jim Crafton wrote:
You don't want to emulate Menus. Qt does this and suffers for it on other platfroms (like OSX). Plus you spend all that time writing menu code from scratch when the OS/windowing system already has it doen for you, and you gain very little
See what you are saying and certainly we can do this incrementally but eventually they have to go. Just stick a glasspane over the desktop and capture all mouse events a la swing will do as an interim solution.
Jim Crafton wrote:
The heavyweight/lightweight choice *only* applies to custom controls. Controls for which there are specific peers (like the tree control, list view control, etc) do not get this choice (the fact that some of the UIToolkit factory methods still have this choice is incorrect and needs to be removed - that's my fault for lack of clarity there).
i'm a little confused, are you saying that in the VCF if there is an appropriate heavyweight peer it will / must be used
|
|
|
|
|
but eventually they have to go
Why? The only things that can't be customized in the current version/impl is embedding controls inside of a menu item. And frankly I see doing that as having pretty dubious real world value. Everything else like custom drawing, etc all work fine. Plus, while this may not matter much for UGLY, emulating menus just leads to heart ache due to all the little picky details that vary for system to system. For example on Win32 how long is the correct wait time to pause over a popup menu for a submenu before displaying the menu? Is it the same for Win200, for NT for Win98 for XP? Now what about MacOSX, GTK etc. Emulating means you have to deal with stupid crap like that, that IMHO, there is probably more important things for me to worry about
I'm a little confused, are you saying that in the VCF if there is an appropriate heavyweight peer it will / must be used
Not quite. If you request a peer for one of the specific controls, like a tree control, list view control, or text control, you'll get whatever the native platforms uses for these controls, and almost certainly they will be "heavyweight" in the sense that the have their own HWND/HDC.
However if you create you own custom control, and derive it from VCF::CustomControl, you specify whether you want to be a heavyweight control or lightweight control. A CustomControl is simply a blank rectangular child window. You are then responsible for adding your own logic for doign painting and event handling.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
Ok lets say that I agree that heavyweight peering of menus are the last to go.
I guess my reservations are more along the lines of keeping the Interface designs clean and pure. Why for instance couldn't a menu be regarded as a specialized form of tree control with a datamodel and cellrenders. And it may well be that we can write adaptors to achieve exactly that.
But I will drop the asynchronous change to the datamodel from a thread extern to the gui requirements for menus ! big of me huh.
|
|
|
|
|
Joey Bloggs wrote:
But I will drop the asynchronous change to the datamodel from a thread extern to the gui requirements for menus ! big of me huh.
Thinking about that a little more. What if a user has a menu open and some async event causes more or less choices to become available, shouldn't we be able to at least grey out or restore options whilst the menu is 'live'.
|
|
|
|
|
Jim Crafton wrote:
You don't want to emulate Menus. Qt does this and suffers for it on other platfroms (like OSX). Plus you spend all that time writing menu code from scratch when the OS/windowing system already has it doen for you, and you gain very little.
I have successfully implemented menus with no trouble at all, and they looked better than the OS's version.
"Blessed are the peacemakers, for they shall be called sons of God." - Jesus
"You must be the change you wish to see in the world." - Mahatma Gandhi
|
|
|
|
|
Big cascading menus that extend beyond the applications main window boundaries ?
|
|
|
|
|
Yes. But they aren't lightweight. I don't know whether you're talking about lightweight menus or not, but I do know that lightweight menus don't work very well.
"Blessed are the peacemakers, for they shall be called sons of God." - Jesus
"You must be the change you wish to see in the world." - Mahatma Gandhi
|
|
|
|
|
Right but are they compliant with the behaviour of OS menus? Plus, if the framework is x-platform (not saying UGLY should be x-platform, but VCF is) there are additional things that come into play that make a royal pain in the butt. IMHO it's just not worth it.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
You're right there - it will be hard, but not impossible. But so far, we have no plans for cross-plantform.
"Blessed are the peacemakers, for they shall be called sons of God." - Jesus
"You must be the change you wish to see in the world." - Mahatma Gandhi
|
|
|
|
|
I have already agreed with you, that it is not a priority. Extracting the interfaces and removing the peering for all the 'standard' controls would keep us busy for quite a while. What are your feelings on that, do you think its worthwhile and a direction you want to take VCF in.
Well I am reasonably certain that you can not change the state of a menu or menuitem once it is already up in win32 ?
But what if longhorn / aero provides such functionality (not that I really expect it to). I am trying to anticipate far enough ahead that we won't have to change the interfaces at least for a good long time ?
|
|
|
|
|
Extracting the interfaces and removing the peering for all the 'standard' controls would keep us busy for quite a while. What are your feelings on that, do you think its worthwhile and a direction you want to take VCF in.
If you mean getting rid of the stuff like the text peer and tree control peer, and replacing it with controls that written entirely with the VCF then yes I do think it is a worthwhile direction to go. That is what I'd like to do eventually.
Well I am reasonably certain that you can not change the state of a menu or menuitem once it is already up in win32 ?
Do you mean that once a menu item is created in Win32 can you change it, such as whether it's checked, enabled, caption, etc? You most certainly can and menus with VCF reflect this.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
Jim Crafton wrote:
Extracting the interfaces
and your feeling on this ? I think that this is one of the fundemental flaws in swing.
Jim Crafton wrote:
Do you mean that once a menu item is created in Win32 can you change it, such as whether it's checked, enabled, caption, etc? You most certainly can and menus with VCF reflect this
No I meant whilst the menu is 'live' on screen
|
|
|
|
|
What is this project about? the same old UI controls with some new cloths?
there are 1000's of such controls and libraries available.
you should have written an article when you had soethign to show and share with teh other people
besides vista beta is already floating. which makes all your effort useless.
you could have come up with some better idea.
|
|
|
|
|
I keep seeing stuff on this project and seeing the requests/ideas that people are asking for, and I can't help but scratch my head in confusion, especially as the project I have been working on for the last 2 years addresses almost all of this.
The project, the Visual Component Framework [^], has:
- a component based system, somewhat similar to .Net.
- support for MVC built it
- abstraction of various common controls and services through peer classes
- easy customization for creating new controls
- controls, and UI items like menus and menu items, are broken into pieces that can be easily customized, particularly for owner drawn stuff (which I keep seeing requested over and over here). For example, if you want an owner drawn menu item, just create a new class that derives from DefaultMenuItem and override the paint method.
- autsizing/layout features - support for auto aligning a control to the right, left, top, bottom or client area. Also support for right,left,top, and bottom anchors.
- some of the common control wrappers that exist are the for the tree and list views. You can customize pratically every aspect of it via the VCF.
- access to the underlying peer and getting at the HWND if neccessary.
- an event callback mechanism very, very similar to .Net's Delegate classes. For example, to add a callback to button click
CommandButton* btn = new CommandButton();
btn->ButtonClicked +=
new ButtonEventHandler<MyWindow>( this, &MyWindow::onButtonClicked, "MyWindow::onButtonClicked" );
The mechanism is easy to add to any class that derives from the one of the core framework base classes.
- support for upating menut items. You can add an event handler for a menu item's state and update it accordingly
- support for default buttons
- support for tabbing behaviour and controlling the order in which controls are tabbed to.
There's alot more, but it would sure seem like you guys could benefit from using this stuff, and I'd love to see it get used and extended. There are no licensing issues for commcercial use (it's a BSD license).
Anyhow, just my thoughts!
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
Jim Crafton wrote:
There's alot more, but it would sure seem like you guys could benefit from using this stuff, and I'd love to see it get used and extended.
I agree that this is a very good starting point for the project at least outside the .NET framework. My question is can your framework work with c#?? To me this is the biggest problem with the project as a whole. It has been suggested that the project have a C# and win32 version developed independently with the same functionality but completely different implementation. I am not sure this kind of approach will be feasible.
John
|
|
|
|
|
John M. Drescher wrote:
My question is can your framework work with c#??
In what sense? Presumably if the classes were __gc classes (or whatever the syntax is for marking C++ classes as managed and .NET friendly) then I would guess there could be a bridge built quite simply. If you mean written in C# tehn that woiuld require a complete C# layer around all of it, no?
John M. Drescher wrote:
It has been suggested that the project have a C# and win32 version developed independently with the same functionality but completely different implementation
IMHO this is a waste of developer time. Pick one. C# already has an extremely sophisticated framework that is written almost exclusively for it. So what do you gain by reinventing all of that? If you write C++ for .Net then you also share in the common framework, making the need for UGLY unclear to me. UGLY (to me) only makes sense in the context of a developer who does not want to use the .Net framework, which imply native C++ development (again IMHO). If you are doing win32 development, yet do not want to use managed C++ or .Net, then to me, using the VCF as a basis makes alot of sense.
It sounds like a firm decision needs to be made as to how and why .Net support needs to happen. If it's simply a matter of being able to operate with managed code (i.e. managed C++ or C#), then I think it would be a pretty simple matter of just making all the VCF classes managed C++. *If* this is the case it would not be too hard (I think, I may be totally off the mark), because most of the UI stuff is alread heap based, and the few classes that are not could be made heap based relatively easily. You could have some sort of macro in front of the classes that toggles wether to use the managed C++ extensions pretty easily. The only other problem (again, just guessing here) would be the event handlers. Again the idea and usage of them is pretty close to .Nets, so it's possible that the EventHandler base class could be written in such a way as to make use of .Net native delegates as opposed to the VCF Delegate class.
Just some thoughts off the top of my head
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
Jim Crafton wrote:
In what sense?
How easy would it be to add / use your controls with .NET? Can they be placed in a C# form without too much difficulty?
John
|
|
|
|
|
Well for that I think three things would have to happen:
- First the whole framework would have to compiled as managed C++, as opposed to standard C++
- Ensure that any places where stack based objects are used, they are changed to heap based allocation.
- Each OS/Windowing system specific service (or collection of services) is defined by a peer interface and then implemented in some concrete class for the appropriate platform. Currently the Win32 version of VCF is implemented via a series of C++ classes using straight Win32 calls. This could be changed so that the various peers are implemented on top of the .Net class libraries (at least for some things) specifically the Windows.Forms API's.
This *should* allow the control to physically show up on a form. The next issue would be the controls properties. Since C++ has no real reflection API, I had to write my own. This includes properties support. Defining this is done on a class by class basis. Assuming that managed C++ can declare properties like C# can, then the VCF property macros could possibly be altered to simply declare properties .Net style vs VCF style depending on how the library was compiled.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
Thank You for your very detailed answers...
From your answers it looks like to me if the project wants to go .NET there must be at least two versions of the code and just not a simple wrapper around the win32 code.
John
|
|
|
|
|