mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 05:17:35 +00:00
Assistant: Convert ResultRows to Coolbar Buttons
This gives search results a more tactile look and feel, consistent with other iconified widgets across the system. Custom provider subtitles now appear as tooltips.
This commit is contained in:
parent
ae3ffdd521
commit
518964e7c7
2 changed files with 21 additions and 94 deletions
|
@ -27,33 +27,33 @@ public:
|
||||||
virtual Gfx::Bitmap const* bitmap() const = 0;
|
virtual Gfx::Bitmap const* bitmap() const = 0;
|
||||||
|
|
||||||
String const& title() const { return m_title; }
|
String const& title() const { return m_title; }
|
||||||
String const& subtitle() const { return m_subtitle; }
|
String const& tooltip() const { return m_tooltip; }
|
||||||
int score() const { return m_score; }
|
int score() const { return m_score; }
|
||||||
bool equals(Result const& other) const
|
bool equals(Result const& other) const
|
||||||
{
|
{
|
||||||
return typeid(this) == typeid(&other)
|
return typeid(this) == typeid(&other)
|
||||||
&& title() == other.title()
|
&& title() == other.title()
|
||||||
&& subtitle() == other.subtitle();
|
&& tooltip() == other.tooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Result(String title, String subtitle, int score = 0)
|
Result(String title, String tooltip, int score = 0)
|
||||||
: m_title(move(title))
|
: m_title(move(title))
|
||||||
, m_subtitle(move(subtitle))
|
, m_tooltip(move(tooltip))
|
||||||
, m_score(score)
|
, m_score(score)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String m_title;
|
String m_title;
|
||||||
String m_subtitle;
|
String m_tooltip;
|
||||||
int m_score { 0 };
|
int m_score { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
class AppResult final : public Result {
|
class AppResult final : public Result {
|
||||||
public:
|
public:
|
||||||
AppResult(RefPtr<Gfx::Bitmap> bitmap, String title, String subtitle, NonnullRefPtr<Desktop::AppFile> af, int score)
|
AppResult(RefPtr<Gfx::Bitmap> bitmap, String title, String tooltip, NonnullRefPtr<Desktop::AppFile> af, int score)
|
||||||
: Result(move(title), move(subtitle), score)
|
: Result(move(title), move(tooltip), score)
|
||||||
, m_app_file(move(af))
|
, m_app_file(move(af))
|
||||||
, m_bitmap(move(bitmap))
|
, m_bitmap(move(bitmap))
|
||||||
{
|
{
|
||||||
|
@ -71,7 +71,7 @@ private:
|
||||||
class CalculatorResult final : public Result {
|
class CalculatorResult final : public Result {
|
||||||
public:
|
public:
|
||||||
explicit CalculatorResult(String title)
|
explicit CalculatorResult(String title)
|
||||||
: Result(move(title), "'Enter' will copy to clipboard"sv, 100)
|
: Result(move(title), "Copy to Clipboard"sv, 100)
|
||||||
, m_bitmap(GUI::Icon::default_icon("app-calculator"sv).bitmap_for_size(16))
|
, m_bitmap(GUI::Icon::default_icon("app-calculator"sv).bitmap_for_size(16))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ private:
|
||||||
class URLResult final : public Result {
|
class URLResult final : public Result {
|
||||||
public:
|
public:
|
||||||
explicit URLResult(const URL& url)
|
explicit URLResult(const URL& url)
|
||||||
: Result(url.to_string(), "'Enter' will open this URL in the browser"sv, 50)
|
: Result(url.to_string(), "Open URL in Browser"sv, 50)
|
||||||
, m_bitmap(GUI::Icon::default_icon("app-browser"sv).bitmap_for_size(16))
|
, m_bitmap(GUI::Icon::default_icon("app-browser"sv).bitmap_for_size(16))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,89 +37,16 @@ struct AppState {
|
||||||
String last_query;
|
String last_query;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ResultRow final : public GUI::Widget {
|
class ResultRow final : public GUI::Button {
|
||||||
C_OBJECT(ResultRow)
|
C_OBJECT(ResultRow)
|
||||||
public:
|
|
||||||
void set_image(RefPtr<Gfx::Bitmap> bitmap)
|
|
||||||
{
|
|
||||||
m_image->set_bitmap(bitmap);
|
|
||||||
}
|
|
||||||
void set_title(String text)
|
|
||||||
{
|
|
||||||
m_title->set_text(move(text));
|
|
||||||
}
|
|
||||||
void set_subtitle(String text)
|
|
||||||
{
|
|
||||||
if (text.is_empty()) {
|
|
||||||
if (m_subtitle)
|
|
||||||
m_subtitle->remove_from_parent();
|
|
||||||
m_subtitle = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!m_subtitle) {
|
|
||||||
m_subtitle = m_label_container->add<GUI::Label>();
|
|
||||||
m_subtitle->set_text_alignment(Gfx::TextAlignment::CenterLeft);
|
|
||||||
}
|
|
||||||
m_subtitle->set_text(move(text));
|
|
||||||
}
|
|
||||||
void set_is_highlighted(bool value)
|
|
||||||
{
|
|
||||||
if (m_is_highlighted == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_is_highlighted = value;
|
|
||||||
m_title->set_font_weight(value ? 700 : 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
Function<void()> on_selected;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ResultRow()
|
ResultRow()
|
||||||
{
|
{
|
||||||
auto& layout = set_layout<GUI::HorizontalBoxLayout>();
|
|
||||||
layout.set_spacing(12);
|
|
||||||
layout.set_margins(4);
|
|
||||||
|
|
||||||
m_image = add<GUI::ImageWidget>();
|
|
||||||
|
|
||||||
m_label_container = add<GUI::Widget>();
|
|
||||||
m_label_container->set_layout<GUI::VerticalBoxLayout>();
|
|
||||||
m_label_container->set_fixed_height(30);
|
|
||||||
|
|
||||||
m_title = m_label_container->add<GUI::Label>();
|
|
||||||
m_title->set_text_alignment(Gfx::TextAlignment::CenterLeft);
|
|
||||||
|
|
||||||
set_shrink_to_fit(true);
|
|
||||||
set_fill_with_background_color(true);
|
|
||||||
set_greedy_for_hits(true);
|
set_greedy_for_hits(true);
|
||||||
|
set_fixed_height(36);
|
||||||
|
set_text_alignment(Gfx::TextAlignment::CenterLeft);
|
||||||
|
set_button_style(Gfx::ButtonStyle::Coolbar);
|
||||||
|
set_focus_policy(GUI::FocusPolicy::NoFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mousedown_event(GUI::MouseEvent&) override
|
|
||||||
{
|
|
||||||
set_background_role(ColorRole::MenuBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseup_event(GUI::MouseEvent&) override
|
|
||||||
{
|
|
||||||
set_background_role(ColorRole::NoRole);
|
|
||||||
on_selected();
|
|
||||||
}
|
|
||||||
|
|
||||||
void enter_event(Core::Event&) override
|
|
||||||
{
|
|
||||||
set_background_role(ColorRole::HoverHighlight);
|
|
||||||
}
|
|
||||||
|
|
||||||
void leave_event(Core::Event&) override
|
|
||||||
{
|
|
||||||
set_background_role(ColorRole::NoRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
RefPtr<GUI::ImageWidget> m_image;
|
|
||||||
RefPtr<GUI::Widget> m_label_container;
|
|
||||||
RefPtr<GUI::Label> m_title;
|
|
||||||
RefPtr<GUI::Label> m_subtitle;
|
|
||||||
bool m_is_highlighted { false };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Database {
|
class Database {
|
||||||
|
@ -218,17 +145,16 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
container.set_fill_with_background_color(true);
|
container.set_fill_with_background_color(true);
|
||||||
container.set_frame_shape(Gfx::FrameShape::Window);
|
container.set_frame_shape(Gfx::FrameShape::Window);
|
||||||
auto& layout = container.set_layout<GUI::VerticalBoxLayout>();
|
auto& layout = container.set_layout<GUI::VerticalBoxLayout>();
|
||||||
layout.set_margins({ 8, 8, 0 });
|
layout.set_margins({ 8 });
|
||||||
|
|
||||||
auto& text_box = container.add<GUI::TextBox>();
|
auto& text_box = container.add<GUI::TextBox>();
|
||||||
auto& results_container = container.add<GUI::Widget>();
|
auto& results_container = container.add<GUI::Widget>();
|
||||||
auto& results_layout = results_container.set_layout<GUI::VerticalBoxLayout>();
|
auto& results_layout = results_container.set_layout<GUI::VerticalBoxLayout>();
|
||||||
results_layout.set_margins({ 10, 0 });
|
|
||||||
|
|
||||||
auto mark_selected_item = [&]() {
|
auto mark_selected_item = [&]() {
|
||||||
for (size_t i = 0; i < app_state.visible_result_count; ++i) {
|
for (size_t i = 0; i < app_state.visible_result_count; ++i) {
|
||||||
auto& row = static_cast<Assistant::ResultRow&>(results_container.child_widgets()[i]);
|
auto& row = static_cast<Assistant::ResultRow&>(results_container.child_widgets()[i]);
|
||||||
row.set_is_highlighted(i == app_state.selected_index);
|
row.set_font_weight(i == app_state.selected_index ? 700 : 400);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -285,14 +211,15 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
|
||||||
auto update_ui_timer = Core::Timer::create_single_shot(10, [&] {
|
auto update_ui_timer = Core::Timer::create_single_shot(10, [&] {
|
||||||
results_container.remove_all_children();
|
results_container.remove_all_children();
|
||||||
|
results_layout.set_margins(app_state.visible_result_count ? GUI::Margins { 4, 0, 0, 0 } : GUI::Margins { 0 });
|
||||||
|
|
||||||
for (size_t i = 0; i < app_state.visible_result_count; ++i) {
|
for (size_t i = 0; i < app_state.visible_result_count; ++i) {
|
||||||
auto& result = app_state.results[i];
|
auto& result = app_state.results[i];
|
||||||
auto& match = results_container.add<Assistant::ResultRow>();
|
auto& match = results_container.add<Assistant::ResultRow>();
|
||||||
match.set_image(result.bitmap());
|
match.set_icon(result.bitmap());
|
||||||
match.set_title(result.title());
|
match.set_text(move(result.title()));
|
||||||
match.set_subtitle(result.subtitle());
|
match.set_tooltip(move(result.tooltip()));
|
||||||
match.on_selected = [&result]() {
|
match.on_click = [&result](auto) {
|
||||||
result.activate();
|
result.activate();
|
||||||
GUI::Application::the()->quit();
|
GUI::Application::the()->quit();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue