My GUI design

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Tux

Re:My GUI design

Post by Tux »

Hmmm.
I am saying a lot of stuff, so I don't want you people to expect it all to be in the GUI, but about the resizing.

I am not thinking to add this method, but here it goes.

Did you ever use those drawing programs when you use a tool like a paint brush, the border (e.g. drawing screen) gets bigger? That may be a solution. Bad thing is, that is only for making the window larger. How about smaller?

My best solution would be to make a trigger that when the user activates it, the user clicks on the screen once where to position the window and another time where to make it end. Like the drawbox tool in Bitmap.

I was also looking at graphic rendering, but I think this is how it goes. Instead of redrawing Window a, then window b, then window c. You cut the screen into boxes (a.k.a. sectors). Now, to clear something up, the app doesn't draw itself (Common belief by beginners). There are two timers, the CMOS, and the PIT. In my opinion, I would use the PIT for apps and CMOS for updating system functions (e.g. play sound and rerender screen).
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:My GUI design

Post by Pype.Clicker »

Tux wrote: I was also looking at graphic rendering, but I think this is how it goes. Instead of redrawing Window a, then window b, then window c. You cut the screen into boxes (a.k.a. sectors).
i've been thinking at a similar scheme for a couples of years but never really had the time to write things down correctly. All i can tell you is that algorithm to create the 'sectoring' of the screen aren't simple, but if you give them enough development time, they can help locating the cursor pretty fast, but at the cost of additionnal complexity for moving/resizing windows.

Now what most Window Managers do is having a "stack" of windows (in the form of a Z-sorted linked list of windows to render, and when the region X1,Y1-X2,Y2 need to be repainted, the windowing stack is scanned to detect which region of which window need to be redrawn ...
Tux

Re:My GUI design

Post by Tux »

Yah, something like that.

The goal is to turn philosopy into code.
I'll do the first part now.

//This example doesn't include checking mouse clicks
1)CMOS cycle kicks in
2)GUI draw procedures execute
3)Window draw by sector loop starting from the top app
1)Check if top app is still ontop
1)Check if top app same size and pos
1)If so, goto the next app
2)If not redraw app
2)If not still ontop, redraw all the sectors with the apps border and make it faded
4)Loop ends
5)Cursor is drawn

That is a small table to explain somewhat of the procees
But please, don't question it much, I am too trying to understand.

Here is a better "viewpoint":

Screen:
//I am tring to use text mode first :/
80*25

GUI window stack:
[ name ] | [X] | [Y] | [SX] | [SY] | [Z]
Window A | 10 | 10 | 10 | 10 | 2
Window B | 2 | 2 | 3 | 3 | 1
Window C | 3 | 12 | 8 | 5 | 3

Let's say the only change detected is that WINDOW A has now moved 3 pixels down. So:

We check if WB (Window B) is on top as usual, yes it is.
Is it the same position?
Yes it is.
Is it the same size, yes it is.
We leave it.

Has a previous sector changed?
Nope.
We check if WA is the same position.
Nope.
Is it the same size?
Yes it is.
So we draw it.
And we set an array of sectors that some sectors have changed.

Now we go to WC.
Has a previous sector changed?
Yes.
Does it affect the window?
Yes.
Is it the same position?
Yes it is.
Is it the same size, yes it is.
Now, we redraw the sector where the app gets extra space and it's done.

To implement this method, the draw window function has to be fixed.

We are humans, so we see things as lines and fillins.

To draw a window, we would draw a line at the top. a line at the bottom, and sides. Then we fill it in. (Very basic window). But if i told you to draw only 2 pixels by the edge of the window, you would need to rewrite the function.

Now the way to do it would be to draw a window pixel by pixel, for example:
draw 0,0
Then draw 1,0
You get to the edge
Drop down
draw pixel 0,1
etc.

Like a typewriter and you can easily draw only partions needed to be used by sectors.
Tim

Re:My GUI design

Post by Tim »

What's all this talk of the CMOS and the PIT? Do you want to redraw everything on every timer tick? Why not just redraw a window when it needs to be redrawn?
Tux

Re:My GUI design

Post by Tux »

That is too slow redrawing all windows.
Let's say the user is using a 640*480*256 bit screen.
307200 pixels to redraw. Plus, the mov opcode and so on takes 3 or 4 cycles or around there: 307200*4.
1,228,800 cycles taken away. That ain't much as it seems, but add the programs and so on. You have taken a lot of cycles around then. About the CMOS/PIT, they are used to rerender the screen on time. So if an app freezes, the items get drawn.
Tim

Re:My GUI design

Post by Tim »

You hardly ever need to redraw all windows.

What GUIs usually do is, for each window, keep track of a rectangle which must be updated. Windows calls this an invalid rectangle. You can invalidate a rectangle, which means that next time you ask for a message, you'll get a paint message. After the paint message has been processed, the invalid rectangle is cleared.

A rectangle is invalidated if something on the window needs to change (e.g. for a button, the user clicks), or part of a window is exposed by some other window moving, or part of a window is exposed because it has been resized.
Tux

Re:My GUI design

Post by Tux »

Yes, that's for INSIDE of windows. If a window moves its position, valid or invalid, another window is affected.
And instead of redrawing the WHOLE other window. You redraw the sectors of the window that were affected by the window you moved, saving valueable cycles. Think outside the box.
mystran

Re:My GUI design

Post by mystran »

@tux, Excuse me, but please explain how are you going to get a nice 1600x1200x32bit screen dumped through AGP bus with an acceptable framerate and still do something else?

Now, fullscreen dump on each frame works fine on small resolutions (say 320x200x8bit) but not for large ones. You just end up spending all your time doing screen refresh and you still don't have acceptable rate.

Basicly, with any modern system, you want to minimize the traffic to the video card, even if it means spending some more CPU cycles in the GUI and the application. That's why you don't realistically use VESA framebuffer, but instead want accelerated drivers for your desktop.

Try switching your favourite desktop os to use vesa drivers, and move a window around with content, and you realize what I mean.. and that system is already transfering only the parts that changed.

Now, when a window moves it's position on top of another window, the moving window only needs to be moved. If you're card does that for you, that's pretty fast. For the window below the moving window, you only want to draw the regions that previously where below the moving window. It's possible to cache that stuff ofcourse, but it takes quite a lot of memory.

I have 9 windows open while writing this, with 32bit screen depth, and average window size of about 1000x1000 so that's 4MB for each -> about 35MB for only caching the windows, if Windows did that. I'm not really doing any real work at the moment. Usually I have much more windows open. Please consider memory usage too.
Tim

Re:My GUI design

Post by Tim »

Tux wrote:Yes, that's for INSIDE of windows. If a window moves its position, valid or invalid, another window is affected.
And instead of redrawing the WHOLE other window. You redraw the sectors of the window that were affected by the window you moved, saving valueable cycles. Think outside the box.
That's exactly what I'm saying!

window::move might look like this:

Code: Select all

void window::move_window(const rect &pos)
{
    window *other;
    foreach other in windows
    {
        rect intersection = other->intersect(this);
        if (!intersection.is_empty())
            other->invalidate(intersection);
    }
}
The aim of this is to redraw any parts (or 'sectors') of exposed windows. The redraw will happen next time each other other windows asks for a message.

Redrawing the entire screen on each clock interrupt is neither desirable nor necessary.
Tux

Re:My GUI design

Post by Tux »

mystran, you are right. But, for now I am sticking to small resolutions. Yes people have graphic cards and 3d-now technology. I seen how Vesa runs in Linux =/ and QNX =/ . I don't think you would expect a person to wake up and know exactly how to build their OS. I am just getting used to the regular sector theory. The GUI is gonna be a plugin BTW. (The plugin allows programs to use GUI functions like w_focus(0); which would focus the window. And the plugin solution is so structured that there is no need for terminal emulators. All you do is change the console plugin with a plugin that writes to a GUI console plugin. That's a little off topic. Anyway, my point is, since it's a plugin, it's gonna be easily changed and upgraded.
mystran

Re:My GUI design

Post by mystran »

Tux wrote: mystran, you are right. But, for now I am sticking to small resolutions. Yes people have graphic cards and 3d-now technology. I seen how Vesa runs in Linux =/ and QNX =/ . I don't think you would expect a person to wake up and know exactly how to build their OS.
Ok, I just wanted to point out that at some point you have to optimize for low bus traffic, and it might be worth the trouble to structure your whole GUI system in such a way that it's possibly to get along with a few accelerated blits and stuff like that. If you do that, you might get better VESA performance as a by-product.
I am just getting used to the regular sector theory. The GUI is gonna be a plugin BTW. (The plugin allows programs to use GUI functions like w_focus(0); which would focus the window. And the plugin solution is so structured that there is no need for terminal emulators. All you do is change the console plugin with a plugin that writes to a GUI console plugin. That's a little off topic. Anyway, my point is, since it's a plugin, it's gonna be easily changed and upgraded.
I've been thinking something along these lines. There are programs where the GUI is plugin (say ViM, emacs or Nethack) at least in the sense that these apps can detect what is available and start in the needed mode.

There's still the problem that the application needs to know what different GUI possibilities there are, or you need a wrapper of some kind.

I think the most succesful user interface abstraction is that of the Web. All web applications are more or less transparent to the users interface. Most of the time it doesn't matter if you are running IE, Firebird, Opera or Lynx. The application just says what it wants to display and the client figures our how.

Anyhow, for complete UI abstraction, you can list some capabilities that limit what can run where. Then you can do an interface that allows for drawing components, and then the GUI system can figure out how to display it. This way you could even switch the GUI on the fly.

Say.. in a textmode terminal, you can't show graphics. So anything that needs to show graphics needs to ask the system if it's ok to use graphics. A web-interface can't really be notified by the server easily, so for some apps you have to ask if it's ok to change the window contents without user request. Same thing for intercepting input, playing sounds...

I think it would be better if there was no application specific plugins, but instead the app would tell the current user interface what it needs to be able to run, and the user interface would then handle all the details.

Java2ME does something like this with it's GUI, since you can't really know for sure what kind of machine the app is running. Might be worth investigating.
Tux

Re:My GUI design

Post by Tux »

Man the guys at the other forum are taking it seriously, but anyhow. I was thinking the same thing. That's why the plugins are direct access. About the terminal, the text.plug is switched with a console text emu.plug
In other words, only a screen emulator is made instead of a whole terminal emulator.
MeLkOr

Re:My GUI design

Post by MeLkOr »

I think it looks great. I don't know much about GUI's or how to use them in programs and such but I think (as long as that IS a GUI and not just a pic you made) that that GUI looks great.
-MeLkOr
Post Reply