My GUI... check, optimization, hints...
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:My GUI... check, optimization, hints...
imho, an updated GUI.EXE is of little use ... what can we do with it ? just see it goes ?fast? (with 60 windows at max, there are chances we won't even notice the difference between the 2 versions if your redrawing function are in the same process than the event processing ...)
oh, or maybe we could dissassemble the GUI.EXE to get the assembler out of it and see it's not even optimized ? no thanks: you can keep your EXE on your HDD: i prefer crawling back in my backup CD and find back the crappy code i wrote 5 years ago :p
oh, or maybe we could dissassemble the GUI.EXE to get the assembler out of it and see it's not even optimized ? no thanks: you can keep your EXE on your HDD: i prefer crawling back in my backup CD and find back the crappy code i wrote 5 years ago :p
Re:My GUI... check, optimization, hints...
You don't really need a specific sort function if all you're doing it moving windows relative to each other.
e.g.:
Bring window to front -> insert at end of list
Move window to bottom -> insert at beginning of list
Keep window on top -> keep at end of list
Clip window to siblings -> remove areas from clip list for all windows after this window in the list
You don't need a separate VB-style 'zorder' property. Additionally, I think that Windows' tab order is the same as its z-order: you don't often overlap controls on dialogs, and you don't often tab between top-level windows, so it makes sense to skip to the next window in the z-order when you press Tab.
e.g.:
Bring window to front -> insert at end of list
Move window to bottom -> insert at beginning of list
Keep window on top -> keep at end of list
Clip window to siblings -> remove areas from clip list for all windows after this window in the list
You don't need a separate VB-style 'zorder' property. Additionally, I think that Windows' tab order is the same as its z-order: you don't often overlap controls on dialogs, and you don't often tab between top-level windows, so it makes sense to skip to the next window in the z-order when you press Tab.
Re:My GUI... check, optimization, hints...
Right, I'll just ignore P.C for now... Fine, no GUI.EXE for you :p - so go get your old code.
Back to business:
As for linked lists and such, I have had no experience with these. I have tried another one of my wierd ideas - I created a sort function that supposedly does this: Get all the window's zorders in order and put them in order (0-63) into a temporary window array (I bet that sounds odd). After the sorting is complete, it transfers the temporary window array into wm_elements, over writing them all... I call that function right at the end of movefrontwin and everything seems fine. I change the drawgui function by deleting the extra loop and making appropriate changes. Right after I do that, the GUI doesn't draw correctly. Does anyone have a sort idea that would do minimum damage to my code?
Back to business:
As for linked lists and such, I have had no experience with these. I have tried another one of my wierd ideas - I created a sort function that supposedly does this: Get all the window's zorders in order and put them in order (0-63) into a temporary window array (I bet that sounds odd). After the sorting is complete, it transfers the temporary window array into wm_elements, over writing them all... I call that function right at the end of movefrontwin and everything seems fine. I change the drawgui function by deleting the extra loop and making appropriate changes. Right after I do that, the GUI doesn't draw correctly. Does anyone have a sort idea that would do minimum damage to my code?
Re:My GUI... check, optimization, hints...
I'll say this again: you don't need to keep track of the z-order for each window.
Don't use arrays at all. Keep a linked list of child windows for every window (top-level windows go into the root window's list), and keep that list sorted all the time -- when you add a window into that list, put it in the correct place. When you create a window, you probably want it to become the active window, right? So when you create a window, you just add it to the end of its parent's list. No arrays. No sort functions. Just a linked list.
BTW, if you really do have no experience with linked lists, I suggest you read up on them very soon, because you will use them all over your OS. Also useful are trees and hash tables.
Don't use arrays at all. Keep a linked list of child windows for every window (top-level windows go into the root window's list), and keep that list sorted all the time -- when you add a window into that list, put it in the correct place. When you create a window, you probably want it to become the active window, right? So when you create a window, you just add it to the end of its parent's list. No arrays. No sort functions. Just a linked list.
BTW, if you really do have no experience with linked lists, I suggest you read up on them very soon, because you will use them all over your OS. Also useful are trees and hash tables.
Re:My GUI... check, optimization, hints...
OK, here's the source for my GUI(not full source - doesn't fit - had to cut out half of it). It's the only way that you people could really see what's happening. I reverted back to my previous code without the sort function. The sort function is still there, but it is never called. Get ready for a long list.
I am sorry I could not log on to actually post this file, My school disabled cookies in a sad attempt to disable hotmail access - now hotmail doesn't use cookies... Totally useless school board we have here... :-\
Code: Select all
#define MAXWINDOWS 64
struct WINDOW
{
unsigned short x;
unsigned short y;
unsigned short width;
unsigned short height;
unsigned char *caption;
unsigned short zorder;
unsigned long flags;
unsigned char handle;
};
struct WINDOW wm_elements [MAXWINDOWS];
void initwm()
{
int i;
for (i = 0; i < MAXWINDOWS; i++)
{
wm_elements[i].handle = i;
wm_elements[i].flags = 0;
}
}
void drawgui()
{
int tz;
int i;
for (tz = MAXWINDOWS - 1; tz >= 0; tz--)
{
for (i = 0; i < MAXWINDOWS; i++)
{
if (wm_elements[i].flags & WMFLAGS_ACTIVE)
{
if (wm_elements[i].zorder == tz)
{
if (wm_elements[i].flags & WMFLAGS_BORDER)
windowbox(wm_elements[i].x, wm_elements[i].y, (wm_elements[i].x + wm_elements[i].width), (wm_elements[i].y + wm_elements[i].height));
else
drawrect(wm_elements[i].x, wm_elements[i].y, (wm_elements[i].x + wm_elements[i].width), (wm_elements[i].y + wm_elements[i].height), 24);
}
}
}
}
}
void winzsort()
{
struct WINDOW tempstruct[MAXWINDOWS];
int tz, i;
for(i = 0; i < MAXWINDOWS - 1; i++)
{
if (wm_elements[i].flags & WMFLAGS_ACTIVE)
{
for (tz = 0; tz < MAXWINDOWS - 1; tz++)
{
if (wm_elements[i].zorder == tz)
{
tempstruct[tz] = wm_elements[i];
}
}
}
}
for (i = 0; i < MAXWINDOWS - 1; i++)
{
wm_elements[i] = tempstruct[i];
}
}
void movefrontwin(unsigned char handle)
{
int tz, i;
unsigned char t_zorder = wm_elements[handle].zorder;
for (i = 0; i < MAXWINDOWS; i++)
{
if (t_zorder > wm_elements[i].zorder)
{
wm_elements[i].zorder++;
}
}
wm_elements[handle].zorder = 0;
}
unsigned char inwhatwin(int x, int y)
{
unsigned int tz;
unsigned char i;
for (tz = 0; tz < MAXWINDOWS; tz++)
{
for (i = 0; i < MAXWINDOWS; i++)
{
if (wm_elements[i].flags & WMFLAGS_ACTIVE)
{
if (wm_elements[i].zorder == tz)
{
if ((x >= wm_elements[i].x) && (x < (wm_elements[i].x + wm_elements[i].width)))
if ((y >= wm_elements[i].y) && (y < (wm_elements[i].y + wm_elements[i].height)))
return i;
}
}
}
}
return 255;
}
Re:My GUI... check, optimization, hints...
Maybe you don't understand my previous two posts. I'll rewrite some of your code then.
Remove this. Don't impose a limit.
Don't need this if your window lists are always sorted.
Add:
prev and next are the pointers to the previous and next children within the parent's list of children. first_child and last_child define this window's list of children (possibly empty). parent provides a link up to the window's parent.
Use malloc to allocate your windows. This will give you a virtually unlimited number of windows without wasting any space for unused elements. If you want to use window handles, have a dynamically-allocated handle-to-window array:
Don't need any of this.
You should virtually never need to redraw the entire screen. Instead, record an "invalid rectangle" for each window: that is, an area within each window which should be repainted next time the application is ready.
Not necessary since the z-order is defined by the ordering of each window's list of children.
Better:
(using unsigned char limits you to 256 windows total)
See my alternate code for this function earlier in the thread.
Code: Select all
#define MAXWINDOWS 64
Code: Select all
struct WINDOW
{
unsigned short x;
unsigned short y;
unsigned short width;
unsigned short height;
unsigned char *caption;
unsigned short zorder;
Code: Select all
unsigned long flags;
unsigned char handle;
};
Code: Select all
struct WINDOW *prev, *next;
struct WINDOW *first_child, *last_child;
struct WINDOW *parent;
Code: Select all
struct WINDOW wm_elements [MAXWINDOWS];
Code: Select all
struct WINDOW** wm_handles;
unsigned num_windows;
typedef unsigned WINDOW_HANDLE;
WINDOW_HANDLE allocate_window(void)
{
struct WINDOW *wnd;
wnd = malloc(sizeof(*wnd));
wm_handles = realloc(wm_handles, sizeof(WINDOW*) * (num_windows + 1));
wm_handles[num_windows] = wnd;
memset(wnd, 0, sizeof(*wnd));
wnd->handle = num_windows++;
return wnd->handle;
}
Code: Select all
void initwm()
{
int i;
for (i = 0; i < MAXWINDOWS; i++)
{
wm_elements[i].handle = i;
wm_elements[i].flags = 0;
}
}
Code: Select all
void drawgui()
{
<snip>
}
Code: Select all
void winzsort()
{
<snip>
}
Code: Select all
void movefrontwin(unsigned char handle)
{
int tz, i;
unsigned char t_zorder = wm_elements[handle].zorder;
for (i = 0; i < MAXWINDOWS; i++)
{
if (t_zorder > wm_elements[i].zorder)
{
wm_elements[i].zorder++;
}
}
wm_elements[handle].zorder = 0;
}
Code: Select all
void movefrontwin(WINDOW_HANDLE handle)
Code: Select all
{
struct WINDOW *wnd;
if (handle >= num_windows)
return;
wnd = wm_handles[handle];
if (wnd == NULL)
return;
/* Remove window from the parent's list of children */
if (wnd->prev != NULL)
wnd->prev->next = wnd->next;
if (wnd->next != NULL)
wnd->next->prev = wnd->prev;
if (wnd == wnd->parent->first_child)
wnd->parent->first_child = wnd->next;
if (wnd == wnd->parent->last_child)
wnd->parent->last_child = wnd->prev;
/* Add window to end of parent's list of children */
wnd->prev = wnd->parent->last_child;
wnd->next = NULL;
if (wnd->parent->last_child != NULL)
wnd->parent->last_child->next = wnd;
wnd->parent->last_child = wnd;
if (wnd->parent->first_child == NULL)
wnd->parent->first_child = wnd;
}
Code: Select all
unsigned char inwhatwin(int x, int y)
{
<snip>
}
Re:My GUI... check, optimization, hints...
I must say thanks alot for the modifications. It is somewhat better cleared up now - partially because of the fact that I read both the linked list and binary tree tutorials at http://www.cprogramming.com (they seem good to me).
I took a quick scan of your code and it looks good to me. By the looks of the structure of this system, it looks like it supports windows inside of windows (MDI - Multiple Document Interfaces). If not, It seems so easy to add on top of this new code. I will definitely add you to my O.S.'es credits (Under special thanks). I have decided that I will recreate my GUI(Decided this last night after reading the tutorials). I wrote up a basic tree on paper as an example for my WM structure. It was based on your design and it makes total sence.
Once again, many thanks
I took a quick scan of your code and it looks good to me. By the looks of the structure of this system, it looks like it supports windows inside of windows (MDI - Multiple Document Interfaces). If not, It seems so easy to add on top of this new code. I will definitely add you to my O.S.'es credits (Under special thanks). I have decided that I will recreate my GUI(Decided this last night after reading the tutorials). I wrote up a basic tree on paper as an example for my WM structure. It was based on your design and it makes total sence.
Once again, many thanks
Re:My GUI... check, optimization, hints...
Glad to be of help. I'll release my own GUI sources soon, which look fairly similar to this.
The child window stuff isn't so much to support MDI (although it could), but controls -- if you think of every text box, button and label as being a window in its own right, you can handle them all the same way (and just handle painting and user input differently).
The child window stuff isn't so much to support MDI (although it could), but controls -- if you think of every text box, button and label as being a window in its own right, you can handle them all the same way (and just handle painting and user input differently).
Re:My GUI... check, optimization, hints...
Do you have MSN? I may need help when I am writing my new gui. I'll have to read the tutorials again. The person at VBWorld made a reply as well. His idea was basically the same as yours but it didn't include the *parent struct and kept the window structs as is. He made a separate structure that is for the linked list. It was something like:
struct list
{
list* prev;
list* next;
WINDOW *data;
}
The main problem was he didn't have PowerC and therefore couldn't test it(Used VC++ to syntax check). When I checked it out the only error was that drawgui(); didn't work at all...
struct list
{
list* prev;
list* next;
WINDOW *data;
}
The main problem was he didn't have PowerC and therefore couldn't test it(Used VC++ to syntax check). When I checked it out the only error was that drawgui(); didn't work at all...