diff --git a/lib/skin_parser/skin_debug.c b/lib/skin_parser/skin_debug.c index 00d09aea7e..4abe6252f0 100644 --- a/lib/skin_parser/skin_debug.c +++ b/lib/skin_parser/skin_debug.c @@ -70,6 +70,9 @@ void skin_error(enum skin_errorcode error) case INT_EXPECTED: error_message = "Expected integer"; break; + case DECIMAL_EXPECTED: + error_message = "Expected decimal"; + break; case SEPERATOR_EXPECTED: error_message = "Expected argument seperator"; break; @@ -236,8 +239,13 @@ void skin_debug_params(int count, struct skin_tag_parameter params[]) printf("[%s]", params[i].data.text); break; - case NUMERIC: - printf("[%d]", params[i].data.numeric); + case INTEGER: + printf("[%d]", params[i].data.number); + break; + + case DECIMAL: + printf("[%d.%d]", params[i].data.number/10, + params[i].data.number%10); break; case CODE: diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c index 2ce41c6d9a..5bc5984fb7 100644 --- a/lib/skin_parser/skin_parser.c +++ b/lib/skin_parser/skin_parser.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "skin_buffer.h" #include "skin_parser.h" @@ -534,7 +535,7 @@ static int skin_parse_tag(struct skin_element* element, char** document) /* Storing the type code */ element->params[i].type_code = *tag_args; - /* Checking a nullable argument for null */ + /* Checking a nullable argument for null. */ if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) { if(islower(*tag_args)) @@ -557,8 +558,36 @@ static int skin_parse_tag(struct skin_element* element, char** document) return 0; } - element->params[i].type = NUMERIC; - element->params[i].data.numeric = scan_int(&cursor); + element->params[i].type = INTEGER; + element->params[i].data.number = scan_int(&cursor); + } + else if(tolower(*tag_args) == 'd') + { + int val = 0; + bool have_point = false; + bool have_tenth = false; + while ( isdigit(*cursor) || *cursor == '.' ) + { + if (*cursor != '.') + { + val *= 10; + val += *cursor - '0'; + if (have_point) + { + have_tenth = true; + cursor++; + break; + } + } + else + have_point = true; + cursor++; + } + if (have_tenth == false) + val *= 10; + + element->params[i].type = DECIMAL; + element->params[i].data.number = val; } else if(tolower(*tag_args) == 'n' || tolower(*tag_args) == 's' || tolower(*tag_args) == 'f') diff --git a/lib/skin_parser/skin_parser.h b/lib/skin_parser/skin_parser.h index 126a014b5a..ad10f90125 100644 --- a/lib/skin_parser/skin_parser.h +++ b/lib/skin_parser/skin_parser.h @@ -56,6 +56,7 @@ enum skin_errorcode UNEXPECTED_NEWLINE, INSUFFICIENT_ARGS, INT_EXPECTED, + DECIMAL_EXPECTED, SEPERATOR_EXPECTED, CLOSE_EXPECTED, MULTILINE_EXPECTED @@ -66,7 +67,8 @@ struct skin_tag_parameter { enum { - NUMERIC, + INTEGER, + DECIMAL, /* stored in data.number as (whole*10)+part */ STRING, CODE, DEFAULT @@ -74,7 +76,7 @@ struct skin_tag_parameter union { - int numeric; + int number; char* text; struct skin_element* code; } data; diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index e0247ef745..dd8df63997 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -120,7 +120,7 @@ struct tag_info legal_tags[] = { SKIN_TOKEN_REMOTE_HOLD, "mr", "", 0 }, { SKIN_TOKEN_REPEAT_MODE, "mm", "", 0 }, { SKIN_TOKEN_PLAYBACK_STATUS, "mp", "", 0 }, - { SKIN_TOKEN_BUTTON_VOLUME, "mv", "|S", 0 }, + { SKIN_TOKEN_BUTTON_VOLUME, "mv", "|D", 0 }, { SKIN_TOKEN_PEAKMETER, "pm", "", 0 }, { SKIN_TOKEN_PLAYER_PROGRESSBAR, "pf", "", 0 }, @@ -131,8 +131,8 @@ struct tag_info legal_tags[] = { SKIN_TOKEN_TRACK_TIME_ELAPSED, "pc", "", 0 }, { SKIN_TOKEN_TRACK_TIME_REMAINING, "pr", "", 0 }, { SKIN_TOKEN_TRACK_LENGTH, "pt", "", 0 }, - { SKIN_TOKEN_TRACK_STARTING, "pS" , "|S", 0 }, - { SKIN_TOKEN_TRACK_ENDING, "pE" , "|S", 0 }, + { SKIN_TOKEN_TRACK_STARTING, "pS" , "|D", 0 }, + { SKIN_TOKEN_TRACK_ENDING, "pE" , "|D", 0 }, { SKIN_TOKEN_PLAYLIST_POSITION, "pp", "", 0 }, { SKIN_TOKEN_PLAYLIST_ENTRIES, "pe", "", 0 }, { SKIN_TOKEN_PLAYLIST_NAME, "pn", "", 0 }, @@ -161,7 +161,7 @@ struct tag_info legal_tags[] = { SKIN_TOKEN_RDS_TEXT, "tz", "", 0 }, { SKIN_TOKEN_SUBLINE_SCROLL, "s", "", 0 }, - { SKIN_TOKEN_SUBLINE_TIMEOUT, "t" , "S", 0 }, + { SKIN_TOKEN_SUBLINE_TIMEOUT, "t" , "D", 0 }, { SKIN_TOKEN_ENABLE_THEME, "we", "", NOBREAK }, { SKIN_TOKEN_DISABLE_THEME, "wd", "", NOBREAK }, @@ -196,7 +196,7 @@ struct tag_info legal_tags[] = { SKIN_TOKEN_TRANSLATEDSTRING, "Sx" , "S", 0 }, { SKIN_TOKEN_LANG_IS_RTL, "Sr" , "", 0 }, - { SKIN_TOKEN_LASTTOUCH, "Tl" , "|S", 0 }, + { SKIN_TOKEN_LASTTOUCH, "Tl" , "|D", 0 }, { SKIN_TOKEN_CURRENT_SCREEN, "cs", "", 0 }, { SKIN_TOKEN_TOUCHREGION, "T" , "IIiiS", NOBREAK }, diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h index 149f148cca..f84d4ac762 100644 --- a/lib/skin_parser/tag_table.h +++ b/lib/skin_parser/tag_table.h @@ -246,6 +246,9 @@ enum skin_token_type { * characters for parameters are: * I - Required integer * i - Nullable integer + * D - Required decimal + * d - Nullable decimal + * Decimals are stored as (whole*10)+part * S - Required string * s - Nullable string * F - Required file name diff --git a/utils/themeeditor/graphics/rbprogressbar.cpp b/utils/themeeditor/graphics/rbprogressbar.cpp index 027520f4da..206a835252 100644 --- a/utils/themeeditor/graphics/rbprogressbar.cpp +++ b/utils/themeeditor/graphics/rbprogressbar.cpp @@ -41,22 +41,22 @@ RBProgressBar::RBProgressBar(RBViewport *parent, const RBRenderInfo &info, if(paramCount > 0 && params[0].type != skin_tag_parameter::DEFAULT) { - x = params[0].data.numeric; + x = params[0].data.number; } if(paramCount > 1 && params[1].type != skin_tag_parameter::DEFAULT) { - y = params[1].data.numeric; + y = params[1].data.number; } if(paramCount > 2 && params[2].type != skin_tag_parameter::DEFAULT) { - w = params[2].data.numeric; + w = params[2].data.number; } if(paramCount > 3 && params[3].type != skin_tag_parameter::DEFAULT) { - h = params[3].data.numeric; + h = params[3].data.number; } if(paramCount > 4 && params[4].type != skin_tag_parameter::DEFAULT) diff --git a/utils/themeeditor/graphics/rbviewport.cpp b/utils/themeeditor/graphics/rbviewport.cpp index 96d7e8b276..e9c58eb6fb 100644 --- a/utils/themeeditor/graphics/rbviewport.cpp +++ b/utils/themeeditor/graphics/rbviewport.cpp @@ -97,24 +97,24 @@ RBViewport::RBViewport(skin_element* node, const RBRenderInfo& info) break; } /* Now we grab the info common to all viewports */ - x = node->params[param++].data.numeric; + x = node->params[param++].data.number; if(x < 0) x = info.screen()->boundingRect().right() + x; - y = node->params[param++].data.numeric; + y = node->params[param++].data.number; if(y < 0) y = info.screen()->boundingRect().bottom() + y; if(node->params[param].type == skin_tag_parameter::DEFAULT) w = info.screen()->getWidth() - x; else - w = node->params[param].data.numeric; + w = node->params[param].data.number; if(w < 0) w = info.screen()->getWidth() + w - x; if(node->params[++param].type == skin_tag_parameter::DEFAULT) h = info.screen()->getHeight() - y; else - h = node->params[param].data.numeric; + h = node->params[param].data.number; if(h < 0) h = info.screen()->getHeight() + h - y; @@ -128,7 +128,7 @@ RBViewport::RBViewport(skin_element* node, const RBRenderInfo& info) if(node->params[++param].type == skin_tag_parameter::DEFAULT) font = screen->getFont(1); else - font = screen->getFont(node->params[param].data.numeric); + font = screen->getFont(node->params[param].data.number); setPos(x, y); size = QRectF(0, 0, w, h); diff --git a/utils/themeeditor/gui/devicestate.cpp b/utils/themeeditor/gui/devicestate.cpp index 89985bf730..e766a64835 100644 --- a/utils/themeeditor/gui/devicestate.cpp +++ b/utils/themeeditor/gui/devicestate.cpp @@ -225,7 +225,7 @@ QVariant DeviceState::data(QString tag, int paramCount, QString path = tag[0].isLower() ? data("file").toString() : data("nextfile").toString(); if(paramCount > 0) - return directory(path, params[0].data.numeric); + return directory(path, params[0].data.number); else return QVariant(); } @@ -255,7 +255,7 @@ QVariant DeviceState::data(QString tag, int paramCount, else if(tag == "pS") { double threshhold = paramCount > 0 - ? std::atof(params[0].data.text) : 10; + ? params[0].data.number / 10. : 10; if(data("?pc").toDouble() <= threshhold) return true; else @@ -264,7 +264,7 @@ QVariant DeviceState::data(QString tag, int paramCount, else if(tag == "pE") { double threshhold = paramCount > 0 - ? std::atof(params[0].data.text) : 10; + ? params[0].data.number / 10. : 10; if(data("?pt").toDouble() - data("?pc").toDouble() <= threshhold) return true; else diff --git a/utils/themeeditor/models/parsetreemodel.cpp b/utils/themeeditor/models/parsetreemodel.cpp index a04a0d9202..66c96213ab 100644 --- a/utils/themeeditor/models/parsetreemodel.cpp +++ b/utils/themeeditor/models/parsetreemodel.cpp @@ -246,8 +246,8 @@ bool ParseTreeModel::setData(const QModelIndex &index, const QVariant &value, if(!value.canConvert(QVariant::Int)) return false; - param->type = skin_tag_parameter::NUMERIC; - param->data.numeric = value.toInt(); + param->type = skin_tag_parameter::INTEGER; + param->data.number = value.toInt(); } else { diff --git a/utils/themeeditor/models/parsetreenode.cpp b/utils/themeeditor/models/parsetreenode.cpp index 1b894b7c33..fbb7b9279f 100644 --- a/utils/themeeditor/models/parsetreenode.cpp +++ b/utils/themeeditor/models/parsetreenode.cpp @@ -246,8 +246,12 @@ QString ParseTreeNode::genCode() const } break; - case skin_tag_parameter::NUMERIC: - buffer.append(QString::number(param->data.numeric, 10)); + case skin_tag_parameter::INTEGER: + buffer.append(QString::number(param->data.number, 10)); + break; + + case skin_tag_parameter::DECIMAL: + buffer.append(QString::number(param->data.number / 10., 'f', 1)); break; case skin_tag_parameter::DEFAULT: @@ -318,8 +322,8 @@ int ParseTreeNode::genHash() const case skin_tag_parameter::CODE: break; - case skin_tag_parameter::NUMERIC: - hash += param->data.numeric * (param->data.numeric / 4); + case skin_tag_parameter::INTEGER: + hash += param->data.number * (param->data.number / 4); break; case skin_tag_parameter::STRING: @@ -331,6 +335,10 @@ int ParseTreeNode::genHash() const hash += param->data.text[i]; } break; + + case skin_tag_parameter::DECIMAL: + hash += param->data.number; + break; } } @@ -396,8 +404,11 @@ QVariant ParseTreeNode::data(int column) const case skin_tag_parameter::STRING: return QObject::tr("String"); - case skin_tag_parameter::NUMERIC: - return QObject::tr("Number"); + case skin_tag_parameter::INTEGER: + return QObject::tr("Integer"); + + case skin_tag_parameter::DECIMAL: + return QObject::tr("Decimal"); case skin_tag_parameter::DEFAULT: return QObject::tr("Default Argument"); @@ -445,11 +456,15 @@ QVariant ParseTreeNode::data(int column) const case skin_tag_parameter::STRING: return QString(param->data.text); - case skin_tag_parameter::NUMERIC: - return QString::number(param->data.numeric, 10); + case skin_tag_parameter::INTEGER: + return QString::number(param->data.number, 10); + + case skin_tag_parameter::DECIMAL: + return QString::number(param->data.number / 10., 'f', 1); case skin_tag_parameter::CODE: return QObject::tr("Seriously, something's wrong here"); + } } else @@ -742,10 +757,10 @@ bool ParseTreeNode::execTag(const RBRenderInfo& info, RBViewport* viewport) id = element->params[0].data.text; filename = info.settings()->value("imagepath", "") + "/" + element->params[1].data.text; - x = element->params[2].data.numeric; - y = element->params[3].data.numeric; + x = element->params[2].data.number; + y = element->params[3].data.number; if(element->params_count > 4) - tiles = element->params[4].data.numeric; + tiles = element->params[4].data.number; else tiles = 1; @@ -758,8 +773,8 @@ bool ParseTreeNode::execTag(const RBRenderInfo& info, RBViewport* viewport) id = element->params[0].data.text; filename = info.settings()->value("imagepath", "") + "/" + element->params[1].data.text; - x = element->params[2].data.numeric; - y = element->params[3].data.numeric; + x = element->params[2].data.number; + y = element->params[3].data.number; image = new RBImage(filename, 1, x, y, viewport); info.screen()->loadImage(id, new RBImage(filename, 1, x, y, viewport)); @@ -780,10 +795,10 @@ bool ParseTreeNode::execTag(const RBRenderInfo& info, RBViewport* viewport) case 'l': /* %Cl */ - x = element->params[0].data.numeric; - y = element->params[1].data.numeric; - maxWidth = element->params[2].data.numeric; - maxHeight = element->params[3].data.numeric; + x = element->params[0].data.number; + y = element->params[1].data.number; + maxWidth = element->params[2].data.number; + maxHeight = element->params[3].data.number; hAlign = element->params_count > 4 ? element->params[4].data.text[0] : 'c'; vAlign = element->params_count > 5 @@ -805,7 +820,7 @@ bool ParseTreeNode::execTag(const RBRenderInfo& info, RBViewport* viewport) case 'l': /* %Fl */ - x = element->params[0].data.numeric; + x = element->params[0].data.number; filename = info.settings()->value("themebase", "") + "/fonts/" + element->params[1].data.text; info.screen()->loadFont(x, new RBFont(filename)); @@ -822,10 +837,10 @@ bool ParseTreeNode::execTag(const RBRenderInfo& info, RBViewport* viewport) /* %T */ if(element->params_count < 5) return false; - int x = element->params[0].data.numeric; - int y = element->params[1].data.numeric; - int width = element->params[2].data.numeric; - int height = element->params[3].data.numeric; + int x = element->params[0].data.number; + int y = element->params[1].data.number; + int width = element->params[2].data.number; + int height = element->params[3].data.number; QString action(element->params[4].data.text); RBTouchArea* temp = new RBTouchArea(width, height, action, info); temp->setPos(x, y); @@ -863,7 +878,7 @@ bool ParseTreeNode::execTag(const RBRenderInfo& info, RBViewport* viewport) case 'p': /* %Vp */ - viewport->showPlaylist(info, element->params[0].data.numeric, + viewport->showPlaylist(info, element->params[0].data.number, element->params[1].data.code, element->params[2].data.code); return true; @@ -1016,7 +1031,7 @@ double ParseTreeNode::findBranchTime(ParseTreeNode *branch, if(current->element->tag->name[0] == 't' && current->element->tag->name[1] == '\0') { - retval = atof(current->element->params[0].data.text); + retval = current->element->params[0].data.number / 10.; } } else if(current->element->type == CONDITIONAL)