/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "ui/ui_window.h" #include "ui/widget_text.h" #include "core/renderer_toolbox.h" #include "core/render_resource_factory.h" using namespace GS; using namespace GS::S2D; //------------------------------------------------------------------------------ iRect Window::GetRect() const { if (!window_flags.IsSet(Window::FlagNoDecoration)) if (skin.IsValid()) return iRect(0, 0, (int)size.x, (int)skin->top->GetHeight()); return iRect(0, 0, (int)size.x, (int)size.y); } iRect Window::GetClientRect() const { if (!window_flags.IsSet(Window::FlagNoDecoration)) if (skin.IsValid()) return iRect(skin->left->GetWidth(), skin->top_left->GetHeight(), int(size.x - skin->right->GetWidth()), int(size.y - skin->bottom_right->GetHeight())); return iRect(0, 0, (int)size.x, (int)size.y); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void Window::SetSize(float _w, float _h) { uint w = (uint)_w, h = (uint)_h; if (cache.IsValid()) { if (w > cache->GetWidth() || h > cache->GetHeight() || w < (cache->GetWidth() / 2) || h < (cache->GetHeight() / 2)) { cache->AllocAs(w, h); if (render_data && render_data->texture) render_data->texture->Resize(w, h); } } Invalidate(); Sprite::SetSize(_w, _h); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ Widget *Window::GetTitleWidget() const { return title_widget; } void Window::SetTitleWidget(Widget *w) { title_widget = w; Invalidate(); } Widget *Window::GetBaseWidget() const { return base_widget; } void Window::SetBaseWidget(Widget *w) { base_widget = w; Invalidate(); } Widget *Window::GetWidget(uint id) { return base_widget ? base_widget->GetChild(id) : NULL; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void Window::ComposeSkin() { if (skin.IsNull()) return; cache->Fill(0, 0, 0, 0); // Fill main area. Rect rect(GetRect()); rect.sx = skin->top_left->GetWidth(); rect.sy = skin->top_left->GetHeight(); rect.ex -= skin->bottom_right->GetWidth(); rect.ey -= skin->bottom_right->GetHeight(); Color _skin_color(skin->color); cache->Fill(_skin_color.x, _skin_color.y, _skin_color.z, _skin_color.w, &rect); // Blit corners. Picture::Blit(*skin->top_left, *cache); rect = GetRect(); rect.sx = rect.ex - skin->top_right->GetWidth(); Picture::Blit(*skin->top_right, *cache, NULL, &rect); rect = GetRect(); rect.sy = rect.ey - skin->bottom_left->GetHeight(); Picture::Blit(*skin->bottom_left, *cache, NULL, &rect); rect = GetRect(); rect.sx = rect.ex - skin->bottom_right->GetWidth(); rect.sy = rect.ey - skin->bottom_right->GetHeight(); Picture::Blit(*skin->bottom_right, *cache, NULL, &rect); // Window left side. { int height = GetRect().GetHeight() - skin->top_left->GetHeight() - skin->bottom_left->GetHeight(); int *dst = (int *)cache->GetData(); dst += skin->top_left->GetHeight() * cache->GetWidth(); int *src = 0; for (int s = 0, _s = 0; s < height; ++s) { if (!src || (++_s == (int)skin->left->GetHeight())) { src = (int *)skin->left->GetData(); _s = 0; } for (uint x = 0; x < skin->left->GetWidth(); ++x) dst[x] = src[x]; src += skin->left->GetWidth(); dst += cache->GetWidth(); } } // Window right side. { int height = GetRect().GetHeight() - skin->top_right->GetHeight() - skin->bottom_right->GetHeight(); int *dst = (int *)cache->GetData(); dst += skin->top_right->GetHeight() * cache->GetWidth() + GetRect().ex - skin->right->GetWidth(); int *src = 0; for (int s = 0, _s = 0; s < height; ++s) { if (!src || (++_s == (int)skin->right->GetHeight())) { src = (int *)skin->right->GetData(); _s = 0; } for (uint x = 0; x < skin->right->GetWidth(); ++x) dst[x] = src[x]; src += skin->right->GetWidth(); dst += cache->GetWidth(); } } // Window top side. { int block_width = skin->top->GetWidth(); int width = GetRect().GetWidth() - skin->top_left->GetWidth() - skin->top_right->GetWidth(), height = skin->top->GetHeight(); int *src = (int *)skin->top->GetData(), *dst = (int *)cache->GetData(); dst += skin->top_left->GetWidth(); for (int y = 0; y < height; ++y) { for (int x = 0, _x = 0; x < width; ++x) { dst[x] = src[_x++]; if (_x == block_width) _x = 0; } src += skin->top->GetWidth(); dst += cache->GetWidth(); } } // Window bottom side. { int block_width = skin->bottom->GetWidth(); int width = GetRect().GetWidth() - skin->bottom_left->GetWidth() - skin->bottom_right->GetWidth(), height = skin->bottom->GetHeight(); int *src = (int *)skin->bottom->GetData(), *dst = (int *)cache->GetData(); dst += skin->bottom_left->GetWidth() + (GetRect().ey - height) * cache->GetWidth(); for (int y = 0; y < height; ++y) { for (int x = 0, _x = 0; x < width; ++x) { dst[x] = src[_x++]; if (_x == block_width) _x = 0; } src += skin->bottom->GetWidth(); dst += cache->GetWidth(); } } // { int height = GetRect().ey - skin->bottom_right->GetHeight() - skin->top_left->GetHeight(), width = GetRect().GetWidth(); // uint *dst = (uint *)cache->GetData(); dst += cache->GetWidth() * skin->top_left->GetHeight();// + system.skin_left->GetWidth(); float alpha = 1.f; int segment_height = (height * 70) / 100; float alpha_step = (0.85f - alpha) / (float)segment_height; for (int y = 0; y < segment_height; ++y) { uint int_alpha = (uint(alpha * 255.f)) & 0xff; // uint scan_color = nColor::ARGBtoRGBA((system.skin_color & 0xffffff00) + int_alpha); for (int x = 0; x < width; ++x) dst[x] = (((((dst[x] >> 24) & 0xff) * int_alpha) >> 8) << 24) + (dst[x] & 0x00ffffff);//scan_color; dst += cache->GetWidth(); alpha += alpha_step; } segment_height = height - segment_height; alpha_step = (1.f - alpha) / (float)segment_height; for (int y = 0; y < segment_height; ++y) { uint int_alpha = (uint(alpha * 255.f)) & 0xff; // uint scan_color = nColor::ARGBtoRGBA((system.skin_color & 0xffffff00) + int_alpha); for (int x = 0; x < width; ++x) dst[x] = (((((dst[x] >> 24) & 0xff) * int_alpha) >> 8) << 24) + (dst[x] & 0x00ffffff);//scan_color; dst += cache->GetWidth(); alpha += alpha_step; } } } void Window::Compose() { if (cache.IsNull()) return; if (background_picture) { cache->Fill(0, 0, 0, 0); Picture::Blit(*background_picture, *cache); } else { bool skinned = false; if (!window_flags.IsSet(Window::FlagNoDecoration)) if (skin.IsValid()) skinned = true; if (skinned) ComposeSkin(); cache->Fill(background_color.x, background_color.y, background_color.z, background_color.w); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void Window::Invalidate() { if (base_widget) base_widget->Invalidate(); if (title_widget) title_widget->Invalidate(); window_flags.Raise(FlagCacheDirty | FlagRenderDirty); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void Window::RenderSetup(Core::ResourceFactories *f) { if ((render_data = new Sprite::RenderData)) if (f && f->render) { render_data->texture = f->render->NewTexture(); render_data->texture->Create(NULL, (int)size.x, (int)size.y, Render::Texture::FormatRGBA8, Render::Texture::NoAA, Render::Texture::Usage(Render::Texture::IsRenderTarget | Render::Texture::IsShaderResource)); window_flags.Raise(FlagRenderDirty); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void Window::Render(Renderer &renderer, GPU::TriangleBatch *batch) { // Compose. bool has_title = !(window_flags.IsSet(Window::FlagNoTitleBar) || background_picture); if (base_widget) { base_widget->Refresh(); if (base_widget->IsDirty()) { Invalidate(); // Compose window skin. Compose(); // Compose window content. Rect compose_rect(GetRect()); if (has_title && skin) { compose_rect.sx = skin->top_left->GetWidth(); compose_rect.sy = skin->title_bottom + 4; compose_rect.ex -= skin->bottom_right->GetWidth(); compose_rect.ey -= skin->bottom_right->GetHeight(); } if (cache.IsValid()) base_widget->Compose(*cache, compose_rect); } } else if (window_flags.IsSet(FlagCacheDirty)) Compose(); // Compose the window title. if (has_title && skin) { iRect title_rect(skin->top_left->GetWidth(), skin->title_top, GetRect().GetWidth() - skin->top_right->GetWidth(), skin->title_bottom); if (cache.IsValid()) title_widget->Compose(*cache, title_rect); } if (window_flags.IsSet(FlagRenderDirty)) if (render_data.IsValid() && render_data->texture.IsValid()) { render_data->texture->Blit((const char *)cache->GetData(), cache->GetWidth(), cache->GetHeight()); window_flags.Remove(FlagRenderDirty); } Sprite::Render(renderer, batch); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void Window::SetSkin(WindowSkin *s) { if ((skin = s)) if (title_widget->GetType() == WidgetTypeText) if (TextWidget *t = (TextWidget *)title_widget.c_ptr()) { Color skin_color(skin->title_color); t->SetFont(s->title_font); t->SetFontColor(skin_color.x, skin_color.y, skin_color.z); t->SetFontSize(s->title_size); t->SetTextAlignment(TextState::Center); } Invalidate(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ Window::Window() { window_flags.Set(FlagCacheDirty); type = Type_Window; cache = new Picture; background_color.Set(0.f, 0.f, 0.f, 0.f); title_widget = new TextWidget(-1, "Window Title"); SetSize(320, 200); } //------------------------------------------------------------------------------