/************************************************************************* * sbTheme.cpp - visual style * * author: Konstantin Maslyuk "Kalemas" mailto:kalemas@mail.ru * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. ************************************************************************/ #include "sbTheme.h" #include "platform\xmlParser.h" #pragma warning(disable : 4018) #pragma warning(disable : 4244) sbTheme * Theme; sbTheme::sbTheme (sbRect screenArea) : rect (screenArea) { // TODO handle global Theme variable here, reinit Theme by new sbTheme XMLNode xml = XMLNode::openFileHelper(".\\theme.xml"); size = min(rect.height(), rect.width()); fadeSurface = false; ItemSubTextColor = sbColor(xml.getChildNodeByPath("List/Item/SubText").getAttribute("color","909090FF")); ItemMenuTextColor = sbColor(xml.getChildNodeByPath("Menu/Text" ).getAttribute("color","FFFFFFFF")); SelectionFrameColor = sbColor(xml.getChildNodeByPath("Selection" ).getAttribute("color","FFE020FF")); FadingColor = sbColor(xml.getChildNodeByPath("Background/Fade" ).getAttribute("color","00000060")); ItemStrongColor = sbColor(xml.getChildNodeByPath("List/Item/Text" ).getAttribute("colorStrong","22007760")); ItemMorphColor = sbColor(xml.getChildNodeByPath("List/Item/Text" ).getAttribute("colorMorph","00553360")); ItemRedColor = sbColor(xml.getChildNodeByPath("List/Item/Text" ).getAttribute("colorRed","FFDD0060")); itemMargins.top = size*atof(xml.getChildNodeByPath("List/Item/Margins").getAttribute("top", "0.01")); itemMargins.left = size*atof(xml.getChildNodeByPath("List/Item/Margins").getAttribute("left", "0.1")); itemMargins.bottom = size*atof(xml.getChildNodeByPath("List/Item/Margins").getAttribute("bottom","0.02")); itemMargins.right = size*atof(xml.getChildNodeByPath("List/Item/Margins").getAttribute("right", "0.1")); ListSeparatorHeight = size*atof(xml.getChildNodeByPath("List/Separator").getAttribute("height","0.008")); BannerBorderSize = size*atof(xml.getChildNodeByPath("List/Banner" ).getAttribute("border","0.03")); PanelSize = size*atof(xml.getChildNodeByPath("Panel" ).getAttribute("size","0.15")); SelectionFrameWidth = size*atof(xml.getChildNodeByPath("Selection" ).getAttribute("width","0.012")); for (int i=0; i"); else if (i == ELEMENT::ITEM_SEPARATOR) e = xml.getChildNodeByPath("List/ItemSeparator/e", ""); else if (i == ELEMENT::ITEM_HIGHLIGHTED) e = xml.getChildNodeByPath("List/ItemHighlighted/e",""); else if (i == ELEMENT::SEPARATOR) e = xml.getChildNodeByPath("List/Separator/e", ""); else if (i == ELEMENT::BACKGROUND) e = xml.getChildNodeByPath("Background/e", ""); else if (i == ELEMENT::MENU) e = xml.getChildNodeByPath("Menu/Button/e", ""); else if (i == ELEMENT::ANOTHER_MENU) e = xml.getChildNodeByPath("Menu/Another/e", ""); else if (i == ELEMENT::PANEL) e = xml.getChildNodeByPath("Panel/e", ""); else if (i == ELEMENT::PANEL_PRESSED) e = xml.getChildNodeByPath("Panel/Pressed/e", ""); else if (i == ELEMENT::TAPPED) e = xml.getChildNodeByPath("Mouse/LongPress/e", ""); else if (i == ELEMENT::BANNER) e = xml.getChildNodeByPath("List/Banner/e", ""); else sbAssert ( true ); if (e.getAttribute("gradient") != NULL && !strcmp(e.getAttribute("gradient"),"1")) elements[i].gradient = true; else elements[i].gradient = false; if (e.getAttribute("vertical") != NULL && !strcmp(e.getAttribute("vertical"),"1")) elements[i].vertical = true; else elements[i].vertical = false; if (e.getAttribute("textColor") != NULL) elements[i].textColor = sbColor (e.getAttribute("textColor","FF0000FF")); for (int p = 0; p < e.nChildNode("s"); p++) { XMLNode n = e.getChildNode("s",p); sbColor color (n.getAttribute("c","000000FF")); int pos = 1000*p/max(e.nChildNode("s")-(elements[i].gradient ? 1 : 0),1); if (n.getAttribute("p") != NULL) pos = atoi(n.getAttribute("p")); elements[i].fill.push_back(std::pair(color,pos)); } } const char * cfont = xml.getChildNodeByPath("List/Item/Text").getAttribute("face","Tahoma"); TCHAR * tfont = new TCHAR [strlen(cfont)+1]; for (int i = 0; i <= strlen ( cfont ); i++) tfont [i] = cfont[i]; styles[STYLE::TEXT].size = size*(atof(xml.getChildNodeByPath("List/Item/Text").getAttribute("fontSize","0.08"))); styles[STYLE::TEXT].font = sbMakeFont(styles[STYLE::TEXT].size, tfont, false, false); styles[STYLE::TEXT_ITALIC].size = styles[STYLE::TEXT].size; styles[STYLE::TEXT_ITALIC].font = sbMakeFont(styles[STYLE::TEXT_ITALIC].size, tfont, false, true); styles[STYLE::BUTTON].size = size*(atof(xml.getChildNodeByPath("Menu").getAttribute("fontSize","0.093"))); styles[STYLE::BUTTON].font = sbMakeFont(styles[STYLE::BUTTON].size, tfont, true, false); styles[STYLE::BUTTON_SMALL].size = styles[STYLE::BUTTON].size*2/3; styles[STYLE::BUTTON_SMALL].font = sbMakeFont(styles[STYLE::BUTTON_SMALL].size, tfont, true, false); styles[STYLE::STANZA].size = size*(atof(xml.getChildNodeByPath("List/Item/SubText").getAttribute("fontSize","0.06"))); styles[STYLE::STANZA].font = sbMakeFont(styles[STYLE::STANZA].size, tfont, true, false); styles[STYLE::DESCRIPTION].size = styles[STYLE::TEXT].size*2/3; styles[STYLE::DESCRIPTION].font = sbMakeFont(styles[STYLE::DESCRIPTION].size, tfont, false, false); styles[STYLE::CAPTION].size = styles[STYLE::TEXT].size/2*3; styles[STYLE::CAPTION].font = sbMakeFont(styles[STYLE::CAPTION].size, tfont, true, false); styles[STYLE::TEXT_UNDER].size = size*(atof(xml.getChildNodeByPath("List/Item/Text").getAttribute("textUnderSize","0.036"))); styles[STYLE::TEXT_UNDER].font = sbMakeFont(styles[STYLE::TEXT_UNDER].size, tfont, true, false); styles[STYLE::TEXT_FOOTNOTE].size = size*(atof(xml.getChildNodeByPath("List/Item/Text").getAttribute("textFootnoteSize","0.05"))); styles[STYLE::TEXT_FOOTNOTE].font = sbMakeFont(styles[STYLE::STANZA].TEXT_FOOTNOTE,tfont, true, false); delete [] tfont; } sbTheme::~sbTheme() { for (int i=0; i < STYLE::COUNT; i++) sbDeleteFont (styles[i].font); } void sbTheme::drawElement ( sbSurface rc , const sbRect * rect , sbTheme::ELEMENT::TYPE type ) const { for (int i = 0; i < elements[type].fill.size(); i++) { sbColor start = elements[type].fill[i].first; sbColor end = elements[type].fill.size()-1 == i ? start : elements[type].fill[i+1].first; sbRect fill = *rect; if (start.alpha == 0 && (elements[type].gradient == false || end.alpha == 0)) continue; if (elements[type].vertical) { fill.top = fill.height()*elements[type].fill[i].second/1000+fill.top; fill.bottom = (elements[type].fill.size()-1 == i ? fill.height() : fill.height()*elements[type].fill[i+1].second/1000)+fill.top; } else { fill.left = fill.width()*elements[type].fill[i].second/1000+fill.left; fill.right = (elements[type].fill.size()-1 == i ? fill.width() : fill.width()*elements[type].fill[i+1].second/1000)+fill.left; } start = fadeColor ( start, fill.left, fill.top ); end = fadeColor ( end, fill.right, fill.bottom ); if (elements[type].gradient) sbDrawGradient ( rc, &fill, start, end, elements[type].vertical ); else sbFillRect ( rc, &fill, start ); } } sbColor sbTheme::fadeColor ( const sbColor & color , int x , int y ) const { sbColor newColor = color; if ( color.alpha < 255 ) { if (elements[sbTheme::ELEMENT::BACKGROUND].fill.size() == 2) { unsigned char r1 = elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first.red; unsigned char g1 = elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first.green; unsigned char b1 = elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first.blue; unsigned char r2 = elements[sbTheme::ELEMENT::BACKGROUND].fill[1].first.red; unsigned char g2 = elements[sbTheme::ELEMENT::BACKGROUND].fill[1].first.green; unsigned char b2 = elements[sbTheme::ELEMENT::BACKGROUND].fill[1].first.blue; int v = min(1000,((y-rect.top)*1000)/rect.height()); sbColor backColor (r1+((r2-r1)*v/1000),g1+((g2-g1)*v/1000),b1+((b2-b1)*v/1000)); newColor.red = backColor.red + (color.red - backColor.red) * color.alpha / 255; newColor.green = backColor.green + (color.green - backColor.green) * color.alpha / 255; newColor.blue = backColor.blue + (color.blue - backColor.blue) * color.alpha / 255; } else { newColor.red = color.red + (elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first.red - color.red) * (255-color.alpha) / 255; newColor.green = color.green + (elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first.green - color.green) * (255-color.alpha) / 255; newColor.blue = color.blue + (elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first.blue - color.blue) * (255-color.alpha) / 255; } } // TODO move fadeSurface to sbTheme if (fadeSurface) { newColor.red = FadingColor.red + ((newColor.red - FadingColor.red) * FadingColor.alpha / 255); newColor.green = FadingColor.green + ((newColor.green - FadingColor.green) * FadingColor.alpha / 255); newColor.blue = FadingColor.blue + ((newColor.blue - FadingColor.blue) * FadingColor.alpha / 255); } return newColor; } void sbTheme::drawFrame( sbSurface surface , const sbRect * rect ) const { int x1 = rect->left, y1 = rect->top, x2 = rect->right, y2 = rect->bottom, round = size*0.04f; sbColor color = fadeColor(SelectionFrameColor,x1,y1); // TODO made inside for-cycle sbDrawLine(surface, sbPoint(x1+round,y1), sbPoint(x2-round,y1),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x2-round,y1), sbPoint(x2-(round/3),y1+(round/3)),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x2-(round/3),y1+(round/3)), sbPoint(x2,y1+round),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x2,y1+round), sbPoint(x2,y2-round),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x2,y2-round), sbPoint(x2-(round/3),y2-(round/3)),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x2-(round/3),y2-(round/3)), sbPoint(x2-round,y2),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x2-round,y2), sbPoint(x1+round,y2),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x1+round,y2), sbPoint(x1+(round/3),y2-(round/3)),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x1+(round/3),y2-(round/3)), sbPoint(x1,y2-round),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x1,y2-round), sbPoint(x1,y1+round),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x1,y1+round), sbPoint(x1+(round/3),y1+(round/3)),color,SelectionFrameWidth); sbDrawLine(surface, sbPoint(x1+(round/3),y1+(round/3)), sbPoint(x1+round,y1),color,SelectionFrameWidth); }