00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "xrb_screen.hpp"
00012
00013 #include "xrb_eventqueue.hpp"
00014 #include "xrb_gl.hpp"
00015 #include "xrb_gui_events.hpp"
00016 #include "xrb_input_events.hpp"
00017 #include "xrb_pal.hpp"
00018
00019 namespace Xrb
00020 {
00021
00022 Screen::~Screen ()
00023 {
00024
00025
00026
00027
00028 DeleteAllChildren();
00029
00030 ASSERT1(OwnerEventQueue() != NULL);
00031 delete OwnerEventQueue();
00032 SetOwnerEventQueue(NULL);
00033
00034 Singleton::Pal().ShutdownVideo();
00035 }
00036
00037 Screen *Screen::Create (
00038 ScreenCoord width,
00039 ScreenCoord height,
00040 Uint32 bit_depth,
00041 bool fullscreen)
00042 {
00043
00044 ASSERT1(width > 0);
00045 ASSERT1(height > 0);
00046 ASSERT1(bit_depth > 0);
00047
00048 if (Singleton::Pal().InitializeVideo(width, height, bit_depth, fullscreen) != Pal::SUCCESS)
00049 return NULL;
00050
00051 GL::Initialize();
00052
00053
00054
00055
00056 Screen *retval = new Screen();
00057
00058 retval->m_current_video_resolution.SetComponents(width, height);
00059 retval->MoveTo(ScreenCoordVector2::ms_zero);
00060 retval->ContainerWidget::Resize(retval->m_current_video_resolution);
00061 retval->FixSize(retval->m_current_video_resolution);
00062 retval->m_widget_skin = new WidgetSkin(retval);
00063 retval->m_delete_widget_skin = true;
00064 retval->InitializeFromWidgetSkinProperties();
00065 retval->SetBackground(NULL);
00066
00067 return retval;
00068 }
00069
00070 void Screen::RequestQuit ()
00071 {
00072 if (!m_is_quit_requested)
00073 {
00074 m_is_quit_requested = true;
00075 fprintf(stderr, "Screen::RequestQuit();\n");
00076 m_sender_quit_requested.Signal();
00077 }
00078 }
00079
00080 void Screen::Draw () const
00081 {
00082
00083
00084 #if !defined(WIN32)
00085 ASSERT1(GL::Integer(GL_MODELVIEW_STACK_DEPTH) == 1 && "mismatched push/pop for GL_MODELVIEW matrix stack");
00086 ASSERT1(GL::Integer(GL_PROJECTION_STACK_DEPTH) == 1 && "mismatched push/pop for GL_PROJECTION matrix stack");
00087 ASSERT1(GL::Integer(GL_TEXTURE_STACK_DEPTH) == 1 && "mismatched push/pop for GL_TEXTURE matrix stack");
00088 #endif // !defined(WIN32)
00089
00090
00091
00092 glClearColor(
00093 ColorBias()[Dim::R]*ColorBias()[Dim::A],
00094 ColorBias()[Dim::G]*ColorBias()[Dim::A],
00095 ColorBias()[Dim::B]*ColorBias()[Dim::A],
00096 0.0f);
00097 glClear(GL_COLOR_BUFFER_BIT);
00098
00099 glMatrixMode(GL_MODELVIEW);
00100 glLoadIdentity();
00101 glMatrixMode(GL_PROJECTION);
00102 glLoadIdentity();
00103 glMatrixMode(GL_TEXTURE);
00104 glLoadIdentity();
00105
00106
00107
00108 ScreenCoordRect screen_rect(ScreenRect());
00109 ASSERT1(screen_rect.Left() == 0);
00110 ASSERT1(screen_rect.Bottom() == 0);
00111 if (screen_rect.Width() > m_current_video_resolution[Dim::X])
00112 screen_rect.SetWidth(m_current_video_resolution[Dim::X]);
00113 if (screen_rect.Height() > m_current_video_resolution[Dim::Y])
00114 screen_rect.SetHeight(m_current_video_resolution[Dim::Y]);
00115
00116
00117
00118
00119
00120
00121
00122 RenderContext render_context(screen_rect, ColorBias(), ColorMask());
00123
00124
00125 render_context.SetupGLClipRect();
00126
00127
00128 ContainerWidget::Draw(render_context);
00129
00130 #if !defined(WIN32)
00131 ASSERT1(GL::Integer(GL_MODELVIEW_STACK_DEPTH) == 1 && "mismatched push/pop for GL_MODELVIEW matrix stack");
00132 ASSERT1(GL::Integer(GL_PROJECTION_STACK_DEPTH) == 1 && "mismatched push/pop for GL_PROJECTION matrix stack");
00133 ASSERT1(GL::Integer(GL_TEXTURE_STACK_DEPTH) == 1 && "mismatched push/pop for GL_TEXTURE matrix stack");
00134 #endif // !defined(WIN32)
00135
00136
00137
00138 glFlush();
00139 Singleton::Pal().FinishFrame();
00140 }
00141
00142 Screen::Screen ()
00143 :
00144 ContainerWidget(NULL, "Screen"),
00145 m_sender_quit_requested(this),
00146 m_receiver_request_quit(&Screen::RequestQuit, this)
00147 {
00148 m_is_quit_requested = false;
00149 m_current_video_resolution = ScreenCoordVector2::ms_zero;
00150
00151
00152
00153 SetOwnerEventQueue(new EventQueue());
00154 }
00155
00156 void Screen::HandleFrame ()
00157 {
00158 ContainerWidget::HandleFrame();
00159
00160
00161 }
00162
00163 bool Screen::HandleEvent (Event const *const e)
00164 {
00165 ASSERT1(e != NULL);
00166
00167 switch (e->GetEventType())
00168 {
00169 case Event::QUIT:
00170 RequestQuit();
00171 return true;
00172
00173 default:
00174 break;
00175 }
00176
00177
00178 {
00179 if (e->IsMouseMotionEvent())
00180 {
00181 EventMouseMotion const *mouse_motion_event =
00182 DStaticCast<EventMouseMotion const *>(e);
00183
00184
00185 EventMouseover mouseover_event(
00186 mouse_motion_event->Position(),
00187 mouse_motion_event->Time());
00188 ProcessEvent(&mouseover_event);
00189 }
00190
00191 if (e->GetEventType() == Event::MOUSEBUTTONDOWN)
00192 {
00193
00194 EventFocus focus_event(
00195 DStaticCast<EventMouseButton const *>(e)->Position(),
00196 e->Time());
00197
00198 ProcessEvent(&focus_event);
00199 }
00200
00201
00202 Widget *modal_widget = NULL;
00203 for (ContainerWidget::WidgetList::reverse_iterator
00204 it = m_modal_widget_stack.rbegin(),
00205 it_end = m_modal_widget_stack.rend();
00206 it != it_end;
00207 ++it)
00208 {
00209 Widget *widget = *it;
00210 ASSERT1(widget != NULL);
00211 if (!widget->IsHidden())
00212 {
00213 modal_widget = widget;
00214 break;
00215 }
00216 }
00217
00218
00219 if (modal_widget != NULL)
00220 {
00221
00222 if (modal_widget->IsMouseGrabbed() && e->IsInputEvent())
00223 return modal_widget->ProcessEvent(e);
00224
00225
00226
00227 if (e->IsMouseEvent())
00228 if (!modal_widget->ScreenRect().IsPointInside(DStaticCast<EventMouse const *>(e)->Position()))
00229 return false;
00230
00231 return modal_widget->ProcessEvent(e);
00232 }
00233 }
00234
00235
00236 return ContainerWidget::HandleEvent(e);
00237 }
00238
00239 }