00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "xrb_label.hpp"
00012
00013 #include <stdarg.h>
00014
00015 #include "xrb_gl.hpp"
00016 #include "xrb_render.hpp"
00017 #include "xrb_screen.hpp"
00018
00019 namespace Xrb
00020 {
00021
00022 Label::Label (
00023 std::string const &text,
00024 ContainerWidget *const parent,
00025 std::string const &name)
00026 :
00027 TextWidget(text, parent, name)
00028 {
00029 DirtyTextFormatting();
00030 m_line_format_vector_source = NULL;
00031 m_alignment = Alignment2(CENTER, CENTER);
00032 m_word_wrap = false;
00033 m_is_picture_label = false;
00034 SetIsMinSizeFixedToTextSize(true);
00035 ASSERT1(!m_picture.IsValid());
00036 ASSERT1(!m_render_picture.IsValid());
00037 }
00038
00039 Label::Label (
00040 Resource<GLTexture> const &picture,
00041 ContainerWidget *const parent,
00042 std::string const &name)
00043 :
00044 TextWidget("", parent, name),
00045 m_picture(picture)
00046 {
00047
00048 m_is_picture_label = true;
00049
00050
00051 SetFont(Resource<Font>());
00052 m_picture_keeps_aspect_ratio = false;
00053 Label::UpdateRenderPicture();
00054 }
00055
00056 void Label::SetText (std::string const &text)
00057 {
00058 if (m_is_picture_label)
00059 return;
00060
00061 DirtyTextFormatting();
00062 TextWidget::SetText(text);
00063 }
00064
00065 void Label::SetAlignment (Alignment2 const &alignment)
00066 {
00067 if (m_is_picture_label)
00068 return;
00069
00070 m_alignment = alignment;
00071 }
00072
00073 void Label::SetAlignment (Uint32 const component, Alignment const alignment)
00074 {
00075 if (m_is_picture_label)
00076 return;
00077
00078 ASSERT1(component <= 1);
00079 m_alignment[component] = alignment;
00080 }
00081
00082 void Label::SetWordWrap (bool const word_wrap)
00083 {
00084 if (m_is_picture_label)
00085 return;
00086
00087 ASSERT1(RenderFont().IsValid());
00088
00089 if (m_word_wrap != word_wrap)
00090 {
00091 m_word_wrap = word_wrap;
00092 DirtyTextFormatting();
00093 UpdateMinAndMaxSizesFromText();
00094 }
00095 }
00096
00097 void Label::SetPicture (std::string const &picture_name)
00098 {
00099 if (!m_is_picture_label)
00100 return;
00101
00102 ASSERT1(!picture_name.empty());
00103
00104 Resource<GLTexture> picture =
00105 Singleton::ResourceLibrary().
00106 LoadPath<GLTexture>(GLTexture::Create, picture_name);
00107 ASSERT1(picture.IsValid());
00108 if (m_picture != picture)
00109 {
00110 m_picture = picture;
00111 UpdateRenderPicture();
00112 }
00113 }
00114
00115 void Label::SetPicture (Resource<GLTexture> const &picture)
00116 {
00117 if (!m_is_picture_label)
00118 return;
00119
00120 if (m_picture != picture)
00121 {
00122 m_picture = picture;
00123 UpdateRenderPicture();
00124 }
00125 }
00126
00127 void Label::Draw (RenderContext const &render_context) const
00128 {
00129
00130 Widget::Draw(render_context);
00131
00132
00133
00134 if (m_is_picture_label)
00135 DrawPicture(render_context);
00136 else
00137 DrawText(render_context);
00138 }
00139
00140 ScreenCoordVector2 Label::Resize (ScreenCoordVector2 const &size)
00141 {
00142 if (!m_is_picture_label && m_word_wrap && Size()[Dim::X] != size[Dim::X])
00143 DirtyTextFormatting();
00144 Widget::Resize(size);
00145 UpdateMinAndMaxSizesFromText();
00146 return Size();
00147 }
00148
00149 void Label::HandleChangedFrameMargins ()
00150 {
00151 DirtyTextFormatting();
00152 TextWidget::HandleChangedFrameMargins();
00153 }
00154
00155 void Label::HandleChangedContentMargins ()
00156 {
00157 DirtyTextFormatting();
00158 TextWidget::HandleChangedContentMargins();
00159 }
00160
00161 void Label::DrawText (RenderContext const &render_context) const
00162 {
00163 ASSERT1(!m_is_picture_label);
00164 ASSERT1(RenderFont().IsValid());
00165
00166 ScreenCoordRect contents_rect(ContentsRect());
00167 if (contents_rect.IsValid())
00168 {
00169
00170
00171 UpdateCachedFormattedText();
00172 ASSERT1(!m_text_formatting_update_required);
00173
00174 RenderContext string_render_context(render_context);
00175
00176 string_render_context.ApplyClipRect(contents_rect);
00177
00178 string_render_context.ApplyColorMask(RenderTextColor());
00179
00180 string_render_context.SetupGLClipRect();
00181
00182 ASSERT1(m_line_format_vector_source != NULL);
00183 RenderFont()->DrawLineFormattedText(
00184 string_render_context,
00185 ContentsRect(),
00186 m_line_format_vector_source->c_str(),
00187 m_line_format_vector,
00188 m_alignment);
00189 }
00190 }
00191
00192 void Label::DrawPicture (RenderContext const &render_context) const
00193 {
00194 ASSERT1(m_is_picture_label);
00195 if (!RenderPicture().IsValid())
00196 return;
00197
00198
00199 ScreenCoordRect picture_rect;
00200 ScreenCoordRect contents_rect(ContentsRect());
00201
00202 if (m_picture_keeps_aspect_ratio)
00203 {
00204 ASSERT1(m_picture->Width() > 0);
00205 ASSERT1(m_picture->Height() > 0);
00206
00207
00208 if (contents_rect.Height() * m_picture->Width() /
00209 m_picture->Height()
00210 <=
00211 contents_rect.Width())
00212 {
00213
00214 ScreenCoordVector2 picture_size(
00215 contents_rect.Height() * m_picture->Width() / m_picture->Height(),
00216 contents_rect.Height());
00217 picture_rect = picture_size;
00218 picture_rect += ScreenCoordVector2((contents_rect.Width() - picture_rect.Width()) / 2, 0);
00219 }
00220 else
00221 {
00222
00223 ScreenCoordVector2 picture_size(
00224 contents_rect.Width(),
00225 contents_rect.Width() * m_picture->Height() / m_picture->Width());
00226 picture_rect = picture_size;
00227 picture_rect += ScreenCoordVector2(0, (contents_rect.Height() - picture_rect.Height()) / 2);
00228 }
00229 picture_rect += contents_rect.BottomLeft();
00230 }
00231 else
00232 {
00233 picture_rect = contents_rect;
00234 }
00235
00236 Render::DrawScreenRectTexture(render_context, *RenderPicture(), picture_rect);
00237 }
00238
00239 void Label::SetRenderFont (Resource<Font> const &render_font)
00240 {
00241 if (m_is_picture_label)
00242 return;
00243
00244 TextWidget::SetRenderFont(render_font);
00245
00246 DirtyTextFormatting();
00247 UpdateMinAndMaxSizesFromText();
00248 }
00249
00250 void Label::SetRenderPicture (Resource<GLTexture> const &render_picture)
00251 {
00252 if (!m_is_picture_label)
00253 return;
00254
00255 m_render_picture = render_picture;
00256 }
00257
00258 void Label::UpdateRenderFont ()
00259 {
00260 if (!m_is_picture_label)
00261 TextWidget::UpdateRenderFont();
00262 }
00263
00264 void Label::UpdateRenderPicture ()
00265 {
00266 SetRenderPicture(Picture());
00267 }
00268
00269 ScreenCoordRect Label::TextRect () const
00270 {
00271 ASSERT1(!m_is_picture_label);
00272 ASSERT1(RenderFont().IsValid());
00273
00274 UpdateCachedFormattedText();
00275 return RenderFont()->StringRect(m_line_format_vector);
00276 }
00277
00278 void Label::UpdateMinAndMaxSizesFromText ()
00279 {
00280
00281 if (m_is_picture_label)
00282 return;
00283
00284 ASSERT1(RenderFont().IsValid());
00285
00286
00287
00288
00289 if (m_word_wrap)
00290 {
00291 m_is_min_width_fixed_to_text_width = false;
00292 m_is_max_width_fixed_to_text_width = false;
00293 }
00294
00295 UpdateCachedFormattedText();
00296 TextWidget::UpdateMinAndMaxSizesFromText();
00297 }
00298
00299 void Label::UpdateCachedFormattedText () const
00300 {
00301 ASSERT1(!m_is_picture_label);
00302 ASSERT1(RenderFont().IsValid());
00303
00304
00305 if (!m_text_formatting_update_required)
00306 return;
00307
00308
00309 m_text_formatting_update_required = false;
00310
00311
00312 if (m_word_wrap)
00313 {
00314
00315 RenderFont()->GenerateWordWrappedString(
00316 m_text,
00317 &m_cached_formatted_text,
00318 ContentsRect().Size());
00319 m_line_format_vector_source = &m_cached_formatted_text;
00320 }
00321
00322 else
00323 {
00324 m_line_format_vector_source = &m_text;
00325 }
00326
00327
00328 RenderFont()->GenerateLineFormatVector(m_line_format_vector_source->c_str(), &m_line_format_vector);
00329 }
00330
00331 }