diff options
Diffstat (limited to 'indra/llui/lltimectrl.cpp')
-rw-r--r-- | indra/llui/lltimectrl.cpp | 517 |
1 files changed, 269 insertions, 248 deletions
diff --git a/indra/llui/lltimectrl.cpp b/indra/llui/lltimectrl.cpp index 516057f8fd..3d404293c6 100644 --- a/indra/llui/lltimectrl.cpp +++ b/indra/llui/lltimectrl.cpp @@ -49,385 +49,406 @@ const U32 HOURS_MAX = 12; const U32 MINUTES_PER_HOUR = 60; const U32 MINUTES_PER_DAY = 24 * MINUTES_PER_HOUR; +class LLTimeValidatorImpl : public LLTextValidate::ValidatorImpl +{ +public: + // virtual + bool validate(const std::string& str) override + { + std::string hours = LLTimeCtrl::getHoursString(str); + if (!LLTimeCtrl::isHoursStringValid(hours)) + return setError("ValidatorInvalidHours", LLSD().with("STR", hours)); + + std::string minutes = LLTimeCtrl::getMinutesString(str); + if (!LLTimeCtrl::isMinutesStringValid(minutes)) + return setError("ValidatorInvalidMinutes", LLSD().with("STR", minutes)); + + std::string ampm = LLTimeCtrl::getAMPMString(str); + if (!LLTimeCtrl::isPMAMStringValid(ampm)) + return setError("ValidatorInvalidAMPM", LLSD().with("STR", ampm)); + + return resetError(); + } + + // virtual + bool validate(const LLWString& wstr) override + { + std::string str = wstring_to_utf8str(wstr); + + return validate(str); + } +} validateTimeImpl; +LLTextValidate::Validator validateTime(validateTimeImpl); LLTimeCtrl::Params::Params() -: label_width("label_width"), - snap_to("snap_to"), - allow_text_entry("allow_text_entry", true), - text_enabled_color("text_enabled_color"), - text_disabled_color("text_disabled_color"), - up_button("up_button"), - down_button("down_button") +: label_width("label_width"), + snap_to("snap_to"), + allow_text_entry("allow_text_entry", true), + text_enabled_color("text_enabled_color"), + text_disabled_color("text_disabled_color"), + up_button("up_button"), + down_button("down_button") {} LLTimeCtrl::LLTimeCtrl(const LLTimeCtrl::Params& p) -: LLUICtrl(p), - mLabelBox(NULL), - mTextEnabledColor(p.text_enabled_color()), - mTextDisabledColor(p.text_disabled_color()), - mTime(0), - mSnapToMin(5) +: LLUICtrl(p), + mLabelBox(NULL), + mTextEnabledColor(p.text_enabled_color()), + mTextDisabledColor(p.text_disabled_color()), + mTime(0), + mSnapToMin(5) { - static LLUICachedControl<S32> spinctrl_spacing ("UISpinctrlSpacing", 0); - static LLUICachedControl<S32> spinctrl_btn_width ("UISpinctrlBtnWidth", 0); - static LLUICachedControl<S32> spinctrl_btn_height ("UISpinctrlBtnHeight", 0); - S32 centered_top = getRect().getHeight(); - S32 centered_bottom = getRect().getHeight() - 2 * spinctrl_btn_height; - S32 label_width = llclamp(p.label_width(), 0, llmax(0, getRect().getWidth() - 40)); - S32 editor_left = label_width + spinctrl_spacing; - - //================= Label =================// - if( !p.label().empty() ) - { - LLRect label_rect( 0, centered_top, label_width, centered_bottom ); - LLTextBox::Params params; - params.name("TimeCtrl Label"); - params.rect(label_rect); - params.initial_value(p.label()); - if (p.font.isProvided()) - { - params.font(p.font); - } - mLabelBox = LLUICtrlFactory::create<LLTextBox> (params); - addChild(mLabelBox); - - editor_left = label_rect.mRight + spinctrl_spacing; - } - - S32 editor_right = getRect().getWidth() - spinctrl_btn_width - spinctrl_spacing; - - //================= Editor ================// - LLRect editor_rect( editor_left, centered_top, editor_right, centered_bottom ); - LLLineEditor::Params params; - params.name("SpinCtrl Editor"); - params.rect(editor_rect); - if (p.font.isProvided()) - { - params.font(p.font); - } - - params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); - params.max_length.chars(8); - params.keystroke_callback(boost::bind(&LLTimeCtrl::onTextEntry, this, _1)); - mEditor = LLUICtrlFactory::create<LLLineEditor> (params); - mEditor->setPrevalidateInput(LLTextValidate::validateNonNegativeS32NoSpace); - mEditor->setPrevalidate(boost::bind(&LLTimeCtrl::isTimeStringValid, this, _1)); - mEditor->setText(LLStringExplicit("12:00 AM")); - addChild(mEditor); - - //================= Spin Buttons ==========// - LLButton::Params up_button_params(p.up_button); - up_button_params.rect = LLRect(editor_right + 1, getRect().getHeight(), editor_right + spinctrl_btn_width, getRect().getHeight() - spinctrl_btn_height); - - up_button_params.click_callback.function(boost::bind(&LLTimeCtrl::onUpBtn, this)); - up_button_params.mouse_held_callback.function(boost::bind(&LLTimeCtrl::onUpBtn, this)); - mUpBtn = LLUICtrlFactory::create<LLButton>(up_button_params); - addChild(mUpBtn); - - LLButton::Params down_button_params(p.down_button); - down_button_params.rect = LLRect(editor_right + 1, getRect().getHeight() - spinctrl_btn_height, editor_right + spinctrl_btn_width, getRect().getHeight() - 2 * spinctrl_btn_height); - down_button_params.click_callback.function(boost::bind(&LLTimeCtrl::onDownBtn, this)); - down_button_params.mouse_held_callback.function(boost::bind(&LLTimeCtrl::onDownBtn, this)); - mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params); - addChild(mDownBtn); - - setUseBoundingRect( TRUE ); + static LLUICachedControl<S32> spinctrl_spacing ("UISpinctrlSpacing", 0); + static LLUICachedControl<S32> spinctrl_btn_width ("UISpinctrlBtnWidth", 0); + static LLUICachedControl<S32> spinctrl_btn_height ("UISpinctrlBtnHeight", 0); + S32 centered_top = getRect().getHeight(); + S32 centered_bottom = getRect().getHeight() - 2 * spinctrl_btn_height; + S32 label_width = llclamp(p.label_width(), 0, llmax(0, getRect().getWidth() - 40)); + S32 editor_left = label_width + spinctrl_spacing; + + //================= Label =================// + if( !p.label().empty() ) + { + LLRect label_rect( 0, centered_top, label_width, centered_bottom ); + LLTextBox::Params params; + params.name("TimeCtrl Label"); + params.rect(label_rect); + params.initial_value(p.label()); + if (p.font.isProvided()) + { + params.font(p.font); + } + mLabelBox = LLUICtrlFactory::create<LLTextBox> (params); + addChild(mLabelBox); + + editor_left = label_rect.mRight + spinctrl_spacing; + } + + S32 editor_right = getRect().getWidth() - spinctrl_btn_width - spinctrl_spacing; + + //================= Editor ================// + LLRect editor_rect( editor_left, centered_top, editor_right, centered_bottom ); + LLLineEditor::Params params; + params.name("SpinCtrl Editor"); + params.rect(editor_rect); + if (p.font.isProvided()) + { + params.font(p.font); + } + + params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); + params.max_length.chars(8); + params.keystroke_callback(boost::bind(&LLTimeCtrl::onTextEntry, this, _1)); + mEditor = LLUICtrlFactory::create<LLLineEditor> (params); + mEditor->setPrevalidateInput(LLTextValidate::validateNonNegativeS32NoSpace); + mEditor->setPrevalidate(validateTime); + mEditor->setText(LLStringExplicit("12:00 AM")); + addChild(mEditor); + + //================= Spin Buttons ==========// + LLButton::Params up_button_params(p.up_button); + up_button_params.rect = LLRect(editor_right + 1, getRect().getHeight(), editor_right + spinctrl_btn_width, getRect().getHeight() - spinctrl_btn_height); + + up_button_params.click_callback.function(boost::bind(&LLTimeCtrl::onUpBtn, this)); + up_button_params.mouse_held_callback.function(boost::bind(&LLTimeCtrl::onUpBtn, this)); + mUpBtn = LLUICtrlFactory::create<LLButton>(up_button_params); + addChild(mUpBtn); + + LLButton::Params down_button_params(p.down_button); + down_button_params.rect = LLRect(editor_right + 1, getRect().getHeight() - spinctrl_btn_height, editor_right + spinctrl_btn_width, getRect().getHeight() - 2 * spinctrl_btn_height); + down_button_params.click_callback.function(boost::bind(&LLTimeCtrl::onDownBtn, this)); + down_button_params.mouse_held_callback.function(boost::bind(&LLTimeCtrl::onDownBtn, this)); + mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params); + addChild(mDownBtn); + + setUseBoundingRect( TRUE ); } F32 LLTimeCtrl::getTime24() const { - // 0.0 - 23.99; - return mTime / 60.0f; + // 0.0 - 23.99; + return mTime / 60.0f; } U32 LLTimeCtrl::getHours24() const { - return (U32) getTime24(); + return (U32) getTime24(); } U32 LLTimeCtrl::getMinutes() const { - return mTime % MINUTES_PER_HOUR; + return mTime % MINUTES_PER_HOUR; } void LLTimeCtrl::setTime24(F32 time) { - time = llclamp(time, 0.0f, 23.99f); // fix out of range values - mTime = ll_round(time * MINUTES_PER_HOUR); // fixes values like 4.99999 + time = llclamp(time, 0.0f, 23.99f); // fix out of range values + mTime = ll_round(time * MINUTES_PER_HOUR); // fixes values like 4.99999 - updateText(); + updateText(); } BOOL LLTimeCtrl::handleKeyHere(KEY key, MASK mask) { - if (mEditor->hasFocus()) - { - if(key == KEY_UP) - { - onUpBtn(); - return TRUE; - } - if(key == KEY_DOWN) - { - onDownBtn(); - return TRUE; - } - if (key == KEY_RETURN) - { - onCommit(); - return TRUE; - } - } - return FALSE; + if (mEditor->hasFocus()) + { + if(key == KEY_UP) + { + onUpBtn(); + return TRUE; + } + if(key == KEY_DOWN) + { + onDownBtn(); + return TRUE; + } + if (key == KEY_RETURN) + { + onCommit(); + return TRUE; + } + } + return FALSE; } void LLTimeCtrl::onUpBtn() { - switch(getEditingPart()) - { - case HOURS: - increaseHours(); - break; - case MINUTES: - increaseMinutes(); - break; - case DAYPART: - switchDayPeriod(); - break; - default: - break; - } - - updateText(); - onCommit(); + switch(getEditingPart()) + { + case HOURS: + increaseHours(); + break; + case MINUTES: + increaseMinutes(); + break; + case DAYPART: + switchDayPeriod(); + break; + default: + break; + } + + updateText(); + onCommit(); } void LLTimeCtrl::onDownBtn() { - switch(getEditingPart()) - { - case HOURS: - decreaseHours(); - break; - case MINUTES: - decreaseMinutes(); - break; - case DAYPART: - switchDayPeriod(); - break; - default: - break; - } - - updateText(); - onCommit(); + switch(getEditingPart()) + { + case HOURS: + decreaseHours(); + break; + case MINUTES: + decreaseMinutes(); + break; + case DAYPART: + switchDayPeriod(); + break; + default: + break; + } + + updateText(); + onCommit(); } void LLTimeCtrl::onFocusLost() { - updateText(); - onCommit(); - LLUICtrl::onFocusLost(); + updateText(); + onCommit(); + LLUICtrl::onFocusLost(); } void LLTimeCtrl::onTextEntry(LLLineEditor* line_editor) { - std::string time_str = line_editor->getText(); - U32 h12 = parseHours(getHoursString(time_str)); - U32 m = parseMinutes(getMinutesString(time_str)); - bool pm = parseAMPM(getAMPMString(time_str)); - - if (h12 == 12) - { - h12 = 0; - } + std::string time_str = line_editor->getText(); + U32 h12 = parseHours(getHoursString(time_str)); + U32 m = parseMinutes(getMinutesString(time_str)); + bool pm = parseAMPM(getAMPMString(time_str)); - U32 h24 = pm ? h12 + 12 : h12; + if (h12 == 12) + { + h12 = 0; + } - mTime = h24 * MINUTES_PER_HOUR + m; -} - -bool LLTimeCtrl::isTimeStringValid(const LLWString &wstr) -{ - std::string str = wstring_to_utf8str(wstr); + U32 h24 = pm ? h12 + 12 : h12; - return isHoursStringValid(getHoursString(str)) && - isMinutesStringValid(getMinutesString(str)) && - isPMAMStringValid(getAMPMString(str)); + mTime = h24 * MINUTES_PER_HOUR + m; } void LLTimeCtrl::increaseMinutes() { - mTime = (mTime + mSnapToMin) % MINUTES_PER_DAY - (mTime % mSnapToMin); + mTime = (mTime + mSnapToMin) % MINUTES_PER_DAY - (mTime % mSnapToMin); } void LLTimeCtrl::increaseHours() { - mTime = (mTime + MINUTES_PER_HOUR) % MINUTES_PER_DAY; + mTime = (mTime + MINUTES_PER_HOUR) % MINUTES_PER_DAY; } void LLTimeCtrl::decreaseMinutes() { - if (mTime < mSnapToMin) - { - mTime = MINUTES_PER_DAY - mTime; - } + if (mTime < mSnapToMin) + { + mTime = MINUTES_PER_DAY - mTime; + } - mTime -= (mTime % mSnapToMin) ? mTime % mSnapToMin : mSnapToMin; + mTime -= (mTime % mSnapToMin) ? mTime % mSnapToMin : mSnapToMin; } void LLTimeCtrl::decreaseHours() { - if (mTime < MINUTES_PER_HOUR) - { - mTime = 23 * MINUTES_PER_HOUR + mTime; - } - else - { - mTime -= MINUTES_PER_HOUR; - } + if (mTime < MINUTES_PER_HOUR) + { + mTime = 23 * MINUTES_PER_HOUR + mTime; + } + else + { + mTime -= MINUTES_PER_HOUR; + } } bool LLTimeCtrl::isPM() const { - return mTime >= (MINUTES_PER_DAY / 2); + return mTime >= (MINUTES_PER_DAY / 2); } void LLTimeCtrl::switchDayPeriod() { - if (isPM()) - { - mTime -= MINUTES_PER_DAY / 2; - } - else - { - mTime += MINUTES_PER_DAY / 2; - } + if (isPM()) + { + mTime -= MINUTES_PER_DAY / 2; + } + else + { + mTime += MINUTES_PER_DAY / 2; + } } void LLTimeCtrl::updateText() { - U32 h24 = getHours24(); - U32 m = getMinutes(); - U32 h12 = h24 > 12 ? h24 - 12 : h24; + U32 h24 = getHours24(); + U32 m = getMinutes(); + U32 h12 = h24 > 12 ? h24 - 12 : h24; - if (h12 == 0) - h12 = 12; + if (h12 == 0) + h12 = 12; - mEditor->setText(llformat("%d:%02d %s", h12, m, isPM() ? "PM":"AM")); + mEditor->setText(llformat("%d:%02d %s", h12, m, isPM() ? "PM":"AM")); } LLTimeCtrl::EEditingPart LLTimeCtrl::getEditingPart() { - S32 cur_pos = mEditor->getCursor(); - std::string time_str = mEditor->getText(); - - S32 colon_index = time_str.find_first_of(':'); - - if (cur_pos <= colon_index) - { - return HOURS; - } - else if (cur_pos > colon_index && cur_pos <= (S32)(time_str.length() - AMPM_LEN)) - { - return MINUTES; - } - else if (cur_pos > (S32)(time_str.length() - AMPM_LEN)) - { - return DAYPART; - } - - return NONE; + S32 cur_pos = mEditor->getCursor(); + std::string time_str = mEditor->getText(); + + S32 colon_index = time_str.find_first_of(':'); + + if (cur_pos <= colon_index) + { + return HOURS; + } + else if (cur_pos > colon_index && cur_pos <= (S32)(time_str.length() - AMPM_LEN)) + { + return MINUTES; + } + else if (cur_pos > (S32)(time_str.length() - AMPM_LEN)) + { + return DAYPART; + } + + return NONE; } // static std::string LLTimeCtrl::getHoursString(const std::string& str) { - size_t colon_index = str.find_first_of(':'); - std::string hours_str = str.substr(0, colon_index); + size_t colon_index = str.find_first_of(':'); + std::string hours_str = str.substr(0, colon_index); - return hours_str; + return hours_str; } // static std::string LLTimeCtrl::getMinutesString(const std::string& str) { - size_t colon_index = str.find_first_of(':'); - ++colon_index; + size_t colon_index = str.find_first_of(':'); + ++colon_index; - int minutes_len = str.length() - colon_index - AMPM_LEN; - std::string minutes_str = str.substr(colon_index, minutes_len); + int minutes_len = str.length() - colon_index - AMPM_LEN; + std::string minutes_str = str.substr(colon_index, minutes_len); - return minutes_str; + return minutes_str; } // static std::string LLTimeCtrl::getAMPMString(const std::string& str) { - return str.substr(str.size() - 2, 2); // returns last two characters + return str.substr(str.size() - 2, 2); // returns last two characters } // static bool LLTimeCtrl::isHoursStringValid(const std::string& str) { - U32 hours; - if ((!LLStringUtil::convertToU32(str, hours) || (hours <= HOURS_MAX)) && str.length() < 3) - return true; + U32 hours; + if ((!LLStringUtil::convertToU32(str, hours) || (hours <= HOURS_MAX)) && str.length() < 3) + return true; - return false; + return false; } // static bool LLTimeCtrl::isMinutesStringValid(const std::string& str) { - U32 minutes; - if (!LLStringUtil::convertToU32(str, minutes) || ((minutes <= MINUTES_MAX) && str.length() < 3)) - return true; + U32 minutes; + if (!LLStringUtil::convertToU32(str, minutes) || ((minutes <= MINUTES_MAX) && str.length() < 3)) + return true; - return false; + return false; } // static bool LLTimeCtrl::isPMAMStringValid(const std::string& str) { - S32 len = str.length(); + S32 len = str.length(); - bool valid = (str[--len] == 'M') && (str[--len] == 'P' || str[len] == 'A'); + bool valid = (str[--len] == 'M') && (str[--len] == 'P' || str[len] == 'A'); - return valid; + return valid; } // static U32 LLTimeCtrl::parseHours(const std::string& str) { - U32 hours; - if (LLStringUtil::convertToU32(str, hours) && (hours >= HOURS_MIN) && (hours <= HOURS_MAX)) - { - return hours; - } - else - { - return HOURS_MIN; - } + U32 hours; + if (LLStringUtil::convertToU32(str, hours) && (hours >= HOURS_MIN) && (hours <= HOURS_MAX)) + { + return hours; + } + else + { + return HOURS_MIN; + } } // static U32 LLTimeCtrl::parseMinutes(const std::string& str) { - U32 minutes; - // not sure of this fix - clang doesnt like compare minutes U32 to >= MINUTES_MIN (0) but MINUTES_MIN can change - if (LLStringUtil::convertToU32(str, minutes) && ((S32)minutes >= MINUTES_MIN) && ((S32)minutes <= MINUTES_MAX)) - { - return minutes; - } - else - { - return MINUTES_MIN; - } + U32 minutes; + // not sure of this fix - clang doesnt like compare minutes U32 to >= MINUTES_MIN (0) but MINUTES_MIN can change + if (LLStringUtil::convertToU32(str, minutes) && ((S32)minutes >= MINUTES_MIN) && ((S32)minutes <= MINUTES_MAX)) + { + return minutes; + } + else + { + return MINUTES_MIN; + } } // static bool LLTimeCtrl::parseAMPM(const std::string& str) { - return str == "PM"; + return str == "PM"; } |