mirror of https://github.com/aseprite/aseprite.git
Improve the layout selector UI
Changes: * Now we use the "user data" icon as the button to expand the layouts combobox * Added a tooltip to this icon * Added buttons to configure the Timeline position in the same combobox * Fixed some bugs in Dock using space for hidden widgets
This commit is contained in:
parent
ec95323856
commit
544f711adc
|
@ -1205,6 +1205,9 @@ help_twitter = Twitter
|
|||
help_enter_license = Enter &License
|
||||
help_about = &About
|
||||
|
||||
[main_window]
|
||||
layout = User Interface Layout
|
||||
|
||||
[mask_by_color]
|
||||
title = Select Color
|
||||
label_color = Color:
|
||||
|
|
|
@ -53,7 +53,8 @@ ConfigureTimelinePopup::ConfigureTimelinePopup()
|
|||
m_box = new app::gen::TimelineConf();
|
||||
addChild(m_box);
|
||||
|
||||
m_box->position()->ItemChange.connect([this] { onChangePosition(); });
|
||||
m_box->position()->ItemChange.connect(
|
||||
[this] { onChangeTimelinePosition(m_box->position()->selectedItem()); });
|
||||
m_box->firstFrame()->Change.connect([this] { onChangeFirstFrame(); });
|
||||
m_box->merge()->Click.connect([this] { onChangeType(); });
|
||||
m_box->tint()->Click.connect([this] { onChangeType(); });
|
||||
|
@ -147,12 +148,12 @@ bool ConfigureTimelinePopup::onProcessMessage(ui::Message* msg)
|
|||
return PopupWindow::onProcessMessage(msg);
|
||||
}
|
||||
|
||||
void ConfigureTimelinePopup::onChangePosition()
|
||||
void ConfigureTimelinePopup::onChangeTimelinePosition(int option)
|
||||
{
|
||||
gen::TimelinePosition newTimelinePos = gen::TimelinePosition::BOTTOM;
|
||||
|
||||
int selITem = m_box->position()->selectedItem();
|
||||
switch (selITem) {
|
||||
int selItem = option;
|
||||
switch (selItem) {
|
||||
case 0: newTimelinePos = gen::TimelinePosition::LEFT; break;
|
||||
case 1: newTimelinePos = gen::TimelinePosition::RIGHT; break;
|
||||
case 2: newTimelinePos = gen::TimelinePosition::BOTTOM; break;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2025 Igara Studio S.A.
|
||||
// Copyright (C) 2022-2025 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
|
@ -31,9 +31,10 @@ class ConfigureTimelinePopup : public ui::PopupWindow {
|
|||
public:
|
||||
ConfigureTimelinePopup();
|
||||
|
||||
static void onChangeTimelinePosition(int option);
|
||||
|
||||
protected:
|
||||
bool onProcessMessage(ui::Message* msg) override;
|
||||
void onChangePosition();
|
||||
void onChangeFirstFrame();
|
||||
void onChangeType();
|
||||
void onOpacity();
|
||||
|
|
|
@ -227,17 +227,16 @@ void Dock::onSizeHint(ui::SizeHintEvent& ev)
|
|||
{
|
||||
gfx::Size sz = border().size();
|
||||
|
||||
if (m_sides[kLeftIndex])
|
||||
if (hasVisibleSide(kLeftIndex))
|
||||
sz.w += m_sides[kLeftIndex]->sizeHint().w + childSpacing();
|
||||
if (m_sides[kRightIndex])
|
||||
if (hasVisibleSide(kRightIndex))
|
||||
sz.w += m_sides[kRightIndex]->sizeHint().w + childSpacing();
|
||||
if (m_sides[kTopIndex])
|
||||
if (hasVisibleSide(kTopIndex))
|
||||
sz.h += m_sides[kTopIndex]->sizeHint().h + childSpacing();
|
||||
if (m_sides[kBottomIndex])
|
||||
if (hasVisibleSide(kBottomIndex))
|
||||
sz.h += m_sides[kBottomIndex]->sizeHint().h + childSpacing();
|
||||
if (m_sides[kCenterIndex]) {
|
||||
if (hasVisibleSide(kCenterIndex))
|
||||
sz += m_sides[kCenterIndex]->sizeHint();
|
||||
}
|
||||
|
||||
ev.setSizeHint(sz);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ private:
|
|||
const gfx::Rect& separator,
|
||||
const int index)> f);
|
||||
|
||||
bool hasVisibleSide(const int i) const { return (m_sides[i] && m_sides[i]->isVisible()); }
|
||||
|
||||
std::array<Widget*, kSides> m_sides;
|
||||
std::array<int, kSides> m_aligns;
|
||||
std::array<gfx::Size, kSides> m_sizes;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2021 Igara Studio S.A.
|
||||
// Copyright (C) 2021-2022 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
@ -11,10 +11,14 @@
|
|||
#include "app/ui/layout_selector.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/i18n/strings.h"
|
||||
#include "app/ui/button_set.h"
|
||||
#include "app/ui/configure_timeline_popup.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/separator_in_view.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "ui/listitem.h"
|
||||
#include "ui/tooltips.h"
|
||||
#include "ui/window.h"
|
||||
|
||||
#define ANI_TICKS 5
|
||||
|
@ -49,6 +53,41 @@ private:
|
|||
LayoutId m_id;
|
||||
};
|
||||
|
||||
// TODO Similar ButtonSet to the one in timeline_conf.xml
|
||||
class TimelineButtons : public ButtonSet {
|
||||
public:
|
||||
TimelineButtons() : ButtonSet(2)
|
||||
{
|
||||
addItem(Strings::timeline_conf_left())->processMnemonicFromText();
|
||||
addItem(Strings::timeline_conf_right())->processMnemonicFromText();
|
||||
addItem(Strings::timeline_conf_bottom(), 2)->processMnemonicFromText();
|
||||
|
||||
Preferences::instance().general.timelinePosition.AfterChange.connect(
|
||||
[this](gen::TimelinePosition position) {
|
||||
int selItem = 0;
|
||||
switch (position) {
|
||||
case gen::TimelinePosition::LEFT: selItem = 0; break;
|
||||
case gen::TimelinePosition::RIGHT: selItem = 1; break;
|
||||
case gen::TimelinePosition::BOTTOM: selItem = 2; break;
|
||||
}
|
||||
setSelectedItem(selItem, false);
|
||||
});
|
||||
|
||||
InitTheme.connect([this] {
|
||||
auto theme = skin::SkinTheme::get(this);
|
||||
setStyle(theme->styles.separatorInView());
|
||||
});
|
||||
initTheme();
|
||||
}
|
||||
|
||||
private:
|
||||
void onItemChange(Item* item) override
|
||||
{
|
||||
ButtonSet::onItemChange(item);
|
||||
ConfigureTimelinePopup::onChangeTimelinePosition(selectedItem());
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
void LayoutSelector::LayoutComboBox::onChange()
|
||||
|
@ -58,7 +97,8 @@ void LayoutSelector::LayoutComboBox::onChange()
|
|||
}
|
||||
}
|
||||
|
||||
LayoutSelector::LayoutSelector() : m_button("", "\xc3\xb7")
|
||||
LayoutSelector::LayoutSelector(TooltipManager* tooltipManager)
|
||||
: m_button(SkinTheme::instance()->parts.iconUserData())
|
||||
{
|
||||
m_button.Click.connect([this]() { switchSelector(); });
|
||||
|
||||
|
@ -66,6 +106,15 @@ LayoutSelector::LayoutSelector() : m_button("", "\xc3\xb7")
|
|||
|
||||
addChild(&m_comboBox);
|
||||
addChild(&m_button);
|
||||
|
||||
setupTooltips(tooltipManager);
|
||||
|
||||
InitTheme.connect([this] {
|
||||
noBorderNoChildSpacing();
|
||||
m_comboBox.noBorderNoChildSpacing();
|
||||
m_button.noBorderNoChildSpacing();
|
||||
});
|
||||
initTheme();
|
||||
}
|
||||
|
||||
LayoutSelector::~LayoutSelector()
|
||||
|
@ -80,8 +129,8 @@ void LayoutSelector::onAnimationFrame()
|
|||
case ANI_EXPANDING:
|
||||
case ANI_COLLAPSING: {
|
||||
const double t = animationTime();
|
||||
m_comboBox.setSizeHint(gfx::Size((1.0 - t) * m_startSize.w + t * m_endSize.w,
|
||||
(1.0 - t) * m_startSize.h + t * m_endSize.h));
|
||||
m_comboBox.setSizeHint(gfx::Size(int(inbetween(m_startSize.w, m_endSize.w, t)),
|
||||
int(inbetween(m_startSize.h, m_endSize.h, t))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -112,8 +161,11 @@ void LayoutSelector::switchSelector()
|
|||
|
||||
// Create the combobox for first time
|
||||
if (m_comboBox.getItemCount() == 0) {
|
||||
m_comboBox.addItem(new SeparatorInView("Layout", HORIZONTAL));
|
||||
m_comboBox.addItem(new LayoutItem(LayoutId::DEFAULT, "Default"));
|
||||
m_comboBox.addItem(new LayoutItem(LayoutId::DEFAULT_MIRROR, "Default / Mirror"));
|
||||
m_comboBox.addItem(new SeparatorInView("Timeline", HORIZONTAL));
|
||||
m_comboBox.addItem(new TimelineButtons());
|
||||
}
|
||||
|
||||
m_comboBox.setVisible(true);
|
||||
|
@ -131,4 +183,9 @@ void LayoutSelector::switchSelector()
|
|||
startAnimation((expand ? ANI_EXPANDING : ANI_COLLAPSING), ANI_TICKS);
|
||||
}
|
||||
|
||||
void LayoutSelector::setupTooltips(TooltipManager* tooltipManager)
|
||||
{
|
||||
tooltipManager->addTooltipFor(&m_button, Strings::main_window_layout(), TOP);
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
|
|
@ -9,13 +9,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "app/ui/dockable.h"
|
||||
#include "app/ui/icon_button.h"
|
||||
#include "ui/animated_widget.h"
|
||||
#include "ui/box.h"
|
||||
#include "ui/combobox.h"
|
||||
#include "ui/link_label.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace ui {
|
||||
class TooltipManager;
|
||||
}
|
||||
|
||||
namespace app {
|
||||
|
||||
class LayoutSelector : public ui::HBox,
|
||||
|
@ -32,19 +36,20 @@ class LayoutSelector : public ui::HBox,
|
|||
};
|
||||
|
||||
public:
|
||||
LayoutSelector();
|
||||
LayoutSelector(ui::TooltipManager* tooltipManager);
|
||||
~LayoutSelector();
|
||||
|
||||
// Dockable impl
|
||||
int dockableAt() const override { return ui::TOP | ui::BOTTOM; }
|
||||
|
||||
private:
|
||||
void setupTooltips(ui::TooltipManager* tooltipManager);
|
||||
void onAnimationFrame() override;
|
||||
void onAnimationStop(int animation) override;
|
||||
void switchSelector();
|
||||
|
||||
LayoutComboBox m_comboBox;
|
||||
ui::LinkLabel m_button;
|
||||
IconButton m_button;
|
||||
gfx::Size m_startSize;
|
||||
gfx::Size m_endSize;
|
||||
};
|
||||
|
|
|
@ -93,7 +93,6 @@ MainWindow::MainWindow()
|
|||
, m_tooltipManager(new TooltipManager)
|
||||
, m_dock(new Dock)
|
||||
, m_customizableDock(new Dock)
|
||||
, m_layoutSelector(new LayoutSelector)
|
||||
, m_mode(NormalMode)
|
||||
, m_homeView(nullptr)
|
||||
, m_scalePanic(nullptr)
|
||||
|
@ -117,7 +116,7 @@ MainWindow::MainWindow()
|
|||
void MainWindow::initialize()
|
||||
{
|
||||
m_menuBar = std::make_unique<MainMenuBar>();
|
||||
m_layoutSelector = std::make_unique<LayoutSelector>();
|
||||
m_layoutSelector = std::make_unique<LayoutSelector>(m_tooltipManager);
|
||||
|
||||
// Register commands to load menus+shortcuts for these commands
|
||||
Editor::registerCommands();
|
||||
|
|
Loading…
Reference in New Issue