mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Implement nice commission slider.
This commit is contained in:
parent
3b3d1aa9cc
commit
5299500d78
1 changed files with 133 additions and 28 deletions
|
@ -104,6 +104,126 @@ private:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] object_ptr<Ui::RpWidget> MakeSliderWithTopTag(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<const style::MediaSlider*> sliderStyle,
|
||||||
|
not_null<const style::FlatLabel*> labelStyle,
|
||||||
|
int valuesCount,
|
||||||
|
Fn<int(int)> valueByIndex,
|
||||||
|
int value,
|
||||||
|
Fn<void(int)> valueProgress,
|
||||||
|
Fn<void(int)> valueFinished,
|
||||||
|
Fn<QString(int)> textByValue) {
|
||||||
|
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
||||||
|
const auto raw = result.data();
|
||||||
|
|
||||||
|
const auto labels = raw->add(object_ptr<Ui::RpWidget>(raw));
|
||||||
|
const auto min = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
raw,
|
||||||
|
textByValue(valueByIndex(0)),
|
||||||
|
*labelStyle);
|
||||||
|
const auto max = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
raw,
|
||||||
|
textByValue(valueByIndex(valuesCount - 1)),
|
||||||
|
*labelStyle);
|
||||||
|
const auto current = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
raw,
|
||||||
|
textByValue(value),
|
||||||
|
*labelStyle);
|
||||||
|
const auto slider = raw->add(object_ptr<Ui::MediaSliderWheelless>(
|
||||||
|
raw,
|
||||||
|
*sliderStyle));
|
||||||
|
labels->resize(labels->width(), current->height());
|
||||||
|
struct State {
|
||||||
|
int index = 0;
|
||||||
|
};
|
||||||
|
const auto state = raw->lifetime().make_state<State>(State{ 0 });
|
||||||
|
const auto updatePalette = [=] {
|
||||||
|
min->setTextColorOverride(!state->index
|
||||||
|
? st::windowActiveTextFg->c
|
||||||
|
: st::windowSubTextFg->c);
|
||||||
|
max->setTextColorOverride((state->index == valuesCount - 1)
|
||||||
|
? st::windowActiveTextFg->c
|
||||||
|
: st::windowSubTextFg->c);
|
||||||
|
current->setTextColorOverride(st::windowActiveTextFg->c);
|
||||||
|
};
|
||||||
|
const auto updateByIndex = [=] {
|
||||||
|
updatePalette();
|
||||||
|
|
||||||
|
current->setVisible(state->index > 0
|
||||||
|
&& state->index < valuesCount - 1);
|
||||||
|
const auto outer = labels->width();
|
||||||
|
const auto minWidth = min->width();
|
||||||
|
const auto maxWidth = max->width();
|
||||||
|
const auto currentWidth = current->width();
|
||||||
|
if (minWidth + maxWidth + currentWidth > outer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
min->moveToLeft(0, 0, outer);
|
||||||
|
max->moveToRight(0, 0, outer);
|
||||||
|
|
||||||
|
const auto sliderSkip = sliderStyle->seekSize.width();
|
||||||
|
const auto availableForCurrent = outer - sliderSkip;
|
||||||
|
const auto ratio = state->index / float64(valuesCount - 1);
|
||||||
|
const auto desiredLeft = (sliderSkip / 2)
|
||||||
|
+ availableForCurrent * ratio
|
||||||
|
- (currentWidth / 2);
|
||||||
|
const auto minLeft = minWidth;
|
||||||
|
const auto maxLeft = outer - maxWidth - currentWidth;
|
||||||
|
current->moveToLeft(
|
||||||
|
std::clamp(int(base::SafeRound(desiredLeft)), minLeft, maxLeft),
|
||||||
|
0,
|
||||||
|
outer);
|
||||||
|
};
|
||||||
|
const auto updateByValue = [=](int value) {
|
||||||
|
current->setText(textByValue(value));
|
||||||
|
|
||||||
|
state->index = 0;
|
||||||
|
auto maxIndex = valuesCount - 1;
|
||||||
|
while (state->index < maxIndex) {
|
||||||
|
const auto mid = (state->index + maxIndex) / 2;
|
||||||
|
const auto midValue = valueByIndex(mid);
|
||||||
|
if (midValue == value) {
|
||||||
|
state->index = mid;
|
||||||
|
break;
|
||||||
|
} else if (midValue < value) {
|
||||||
|
state->index = mid + 1;
|
||||||
|
} else {
|
||||||
|
maxIndex = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateByIndex();
|
||||||
|
};
|
||||||
|
const auto progress = [=](int value) {
|
||||||
|
updateByValue(value);
|
||||||
|
valueProgress(value);
|
||||||
|
};
|
||||||
|
const auto finished = [=](int value) {
|
||||||
|
updateByValue(value);
|
||||||
|
valueFinished(value);
|
||||||
|
};
|
||||||
|
style::PaletteChanged() | rpl::start_with_next([=] {
|
||||||
|
updatePalette();
|
||||||
|
}, raw->lifetime());
|
||||||
|
updateByValue(value);
|
||||||
|
|
||||||
|
slider->setPseudoDiscrete(
|
||||||
|
valuesCount,
|
||||||
|
valueByIndex,
|
||||||
|
value,
|
||||||
|
progress,
|
||||||
|
finished);
|
||||||
|
slider->resize(slider->width(), sliderStyle->seekSize.height());
|
||||||
|
|
||||||
|
raw->widthValue() | rpl::start_with_next([=](int width) {
|
||||||
|
labels->resizeToWidth(width);
|
||||||
|
updateByIndex();
|
||||||
|
}, slider->lifetime());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
InnerWidget::InnerWidget(QWidget *parent, not_null<Controller*> controller)
|
InnerWidget::InnerWidget(QWidget *parent, not_null<Controller*> controller)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
|
@ -165,36 +285,21 @@ void InnerWidget::setupCommission() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto valuesCount = int(values.size());
|
const auto valuesCount = int(values.size());
|
||||||
|
|
||||||
auto sliderWithLabel = ::Settings::MakeSliderWithLabel(
|
|
||||||
_container,
|
|
||||||
st::settingsScale,
|
|
||||||
st::settingsScaleLabel,
|
|
||||||
st::normalFont->spacew * 2,
|
|
||||||
st::settingsScaleLabel.style.font->width("89.9%"),
|
|
||||||
true);
|
|
||||||
_container->add(
|
|
||||||
std::move(sliderWithLabel.widget),
|
|
||||||
st::settingsBigScalePadding);
|
|
||||||
const auto slider = sliderWithLabel.slider;
|
|
||||||
const auto label = sliderWithLabel.label;
|
|
||||||
|
|
||||||
const auto updateLabel = [=](int value) {
|
|
||||||
const auto labelText = QString::number(value / 10.) + '%';
|
|
||||||
label->setText(labelText);
|
|
||||||
};
|
|
||||||
const auto setCommission = [=](int value) {
|
const auto setCommission = [=](int value) {
|
||||||
_state.program.commission = value;
|
_state.program.commission = value;
|
||||||
updateLabel(value);
|
|
||||||
};
|
};
|
||||||
updateLabel(commission);
|
_container->add(
|
||||||
|
MakeSliderWithTopTag(
|
||||||
slider->setPseudoDiscrete(
|
_container,
|
||||||
valuesCount,
|
&st::settingsScale,
|
||||||
[=](int index) { return values[index]; },
|
&st::settingsScaleLabel,
|
||||||
commission,
|
valuesCount,
|
||||||
setCommission,
|
[=](int index) { return values[index]; },
|
||||||
setCommission);
|
commission,
|
||||||
|
setCommission,
|
||||||
|
setCommission,
|
||||||
|
[=](int value) { return QString::number(value / 10.) + '%'; }),
|
||||||
|
st::boxRowPadding);
|
||||||
|
|
||||||
Ui::AddSkip(_container);
|
Ui::AddSkip(_container);
|
||||||
Ui::AddDividerText(_container, tr::lng_star_ref_commission_about());
|
Ui::AddDividerText(_container, tr::lng_star_ref_commission_about());
|
||||||
|
@ -233,7 +338,7 @@ void InnerWidget::setupDuration() {
|
||||||
_state.program.durationMonths = (value == kDurationForeverValue)
|
_state.program.durationMonths = (value == kDurationForeverValue)
|
||||||
? 0
|
? 0
|
||||||
: value;
|
: value;
|
||||||
updateLabel(durationMonths);
|
updateLabel(value);
|
||||||
};
|
};
|
||||||
updateLabel(durationMonths);
|
updateLabel(durationMonths);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue