mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-09-18 10:23:43 +08:00
cabana: center speed dropdown label, add divider after loop button (#38785)
This commit is contained in:
@@ -442,18 +442,21 @@ bool menuButton(const char *id, const std::string &text, const char *popup_id, b
|
||||
// on press; a press while it is open toggles it closed (imgui closes the popup at the end of the frame of
|
||||
// a click outside it, so only open when it is not already open)
|
||||
if (bold) pushBoldFont();
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, popup_open ? style.Colors[ImGuiCol_ButtonActive] : ImVec4(0, 0, 0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
|
||||
const bool clicked = ImGui::ButtonEx((text + "###" + id).c_str(), ImVec2(width, 0.0f), ImGuiButtonFlags_PressedOnClick);
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor();
|
||||
const float text_width = ImGui::CalcTextSize(text.c_str(), nullptr, true).x;
|
||||
const float ascent = ImGui::GetFontBaked()->Ascent;
|
||||
// the text and the arrow are centered as a group in the button
|
||||
const float padding_x = std::max(style.FramePadding.x, (width - (text_width + MENU_ARROW_SPACING + MENU_ARROW_SIZE)) * 0.5f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, popup_open ? style.Colors[ImGuiCol_ButtonActive] : ImVec4(0, 0, 0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(padding_x, style.FramePadding.y));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
|
||||
const bool clicked = ImGui::ButtonEx((text + "###" + id).c_str(), ImVec2(width, 0.0f), ImGuiButtonFlags_PressedOnClick);
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleColor();
|
||||
if (bold) popBoldFont();
|
||||
// a 6 px arrow right after the text, sitting on the text baseline
|
||||
const ImVec2 min = ImGui::GetItemRectMin();
|
||||
const float x = min.x + style.FramePadding.x + text_width + MENU_ARROW_SPACING;
|
||||
const float x = min.x + padding_x + text_width + MENU_ARROW_SPACING;
|
||||
const float baseline = min.y + style.FramePadding.y + ascent;
|
||||
ImGui::GetWindowDrawList()->AddTriangleFilled(ImVec2(x, baseline - MENU_ARROW_SIZE * 0.5f),
|
||||
ImVec2(x + MENU_ARROW_SIZE, baseline - MENU_ARROW_SIZE * 0.5f),
|
||||
|
||||
@@ -182,7 +182,7 @@ float toolbarWidth(const std::vector<ToolbarItem> &items, size_t spacer_index);
|
||||
void drawToolbar(const std::vector<ToolbarItem> &items, size_t spacer_index);
|
||||
|
||||
// an auto-raise button that opens `popup_id` below itself, with a dropdown arrow after the text. width 0:
|
||||
// sized to the text, otherwise the arrow sits at the right edge
|
||||
// sized to the text, otherwise the text and the arrow are centered in the button
|
||||
float menuButtonWidth(const std::string &text, bool bold = false);
|
||||
bool menuButton(const char *id, const std::string &text, const char *popup_id, bool bold = false, float width = 0.0f);
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ static float toolbarHeight() { return TOOLBAR_MARGIN_Y + ImGui::GetFrameHeight()
|
||||
void VideoWidget::drawPlaybackController() {
|
||||
beginToolbar();
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + TOOLBAR_MARGIN_Y);
|
||||
const float speed_width = menuButtonWidth("0.05x ", true);
|
||||
const float speed_width = menuButtonWidth("0.05x", true);
|
||||
|
||||
const char *play_icon = can->isPaused() ? icon::PLAY : icon::PAUSE;
|
||||
const char *play_tooltip = can->isPaused() ? "Play" : "Pause";
|
||||
@@ -186,21 +186,25 @@ void VideoWidget::drawPlaybackController() {
|
||||
}
|
||||
// the expanding spacer: the items after it are right aligned as long as everything fits
|
||||
const size_t spacer_index = items.size();
|
||||
if (!can->liveStreaming()) {
|
||||
items.push_back({toolbarButtonWidth(loop_icon), [&]() { if (toolButton("loop", loop_icon, "Loop playback")) loopPlaybackClicked(); },
|
||||
"Loop playback", [this]() { loopPlaybackClicked(); }});
|
||||
}
|
||||
items.push_back({speed_width, [&]() { drawSpeedDropdown(speed_width); }});
|
||||
if (!can->liveStreaming()) {
|
||||
ToolbarItem separator{TOOLBAR_SEPARATOR_EXTENT, []() {
|
||||
auto separator = []() {
|
||||
ToolbarItem item{TOOLBAR_SEPARATOR_EXTENT, []() {
|
||||
// a 1 px separator line centered in TOOLBAR_SEPARATOR_EXTENT, inset from the top and bottom
|
||||
const ImVec2 min = ImGui::GetCursorScreenPos();
|
||||
ImGui::Dummy(ImVec2(TOOLBAR_SEPARATOR_EXTENT, ImGui::GetFrameHeight()));
|
||||
const float x = std::floor(min.x + TOOLBAR_SEPARATOR_EXTENT * 0.5f);
|
||||
ImGui::GetWindowDrawList()->AddLine(ImVec2(x, min.y + 4.0f), ImVec2(x, min.y + ImGui::GetFrameHeight() - 4.0f), ImGui::GetColorU32(ImGuiCol_Separator));
|
||||
}};
|
||||
separator.in_menu = false;
|
||||
items.push_back(std::move(separator));
|
||||
item.in_menu = false;
|
||||
return item;
|
||||
};
|
||||
if (!can->liveStreaming()) {
|
||||
items.push_back({toolbarButtonWidth(loop_icon), [&]() { if (toolButton("loop", loop_icon, "Loop playback")) loopPlaybackClicked(); },
|
||||
"Loop playback", [this]() { loopPlaybackClicked(); }});
|
||||
items.push_back(separator());
|
||||
}
|
||||
items.push_back({speed_width, [&]() { drawSpeedDropdown(speed_width); }});
|
||||
if (!can->liveStreaming()) {
|
||||
items.push_back(separator());
|
||||
items.push_back({toolbarButtonWidth(icon::INFO_CIRCLE),
|
||||
[&]() { if (toolButton("route_info", icon::INFO_CIRCLE, "View route details")) showRouteInfo(); },
|
||||
"View route details", [this]() { showRouteInfo(); }});
|
||||
@@ -221,16 +225,16 @@ void VideoWidget::toggleTimeDisplay() {
|
||||
settings.absolute_time = !settings.absolute_time;
|
||||
}
|
||||
|
||||
static std::string speedText(float speed, const char *suffix) {
|
||||
static std::string speedText(float speed) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "%gx%s", speed, suffix);
|
||||
snprintf(buf, sizeof(buf), "%gx", speed);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void VideoWidget::createSpeedDropdown() {
|
||||
speed_index_ = NORMAL_SPEED_INDEX;
|
||||
can->setSpeed(speeds[speed_index_]);
|
||||
speed_text_ = speedText(speeds[speed_index_], " ");
|
||||
speed_text_ = speedText(speeds[speed_index_]);
|
||||
}
|
||||
|
||||
void VideoWidget::drawSpeedDropdown(float width) {
|
||||
@@ -247,14 +251,14 @@ void VideoWidget::drawSpeedMenuItems() {
|
||||
const float indent = ImGui::GetFontSize();
|
||||
float label_width = 0;
|
||||
for (int i = 0; i < (int)std::size(speeds); ++i) {
|
||||
label_width = std::max(label_width, ImGui::CalcTextSize(speedText(speeds[i], "").c_str()).x);
|
||||
label_width = std::max(label_width, ImGui::CalcTextSize(speedText(speeds[i]).c_str()).x);
|
||||
}
|
||||
for (int i = 0; i < (int)std::size(speeds); ++i) {
|
||||
const float speed = speeds[i];
|
||||
if (radioMenuItem(speedText(speed, "").c_str(), speed_index_ == i, indent + label_width + indent)) {
|
||||
if (radioMenuItem(speedText(speed).c_str(), speed_index_ == i, indent + label_width + indent)) {
|
||||
speed_index_ = i;
|
||||
can->setSpeed(speed);
|
||||
speed_text_ = speedText(speed, " ");
|
||||
speed_text_ = speedText(speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user