aseprite/src/app/console.cpp

204 lines
4.2 KiB
C++
Raw Normal View History

2015-02-12 23:16:25 +08:00
// Aseprite
// Copyright (C) 2018-2020 Igara Studio S.A.
2018-07-04 23:35:15 +08:00
// Copyright (C) 2001-2018 David Capello
2015-02-12 23:16:25 +08:00
//
2016-08-27 04:02:58 +08:00
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
2007-09-19 07:57:02 +08:00
#ifdef HAVE_CONFIG_H
2007-09-19 07:57:02 +08:00
#include "config.h"
#endif
2007-09-19 07:57:02 +08:00
#include "app/console.h"
2007-09-19 07:57:02 +08:00
#include "app/app.h"
#include "app/context.h"
#include "app/modules/gui.h"
#include "app/ui/status_bar.h"
#include "base/bind.h"
#include "base/memory.h"
#include "base/string.h"
2018-07-04 23:35:15 +08:00
#include "ui/system.h"
#include "ui/ui.h"
#include <cstdarg>
#include <cstdio>
#include <memory>
namespace app {
2007-09-19 07:57:02 +08:00
using namespace ui;
2018-12-15 05:08:12 +08:00
class Console::ConsoleWindow : public Window {
public:
ConsoleWindow() : Window(Window::WithTitleBar, "Console"),
m_textbox("", WORDWRAP),
m_button("Cancel") {
2018-12-15 05:08:12 +08:00
m_button.Click.connect(base::Bind<void>(&ConsoleWindow::closeWindow, this, &m_button));
// When the window is closed, we clear the text
Close.connect(
base::Bind<void>(
[this] {
m_textbox.setText(std::string());
}));
m_view.attachToView(&m_textbox);
Grid* grid = new Grid(1, false);
grid->addChildInCell(&m_view, 1, 1, HORIZONTAL | VERTICAL);
grid->addChildInCell(&m_button, 1, 1, CENTER);
addChild(grid);
m_textbox.setFocusMagnet(true);
2018-12-15 05:08:12 +08:00
m_button.setFocusMagnet(true);
m_view.setExpansive(true);
initTheme();
2018-12-15 05:08:12 +08:00
}
void addMessage(const std::string& msg) {
if (!m_hasText) {
m_hasText = true;
centerConsole();
2018-12-15 05:08:12 +08:00
}
m_textbox.setText(m_textbox.text() + msg);
}
bool isConsoleVisible() const {
return (m_hasText && isVisible());
}
void centerConsole() {
initTheme();
remapWindow();
setBounds(gfx::Rect(0, 0, ui::display_w()*9/10, ui::display_h()*6/10));
centerWindow();
invalidate();
}
2018-12-15 05:08:12 +08:00
private:
bool onProcessMessage(ui::Message* msg) override {
switch (msg->type()) {
case ui::kKeyDownMessage:
#if defined __APPLE__
if (msg->onlyCmdPressed())
#else
if (msg->onlyCtrlPressed())
#endif
{
if (static_cast<KeyMessage*>(msg)->scancode() == kKeyC)
set_clipboard_text(m_textbox.text());
}
break;
}
return Window::onProcessMessage(msg);
}
void onInitTheme(InitThemeEvent& ev) override {
Window::onInitTheme(ev);
m_button.setMinSize(gfx::Size(60*ui::guiscale(), 0));
}
2018-12-15 05:08:12 +08:00
View m_view;
TextBox m_textbox;
Button m_button;
bool m_hasText = false;
};
int Console::m_consoleCounter = 0;
std::unique_ptr<Console::ConsoleWindow> Console::m_console = nullptr;
2007-09-19 07:57:02 +08:00
Console::Console(Context* ctx)
: m_withUI(false)
2007-09-19 07:57:02 +08:00
{
2018-07-04 23:35:15 +08:00
if (!ui::is_ui_thread())
return;
if (ctx)
m_withUI = (ctx->isUIAvailable());
else
m_withUI =
(App::instance() &&
App::instance()->isGui() &&
Manager::getDefault() &&
Manager::getDefault()->getDisplay());
if (!m_withUI)
return;
2007-09-19 07:57:02 +08:00
2018-12-15 05:08:12 +08:00
++m_consoleCounter;
if (m_console || m_consoleCounter > 1)
2007-09-19 07:57:02 +08:00
return;
m_console.reset(new ConsoleWindow);
2007-09-19 07:57:02 +08:00
}
Console::~Console()
2007-09-19 07:57:02 +08:00
{
if (!m_withUI)
return;
2018-12-15 05:08:12 +08:00
--m_consoleCounter;
2007-09-19 07:57:02 +08:00
2018-12-15 05:08:12 +08:00
if (m_console && m_console->isConsoleVisible()) {
m_console->manager()->attractFocus(m_console.get());
2018-12-15 05:08:12 +08:00
m_console->openWindowInForeground();
}
2007-09-19 07:57:02 +08:00
if (m_consoleCounter == 0)
m_console.reset();
2007-09-19 07:57:02 +08:00
}
void Console::printf(const char* format, ...)
2007-09-19 07:57:02 +08:00
{
std::va_list ap;
va_start(ap, format);
std::string msg = base::string_vprintf(format, ap);
va_end(ap);
2007-09-19 07:57:02 +08:00
2018-12-15 05:08:12 +08:00
if (!m_withUI || !m_console) {
fputs(msg.c_str(), stdout);
fflush(stdout);
return;
}
2007-09-19 07:57:02 +08:00
// Open the window
2018-12-15 05:08:12 +08:00
if (!m_console->isVisible()) {
m_console->openWindow();
ui::Manager::getDefault()->invalidate();
}
// Update the textbox
2018-12-15 05:08:12 +08:00
m_console->addMessage(msg);
2007-09-19 07:57:02 +08:00
}
// static
void Console::showException(const std::exception& e)
{
ui::assert_ui_thread();
if (!ui::is_ui_thread()) {
LOG(ERROR, "A problem has occurred.\n\nDetails:\n%s\n", e.what());
return;
}
Console console;
if (typeid(e) == typeid(std::bad_alloc))
console.printf("There is not enough memory to complete the action.");
else
console.printf("A problem has occurred.\n\nDetails:\n%s\n", e.what());
}
// static
void Console::notifyNewDisplayConfiguration()
{
if (m_console)
m_console->centerConsole();
}
} // namespace app