Mason McCuskey - Developing a GUI in C++ and DirectX

Здесь есть возможность читать онлайн «Mason McCuskey - Developing a GUI in C++ and DirectX» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Developing a GUI in C++ and DirectX: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Developing a GUI in C++ and DirectX»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

At first glance, it may seem like I’m reinventing the wheel; Windows already comes with a very complex, very functional GUI. Unfortunately, while the Windows GUI is great for office apps, quite frequently, it’s not suited for many games. Games tend to want a more precise control over the GUI than Windows can provide (for example, games may want to use alpha-blending to implement partially transparent windows - easy if you’ve written your own GUI, but next to impossible using the Windows GUI).
This article will walk you though how to create a GUI using C++ and DirectX. The series is divided into several parts, each dealing with a specific aspect of GUI programming:
Part I: The Basics, and the Mouse
Part II: Windows
Part III: Controls
Part IV: Resource Editors and Other Madness
NOTE: This document was originally four separate articles on www.gamedev.net. I’ve concatenated all four into one for the XGDC, but they remain otherwise unchanged. - Mason

Developing a GUI in C++ and DirectX — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Developing a GUI in C++ and DirectX», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

That’s the main reason behind why I decided that my GUI would not own the window pointer. If you’re passing a lot of complex window classes into and out of your GUI (say, for example, you’re populating a tabbed property sheet), you might prefer a system where the GUI doesn’t keep track of the pointers, and where remove simply means “the pointer is now in my control; remove it from your array, but don’t delete it.” This would also allow you to (carefully) use addresses of local variables on the stack, provided you made sure that you removewindow()’ed them before they went out of scope.

Moving on… Showing and hiding windows is accompished through a boolean variable. Showwindow() and hidewindow() simply set or clear this variable; the window drawing and message processing functions check this “is window shown” flag before they do anything. Pretty easy stuff.

Z-ordering was also fairly easy. For those unfamiliar with the term, z-ordering refers to the “stacking” of windows on top of each other. At first thought, you may decide to implement z-ordering similar to how DirectDraw does it for overlays - you might decide to give each window an integer that describes its absolute z-order position, their place on the z axis - say, maybe, 0 is the top of the screen, and negative -1000 is furthest back. I thought a bit about implementing this type of z-ordering, but decided against it - absolutez-order positions don’t concern me; I care more about relative z-order positions. That is, I don’t really need to know “how far back” one window is from another; I simply need to know whether a given window is behind another, or in front of it.

So, I decided to implement z-order like this: The window with the highest index in the array, m_subwins, would be the window “on top.” The window at [size-1] would be directly under it, followed by [size-2], etc. The window at position [0] would be on the very bottom. In this way, processing z-ordering became very easy. Also, killing two birds with one stone, I deemed that the topmost window would always be the activewindow, or more technically, the window with input focus. Although this restricted my GUI from making “always on top” windows (for example: Windows NT’s task manager is always on top of all other windows, regardless of who has the input focus), I felt it was worth it to keep the code as simple as possible.

Also, I paid a small price for using array indices as z-orders was the array shuffle that occurs when I tell a given window to move to the top of the z-order. Say I tell window #2 to move to the top of a 50 window list; I’ve got to shift 48 windows down a slot to accommodate window #2’s new position at the end. The good news is that moving a window to top of the z-order isn’t really a time-critical function, and even if it were, there’s dozens of good, quick ways to juggle array items like this - linked lists spring to mind.

Check out the cheap trick I used in the bringtotop() function. Since I know that the window doesn’t own the pointers, I can just clobber the window and then immediate re-add him, effectively repositioning him at the top of the array. I did this solely because my pointer class, uti_pointerarray, already had code that would delete an element and slide all higher elements backwards one slot.

So that’s window management. Now, onto the joy of coordinate systems…

Coordinate Systems

/****************************************************************************

virtual coordinate system to graphics card resolution converters

****************************************************************************/

const double GUI_SCALEX = 10000.0;

const double GUI_SCALEY = 10000.0;

int gui_window::virtxtopixels(int virtx) {

int width = (m_parent) ? m_parent-›getpos().getwidth() : getscreendims().getwidth();

return((int)((double)virtx*(double)width/GUI_SCALEX));

}

int gui_window::virtytopixels(int virty) {

int height = (m_parent) ? m_parent-›getpos().getheight() : getscreendims().getheight();

return((int)((double)virty*(double)height/GUI_SCALEY));

}

/****************************************************************************

findchildatcoord: returns the top-most child window at coord (x,y); recursive.

****************************************************************************/

gui_window *gui_window::findchildatcoord(coord x, coord y, int flags) {

for (int q = m_subwins.getsize()-1; q ›= 0; q--) {

gui_window *ww = (gui_window *)m_subwins.getat(q);

if (ww) {

gui_window *found = ww-›findchildatcoord(x-m_position.getx1(), y-m_position.gety1(), flags);

if (found) return(found);

}

}

// check to see if this window itself is at the coord - this breaks the recursion

if (!getinvisible() && m_position.ispointin(x,y)) return(this);

return(NULL);

}

One of the top priorities for my GUI was resolution independence, and what I call “stretchy dialog boxes.” Basically, I wanted my windows and dialog boxes to scale themselves larger or smaller, depending on the screen resolution of the system they were running on. On systems with higher resolutions, I wanted the windows, controls, etc. to expand; on 640×480, I wanted things to shrink.

What this really meant was that I needed to implement a virtual coordinate system. I based my virtual coordinate system around an arbitrary number - I effectively said, “Henceforth, I will assume that every window is 10,000×10,000 units, regardless of the actual size of that window,” and then let my GUI do the work of scaling the coordinates. For the desktop window, the coordinates are scaled to the physical resolution of the monitor.

I accomplished this through four functions: virtxtopixels(), virtytopixels(), pixelstovirtx(), and pixelstovirty(). (Note: only two are listed in the code; I figured you got the idea). These functions are responsible for converting between the virtual 10,000×10,000 unit coordinates and either the actual dimensions of the parent window, or the physical coordinates of the monitor. Obviously, the rendering functions of the windows use these functions heavily.

The screentoclient() function is responsible for taking an absolute screen position and converting it into relativevirtual coordinates. Relative coordinates have their origin at the upper-left of a window; it’s the same idea as world space and object space, in 3D. Relative coordinates are indispensable for dialog boxes.

All coordinates in the GUI system are relative to something. The only exception to this is the desktop window, whose coordinates are absolute. This relative way of doing things ensures that child windows move when their parents do, and that the structure of dialog boxes is consistent as the user drags them to different locations. Also, because our entire virtual coordinate system is relative, when a use stretches or shrinks a dialog box, all of the controls within that dialog will stretch and shrink also, automatically trying their best to completely fill up their new dimensions. This is an amazing trait, for those of us who have ever tried to do the same thing in Win32.

Finally, the findchildatcoord() function takes a (virtual) coordinate and determines which child window (if any) is under that coordinate - useful, for example, when a mouse button is clicked, and we need to know which window to send the button click event to. The function works by looping through the subwindow array backwards(remember, the topmost window is at the back of the array), doing some rectangle geometry to see if the point is in that window’s rectangle. The flags parameter provides some extra conditions for determining if a “hit” occurred; for example, when we start implementing controls, we’ll realize that it’s often useful to prevent label and icon controls from registering a “hit,” instead giving the windows beneath them a chance at the test - if a label is placed on top of a button, the user can hit the button, even if technically, they’re clicking on the label. The flags parameter controls those special cases.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Developing a GUI in C++ and DirectX»

Представляем Вашему вниманию похожие книги на «Developing a GUI in C++ and DirectX» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Developing a GUI in C++ and DirectX»

Обсуждение, отзывы о книге «Developing a GUI in C++ and DirectX» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x