added printf function for <drawtext>

This commit is contained in:
louis 2014-11-01 13:03:52 +01:00
parent 13817c785f
commit f9f2c47cb2
5 changed files with 99 additions and 5 deletions

View File

@ -48,5 +48,6 @@ Version 0.0.3
- added "active" Token for cutting marks so that a mark can be displayed in a dedicated way if current position - added "active" Token for cutting marks so that a mark can be displayed in a dedicated way if current position
in replay exactly hits the mark in replay exactly hits the mark
- added {channelname}, {channelid}, {channellogoexists} for all schedules list and current views - added {channelname}, {channelid}, {channellogoexists} for all schedules list and current views
- added printf function for <drawtext>, see Wiki for documentation

View File

@ -83,13 +83,15 @@ public:
enum eTextTokenType { enum eTextTokenType {
ttConstString, ttConstString,
ttToken, ttToken,
ttConditionalToken ttConditionalToken,
ttPrintfToken
}; };
class cTextToken { class cTextToken {
public: public:
eTextTokenType type; eTextTokenType type;
string value; string value;
vector<string> parameters;
vector<cTextToken> subTokens; vector<cTextToken> subTokens;
}; };

View File

@ -844,7 +844,9 @@ bool cTemplateFunction::SetTextTokens(string value) {
//search for conditional token or normal token //search for conditional token or normal token
size_t tokenStart = value.find_first_of('{'); size_t tokenStart = value.find_first_of('{');
size_t conditionStart = value.find_first_of('|'); size_t conditionStart = value.find_first_of('|');
size_t printfStart = value.find("{printf(");
if (tokenStart == string::npos && conditionStart == string::npos) { if (tokenStart == string::npos && conditionStart == string::npos) {
//find constant strings
if (value.size() > 0) { if (value.size() > 0) {
cTextToken token; cTextToken token;
token.type = ttConstString; token.type = ttConstString;
@ -855,12 +857,25 @@ bool cTemplateFunction::SetTextTokens(string value) {
continue; continue;
} else if (tokenStart != string::npos && conditionStart == string::npos) { } else if (tokenStart != string::npos && conditionStart == string::npos) {
size_t tokenEnd = value.find_first_of('}'); size_t tokenEnd = value.find_first_of('}');
ParseTextToken(value, tokenStart, tokenEnd); if (printfStart != string::npos && printfStart <= tokenStart) {
//replace printf text token
ParsePrintfTextToken(value, printfStart, tokenEnd);
} else {
//replace normal text token
ParseTextToken(value, tokenStart, tokenEnd);
}
} else if (tokenStart != string::npos && conditionStart != string::npos) { } else if (tokenStart != string::npos && conditionStart != string::npos) {
if (tokenStart < conditionStart) { if (tokenStart < conditionStart) {
size_t tokenEnd = value.find_first_of('}'); size_t tokenEnd = value.find_first_of('}');
ParseTextToken(value, tokenStart, tokenEnd); if (printfStart != string::npos && printfStart <= tokenStart) {
//replace printf text token
ParsePrintfTextToken(value, printfStart, tokenEnd);
} else {
//replace normal text token
ParseTextToken(value, tokenStart, tokenEnd);
}
} else { } else {
//replace conditional text token
size_t conditionEnd = value.find_first_of('|', conditionStart+1); size_t conditionEnd = value.find_first_of('|', conditionStart+1);
ParseConditionalTextToken(value, conditionStart, conditionEnd); ParseConditionalTextToken(value, conditionStart, conditionEnd);
} }
@ -931,6 +946,26 @@ void cTemplateFunction::ParseConditionalTextToken(string &value, size_t start, s
} }
void cTemplateFunction::ParsePrintfTextToken(string &value, size_t start, size_t end) {
cTextToken token;
token.type = ttPrintfToken;
//fetch parameter list from printf
string printfParams = value.substr(start + 8, end - start - 9);
value = value.replace(0, end - start + 1, "");
splitstring s(printfParams.c_str());
vector<string> flds = s.split(',', 1);
int numParams = flds.size();
if (numParams < 1)
return;
string formatString = trim(flds[0]);
token.value = formatString.substr(1, formatString.size() - 2);
for (int i=1; i < numParams; i++) {
token.parameters.push_back(trim(flds[i]));
}
textTokens.push_back(token);
}
bool cTemplateFunction::SetScrollMode(string value) { bool cTemplateFunction::SetScrollMode(string value) {
eScrollMode mode = smNone; eScrollMode mode = smNone;
bool ok = true; bool ok = true;
@ -1063,6 +1098,45 @@ void cTemplateFunction::ParseStringParameters(void) {
found = true; found = true;
} }
} }
} else if ((*it).type == ttPrintfToken) {
cTextToken token = *it;
int paramCount = token.parameters.size();
string printfResult = "";
switch (paramCount) {
case 1: {
int param1 = ReplaceIntToken(token.parameters[0]);
printfResult = *cString::sprintf(token.value.c_str(), param1);
break; }
case 2: {
int param1 = ReplaceIntToken(token.parameters[0]);
int param2 = ReplaceIntToken(token.parameters[1]);
printfResult = *cString::sprintf(token.value.c_str(), param1, param2);
break; }
case 3: {
int param1 = ReplaceIntToken(token.parameters[0]);
int param2 = ReplaceIntToken(token.parameters[1]);
int param3 = ReplaceIntToken(token.parameters[2]);
printfResult = *cString::sprintf(token.value.c_str(), param1, param2, param3);
break; }
case 4: {
int param1 = ReplaceIntToken(token.parameters[0]);
int param2 = ReplaceIntToken(token.parameters[1]);
int param3 = ReplaceIntToken(token.parameters[2]);
int param4 = ReplaceIntToken(token.parameters[3]);
printfResult = *cString::sprintf(token.value.c_str(), param1, param2, param3, param4);
break; }
case 5: {
int param1 = ReplaceIntToken(token.parameters[0]);
int param2 = ReplaceIntToken(token.parameters[1]);
int param3 = ReplaceIntToken(token.parameters[2]);
int param4 = ReplaceIntToken(token.parameters[3]);
int param5 = ReplaceIntToken(token.parameters[4]);
printfResult = *cString::sprintf(token.value.c_str(), param1, param2, param3, param4, param5);
break; }
default:
break;
}
text << printfResult;
} }
} }
parsedText = text.str(); parsedText = text.str();
@ -1239,6 +1313,21 @@ int cTemplateFunction::CalculateTextBoxHeight(void) {
return ((textLinesTall+textLinesFull) * fontHeight); return ((textLinesTall+textLinesFull) * fontHeight);
} }
int cTemplateFunction::ReplaceIntToken(string intTok) {
if (intTokens) {
map<string,int>::iterator hit = intTokens->find(intTok);
if (hit != intTokens->end())
return hit->second;
}
if (stringTokens) {
map<string,string>::iterator hit = stringTokens->find(intTok);
if (hit != stringTokens->end()) {
return atoi(hit->second.c_str());
}
}
return 0;
}
/******************************************************************* /*******************************************************************
* Helper Functions * Helper Functions
*******************************************************************/ *******************************************************************/

View File

@ -143,6 +143,7 @@ protected:
bool SetTextTokens(string value); bool SetTextTokens(string value);
void ParseTextToken(string &value, size_t start, size_t end); void ParseTextToken(string &value, size_t start, size_t end);
void ParseConditionalTextToken(string &value, size_t start, size_t end); void ParseConditionalTextToken(string &value, size_t start, size_t end);
void ParsePrintfTextToken(string &value, size_t start, size_t end);
bool SetScrollMode(string value); bool SetScrollMode(string value);
bool SetScrollSpeed(string value); bool SetScrollSpeed(string value);
bool SetOrientation(string value); bool SetOrientation(string value);
@ -152,6 +153,7 @@ protected:
void ParseNumericalParameters(void); void ParseNumericalParameters(void);
void CalculateAlign(int elementWidth, int elementHeight); void CalculateAlign(int elementWidth, int elementHeight);
int CalculateTextBoxHeight(void); int CalculateTextBoxHeight(void);
int ReplaceIntToken(string intTok);
public: public:
cTemplateFunction(eFuncType type); cTemplateFunction(eFuncType type);
virtual ~cTemplateFunction(void); virtual ~cTemplateFunction(void);

View File

@ -3,7 +3,7 @@
<!-- Available Variables recordings menu listelement: <!-- Available Variables recordings menu listelement:
{nummenuitem} number of item in list, starts with 1 {nummenuitem} number of item in list, starts with 1
{name} Name of recording {name} Name of recording
{date} Date of recording {date} Date of recording (day dd.mm.yyyy)
{time} Time of recording {time} Time of recording
{daynumeric} day as number {daynumeric} day as number
{month} month as number {month} month as number
@ -39,7 +39,7 @@
</area> </area>
<!-- recording item --> <!-- recording item -->
<area condition="not{folder}" x="1%" width="58%" layer="2"> <area condition="not{folder}" x="1%" width="58%" layer="2">
<drawtext x="10" valign="center" font="{light}" fontsize="85%" color="{clrWhite}" text="{date} {time}" /> <drawtext x="10" valign="center" font="{light}" fontsize="85%" color="{clrWhite}" text="{printf('%02d.%02d.%d', daynumeric, month, year)} {time}" />
<drawtext x="35%" width="60%" valign="center" font="{light}" fontsize="85%" color="{clrWhite}" text="{name}" /> <drawtext x="35%" width="60%" valign="center" font="{light}" fontsize="85%" color="{clrWhite}" text="{name}" />
<drawimage condition="{new}" name="new" imagetype="icon" path="ico_recnew" x="{areawidth} - {areaheight}" width="0.9*{areaheight}" height="0.9*{areaheight}" valign="center" /> <drawimage condition="{new}" name="new" imagetype="icon" path="ico_recnew" x="{areawidth} - {areaheight}" width="0.9*{areaheight}" height="0.9*{areaheight}" valign="center" />
<drawimage condition="{new}++{cutted}" imagetype="icon" path="ico_cutted" x="{areawidth} - 2*{areaheight}" width="0.9*{areaheight}" height="0.9*{areaheight}" valign="center" /> <drawimage condition="{new}++{cutted}" imagetype="icon" path="ico_cutted" x="{areawidth} - 2*{areaheight}" width="0.9*{areaheight}" height="0.9*{areaheight}" valign="center" />