diff --git a/src/app/script/dialog_class.cpp b/src/app/script/dialog_class.cpp index 14c86e62a..e3b555445 100644 --- a/src/app/script/dialog_class.cpp +++ b/src/app/script/dialog_class.cpp @@ -143,13 +143,17 @@ struct Dialog { gfx::Rect getWindowBounds() const { gfx::Rect bounds = window.bounds(); - // Bounds in scripts will be relative to the the main window - // origin/scale. + // Bounds in scripts will be relative to the parent window + // origin/scale (or main window if a parent window wasn't specified). if (window.ownDisplay()) { - const auto mainWindow = App::instance()->mainWindow(); - const int scale = mainWindow->display()->scale(); + const Display* parentDisplay = window.parentDisplay(); + if (!parentDisplay) { + const auto mainWindow = App::instance()->mainWindow(); + parentDisplay = mainWindow->display(); + } + const int scale = parentDisplay->scale(); const gfx::Point dialogOrigin = window.display()->nativeWindow()->contentRect().origin(); - const gfx::Point mainOrigin = mainWindow->display()->nativeWindow()->contentRect().origin(); + const gfx::Point mainOrigin = parentDisplay->nativeWindow()->contentRect().origin(); bounds.setOrigin((dialogOrigin - mainOrigin) / scale); } return bounds; @@ -159,9 +163,14 @@ struct Dialog { if (window.ownDisplay()) { window.expandWindow(rc.size()); - const auto mainWindow = App::instance()->mainWindow(); - const int scale = mainWindow->display()->scale(); - const gfx::Point mainOrigin = mainWindow->display()->nativeWindow()->contentRect().origin(); + const Display* parentDisplay = window.parentDisplay(); + if (!parentDisplay) { + const auto mainWindow = App::instance()->mainWindow(); + parentDisplay = mainWindow->display(); + } + + const int scale = parentDisplay->scale(); + const gfx::Point mainOrigin = parentDisplay->nativeWindow()->contentRect().origin(); gfx::Rect frame = window.display()->nativeWindow()->contentRect(); frame.setOrigin(mainOrigin + rc.origin() * scale); window.display()->nativeWindow()->setFrame(frame); @@ -264,6 +273,13 @@ int Dialog_new(lua_State* L) dlg->window.setText(lua_tostring(L, -1)); lua_pop(L, 1); + type = lua_getfield(L, 1, "parent"); + if (type != LUA_TNIL) { + if (auto parentDlg = may_get_obj(L, -1)) + dlg->window.setParentDisplay(parentDlg->window.display()); + } + lua_pop(L, 1); + type = lua_getfield(L, 1, "onclose"); if (type == LUA_TFUNCTION) { Dialog_connect_signal( diff --git a/src/ui/manager.cpp b/src/ui/manager.cpp index 8a0f56fe4..5dc48fd83 100644 --- a/src/ui/manager.cpp +++ b/src/ui/manager.cpp @@ -1318,7 +1318,9 @@ void Manager::_closingAppWithException() // Configures the window for begin the loop void Manager::_openWindow(Window* window, bool center) { - Display* parentDisplay = getForegroundDisplay(); + Display* parentDisplay = (window->parentDisplay() ? + window->parentDisplay(): + getForegroundDisplay()); ASSERT(parentDisplay); // Opening other window in the "close app" state, ok, let's back to normal. diff --git a/src/ui/window.cpp b/src/ui/window.cpp index fe6ba862c..bd322db3a 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2018-2022 Igara Studio S.A. +// Copyright (C) 2018-2023 Igara Studio S.A. // Copyright (C) 2001-2017 David Capello // // This file is released under the terms of the MIT license. @@ -335,8 +335,12 @@ void Window::centerWindow(Display* parentDisplay) if (m_isAutoRemap) remapWindow(); - if (!parentDisplay) - parentDisplay = manager()->getDefault()->display(); + if (!parentDisplay) { + if (m_parentDisplay) + parentDisplay = m_parentDisplay; + else + parentDisplay = manager()->getDefault()->display(); + } ASSERT(parentDisplay); diff --git a/src/ui/window.h b/src/ui/window.h index ab926eb0d..80a1b1382 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2019-2022 Igara Studio S.A. +// Copyright (C) 2019-2023 Igara Studio S.A. // Copyright (C) 2001-2017 David Capello // // This file is released under the terms of the MIT license. @@ -28,6 +28,12 @@ namespace ui { explicit Window(Type type, const std::string& text = ""); ~Window(); + // Preset parent display (instead of using the foreground/main + // window). Useful to display an alert/subdialog inside a specific + // window. + void setParentDisplay(Display* display) { m_parentDisplay = display; } + Display* parentDisplay() const { return m_parentDisplay; } + bool ownDisplay() const { return m_ownDisplay; } Display* display() const; void setDisplay(Display* display, const bool own); @@ -109,6 +115,7 @@ namespace ui { void limitSize(int* w, int* h); void moveWindow(const gfx::Rect& rect, bool use_blit); + Display* m_parentDisplay = nullptr; Display* m_display; Widget* m_closer; Label* m_titleLabel;