1// Aseprite
2// Copyright (C) 2020 Igara Studio S.A.
3// Copyright (C) 2018 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/expr_entry.h"
13
14#include "ui/message.h"
15
16#include "fmt/format.h"
17#include "tinyexpr.h"
18
19#include <cmath>
20#include <cstdio>
21
22namespace app {
23
24ExprEntry::ExprEntry()
25 : ui::Entry(1024, "")
26 , m_decimals(0)
27{
28}
29
30bool ExprEntry::onProcessMessage(ui::Message* msg)
31{
32 switch (msg->type()) {
33 case ui::kFocusLeaveMessage: {
34 std::string buf;
35 onFormatExprFocusLeave(buf);
36 if (text() != buf)
37 setText(buf);
38 break;
39 }
40 }
41 return ui::Entry::onProcessMessage(msg);
42}
43
44void ExprEntry::onChange()
45{
46 Entry::onChange();
47 // TODO show expression errors?
48}
49
50int ExprEntry::onGetTextInt() const
51{
52 int err = 0;
53 double v = te_interp(text().c_str(), &err);
54 if (std::isnan(v))
55 return Entry::onGetTextInt();
56 else
57 return int(v);
58}
59
60double ExprEntry::onGetTextDouble() const
61{
62 int err = 0;
63 double v = te_interp(text().c_str(), &err);
64 if (std::isnan(v))
65 return Entry::onGetTextDouble();
66 else
67 return v;
68}
69
70void ExprEntry::onFormatExprFocusLeave(std::string& buf)
71{
72 if (m_decimals == 0)
73 buf = fmt::format("{}", onGetTextInt());
74 else
75 buf = fmt::format("{:.{}f}", onGetTextDouble(), m_decimals);
76}
77
78} // namespace app
79