nux-1.16.0
Painter.cpp
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 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends