MAINT-8344 implement slider support for an overlap threshold and reenable shift-copy

master
andreykproductengine 2018-07-20 19:10:22 +03:00
parent bb836fcdec
commit c822d8af16
7 changed files with 116 additions and 44 deletions

View File

@ -41,8 +41,6 @@
static LLDefaultChildRegistry::Register<LLMultiSlider> r("multi_slider_bar");
const F32 FLOAT_THRESHOLD = 0.00001f;
S32 LLMultiSlider::mNameCounter = 0;
LLMultiSlider::SliderParams::SliderParams()
@ -54,6 +52,7 @@ LLMultiSlider::SliderParams::SliderParams()
LLMultiSlider::Params::Params()
: max_sliders("max_sliders", 1),
allow_overlap("allow_overlap", false),
overlap_threshold("overlap_threshold", 0),
draw_track("draw_track", true),
use_triangle("use_triangle", false),
track_color("track_color"),
@ -98,6 +97,15 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
}
if (p.overlap_threshold.isProvided())
{
mOverlapThreshold = p.overlap_threshold;
}
else
{
mOverlapThreshold = 0;
}
for (LLInitParam::ParamIterator<SliderParams>::const_iterator it = p.sliders.begin();
it != p.sliders.end();
++it)
@ -143,11 +151,14 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from
// look at the current spot
// and see if anything is there
LLSD::map_iterator mIt = mValue.beginMap();
F32 threshold = mOverlapThreshold + (mIncrement / 4); // increment is our distance between points, use to eliminate round error
for(;mIt != mValue.endMap(); mIt++) {
F32 testVal = (F32)mIt->second.asReal() - newValue;
if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD &&
mIt->first != name) {
if (testVal > -threshold
&& testVal < threshold
&& mIt->first != name)
{
hit = true;
break;
}
@ -300,11 +311,13 @@ bool LLMultiSlider::findUnusedValue(F32& initVal)
// look at the current spot
// and see if anything is there
F32 threshold = mOverlapThreshold + (mIncrement / 4);
LLSD::map_iterator mIt = mValue.beginMap();
for(;mIt != mValue.endMap(); mIt++) {
F32 testVal = (F32)mIt->second.asReal() - initVal;
if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD) {
if(testVal > -threshold && testVal < threshold)
{
hit = true;
break;
}

View File

@ -50,6 +50,8 @@ public:
draw_track,
use_triangle;
Optional<F32> overlap_threshold;
Optional<LLUIColor> track_color,
thumb_disabled_color,
thumb_outline_color,
@ -107,6 +109,7 @@ protected:
S32 mMaxNumSliders;
BOOL mAllowOverlap;
F32 mOverlapThreshold;
BOOL mDrawTrack;
BOOL mUseTriangle; /// hacked in toggle to use a triangle

View File

@ -53,6 +53,7 @@ LLMultiSliderCtrl::Params::Params()
can_edit_text("can_edit_text", false),
max_sliders("max_sliders", 1),
allow_overlap("allow_overlap", false),
overlap_threshold("overlap_threshold", 0),
draw_track("draw_track", true),
use_triangle("use_triangle", false),
decimal_digits("decimal_digits", 3),
@ -167,6 +168,10 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
params.increment(p.increment);
params.max_sliders(p.max_sliders);
params.allow_overlap(p.allow_overlap);
if (p.overlap_threshold.isProvided())
{
params.overlap_threshold = p.overlap_threshold;
}
params.draw_track(p.draw_track);
params.use_triangle(p.use_triangle);
params.control_name(p.control_name);

View File

@ -57,6 +57,8 @@ public:
draw_track,
use_triangle;
Optional<F32> overlap_threshold;
Optional<LLUIColor> text_color,
text_disabled_color;

View File

@ -108,7 +108,7 @@ namespace {
const F32 DAY_CYCLE_PLAY_TIME_SECONDS = 60;
const F32 FRAME_SLOP_FACTOR = 0.025f;
const F32 FRAME_SLOP_FACTOR = 0.0251f;
}
//=========================================================================
@ -122,6 +122,7 @@ LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
mFlyoutControl(nullptr),
mDayLength(0),
mCurrentTrack(1),
mShiftCopyEnabled(false),
mTimeSlider(nullptr),
mFramesSlider(nullptr),
mCurrentTimeLabel(nullptr),
@ -246,7 +247,6 @@ void LLFloaterEditExtDayCycle::onOpen(const LLSD& key)
}
const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes();
for (S32 idx = 1; idx < 4; ++idx)
{
std::stringstream label;
@ -307,6 +307,40 @@ void LLFloaterEditExtDayCycle::refresh()
LLFloater::refresh();
}
/* virtual */
BOOL LLFloaterEditExtDayCycle::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
{
LL_DEBUGS("LAPRAS") << "Key: " << key << " mask: " << mask << LL_ENDL;
if (mask == MASK_SHIFT && mShiftCopyEnabled)
{
mShiftCopyEnabled = false;
std::string curslider = mFramesSlider->getCurSlider();
if (!curslider.empty())
{
F32 sliderpos = mFramesSlider->getCurSliderValue();
keymap_t::iterator it = mSliderKeyMap.find(curslider);
if (it != mSliderKeyMap.end())
{
LL_DEBUGS("LAPRAS") << "Moving frame from " << (*it).second.mFrame << " to " << sliderpos << LL_ENDL;
if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos))
{
(*it).second.mFrame = sliderpos;
}
else
{
mFramesSlider->setCurSliderValue((*it).second.mFrame);
}
}
else
{
LL_WARNS("LAPRAS") << "Failed to find frame " << sliderpos << " for slider " << curslider << LL_ENDL;
}
}
}
return LLFloater::handleKeyUp(key, mask, called_from_parent);
}
void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
{
@ -459,46 +493,53 @@ void LLFloaterEditExtDayCycle::onFrameSliderCallback(const LLSD &data)
keymap_t::iterator it = mSliderKeyMap.find(curslider);
if (it != mSliderKeyMap.end())
{
// if (gKeyboard->currentMask(TRUE) == MASK_SHIFT)
// {
// LL_DEBUGS() << "Copying frame from " << iter->second.mFrame << " to " << new_frame << LL_ENDL;
// LLSettingsBase::ptr_t new_settings;
//
// // mEditDay still remembers old position, add copy at new position
// if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
// {
// LLSettingsWaterPtr_t water_ptr = std::dynamic_pointer_cast<LLSettingsWater>(iter->second.pSettings)->buildClone();
// mEditDay->setWaterAtKeyframe(water_ptr, new_frame);
// new_settings = water_ptr;
// }
// else
// {
// LLSettingsSkyPtr_t sky_ptr = std::dynamic_pointer_cast<LLSettingsSky>(iter->second.pSettings)->buildClone();
// mEditDay->setSkyAtKeyframe(sky_ptr, new_frame, mCurrentTrack);
// new_settings = sky_ptr;
// }
//
// // mSliderKeyMap still remembers old position, for simplicity, just move it to be identical to slider
// F32 old_frame = iter->second.mFrame;
// iter->second.mFrame = new_frame;
// // slider already moved old frame, create new one in old place
// addSliderFrame(old_frame, new_settings, false /*because we are going to reselect new one*/);
// // reselect new frame
// mFramesSlider->setCurSlider(iter->first);
// }
// else
// {
LL_WARNS("LAPRAS") << "Moving frame from " << (*it).second.mFrame << " to " << sliderpos << LL_ENDL;
if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos))
if (gKeyboard->currentMask(TRUE) == MASK_SHIFT && mShiftCopyEnabled)
{
(*it).second.mFrame = sliderpos;
// don't move the point/frame as long as shift is pressed and user is attempting to copy
// handleKeyUp will do the move if user releases key too early.
if (!(mEditDay->getSettingsNearKeyframe(sliderpos, mCurrentTrack, FRAME_SLOP_FACTOR)).second)
{
LL_DEBUGS() << "Copying frame from " << it->second.mFrame << " to " << sliderpos << LL_ENDL;
LLSettingsBase::ptr_t new_settings;
// mEditDay still remembers old position, add copy at new position
if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
{
LLSettingsWaterPtr_t water_ptr = std::dynamic_pointer_cast<LLSettingsWater>(it->second.pSettings)->buildClone();
mEditDay->setWaterAtKeyframe(water_ptr, sliderpos);
new_settings = water_ptr;
}
else
{
LLSettingsSkyPtr_t sky_ptr = std::dynamic_pointer_cast<LLSettingsSky>(it->second.pSettings)->buildClone();
mEditDay->setSkyAtKeyframe(sky_ptr, sliderpos, mCurrentTrack);
new_settings = sky_ptr;
}
// mSliderKeyMap still remembers old position, for simplicity, just move it to be identical to slider
F32 old_frame = it->second.mFrame;
it->second.mFrame = sliderpos;
// slider already moved old frame, create new one in old place
addSliderFrame(old_frame, new_settings, false /*because we are going to reselect new one*/);
// reselect new frame
mFramesSlider->setCurSlider(it->first);
mShiftCopyEnabled = false;
}
}
else
else
{
mFramesSlider->setCurSliderValue((*it).second.mFrame);
LL_WARNS("LAPRAS") << "Moving frame from " << (*it).second.mFrame << " to " << sliderpos << LL_ENDL;
if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos))
{
(*it).second.mFrame = sliderpos;
}
else
{
mFramesSlider->setCurSliderValue((*it).second.mFrame);
}
mShiftCopyEnabled = false;
}
}
}
mTimeSlider->setCurSliderValue(sliderpos);
@ -509,6 +550,7 @@ void LLFloaterEditExtDayCycle::onFrameSliderCallback(const LLSD &data)
void LLFloaterEditExtDayCycle::onFrameSliderDoubleClick(S32 x, S32 y, MASK mask)
{
stopPlay();
onAddTrack();
}
@ -519,6 +561,8 @@ void LLFloaterEditExtDayCycle::onFrameSliderMouseDown(S32 x, S32 y, MASK mask)
std::string slidername = mFramesSlider->getCurSlider();
mShiftCopyEnabled = !slidername.empty() && gKeyboard->currentMask(TRUE) == MASK_SHIFT;
if (!slidername.empty())
{
F32 sliderval = mFramesSlider->getSliderValue(slidername);

View File

@ -77,6 +77,8 @@ public:
virtual void refresh() override;
/* virtual */ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent);
private:
F32 getCurrentFrame() const;
@ -148,6 +150,7 @@ private:
LLSettingsDay::Seconds mDayLength;
U32 mCurrentTrack;
std::string mLastFrameSlider;
bool mShiftCopyEnabled;
LLButton* mAddFrameButton;
LLButton* mDeleteFrameButton;

View File

@ -219,7 +219,8 @@
draw_track="false"
follows="bottom"
height="10"
increment="0.01"
increment="0.005"
overlap_threshold="0.026"
initial_value="0"
layout="topleft"
left="10"
@ -235,7 +236,8 @@
decimal_digits="0"
follows="bottom"
height="10"
increment="0.01"
increment="0.005"
overlap_threshold="0.026"
initial_value="0"
layout="topleft"
left="10"