<commit_before>/**
 * @file lltimectrl.cpp
 * @brief LLTimeCtrl base class
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2011, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "linden_common.h"

#include "lltimectrl.h"

#include "llui.h"
#include "lluiconstants.h"

#include "llbutton.h"
#include "llfontgl.h"
#include "lllineeditor.h"
#include "llkeyboard.h"
#include "llstring.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"

static LLDefaultChildRegistry::Register<LLTimeCtrl> time_r("time");

const U32 AMPM_LEN = 3;
const U32 MINUTES_MIN = 0;
const U32 MINUTES_MAX = 59;
const U32 HOURS_MIN = 1;
const U32 HOURS_MAX = 12;

LLTimeCtrl::Params::Params()
:	label_width("label_width"),
	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()),
	mHours(HOURS_MIN),
	mMinutes(MINUTES_MIN)
{
	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 );
}

F32 LLTimeCtrl::getTime24() const
{
	return getHours24() + getMinutes() / 60.0f;
}

U32 LLTimeCtrl::getHours24() const
{
	U32 h = mHours;

	if (h == 12)
    {
        h = 0;
    }

    if (mCurrentDayPeriod == PM)
    {
        h += 12;
    }

    return h;
}

U32 LLTimeCtrl::getMinutes() const
{
	return mMinutes;
}

void LLTimeCtrl::setTime24(F32 time)
{
	time = llclamp(time, 0.0f, 23.99f); // fix out of range values

	U32 h = time;
	U32 m = llround((time - h) * 60); // fixes values like 4.99999

	// fix rounding error
	if (m == 60)
	{
		m = 0;
		++h;
	}

	mCurrentDayPeriod = (h >= 12 ? PM : AM);

	if (h >= 12)
	{
		h -= 12;
	}

	if (h == 0)
	{<commit_msg>STORM-1253 WIP Fixed a compiler warning.<commit_after>/**
 * @file lltimectrl.cpp
 * @brief LLTimeCtrl base class
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2011, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "linden_common.h"

#include "lltimectrl.h"

#include "llui.h"
#include "lluiconstants.h"

#include "llbutton.h"
#include "llfontgl.h"
#include "lllineeditor.h"
#include "llkeyboard.h"
#include "llstring.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"

static LLDefaultChildRegistry::Register<LLTimeCtrl> time_r("time");

const U32 AMPM_LEN = 3;
const U32 MINUTES_MIN = 0;
const U32 MINUTES_MAX = 59;
const U32 HOURS_MIN = 1;
const U32 HOURS_MAX = 12;

LLTimeCtrl::Params::Params()
:	label_width("label_width"),
	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()),
	mHours(HOURS_MIN),
	mMinutes(MINUTES_MIN)
{
	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 );
}

F32 LLTimeCtrl::getTime24() const
{
	return getHours24() + getMinutes() / 60.0f;
}

U32 LLTimeCtrl::getHours24() const
{
	U32 h = mHours;

	if (h == 12)
    {
        h = 0;
    }

    if (mCurrentDayPeriod == PM)
    {
        h += 12;
    }

    return h;
}

U32 LLTimeCtrl::getMinutes() const
{
	return mMinutes;
}

void LLTimeCtrl::setTime24(F32 time)
{
	time = llclamp(time, 0.0f, 23.99f); // fix out of range values

	U32 h = (U32) time;
	U32 m = llround((time - h) * 60); // fixes values like 4.99999

	// fix rounding error
	if (m == 60)
	{
		m = 0;
		++h;
	}

	mCurrentDayPeriod = (h >= 12 ? PM : AM);

	if (h >= 12)
	{
		h -= 12;
	}

	if (h == 0)
	{
{'fraction_non_alphanumeric': 0.14544785050170303, 'fraction_numerical': 0.025775568443339777, 'mean_word_length': 5.4782349433512225, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7025981', 'n_tokens_mistral': 4111, 'n_tokens_neox': 3794, 'n_words': 832}