Added: Size attributes to img (width, height, max-width, max-height)

--HG--
branch : develop
This commit is contained in:
Nimetu 2015-12-08 21:53:54 +02:00
parent 1d00f974b6
commit 612125a243
2 changed files with 251 additions and 43 deletions

View file

@ -73,6 +73,33 @@ namespace NLGUI
}; };
static SWebOptions options; static SWebOptions options;
class CStyleParams
{
public:
CStyleParams () : TextColor(255,255,255,255)
{
FontSize=10;
FontWeight=400;
FontOblique=false;
Underlined=false;
StrikeThrough=false;
Width=-1;
Height=-1;
MaxWidth=-1;
MaxHeight=-1;
}
uint FontSize;
uint FontWeight;
bool FontOblique;
NLMISC::CRGBA TextColor;
bool Underlined;
bool StrikeThrough;
sint32 Width;
sint32 Height;
sint32 MaxWidth;
sint32 MaxHeight;
};
// Constructor // Constructor
CGroupHTML(const TCtorParam &param); CGroupHTML(const TCtorParam &param);
@ -311,7 +338,7 @@ namespace NLGUI
void addString(const ucstring &str); void addString(const ucstring &str);
// Add an image in the current paragraph // Add an image in the current paragraph
void addImage(const char *image, bool globalColor, bool reloadImg=false); void addImage(const char *image, bool globalColor, bool reloadImg=false, const CStyleParams &style = CStyleParams());
// Add a text area in the current paragraph // Add a text area in the current paragraph
CInterfaceGroup *addTextArea (const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content, uint maxlength); CInterfaceGroup *addTextArea (const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content, uint maxlength);
@ -321,7 +348,8 @@ namespace NLGUI
// Add a button in the current paragraph. actionHandler, actionHandlerParams and tooltip can be NULL. // Add a button in the current paragraph. actionHandler, actionHandlerParams and tooltip can be NULL.
CCtrlButton *addButton(CCtrlButton::EType type, const std::string &name, const std::string &normalBitmap, const std::string &pushedBitmap, CCtrlButton *addButton(CCtrlButton::EType type, const std::string &name, const std::string &normalBitmap, const std::string &pushedBitmap,
const std::string &overBitmap, bool useGlobalColor, const char *actionHandler, const char *actionHandlerParams, const char *tooltip); const std::string &overBitmap, bool useGlobalColor, const char *actionHandler, const char *actionHandlerParams, const char *tooltip,
const CStyleParams &style = CStyleParams());
// Set the background color // Set the background color
void setBackgroundColor (const NLMISC::CRGBA &bgcolor); void setBackgroundColor (const NLMISC::CRGBA &bgcolor);
@ -625,26 +653,6 @@ namespace NLGUI
}; };
std::vector<CCellParams> _CellParams; std::vector<CCellParams> _CellParams;
class CStyleParams
{
public:
CStyleParams () : TextColor(255,255,255,255)
{
FontSize=10;
FontWeight=400;
FontOblique=false;
Underlined=false;
StrikeThrough=false;
}
uint FontSize;
uint FontWeight;
bool FontOblique;
NLMISC::CRGBA TextColor;
bool Underlined;
bool StrikeThrough;
};
// Indentation // Indentation
uint _Indent; uint _Indent;
@ -719,6 +727,7 @@ namespace NLGUI
// read style attribute // read style attribute
void getStyleParams(const std::string &styleString, CStyleParams &style, bool inherit = true); void getStyleParams(const std::string &styleString, CStyleParams &style, bool inherit = true);
void applyCssMinMax(sint32 &width, sint32 &height, sint32 minw=0, sint32 minh=0, sint32 maxw=0, sint32 maxh=0);
// load and render local html file (from bnp for example) // load and render local html file (from bnp for example)
void doBrowseLocalFile(const std::string &filename); void doBrowseLocalFile(const std::string &filename);
@ -738,13 +747,24 @@ namespace NLGUI
// ImageDownload system // ImageDownload system
enum TDataType {ImgType= 0, BnpType}; enum TDataType {ImgType= 0, BnpType};
struct CDataImageDownload
{
public:
CDataImageDownload(CViewBase *img, CStyleParams style): Image(img), Style(style)
{
}
public:
CViewBase * Image;
CStyleParams Style;
};
struct CDataDownload struct CDataDownload
{ {
public: public:
CDataDownload(CURL *c, const std::string &u, const std::string &d, FILE *f, TDataType t, CViewBase *i, const std::string &s, const std::string &m) : curl(c), url(u), dest(d), luaScript(s), md5sum(m), type(t), fp(f) CDataDownload(CURL *c, const std::string &u, const std::string &d, FILE *f, TDataType t, CViewBase *i, const std::string &s, const std::string &m, const CStyleParams &style = CStyleParams()) : curl(c), url(u), dest(d), luaScript(s), md5sum(m), type(t), fp(f)
{ {
if (t == ImgType) imgs.push_back(i); if (t == ImgType) imgs.push_back(CDataImageDownload(i, style));
} }
public: public:
@ -755,7 +775,7 @@ namespace NLGUI
std::string md5sum; std::string md5sum;
TDataType type; TDataType type;
FILE *fp; FILE *fp;
std::vector<CViewBase *> imgs; std::vector<CDataImageDownload> imgs;
}; };
std::vector<CDataDownload> Curls; std::vector<CDataDownload> Curls;
@ -764,12 +784,13 @@ namespace NLGUI
void initImageDownload(); void initImageDownload();
void checkImageDownload(); void checkImageDownload();
void addImageDownload(const std::string &url, CViewBase *img); void addImageDownload(const std::string &url, CViewBase *img, const CStyleParams &style = CStyleParams());
std::string localImageName(const std::string &url); std::string localImageName(const std::string &url);
std::string getAbsoluteUrl(const std::string &url); std::string getAbsoluteUrl(const std::string &url);
bool isTrustedDomain(const std::string &domain); bool isTrustedDomain(const std::string &domain);
void setImage(CViewBase *view, const std::string &file); void setImage(CViewBase *view, const std::string &file);
void setImageSize(CViewBase *view, const CStyleParams &style = CStyleParams());
// BnpDownload system // BnpDownload system
void initBnpDownload(); void initBnpDownload();

View file

@ -126,6 +126,7 @@ namespace NLGUI
return it != options.trustedDomains.end(); return it != options.trustedDomains.end();
} }
// Update view after download has finished
void CGroupHTML::setImage(CViewBase * view, const string &file) void CGroupHTML::setImage(CViewBase * view, const string &file)
{ {
CCtrlButton *btn = dynamic_cast<CCtrlButton*>(view); CCtrlButton *btn = dynamic_cast<CCtrlButton*>(view);
@ -166,7 +167,90 @@ namespace NLGUI
} }
} }
} }
// Force image width, height
void CGroupHTML::setImageSize(CViewBase *view, const CStyleParams &style)
{
sint32 width = style.Width;
sint32 height = style.Height;
sint32 maxw = style.MaxWidth;
sint32 maxh = style.MaxHeight;
sint32 imageWidth, imageHeight;
bool changed = true;
// get image texture size
// if image is being downloaded, then correct size is set after thats done
CCtrlButton *btn = dynamic_cast<CCtrlButton*>(view);
if(btn)
{
btn->fitTexture();
imageWidth = btn->getW(false);
imageHeight = btn->getH(false);
}
else
{
CViewBitmap *btm = dynamic_cast<CViewBitmap*>(view);
if(btm)
{
btm->fitTexture();
imageWidth = btm->getW(false);
imageHeight = btm->getH(false);
}
else
{
// not supported
return;
}
}
// if width/height is not requested, then use image size
// else recalculate missing value, keep image ratio
if (width == -1 && height == -1)
{
width = imageWidth;
height = imageHeight;
changed = false;
}
else
if (width == -1 || height == -1) {
float ratio = (float) imageWidth / std::max(1, imageHeight);
if (width == -1)
width = height * ratio;
else
height = width / ratio;
}
// apply max-width, max-height rules if asked
if (maxw > -1 || maxh > -1)
{
applyCssMinMax(width, height, 0, 0, maxw, maxh);
changed = true;
}
if (changed)
{
CCtrlButton *btn = dynamic_cast<CCtrlButton*>(view);
if(btn)
{
btn->setScale(true);
btn->setW(width);
btn->setH(height);
}
else
{
CViewBitmap *image = dynamic_cast<CViewBitmap*>(view);
if(image)
{
image->setScale(true);
image->setW(width);
image->setH(height);
}
}
}
}
// Get an url and return the local filename with the path where the url image should be // Get an url and return the local filename with the path where the url image should be
string CGroupHTML::localImageName(const string &url) string CGroupHTML::localImageName(const string &url)
{ {
@ -177,7 +261,7 @@ namespace NLGUI
} }
// Add a image download request in the multi_curl // Add a image download request in the multi_curl
void CGroupHTML::addImageDownload(const string &url, CViewBase *img) void CGroupHTML::addImageDownload(const string &url, CViewBase *img, const CStyleParams &style)
{ {
string finalUrl = getAbsoluteUrl(url); string finalUrl = getAbsoluteUrl(url);
@ -189,7 +273,7 @@ namespace NLGUI
#ifdef LOG_DL #ifdef LOG_DL
nlwarning("already downloading '%s' img %p", finalUrl.c_str(), img); nlwarning("already downloading '%s' img %p", finalUrl.c_str(), img);
#endif #endif
Curls[i].imgs.push_back(img); Curls[i].imgs.push_back(CDataImageDownload(img, style));
return; return;
} }
} }
@ -234,7 +318,7 @@ namespace NLGUI
curl_easy_setopt(curl, CURLOPT_FILE, fp); curl_easy_setopt(curl, CURLOPT_FILE, fp);
curl_multi_add_handle(MultiCurl, curl); curl_multi_add_handle(MultiCurl, curl);
Curls.push_back(CDataDownload(curl, finalUrl, dest, fp, ImgType, img, "", "")); Curls.push_back(CDataDownload(curl, finalUrl, dest, fp, ImgType, img, "", "", style));
#ifdef LOG_DL #ifdef LOG_DL
nlwarning("adding handle %x, %d curls", curl, Curls.size()); nlwarning("adding handle %x, %d curls", curl, Curls.size());
#endif #endif
@ -243,6 +327,7 @@ namespace NLGUI
else else
{ {
setImage(img, dest); setImage(img, dest);
setImageSize(img, style);
} }
} }
@ -499,7 +584,8 @@ namespace NLGUI
{ {
for(uint i = 0; i < it->imgs.size(); i++) for(uint i = 0; i < it->imgs.size(); i++)
{ {
setImage(it->imgs[i], it->dest); setImage(it->imgs[i].Image, it->dest);
setImageSize(it->imgs[i].Image, it->imgs[i].Style);
} }
} }
} }
@ -1272,6 +1358,17 @@ namespace NLGUI
// Get the string name // Get the string name
if (present[MY_HTML_IMG_SRC] && value[MY_HTML_IMG_SRC]) if (present[MY_HTML_IMG_SRC] && value[MY_HTML_IMG_SRC])
{ {
CStyleParams style;
float tmpf;
if (present[MY_HTML_IMG_WIDTH] && value[MY_HTML_IMG_WIDTH])
getPercentage(style.Width, tmpf, value[MY_HTML_IMG_WIDTH]);
if (present[MY_HTML_IMG_HEIGHT] && value[MY_HTML_IMG_HEIGHT])
getPercentage(style.Height, tmpf, value[MY_HTML_IMG_HEIGHT]);
// width, height from inline css
if (present[MY_HTML_IMG_STYLE] && value[MY_HTML_IMG_STYLE])
getStyleParams(value[MY_HTML_IMG_STYLE], style);
// Get the global color name // Get the global color name
bool globalColor = false; bool globalColor = false;
if (present[MY_HTML_IMG_GLOBAL_COLOR]) if (present[MY_HTML_IMG_GLOBAL_COLOR])
@ -1286,20 +1383,20 @@ namespace NLGUI
string params = "name=" + getId() + "|url=" + getLink (); string params = "name=" + getId() + "|url=" + getLink ();
addButton(CCtrlButton::PushButton, value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC], addButton(CCtrlButton::PushButton, value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC],
"", globalColor, "browse", params.c_str(), tooltip); "", globalColor, "browse", params.c_str(), tooltip, style);
} }
else else
{ {
// Get the option to reload (class==reload) // Get the option to reload (class==reload)
bool reloadImg = false; bool reloadImg = false;
string style; string styleString;
if (present[MY_HTML_IMG_STYLE] && value[MY_HTML_IMG_STYLE]) if (present[MY_HTML_IMG_STYLE] && value[MY_HTML_IMG_STYLE])
style = value[MY_HTML_IMG_STYLE]; styleString = value[MY_HTML_IMG_STYLE];
if (!style.empty()) if (!styleString.empty())
{ {
TStyle styles = parseStyle(style); TStyle styles = parseStyle(styleString);
TStyle::iterator it; TStyle::iterator it;
it = styles.find("reload"); it = styles.find("reload");
@ -1307,7 +1404,7 @@ namespace NLGUI
reloadImg = true; reloadImg = true;
} }
addImage (value[MY_HTML_IMG_SRC], globalColor, reloadImg); addImage (value[MY_HTML_IMG_SRC], globalColor, reloadImg, style);
} }
} }
} }
@ -1346,6 +1443,11 @@ namespace NLGUI
string type = toLower(value[MY_HTML_INPUT_TYPE]); string type = toLower(value[MY_HTML_INPUT_TYPE]);
if (type == "image") if (type == "image")
{ {
CStyleParams style;
// width, height from inline css
if (present[MY_HTML_INPUT_STYLE] && value[MY_HTML_INPUT_STYLE])
getStyleParams(value[MY_HTML_INPUT_STYLE], style);
// The submit button // The submit button
string name; string name;
string normal; string normal;
@ -1361,7 +1463,7 @@ namespace NLGUI
// Add the ctrl button // Add the ctrl button
addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over, addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
globalColor, "html_submit_form", param.c_str(), tooltip); globalColor, "html_submit_form", param.c_str(), tooltip, style);
} }
if (type == "button" || type == "submit") if (type == "button" || type == "submit")
{ {
@ -3569,7 +3671,7 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
void CGroupHTML::addImage(const char *img, bool globalColor, bool reloadImg) void CGroupHTML::addImage(const char *img, bool globalColor, bool reloadImg, const CStyleParams &style)
{ {
// In a paragraph ? // In a paragraph ?
if (!_Paragraph) if (!_Paragraph)
@ -3615,14 +3717,16 @@ namespace NLGUI
// 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache // 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache
// //
image = "web_del.tga"; image = "web_del.tga";
addImageDownload(img, newImage); addImageDownload(img, newImage, style);
} }
} }
newImage->setTexture (image); newImage->setTexture (image);
newImage->setModulateGlobalColor(globalColor); newImage->setModulateGlobalColor(globalColor);
getParagraph()->addChild(newImage); getParagraph()->addChild(newImage);
paragraphChange (); paragraphChange ();
setImageSize(newImage, style);
} }
// *************************************************************************** // ***************************************************************************
@ -3720,7 +3824,7 @@ namespace NLGUI
CCtrlButton *CGroupHTML::addButton(CCtrlButton::EType type, const std::string &/* name */, const std::string &normalBitmap, const std::string &pushedBitmap, CCtrlButton *CGroupHTML::addButton(CCtrlButton::EType type, const std::string &/* name */, const std::string &normalBitmap, const std::string &pushedBitmap,
const std::string &overBitmap, bool useGlobalColor, const char *actionHandler, const char *actionHandlerParams, const std::string &overBitmap, bool useGlobalColor, const char *actionHandler, const char *actionHandlerParams,
const char *tooltip) const char *tooltip, const CStyleParams &style)
{ {
// In a paragraph ? // In a paragraph ?
if (!_Paragraph) if (!_Paragraph)
@ -3748,7 +3852,7 @@ namespace NLGUI
if(!CFile::fileExists(normal)) if(!CFile::fileExists(normal))
{ {
normal = "web_del.tga"; normal = "web_del.tga";
addImageDownload(normalBitmap, ctrlButton); addImageDownload(normalBitmap, ctrlButton, style);
} }
} }
} }
@ -3803,6 +3907,8 @@ namespace NLGUI
getParagraph()->addChild (ctrlButton); getParagraph()->addChild (ctrlButton);
paragraphChange (); paragraphChange ();
setImageSize(ctrlButton, style);
return ctrlButton; return ctrlButton;
} }
@ -5116,6 +5222,7 @@ namespace NLGUI
// style.StrikeThrough; // text-decoration: line-through; text-decoration-line: line-through; // style.StrikeThrough; // text-decoration: line-through; text-decoration-line: line-through;
void CGroupHTML::getStyleParams(const std::string &styleString, CStyleParams &style, bool inherit) void CGroupHTML::getStyleParams(const std::string &styleString, CStyleParams &style, bool inherit)
{ {
float tmpf;
TStyle styles = parseStyle(styleString); TStyle styles = parseStyle(styleString);
TStyle::iterator it; TStyle::iterator it;
for (it=styles.begin(); it != styles.end(); ++it) for (it=styles.begin(); it != styles.end(); ++it)
@ -5179,6 +5286,18 @@ namespace NLGUI
style.Underlined = (prop.find("underline") != std::string::npos); style.Underlined = (prop.find("underline") != std::string::npos);
style.StrikeThrough = (prop.find("line-through") != std::string::npos); style.StrikeThrough = (prop.find("line-through") != std::string::npos);
} }
else
if (it->first == "width")
getPercentage(style.Width, tmpf, it->second.c_str());
else
if (it->first == "height")
getPercentage(style.Height, tmpf, it->second.c_str());
else
if (it->first == "max-width")
getPercentage(style.MaxWidth, tmpf, it->second.c_str());
else
if (it->first == "max-height")
getPercentage(style.MaxHeight, tmpf, it->second.c_str());
} }
if (inherit) if (inherit)
{ {
@ -5187,6 +5306,74 @@ namespace NLGUI
} }
} }
// ***************************************************************************
void CGroupHTML::applyCssMinMax(sint32 &width, sint32 &height, sint32 minw, sint32 minh, sint32 maxw, sint32 maxh)
{
if (maxw <= 0) maxw = width;
if (maxh <= 0) maxh = height;
maxw = std::max(minw, maxw);
maxh = std::max(minh, maxh);
float ratio = (float) width / std::max(1, height);
if (width > maxw)
{
width = maxw;
height = std::max((sint32)(maxw /ratio), minh);
}
if (width < minw)
{
width = minw;
height = std::min((sint32)(minw / ratio), maxh);
}
if (height > maxh)
{
width = std::max((sint32)(maxh * ratio), minw);
height = maxh;
}
if (height < minh)
{
width = std::min((sint32)(minh * ratio), maxw);
height = minh;
}
if (width > maxw && height > maxh)
{
if (maxw/width <= maxh/height)
{
width = maxw;
height = std::max(minh, (sint32)(maxw / ratio));
}
else
{
width = std::max(minw, (sint32)(maxh * ratio));
height = maxh;
}
}
if (width < minw && height < minh)
{
if (minw / width <= minh / height)
{
width = std::min(maxw, (sint32)(minh * ratio));
height = minh;
}
else
{
width = minw;
height = std::min(maxh, (sint32)(minw / ratio));
}
}
if (width < minw && height > maxh)
{
width = minw;
height = maxh;
}
if (width > maxw && height < minh)
{
width = maxw;
height = minh;
}
}
// *************************************************************************** // ***************************************************************************
size_t CGroupHTML::curlHeaderCallback(char *buffer, size_t size, size_t nmemb, void *pCCurlWWWData) size_t CGroupHTML::curlHeaderCallback(char *buffer, size_t size, size_t nmemb, void *pCCurlWWWData)
{ {