1// Aseprite
2// Copyright (c) 2020-2022 Igara Studio S.A.
3// Copyright (C) 2001-2015 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "app/ui/search_entry.h"
13
14#include "app/ui/skin/skin_theme.h"
15#include "os/surface.h"
16#include "ui/graphics.h"
17#include "ui/message.h"
18#include "ui/paint_event.h"
19#include "ui/size_hint_event.h"
20
21#include <algorithm>
22
23namespace app {
24
25using namespace app::skin;
26using namespace gfx;
27using namespace ui;
28
29SearchEntry::SearchEntry()
30 : Entry(256, "")
31{
32}
33
34bool SearchEntry::onProcessMessage(ui::Message* msg)
35{
36 switch (msg->type()) {
37 case kMouseDownMessage: {
38 Rect closeBounds = getCloseIconBounds();
39 Point mousePos = static_cast<MouseMessage*>(msg)->position()
40 - bounds().origin();
41
42 if (closeBounds.contains(mousePos)) {
43 setText("");
44 onChange();
45 return true;
46 }
47 break;
48 }
49 }
50 return Entry::onProcessMessage(msg);
51}
52
53void SearchEntry::onPaint(ui::PaintEvent& ev)
54{
55 auto theme = SkinTheme::get(this);
56 theme->paintEntry(ev);
57
58 os::Surface* icon = theme->parts.iconSearch()->bitmap(0);
59 Rect bounds = clientBounds();
60 ev.graphics()->drawColoredRgbaSurface(
61 icon, theme->colors.text(),
62 bounds.x + border().left(),
63 bounds.y + bounds.h/2 - icon->height()/2);
64
65 if (!text().empty()) {
66 icon = theme->parts.iconClose()->bitmap(0);
67 ev.graphics()->drawColoredRgbaSurface(
68 icon, theme->colors.text(),
69 bounds.x + bounds.w - border().right() - childSpacing() - icon->width(),
70 bounds.y + bounds.h/2 - icon->height()/2);
71 }
72}
73
74void SearchEntry::onSizeHint(SizeHintEvent& ev)
75{
76 Entry::onSizeHint(ev);
77 Size sz = ev.sizeHint();
78
79 auto theme = SkinTheme::get(this);
80 auto icon = theme->parts.iconSearch()->bitmap(0);
81 sz.h = std::max(sz.h, icon->height()+border().height());
82
83 ev.setSizeHint(sz);
84}
85
86Rect SearchEntry::onGetEntryTextBounds() const
87{
88 auto theme = SkinTheme::get(this);
89 Rect bounds = Entry::onGetEntryTextBounds();
90 auto icon1 = theme->parts.iconSearch()->bitmap(0);
91 auto icon2 = theme->parts.iconClose()->bitmap(0);
92 bounds.x += childSpacing() + icon1->width();
93 bounds.w -= 2*childSpacing() + icon1->width() + icon2->width();
94 return bounds;
95}
96
97Rect SearchEntry::getCloseIconBounds() const
98{
99 auto theme = SkinTheme::get(this);
100 Rect bounds = clientBounds();
101 auto icon = theme->parts.iconClose()->bitmap(0);
102 bounds.x += bounds.w - border().right() - childSpacing() - icon->width();
103 bounds.y += bounds.h/2 - icon->height()/2;
104 bounds.w = icon->width();
105 bounds.h = icon->height();
106 return bounds;
107}
108
109} // namespace app
110