nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "Nux.h" 00024 #include "InputArea.h" 00025 #include "Painter.h" 00026 00027 #include "NuxGraphics/GLTextureResourceManager.h" 00028 00029 namespace nux 00030 { 00031 00032 const unsigned int STENCIL_TEST_REF = 0xFF; 00033 const unsigned int STENCIL_TEST_MASK = 0xFFFFFFFF; 00034 const unsigned int STENCIL_CLEAR = 0x0; 00035 const float ALPHA_TEST_REF = 0.0f; 00036 00037 GeometryPositioning::GeometryPositioning() 00038 { 00039 m_stretch_horizontal = true; 00040 m_stretch_vertical = true; 00041 00042 m_vertical_aligment = eVACenter; 00043 m_horizontal_aligment = eHACenter; 00044 00045 m_horizontal_margin = 0; 00046 m_vertical_margin = 0; 00047 } 00048 00049 GeometryPositioning::GeometryPositioning ( 00050 HorizontalAlignment horizontal_aligment, 00051 VerticalAlignment vertical_aligment, 00052 bool stretch_horizontal, 00053 bool stretch_vertical, 00054 int horizontal_margin, 00055 int vertical_margin) 00056 { 00057 m_stretch_horizontal = stretch_horizontal; 00058 m_stretch_vertical = stretch_vertical; 00059 00060 m_vertical_aligment = eVACenter; 00061 m_horizontal_aligment = eHACenter; 00062 00063 m_horizontal_margin = horizontal_margin; 00064 m_vertical_margin = vertical_margin; 00065 } 00066 00067 GeometryPositioning::~GeometryPositioning() 00068 { 00069 00070 } 00071 00072 Geometry ComputeGeometryPositioning (const Geometry &container_geo, const Geometry &content_geo, GeometryPositioning gctx) 00073 { 00074 int x_pos, y_pos; 00075 int w, h; 00076 00077 if (gctx.m_stretch_horizontal) 00078 { 00079 w = container_geo.GetWidth() - 2 * gctx.m_horizontal_margin; 00080 } 00081 else 00082 { 00083 w = content_geo.GetWidth(); 00084 } 00085 00086 if (gctx.m_stretch_horizontal) 00087 { 00088 h = container_geo.GetHeight() - 2 * gctx.m_vertical_margin; 00089 } 00090 else 00091 { 00092 h = content_geo.GetHeight(); 00093 } 00094 00095 if (gctx.m_horizontal_aligment == eHACenter) 00096 { 00097 int offset = (container_geo.GetWidth() - w) / 2.0f; 00098 //offset = (offset < 0) ? 0 : offset; 00099 x_pos = container_geo.x + offset; 00100 } 00101 else if (gctx.m_horizontal_aligment == eHALeft) 00102 { 00103 x_pos = container_geo.x + gctx.m_horizontal_margin; 00104 00105 if (x_pos > container_geo.x + container_geo.GetWidth() ) 00106 x_pos = container_geo.x; 00107 } 00108 else if (gctx.m_horizontal_aligment == eHARight) 00109 { 00110 x_pos = container_geo.x + container_geo.GetWidth() - w - gctx.m_horizontal_margin; 00111 00112 if (x_pos < container_geo.x) 00113 x_pos = container_geo.x; 00114 } 00115 else 00116 { 00117 x_pos = container_geo.x + gctx.m_horizontal_margin; 00118 } 00119 00120 if (gctx.m_vertical_aligment == eVACenter) 00121 { 00122 int offset = (container_geo.GetHeight() - h) / 2.0f; 00123 //offset = (offset < 0) ? 0 : offset; 00124 y_pos = container_geo.y + offset; 00125 } 00126 else if (gctx.m_vertical_aligment == eVATop) 00127 { 00128 y_pos = container_geo.y + gctx.m_vertical_margin; 00129 00130 if (y_pos > container_geo.y + container_geo.GetHeight() ) 00131 y_pos = container_geo.y; 00132 } 00133 else if (gctx.m_vertical_aligment == eVABottom) 00134 { 00135 y_pos = container_geo.y + container_geo.GetHeight() - h - gctx.m_vertical_margin; 00136 00137 if (y_pos < container_geo.y) 00138 y_pos = container_geo.y; 00139 } 00140 else 00141 { 00142 y_pos = container_geo.y + gctx.m_vertical_margin; 00143 } 00144 00145 return Geometry (x_pos, y_pos, w, h); 00146 } 00147 00148 InteractState::InteractState() 00149 { 00150 is_on = false; 00151 is_focus = false; 00152 is_prelight = false; 00153 is_disable = false; 00154 } 00155 00156 InteractState::InteractState (bool on, bool focus, bool prelight, bool disable) 00157 { 00158 is_on = on; 00159 is_focus = focus; 00160 is_prelight = prelight; 00161 is_disable = disable; 00162 } 00163 00164 InteractState::~InteractState() 00165 { 00166 00167 } 00168 00169 BasePainter::BasePainter() 00170 { 00171 } 00172 00173 BasePainter::~BasePainter() 00174 { 00175 EmptyBackgroundStack(); 00176 } 00177 00178 int BasePainter::PaintColorTextLineEdit (GraphicsEngine &GfxContext, const Geometry &g, const NString &Str, 00179 Color TextColor, 00180 bool WriteAlphaChannel, 00181 Color SelectedTextColor, 00182 Color SelectedTextBackgroundColor, 00183 Color TextBlinkColor, 00184 Color CursorColor, 00185 bool ShowCursor, unsigned int CursorPosition, 00186 int offset, 00187 int selection_start, int selection_end) const 00188 { 00189 PageBBox page; 00190 page.xmin = g.x; 00191 page.xmax = g.x + g.GetWidth(); 00192 page.ymin = g.y; 00193 page.ymax = g.y + g.GetHeight(); 00194 page.x_margin = DEFAULT_TEXT_X_MARGIN; 00195 page.y_margin = DEFAULT_TEXT_Y_MARGIN; 00196 return GfxContext.RenderColorTextLineEdit (GetSysFont(), page, Str, 00197 TextColor, 00198 WriteAlphaChannel, 00199 SelectedTextColor, 00200 SelectedTextBackgroundColor, 00201 TextBlinkColor, 00202 CursorColor, 00203 ShowCursor, CursorPosition, offset, selection_start, selection_end); 00204 } 00205 00206 int BasePainter::PaintTextLineStatic (GraphicsEngine &GfxContext, 00207 ObjectPtr<FontTexture> Font, 00208 const Geometry &g, 00209 const NString &Str, 00210 const Color &color, 00211 bool WriteAlphaChannel, 00212 TextAlignment alignment) const 00213 { 00214 PageBBox page; 00215 page.xmin = g.x; 00216 page.xmax = g.x + g.GetWidth(); 00217 page.ymin = g.y; 00218 page.ymax = g.y + g.GetHeight(); 00219 page.x_margin = DEFAULT_TEXT_X_MARGIN; 00220 page.y_margin = DEFAULT_TEXT_Y_MARGIN; 00221 return GfxContext.RenderColorTextLineStatic (Font, page, Str, color, WriteAlphaChannel, alignment); 00222 } 00223 00224 void BasePainter::Draw2DTexture (GraphicsEngine &GfxContext, BaseTexture *texture, int x, int y) const 00225 { 00226 float tex_w, tex_h; 00227 tex_w = (float) texture->GetWidth(); 00228 tex_h = (float) texture->GetHeight(); 00229 00230 TexCoordXForm texxform; 00231 GfxContext.QRP_1Tex (x, y, tex_w, tex_h, texture->GetDeviceTexture(), texxform, color::White); 00232 } 00233 00234 void BasePainter::Draw2DTextureAligned (GraphicsEngine &GfxContext, BaseTexture *texture, const Geometry &g, TextureAlignmentStyle tex_align) const 00235 { 00236 int x_pos, y_pos; 00237 int tex_w, tex_h; 00238 tex_w = (float) texture->GetWidth(); 00239 tex_h = (float) texture->GetHeight(); 00240 00241 if (tex_align.horz_alignment == eTACenter) 00242 { 00243 int offset = (g.GetWidth() - tex_w) / 2.0f; 00244 offset = (offset < 0) ? 0 : offset; 00245 x_pos = g.x + offset; 00246 } 00247 else if (tex_align.horz_alignment == eTALeft) 00248 { 00249 x_pos = g.x + tex_align.horizontal_margin; 00250 } 00251 else if (tex_align.horz_alignment == eTARight) 00252 { 00253 x_pos = g.x + g.GetWidth() - tex_w - tex_align.horizontal_margin; 00254 } 00255 else 00256 { 00257 x_pos = g.x + tex_align.horizontal_margin; 00258 } 00259 00260 if (tex_align.vert_alignment == eTACenter) 00261 { 00262 int offset = (g.GetHeight() - tex_h) / 2.0f; 00263 offset = (offset < 0) ? 0 : offset; 00264 y_pos = g.y + offset; 00265 } 00266 else if (tex_align.vert_alignment == eTATop) 00267 { 00268 y_pos = g.y + tex_align.vertical_margin; 00269 } 00270 else if (tex_align.vert_alignment == eTABottom) 00271 { 00272 y_pos = g.y + g.GetHeight() - tex_h - tex_align.vertical_margin; 00273 } 00274 else 00275 { 00276 y_pos = g.y + tex_align.vertical_margin; 00277 } 00278 00279 PaintTextureShape (GfxContext, Geometry (x_pos, y_pos, tex_w, tex_h), texture, 0, 0, 0, 0, 0); 00280 } 00281 00283 // Draw QUADS // 00285 00286 void BasePainter::Paint2DQuadColor (GraphicsEngine &GfxContext, const Geometry &g, Color c0) const 00287 { 00288 GfxContext.QRP_Color (g.x, g.y, g.GetWidth(), g.GetHeight(), c0); 00289 } 00290 00291 void BasePainter::Paint2DQuadColor (GraphicsEngine &GfxContext, const Geometry &g, Color c0_top_left, Color c1_bottom_left, Color c2_bottom_right, Color c3_top_right) const 00292 { 00293 GfxContext.QRP_Color (g.x, g.y, g.GetWidth(), g.GetHeight(), c0_top_left, c1_bottom_left, c2_bottom_right, c3_top_right); 00294 } 00295 00296 void BasePainter::Paint2DQuadColor (GraphicsEngine &GfxContext, int x, int y, int width, int height, Color c0) const 00297 { 00298 GfxContext.QRP_Color (x, y, width, height, c0); 00299 } 00300 00301 00302 void BasePainter::Paint2DQuadColor (GraphicsEngine &GfxContext, int x, int y, int width, int height, Color c0_top_left, Color c1_bottom_left, Color c2_bottom_right, Color c3_top_right) const 00303 { 00304 GfxContext.QRP_Color (x, y, width, height, c0_top_left, c1_bottom_left, c2_bottom_right, c3_top_right); 00305 } 00306 00307 void BasePainter::Paint2DQuadVGradient (GraphicsEngine &GfxContext, const Geometry &g, Color TopColor, Color BottomColor) const 00308 { 00309 Paint2DQuadColor (GfxContext, g, TopColor, BottomColor, BottomColor, TopColor); 00310 } 00311 00312 void BasePainter::Paint2DQuadHGradient (GraphicsEngine &GfxContext, const Geometry &g, Color LeftColor, Color RightColor) const 00313 { 00314 Paint2DQuadColor (GfxContext, g, LeftColor, LeftColor, RightColor, LeftColor); 00315 } 00316 00317 00319 // Draw QUADS WIREFRAME // 00321 void BasePainter::Paint2DQuadWireframe (GraphicsEngine &GfxContext, const Geometry &g, Color c0) const 00322 { 00323 GfxContext.QRP_QuadWireframe (g.x, g.y, g.GetWidth(), g.GetHeight(), c0, c0, c0, c0); 00324 } 00325 00326 // void BasePainter::Paint2DQuadWireframe(GraphicsEngine& GfxContext, const Geometry &g, Color c0_left, Color c1_right) const 00327 // { 00328 // GfxContext.QRP_QuadWireframe(g.x, g.y, g.GetWidth(), g.GetHeight(), c0_left, c0_left, c1_right, c1_right); 00329 // } 00330 00331 void BasePainter::Paint2DQuadWireframe (GraphicsEngine &GfxContext, const Geometry &g, Color c_top_left, Color c_bottom_left, Color c_bottom_right, Color c_top_right) const 00332 { 00333 GfxContext.QRP_QuadWireframe (g.x, g.y, g.GetWidth(), g.GetHeight(), c_top_left, c_bottom_left, c_bottom_right, c_top_right); 00334 } 00335 00336 void BasePainter::Paint2DQuadWireframe (GraphicsEngine &GfxContext, int x, int y, int width, int height, Color c0) const 00337 { 00338 GfxContext.QRP_QuadWireframe (x, y, width, height, c0, c0, c0, c0); 00339 } 00340 00341 // void BasePainter::Paint2DQuadWireframe(GraphicsEngine& GfxContext, int x, int y, int width, int height, Color c0_left, Color c1_right) const 00342 // { 00343 // GfxContext.QRP_QuadWireframe(x, y, width, height, c0_left, c0_left, c1_right, c1_right); 00344 // } 00345 00346 void BasePainter::Paint2DQuadWireframe (GraphicsEngine &GfxContext, int x, int y, int width, int height, Color c_top_left, Color c_bottom_left, Color c_bottom_right, Color c_top_right) const 00347 { 00348 GfxContext.QRP_QuadWireframe (x, y, width, height, c_top_left, c_bottom_left, c_bottom_right, c_top_right); 00349 } 00350 00352 // Draw TRIANGLES // 00354 void BasePainter::Draw2DTriangleColor (GraphicsEngine &GfxContext, int x0, int y0, 00355 int x1, int y1, 00356 int x2, int y2, 00357 Color c0) 00358 { 00359 GfxContext.QRP_Triangle (x0, y0, x1, y1, x2, y2, c0); 00360 } 00361 00362 void BasePainter::Draw2DTriangleColor (GraphicsEngine &GfxContext, int x0, int y0, 00363 int x1, int y1, 00364 int x2, int y2, 00365 Color c0, Color c1, Color c2) 00366 { 00367 GfxContext.QRP_Triangle (x0, y0, x1, y1, x2, y2, c0, c1, c2); 00368 } 00369 00371 // DRAW LINES // 00373 void BasePainter::Draw2DLine (GraphicsEngine &GfxContext, int x0, int y0, 00374 int x1, int y1, Color c0) const 00375 { 00376 GfxContext.QRP_Line (x0, y0, x1, y1, c0); 00377 } 00378 void BasePainter::Draw2DLine (GraphicsEngine &GfxContext, int x0, int y0, 00379 int x1, int y1, Color c0, Color c1) const 00380 { 00381 GfxContext.QRP_Line (x0, y0, x1, y1, c0, c1); 00382 } 00383 00385 // Themes // 00387 00388 00389 void BasePainter::PaintShape (GraphicsEngine &GfxContext, const Geometry &geo, Color c0, UXStyleImageRef style, bool WriteAlpha) const 00390 { 00391 ROPConfig ROP; 00392 ROP.Blend = true; 00393 ROP.SrcBlend = GL_SRC_ALPHA; 00394 ROP.DstBlend = GL_ONE_MINUS_SRC_ALPHA; 00395 PaintShapeCornerROP (GfxContext, geo, c0, style, eCornerTopLeft | eCornerTopRight | eCornerBottomLeft | eCornerBottomRight, WriteAlpha, ROP); 00396 } 00397 00398 void BasePainter::PaintShapeCorner (GraphicsEngine &GfxContext, const Geometry &geo, Color c0, UXStyleImageRef style, long corners, bool WriteAlpha) const 00399 { 00400 ROPConfig ROP; 00401 ROP.Blend = true; 00402 ROP.SrcBlend = GL_SRC_ALPHA; 00403 ROP.DstBlend = GL_ONE_MINUS_SRC_ALPHA; 00404 PaintShapeCornerROP (GfxContext, geo, c0, style, corners, WriteAlpha, ROP); 00405 } 00406 00407 void BasePainter::PaintShapeROP (GraphicsEngine &GfxContext, const Geometry &geo, Color c0, UXStyleImageRef style, bool WriteAlpha, const ROPConfig &ROP) const 00408 { 00409 PaintShapeCornerROP (GfxContext, geo, c0, style, eCornerTopLeft | eCornerTopRight | eCornerBottomLeft | eCornerBottomRight, WriteAlpha, ROP); 00410 } 00411 00412 void BasePainter::PaintShapeCornerROP (GraphicsEngine &GfxContext, const Geometry &geo, Color c0, UXStyleImageRef style, long corners, bool WriteAlpha, const ROPConfig &ROP) const 00413 { 00414 const PainterImage *pimage = GetTheme().GetImage (style); 00415 00416 if (pimage == 0) 00417 return; 00418 00419 BaseTexture *texture = pimage->texture; 00420 00421 int border_left = pimage->border_left; 00422 int border_right = pimage->border_right; 00423 int border_top = pimage->border_top; 00424 int border_bottom = pimage->border_bottom; 00425 bool draw_borders_only = pimage->draw_borders_only; 00426 t_u32 current_alpha_blend; 00427 t_u32 current_src_blend_factor; 00428 t_u32 current_dest_blend_factor; 00429 t_u32 current_red_mask; 00430 t_u32 current_green_mask; 00431 t_u32 current_blue_mask; 00432 t_u32 current_alpha_mask; 00433 00434 // Get the current color mask and blend states. They will be restored later. 00435 GfxContext.GetRenderStates ().GetColorMask (current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); 00436 GfxContext.GetRenderStates ().GetBlend (current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); 00437 00438 00439 GfxContext.GetRenderStates().SetColorMask (GL_TRUE, GL_TRUE, GL_TRUE, WriteAlpha ? GL_TRUE : GL_FALSE); 00440 GfxContext.GetRenderStates().SetBlend (ROP.Blend, ROP.SrcBlend, ROP.DstBlend); 00441 00442 int tex_w = texture->GetWidth(); 00443 int tex_h = texture->GetHeight(); 00444 00445 int r_x = geo.x; 00446 int r_y = geo.y; 00447 int r_w = geo.GetWidth(); 00448 int r_h = geo.GetHeight(); 00449 00450 TexCoordXForm texxform; 00451 texxform.SetTexCoordType (TexCoordXForm::UNNORMALIZED_COORD); 00452 00453 if (r_w < border_left + border_right) 00454 { 00455 // Do not apply this correction: just show the drawing as it is; 00456 //border_left = border_right = 0; 00457 } 00458 00459 if (r_h < border_top + border_bottom) 00460 { 00461 // Do not apply this correction: just show the drawing as it is; 00462 //border_top = border_bottom = 0; 00463 } 00464 00465 // Draw TOP-LEFT CORNER 00466 if (corners & eCornerTopLeft) 00467 { 00468 texxform.u0 = 0; 00469 texxform.v0 = 0; 00470 texxform.u1 = border_left; 00471 texxform.v1 = border_top; 00472 GfxContext.QRP_ColorModTexAlpha (r_x, r_y, border_left, border_top, texture->GetDeviceTexture(), texxform, c0); 00473 } 00474 else 00475 { 00476 GfxContext.QRP_Color (r_x, r_y, border_left, border_top, c0); 00477 } 00478 00479 // Draw TOP-RIGHT CORNER 00480 if (corners & eCornerTopRight) 00481 { 00482 texxform.u0 = tex_w - border_right; 00483 texxform.v0 = 0; 00484 texxform.u1 = tex_w; 00485 texxform.v1 = border_top; 00486 GfxContext.QRP_ColorModTexAlpha (r_x + r_w - border_right, r_y, border_right, border_top, texture->GetDeviceTexture(), texxform, c0); 00487 } 00488 else 00489 { 00490 GfxContext.QRP_Color (r_x + r_w - border_right, r_y, border_right, border_top, c0); 00491 } 00492 00493 // Draw BOTTOM-LEFT CORNER 00494 if (corners & eCornerBottomLeft) 00495 { 00496 texxform.u0 = 0; 00497 texxform.v0 = tex_h - border_bottom; 00498 texxform.u1 = border_left; 00499 texxform.v1 = tex_h; 00500 GfxContext.QRP_ColorModTexAlpha (r_x, r_y + r_h - border_bottom, border_left, border_bottom, texture->GetDeviceTexture(), texxform, c0); 00501 } 00502 else 00503 { 00504 GfxContext.QRP_Color (r_x, r_y + r_h - border_bottom, border_left, border_bottom, c0); 00505 } 00506 00507 // Draw BOTTOM-RIGHT CORNER 00508 if (corners & eCornerBottomRight) 00509 { 00510 texxform.u0 = tex_w - border_right; 00511 texxform.v0 = tex_h - border_bottom; 00512 texxform.u1 = tex_w; 00513 texxform.v1 = tex_h; 00514 GfxContext.QRP_ColorModTexAlpha (r_x + r_w - border_right, r_y + r_h - border_bottom, border_right, border_bottom, texture->GetDeviceTexture(), texxform, c0); 00515 } 00516 else 00517 { 00518 GfxContext.QRP_Color (r_x + r_w - border_right, r_y + r_h - border_bottom, border_right, border_bottom, c0); 00519 } 00520 00521 texxform.u0 = border_left; 00522 texxform.v0 = 0; 00523 texxform.u1 = tex_w - border_right; 00524 texxform.v1 = border_top; 00525 GfxContext.QRP_ColorModTexAlpha (r_x + border_left, r_y, r_w - border_left - border_right, border_top, texture->GetDeviceTexture(), texxform, c0); 00526 // Draw BOTTOM BORDER 00527 texxform.u0 = border_left; 00528 texxform.v0 = tex_h - border_bottom; 00529 texxform.u1 = tex_w - border_right; 00530 texxform.v1 = tex_h; 00531 GfxContext.QRP_ColorModTexAlpha (r_x + border_left, r_y + r_h - border_bottom, r_w - border_left - border_right, border_bottom, texture->GetDeviceTexture(), texxform, c0); 00532 // Draw LEFT BORDER 00533 texxform.u0 = 0; 00534 texxform.v0 = border_top; 00535 texxform.u1 = border_left; 00536 texxform.v1 = tex_h - border_bottom; 00537 GfxContext.QRP_ColorModTexAlpha (r_x, r_y + border_top, border_left, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, c0); 00538 // Draw RIGHT BORDER 00539 texxform.u0 = tex_w - border_right; 00540 texxform.v0 = border_top; 00541 texxform.u1 = tex_w; 00542 texxform.v1 = tex_h - border_bottom; 00543 GfxContext.QRP_ColorModTexAlpha (r_x + r_w - border_right, r_y + border_top, border_right, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, c0); 00544 00545 // Draw CENTER 00546 if (draw_borders_only == false) 00547 { 00548 texxform.u0 = border_left; 00549 texxform.v0 = border_top; 00550 texxform.u1 = tex_w - border_right; 00551 texxform.v1 = tex_h - border_bottom; 00552 GfxContext.QRP_ColorModTexAlpha (r_x + border_left, r_y + border_top, r_w - border_left - border_right, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, c0); 00553 } 00554 00555 // Restore Color mask and blend states. 00556 GfxContext.GetRenderStates ().SetColorMask (current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); 00557 GfxContext.GetRenderStates ().SetBlend (current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); 00558 } 00559 00560 void BasePainter::PaintTextureShape (GraphicsEngine &GfxContext, const Geometry &geo, UXStyleImageRef style) const 00561 { 00562 const PainterImage *pimage = GetTheme().GetImage (style); 00563 00564 if (pimage == 0) 00565 return; 00566 00567 BaseTexture *texture = pimage->texture; 00568 00569 00570 int border_left = pimage->border_left; 00571 int border_right = pimage->border_right; 00572 int border_top = pimage->border_top; 00573 int border_bottom = pimage->border_bottom; 00574 bool draw_borders_only = pimage->draw_borders_only; 00575 00576 PaintTextureShape (GfxContext, geo, texture, 00577 border_left, border_right, border_top, border_bottom, draw_borders_only); 00578 } 00579 00580 void BasePainter::PaintTextureShape (GraphicsEngine &GfxContext, const Geometry &geo, BaseTexture *texture, 00581 int border_left, int border_right, int border_top, int border_bottom, 00582 bool draw_borders_only, bool premultiply) const 00583 { 00584 int tex_w = texture->GetWidth(); 00585 int tex_h = texture->GetHeight(); 00586 00587 int r_x = geo.x; 00588 int r_y = geo.y; 00589 int r_w = geo.GetWidth(); 00590 int r_h = geo.GetHeight(); 00591 00592 if (r_w < border_left + border_right) 00593 { 00594 border_left = border_right = 0; 00595 } 00596 00597 if (r_h < border_top + border_bottom) 00598 { 00599 border_top = border_bottom = 0; 00600 } 00601 00602 if (premultiply) 00603 GfxContext.GetRenderStates().SetBlend (TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 00604 else 00605 GfxContext.GetRenderStates().SetBlend (TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00606 00607 TexCoordXForm texxform; 00608 texxform.SetTexCoordType (TexCoordXForm::UNNORMALIZED_COORD); 00609 00610 // Draw TOP-LEFT CORNER 00611 texxform.u0 = 0; 00612 texxform.v0 = 0; 00613 texxform.u1 = border_left; 00614 texxform.v1 = border_top; 00615 GfxContext.QRP_1Tex (r_x, r_y, border_left, border_top, texture->GetDeviceTexture(), texxform, color::White); 00616 // Draw TOP-RIGHT CORNER 00617 texxform.u0 = tex_w - border_right; 00618 texxform.v0 = 0; 00619 texxform.u1 = tex_w; 00620 texxform.v1 = border_top; 00621 GfxContext.QRP_1Tex (r_x + r_w - border_right, r_y, border_right, border_top, texture->GetDeviceTexture(), texxform, color::White); 00622 // Draw BOTTOM-LEFT CORNER 00623 texxform.u0 = 0; 00624 texxform.v0 = tex_h - border_bottom; 00625 texxform.u1 = border_left; 00626 texxform.v1 = tex_h; 00627 GfxContext.QRP_1Tex (r_x, r_y + r_h - border_bottom, border_left, border_bottom, texture->GetDeviceTexture(), texxform, color::White); 00628 // Draw BOTTOM-RIGHT CORNER 00629 texxform.u0 = tex_w - border_right; 00630 texxform.v0 = tex_h - border_bottom; 00631 texxform.u1 = tex_w; 00632 texxform.v1 = tex_h; 00633 GfxContext.QRP_1Tex (r_x + r_w - border_right, r_y + r_h - border_bottom, border_right, border_bottom, texture->GetDeviceTexture(), texxform, color::White); 00634 // Draw TOP BORDER 00635 texxform.u0 = border_left; 00636 texxform.v0 = 0; 00637 texxform.u1 = tex_w - border_right; 00638 texxform.v1 = border_top; 00639 GfxContext.QRP_1Tex (r_x + border_left, r_y, r_w - border_left - border_right, border_top, texture->GetDeviceTexture(), texxform, color::White); 00640 // Draw BOTTOM BORDER 00641 texxform.u0 = border_left; 00642 texxform.v0 = tex_h - border_bottom; 00643 texxform.u1 = tex_w - border_right; 00644 texxform.v1 = tex_h; 00645 GfxContext.QRP_1Tex (r_x + border_left, r_y + r_h - border_bottom, r_w - border_left - border_right, border_bottom, texture->GetDeviceTexture(), texxform, color::White); 00646 // Draw LEFT BORDER 00647 texxform.u0 = 0; 00648 texxform.v0 = border_top; 00649 texxform.u1 = border_left; 00650 texxform.v1 = tex_h - border_bottom; 00651 GfxContext.QRP_1Tex (r_x, r_y + border_top, border_left, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, color::White); 00652 // Draw RIGHT BORDER 00653 texxform.u0 = tex_w - border_right; 00654 texxform.v0 = border_top; 00655 texxform.u1 = tex_w; 00656 texxform.v1 = tex_h - border_bottom; 00657 GfxContext.QRP_1Tex (r_x + r_w - border_right, r_y + border_top, border_right, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, color::White); 00658 00659 // Draw CENTER 00660 if (draw_borders_only == false) 00661 { 00662 texxform.u0 = border_left; 00663 texxform.v0 = border_top; 00664 texxform.u1 = tex_w - border_right; 00665 texxform.v1 = tex_h - border_bottom; 00666 GfxContext.QRP_1Tex (r_x + border_left, r_y + border_top, r_w - border_left - border_right, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, color::White); 00667 } 00668 00669 GfxContext.GetRenderStates().SetBlend (FALSE); 00670 } 00671 00672 void BasePainter::PaintHorizontalGradientQuad (GraphicsEngine &GfxContext, const Geometry &geo, int array_size, float *percentage_array, Color *color_array) 00673 { 00674 for (int i = 0; i < array_size - 1; i++) 00675 { 00676 float p0 = percentage_array[i] / 100.0f; 00677 float p1 = percentage_array[i+1] / 100.0f; 00678 00679 Paint2DQuadColor (GfxContext, geo.x, geo.y + geo.GetHeight() * p0, geo.GetWidth(), geo.GetHeight() * p1 - geo.GetHeight() * p0, 00680 color_array[i], color_array[i], 00681 color_array[i+1], color_array[i+1]); 00682 } 00683 } 00684 00685 void BasePainter::PaintCheckBox (GraphicsEngine &GfxContext, const Geometry &geo, const InteractState &interaction_state, 00686 Color check_mark_color, Color check_box_color) 00687 { 00688 00689 GeometryPositioning pctx (eHACenter, eVACenter); 00690 pctx.m_stretch_horizontal = false; 00691 pctx.m_stretch_vertical = false; 00692 00693 const PainterImage *pimage = GetTheme().GetImage (eCHECKBOX_NORMAL_ON); 00694 00695 if (pimage == 0) 00696 return; 00697 00698 BaseTexture *texture = pimage->texture; 00699 Geometry content_geo (0, 0, texture->GetWidth(), texture->GetHeight() ) ; 00700 content_geo = ComputeGeometryPositioning (geo, content_geo, pctx); 00701 00702 GfxContext.GetRenderStates().SetBlend (true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00703 00704 if (interaction_state.is_focus && interaction_state.is_on) 00705 { 00706 Draw2DTexture (GfxContext, GetTheme().GetImage (eCHECKBOX_FOCUS_ON)->texture, content_geo.x, content_geo.y); 00707 } 00708 else if (interaction_state.is_focus && !interaction_state.is_on) 00709 { 00710 Draw2DTexture (GfxContext, GetTheme().GetImage (eCHECKBOX_FOCUS_OFF)->texture, content_geo.x, content_geo.y); 00711 } 00712 else if (interaction_state.is_prelight && interaction_state.is_on) 00713 { 00714 Draw2DTexture (GfxContext, GetTheme().GetImage (eCHECKBOX_PRELIGHT_ON)->texture, content_geo.x, content_geo.y); 00715 } 00716 else if (interaction_state.is_prelight && !interaction_state.is_on) 00717 { 00718 Draw2DTexture (GfxContext, GetTheme().GetImage (eCHECKBOX_PRELIGHT_OFF)->texture, content_geo.x, content_geo.y); 00719 } 00720 else if (interaction_state.is_on) 00721 { 00722 Draw2DTexture (GfxContext, GetTheme().GetImage (eCHECKBOX_NORMAL_ON)->texture, content_geo.x, content_geo.y); 00723 } 00724 else 00725 { 00726 Draw2DTexture (GfxContext, GetTheme().GetImage (eCHECKBOX_NORMAL_OFF)->texture, content_geo.x, content_geo.y); 00727 } 00728 00729 GfxContext.GetRenderStates().SetBlend (false); 00730 //PaintShape(content_geo, check_box_color, eSHAPE_CHECK_BOX); 00731 //Draw2DTexture(GetTheme().GetImage(eSHAPE_CHECK_BOX)->texture, content_geo); 00732 00733 //PaintShape(const Geometry& geo, Color c0, UXStyleImageRef style) 00734 } 00735 00736 void BasePainter::PaintRadioButton (GraphicsEngine &GfxContext, const Geometry &geo, const InteractState &interaction_state, 00737 Color check_mark_color, Color check_box_color) 00738 { 00739 PaintBackground (GfxContext, geo); 00740 GeometryPositioning pctx (eHACenter, eVACenter); 00741 pctx.m_stretch_horizontal = false; 00742 pctx.m_stretch_vertical = false; 00743 00744 const PainterImage *pimage = GetTheme().GetImage (eRADIO_NORMAL_ON); 00745 00746 if (pimage == 0) 00747 return; 00748 00749 BaseTexture *texture = pimage->texture; 00750 00751 // CachedBaseTexture* glr = (CachedBaseTexture*)GetGraphicsDisplay()->GetGraphicsEngine()->ResourceCache.GetCachedResource(texture); 00752 // glr->m_Texture->SetFiltering(GL_LINEAR, GL_LINEAR); 00753 00754 Geometry content_geo (0, 0, texture->GetWidth(), texture->GetHeight() ) ; 00755 content_geo = ComputeGeometryPositioning (geo, content_geo, pctx); 00756 00757 GfxContext.GetRenderStates().SetBlend (true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 00758 00759 if (interaction_state.is_focus && interaction_state.is_on) 00760 { 00761 Draw2DTexture (GfxContext, GetTheme().GetImage (eRADIO_FOCUS_ON)->texture, content_geo.x, content_geo.y); 00762 } 00763 else if (interaction_state.is_focus && !interaction_state.is_on) 00764 { 00765 Draw2DTexture (GfxContext, GetTheme().GetImage (eRADIO_FOCUS_OFF)->texture, content_geo.x, content_geo.y); 00766 } 00767 else if (interaction_state.is_prelight && interaction_state.is_on) 00768 { 00769 Draw2DTexture (GfxContext, GetTheme().GetImage (eRADIO_PRELIGHT_ON)->texture, content_geo.x, content_geo.y); 00770 } 00771 else if (interaction_state.is_prelight && !interaction_state.is_on) 00772 { 00773 Draw2DTexture (GfxContext, GetTheme().GetImage (eRADIO_PRELIGHT_OFF)->texture, content_geo.x, content_geo.y); 00774 } 00775 else if (interaction_state.is_on) 00776 { 00777 Draw2DTexture (GfxContext, GetTheme().GetImage (eRADIO_NORMAL_ON)->texture, content_geo.x, content_geo.y); 00778 } 00779 else 00780 { 00781 Draw2DTexture (GfxContext, GetTheme().GetImage (eRADIO_NORMAL_OFF)->texture, content_geo.x, content_geo.y); 00782 } 00783 00784 GfxContext.GetRenderStates().SetBlend (false); 00785 } 00786 00787 void BasePainter::PaintBackground (GraphicsEngine &GfxContext, const Geometry &geo) 00788 { 00789 if (m_BackgroundStack.empty()) 00790 { 00791 return; 00792 } 00793 00794 std::list<AbstractPaintLayer *>::const_reverse_iterator rev_it; 00795 00796 bool first = true; 00797 00798 for (rev_it = m_BackgroundStack.rbegin (); rev_it != m_BackgroundStack.rend (); rev_it++) 00799 { 00800 AbstractPaintLayer *layer = (*rev_it); 00801 Geometry layer_geo = layer->GetGeometry (); 00802 Geometry xform_geo = GfxContext.ModelViewXFormRect (geo); 00803 00804 GfxContext.PushClippingRectangle (geo); 00805 GfxContext.SetModelViewMatrix (layer->GetModelViewMatrix ()); 00806 00807 if (first) 00808 { 00809 Paint2DQuadColor (GfxContext, layer_geo, Color (0x0)); 00810 first = false; 00811 } 00812 00813 RenderSinglePaintLayer (GfxContext, layer_geo, layer); 00814 00815 // restore the model view matrix stack and the clipping rectangle stack. 00816 GfxContext.ApplyModelViewMatrix (); 00817 GfxContext.PopClippingRectangle (); 00818 } 00819 } 00820 00821 void BasePainter::RenderSinglePaintLayer (GraphicsEngine &GfxContext, Geometry geo, AbstractPaintLayer *paint_layer) 00822 { 00823 paint_layer->Renderlayer (GfxContext); 00824 } 00825 00826 void BasePainter::PushLayer (GraphicsEngine &GfxContext, const Geometry &geo, AbstractPaintLayer *layer) 00827 { 00828 AbstractPaintLayer *l = layer->Clone(); 00829 l->SetModelViewMatrix (GetGraphicsEngine ().GetModelViewMatrix ()); 00830 l->SetGeometry (geo); 00831 m_BackgroundStack.push_front (l); 00832 } 00833 00834 void BasePainter::PushDrawLayer (GraphicsEngine &GfxContext, const Geometry &geo, AbstractPaintLayer *layer) 00835 { 00836 PushLayer (GfxContext, geo, layer); 00837 PaintBackground (GfxContext, geo); 00838 } 00839 00840 void BasePainter::PushColorLayer (GraphicsEngine &GfxContext, const Geometry &geo, 00841 Color color, 00842 bool WriteAlpha, 00843 const ROPConfig &ROP) 00844 { 00845 ColorLayer *cl = new ColorLayer (color, WriteAlpha, ROP); 00846 cl->SetModelViewMatrix (GetGraphicsEngine ().GetModelViewMatrix ()); 00847 cl->SetGeometry (geo); 00848 m_BackgroundStack.push_front (cl); 00849 } 00850 00851 void BasePainter::PushDrawColorLayer (GraphicsEngine &GfxContext, const Geometry &geo, 00852 Color color, 00853 bool WriteAlpha, 00854 const ROPConfig &ROP) 00855 { 00856 PushColorLayer (GfxContext, geo, color, WriteAlpha, ROP); 00857 PaintBackground (GfxContext, geo); 00858 } 00859 00860 void BasePainter::PushShapeLayer (GraphicsEngine &GfxContext, Geometry geo, 00861 UXStyleImageRef imageStyle, 00862 const Color &color, 00863 unsigned long Corners, 00864 bool WriteAlpha, 00865 const ROPConfig &ROP) 00866 { 00867 ShapeLayer *sl = new ShapeLayer (imageStyle, color, Corners, WriteAlpha, ROP); 00868 sl->SetModelViewMatrix (GetGraphicsEngine ().GetModelViewMatrix ()); 00869 sl->SetGeometry (geo); 00870 m_BackgroundStack.push_front (sl); 00871 } 00872 00873 void BasePainter::PushDrawShapeLayer (GraphicsEngine &GfxContext, Geometry geo, 00874 UXStyleImageRef imageStyle, 00875 const Color &color, 00876 unsigned long Corners, 00877 bool WriteAlpha, 00878 const ROPConfig &ROP) 00879 { 00880 PushShapeLayer (GfxContext, geo, imageStyle, color, Corners, WriteAlpha, ROP); 00881 PaintBackground (GfxContext, geo); 00882 } 00883 00884 void BasePainter::PushSliceScaledTextureLayer (GraphicsEngine &GfxContext, Geometry geo, 00885 UXStyleImageRef imageStyle, 00886 const Color &color, 00887 unsigned long Corners, 00888 bool WriteAlpha, 00889 const ROPConfig &ROP) 00890 { 00891 SliceScaledTextureLayer *sl = new SliceScaledTextureLayer (imageStyle, color, Corners, WriteAlpha, ROP); 00892 sl->SetModelViewMatrix (GetGraphicsEngine ().GetModelViewMatrix ()); 00893 sl->SetGeometry (geo); 00894 m_BackgroundStack.push_front (sl); 00895 } 00896 00897 void BasePainter::PushDrawSliceScaledTextureLayer (GraphicsEngine &GfxContext, Geometry geo, 00898 UXStyleImageRef imageStyle, 00899 const Color &color, 00900 unsigned long Corners, 00901 bool WriteAlpha, 00902 const ROPConfig &ROP) 00903 { 00904 PushSliceScaledTextureLayer (GfxContext, geo, imageStyle, color, Corners, WriteAlpha, ROP); 00905 PaintBackground (GfxContext, geo); 00906 } 00907 00908 void BasePainter::PushTextureLayer (GraphicsEngine &GfxContext, Geometry geo, 00909 ObjectPtr<IOpenGLBaseTexture> DeviceTexture, 00910 TexCoordXForm texxform, 00911 const Color &color, 00912 bool WriteAlpha, 00913 const ROPConfig &ROP) 00914 { 00915 TextureLayer *tl = new TextureLayer (DeviceTexture, texxform, color, WriteAlpha, ROP); 00916 tl->SetModelViewMatrix (GetGraphicsEngine ().GetModelViewMatrix ()); 00917 tl->SetGeometry (geo); 00918 m_BackgroundStack.push_front (tl); 00919 } 00920 00921 void BasePainter::PushDrawTextureLayer (GraphicsEngine &GfxContext, Geometry geo, 00922 ObjectPtr<IOpenGLBaseTexture> DeviceTexture, 00923 TexCoordXForm texxform, 00924 const Color &color, 00925 bool WriteAlpha, 00926 const ROPConfig &ROP) 00927 { 00928 PushTextureLayer (GfxContext, geo, DeviceTexture, texxform, color, WriteAlpha, ROP); 00929 PaintBackground (GfxContext, geo); 00930 } 00931 00932 void BasePainter::PopBackground (int level) 00933 { 00934 nuxAssert (level >= 0); 00935 00936 while ((level >= 1) && (m_BackgroundStack.size() > 0)) 00937 { 00938 AbstractPaintLayer *paint_layer = (*m_BackgroundStack.begin() ); 00939 delete paint_layer; 00940 m_BackgroundStack.pop_front(); 00941 level--; 00942 } 00943 } 00944 00945 void BasePainter::EmptyBackgroundStack() 00946 { 00947 std::list<AbstractPaintLayer*>::iterator background_layer_it; 00948 for (background_layer_it = m_BackgroundStack.begin(); background_layer_it != m_BackgroundStack.end(); ++background_layer_it) 00949 { 00950 delete (*background_layer_it); 00951 } 00952 m_BackgroundStack.clear(); 00953 } 00954 00955 namespace local 00956 { 00957 namespace 00958 { 00959 std::list<std::list<AbstractPaintLayer*> > hack_stack; 00960 } 00961 } 00962 00963 void BasePainter::PushBackgroundStack() 00964 { 00965 local::hack_stack.push_back(m_BackgroundStack); 00966 m_BackgroundStack.clear(); 00967 } 00968 00969 void BasePainter::PopBackgroundStack() 00970 { 00971 // clear and delete 00972 EmptyBackgroundStack(); 00973 00974 m_BackgroundStack = local::hack_stack.back(); 00975 local::hack_stack.pop_back(); 00976 } 00977 }