mirror of https://github.com/aseprite/aseprite.git
Add support to close Home tab with middle mouse button or right-click popup menu
This commit is contained in:
parent
926e714f74
commit
ff66ea025c
|
@ -615,6 +615,10 @@
|
||||||
</menu>
|
</menu>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
|
<menu id="tab_popup">
|
||||||
|
<item command="CloseFile" text="&Close" />
|
||||||
|
</menu>
|
||||||
|
|
||||||
<menu id="document_tab_popup">
|
<menu id="document_tab_popup">
|
||||||
<item command="CloseFile" text="&Close" />
|
<item command="CloseFile" text="&Close" />
|
||||||
<separator />
|
<separator />
|
||||||
|
|
|
@ -78,6 +78,7 @@ void AppMenus::reload()
|
||||||
|
|
||||||
PRINTF("Main menu loaded.\n");
|
PRINTF("Main menu loaded.\n");
|
||||||
|
|
||||||
|
m_tabPopupMenu.reset(loadMenuById(handle, "tab_popup"));
|
||||||
m_documentTabPopupMenu.reset(loadMenuById(handle, "document_tab_popup"));
|
m_documentTabPopupMenu.reset(loadMenuById(handle, "document_tab_popup"));
|
||||||
m_layerPopupMenu.reset(loadMenuById(handle, "layer_popup"));
|
m_layerPopupMenu.reset(loadMenuById(handle, "layer_popup"));
|
||||||
m_framePopupMenu.reset(loadMenuById(handle, "frame_popup"));
|
m_framePopupMenu.reset(loadMenuById(handle, "frame_popup"));
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace app {
|
||||||
|
|
||||||
Menu* getRootMenu() { return m_rootMenu; }
|
Menu* getRootMenu() { return m_rootMenu; }
|
||||||
MenuItem* getRecentListMenuitem() { return m_recentListMenuitem; }
|
MenuItem* getRecentListMenuitem() { return m_recentListMenuitem; }
|
||||||
|
Menu* getTabPopupMenu() { return m_tabPopupMenu; }
|
||||||
Menu* getDocumentTabPopupMenu() { return m_documentTabPopupMenu; }
|
Menu* getDocumentTabPopupMenu() { return m_documentTabPopupMenu; }
|
||||||
Menu* getLayerPopupMenu() { return m_layerPopupMenu; }
|
Menu* getLayerPopupMenu() { return m_layerPopupMenu; }
|
||||||
Menu* getFramePopupMenu() { return m_framePopupMenu; }
|
Menu* getFramePopupMenu() { return m_framePopupMenu; }
|
||||||
|
@ -56,6 +57,7 @@ namespace app {
|
||||||
|
|
||||||
base::UniquePtr<Menu> m_rootMenu;
|
base::UniquePtr<Menu> m_rootMenu;
|
||||||
MenuItem* m_recentListMenuitem;
|
MenuItem* m_recentListMenuitem;
|
||||||
|
base::UniquePtr<Menu> m_tabPopupMenu;
|
||||||
base::UniquePtr<Menu> m_documentTabPopupMenu;
|
base::UniquePtr<Menu> m_documentTabPopupMenu;
|
||||||
base::UniquePtr<Menu> m_layerPopupMenu;
|
base::UniquePtr<Menu> m_layerPopupMenu;
|
||||||
base::UniquePtr<Menu> m_framePopupMenu;
|
base::UniquePtr<Menu> m_framePopupMenu;
|
||||||
|
|
|
@ -29,53 +29,30 @@ namespace app {
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
|
|
||||||
static bool close_active_document(Context* context);
|
|
||||||
|
|
||||||
class CloseFileCommand : public Command {
|
class CloseFileCommand : public Command {
|
||||||
public:
|
public:
|
||||||
CloseFileCommand()
|
CloseFileCommand()
|
||||||
: Command("CloseFile",
|
: Command("CloseFile",
|
||||||
"Close File",
|
"Close File",
|
||||||
CmdUIOnlyFlag)
|
CmdUIOnlyFlag) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Command* clone() const override { return new CloseFileCommand(*this); }
|
Command* clone() const override { return new CloseFileCommand(*this); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool onEnabled(Context* context)
|
bool onEnabled(Context* context) override {
|
||||||
{
|
|
||||||
const ContextReader reader(context);
|
|
||||||
const Sprite* sprite(reader.sprite());
|
|
||||||
return sprite != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void onExecute(Context* context)
|
|
||||||
{
|
|
||||||
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||||
|
|
||||||
if (workspace->activeView() == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (DocumentView* docView =
|
|
||||||
dynamic_cast<DocumentView*>(workspace->activeView())) {
|
|
||||||
Document* document = docView->getDocument();
|
|
||||||
if (static_cast<UIContext*>(context)->countViewsOf(document) == 1) {
|
|
||||||
// If we have only one view for this document, close the file.
|
|
||||||
close_active_document(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the active view.
|
|
||||||
WorkspaceView* view = workspace->activeView();
|
WorkspaceView* view = workspace->activeView();
|
||||||
workspace->removeView(view);
|
return (view != nullptr);
|
||||||
delete view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
void onExecute(Context* context) override {
|
||||||
static char* read_authors_txt(const char *filename);
|
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||||
|
WorkspaceView* view = workspace->activeView();
|
||||||
|
if (view)
|
||||||
|
workspace->closeView(view);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CloseAllFilesCommand : public Command {
|
class CloseAllFilesCommand : public Command {
|
||||||
|
@ -83,96 +60,31 @@ public:
|
||||||
CloseAllFilesCommand()
|
CloseAllFilesCommand()
|
||||||
: Command("CloseAllFiles",
|
: Command("CloseAllFiles",
|
||||||
"Close All Files",
|
"Close All Files",
|
||||||
CmdRecordableFlag)
|
CmdRecordableFlag) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Command* clone() const override { return new CloseAllFilesCommand(*this); }
|
Command* clone() const override { return new CloseAllFilesCommand(*this); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool onEnabled(Context* context)
|
void onExecute(Context* context) override {
|
||||||
{
|
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||||
return !context->documents().empty();
|
|
||||||
|
std::vector<DocumentView*> docViews;
|
||||||
|
for (auto view : *workspace) {
|
||||||
|
DocumentView* docView = dynamic_cast<DocumentView*>(view);
|
||||||
|
if (docView)
|
||||||
|
docViews.push_back(docView);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onExecute(Context* context)
|
for (auto docView : docViews) {
|
||||||
{
|
if (!workspace->closeView(docView))
|
||||||
while (true) {
|
|
||||||
if (context->activeDocument() != NULL) {
|
|
||||||
if (!close_active_document(context))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Closes the active document, asking to the user to save it if it is
|
|
||||||
// modified.
|
|
||||||
static bool close_active_document(Context* context)
|
|
||||||
{
|
|
||||||
Document* closedDocument = NULL;
|
|
||||||
bool save_it;
|
|
||||||
bool try_again = true;
|
|
||||||
|
|
||||||
while (try_again) {
|
|
||||||
// This flag indicates if we have to sabe the sprite before to destroy it
|
|
||||||
save_it = false;
|
|
||||||
{
|
|
||||||
// The sprite is locked as reader temporaly
|
|
||||||
const ContextReader reader(context);
|
|
||||||
const Document* document = reader.document();
|
|
||||||
closedDocument = const_cast<Document*>(document);
|
|
||||||
|
|
||||||
// see if the sprite has changes
|
|
||||||
while (document->isModified()) {
|
|
||||||
// ask what want to do the user with the changes in the sprite
|
|
||||||
int ret = Alert::show("Warning<<Saving changes in:<<%s||&Save||Do&n't Save||&Cancel",
|
|
||||||
document->name().c_str());
|
|
||||||
|
|
||||||
if (ret == 1) {
|
|
||||||
// "save": save the changes
|
|
||||||
save_it = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (ret != 2) {
|
|
||||||
// "cancel" or "ESC" */
|
|
||||||
return false; // we back doing nothing
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// "discard"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does we need to save the sprite?
|
|
||||||
if (save_it) {
|
|
||||||
Command* save_command =
|
|
||||||
CommandsModule::instance()->getCommandByName(CommandId::SaveFile);
|
|
||||||
context->executeCommand(save_command);
|
|
||||||
|
|
||||||
try_again = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
try_again = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy the sprite (locking it as writer)
|
|
||||||
{
|
|
||||||
DocumentDestroyer document(context, closedDocument);
|
|
||||||
StatusBar::instance()
|
|
||||||
->setStatusText(0, "Sprite '%s' closed.",
|
|
||||||
document->name().c_str());
|
|
||||||
document.destroyDocument();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Command* CommandFactory::createCloseFileCommand()
|
Command* CommandFactory::createCloseFileCommand()
|
||||||
{
|
{
|
||||||
return new CloseFileCommand;
|
return new CloseFileCommand;
|
||||||
|
|
|
@ -11,9 +11,11 @@
|
||||||
|
|
||||||
#include "app/ui/devconsole_view.h"
|
#include "app/ui/devconsole_view.h"
|
||||||
|
|
||||||
|
#include "app/app_menus.h"
|
||||||
#include "app/ui/workspace.h"
|
#include "app/ui/workspace.h"
|
||||||
#include "ui/entry.h"
|
#include "ui/entry.h"
|
||||||
#include "ui/message.h"
|
#include "ui/message.h"
|
||||||
|
#include "ui/system.h"
|
||||||
#include "ui/textbox.h"
|
#include "ui/textbox.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
|
||||||
|
@ -103,9 +105,19 @@ void DevConsoleView::onClonedFrom(WorkspaceView* from)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevConsoleView::onCloseView(Workspace* workspace)
|
bool DevConsoleView::onCloseView(Workspace* workspace)
|
||||||
{
|
{
|
||||||
workspace->removeView(this);
|
workspace->removeView(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevConsoleView::onTabPopup(Workspace* workspace)
|
||||||
|
{
|
||||||
|
Menu* menu = AppMenus::instance()->getTabPopupMenu();
|
||||||
|
if (!menu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
menu->showPopup(ui::get_mouse_position());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DevConsoleView::onProcessMessage(Message* msg)
|
bool DevConsoleView::onProcessMessage(Message* msg)
|
||||||
|
|
|
@ -33,7 +33,8 @@ namespace app {
|
||||||
WorkspaceView* cloneWorkspaceView() override;
|
WorkspaceView* cloneWorkspaceView() override;
|
||||||
void onWorkspaceViewSelected() override;
|
void onWorkspaceViewSelected() override;
|
||||||
void onClonedFrom(WorkspaceView* from) override;
|
void onClonedFrom(WorkspaceView* from) override;
|
||||||
void onCloseView(Workspace* workspace) override;
|
bool onCloseView(Workspace* workspace) override;
|
||||||
|
void onTabPopup(Workspace* workspace) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool onProcessMessage(ui::Message* msg) override;
|
bool onProcessMessage(ui::Message* msg) override;
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
#include "app/ui/document_view.h"
|
#include "app/ui/document_view.h"
|
||||||
|
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
|
#include "app/app_menus.h"
|
||||||
#include "app/commands/commands.h"
|
#include "app/commands/commands.h"
|
||||||
|
#include "app/document_access.h"
|
||||||
#include "app/modules/editors.h"
|
#include "app/modules/editors.h"
|
||||||
#include "app/modules/palettes.h"
|
#include "app/modules/palettes.h"
|
||||||
#include "app/ui/editor/editor.h"
|
#include "app/ui/editor/editor.h"
|
||||||
|
@ -21,6 +23,7 @@
|
||||||
#include "app/ui/keyboard_shortcuts.h"
|
#include "app/ui/keyboard_shortcuts.h"
|
||||||
#include "app/ui/main_window.h"
|
#include "app/ui/main_window.h"
|
||||||
#include "app/ui/preview_editor.h"
|
#include "app/ui/preview_editor.h"
|
||||||
|
#include "app/ui/status_bar.h"
|
||||||
#include "app/ui/workspace.h"
|
#include "app/ui/workspace.h"
|
||||||
#include "app/ui_context.h"
|
#include "app/ui_context.h"
|
||||||
#include "base/path.h"
|
#include "base/path.h"
|
||||||
|
@ -28,6 +31,8 @@
|
||||||
#include "doc/layer.h"
|
#include "doc/layer.h"
|
||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
#include "ui/accelerator.h"
|
#include "ui/accelerator.h"
|
||||||
|
#include "ui/alert.h"
|
||||||
|
#include "ui/menu.h"
|
||||||
#include "ui/message.h"
|
#include "ui/message.h"
|
||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
@ -224,16 +229,76 @@ void DocumentView::onClonedFrom(WorkspaceView* from)
|
||||||
->setViewScroll(View::getView(srcEditor)->getViewScroll());
|
->setViewScroll(View::getView(srcEditor)->getViewScroll());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentView::onCloseView(Workspace* workspace)
|
bool DocumentView::onCloseView(Workspace* workspace)
|
||||||
{
|
{
|
||||||
|
Context* ctx = UIContext::instance();
|
||||||
|
bool save_it;
|
||||||
|
bool try_again = true;
|
||||||
|
|
||||||
|
while (try_again) {
|
||||||
|
// This flag indicates if we have to sabe the sprite before to destroy it
|
||||||
|
save_it = false;
|
||||||
|
{
|
||||||
|
// see if the sprite has changes
|
||||||
|
while (m_document->isModified()) {
|
||||||
|
// ask what want to do the user with the changes in the sprite
|
||||||
|
int ret = Alert::show("Warning<<Saving changes in:<<%s||&Save||Do&n't Save||&Cancel",
|
||||||
|
m_document->name().c_str());
|
||||||
|
|
||||||
|
if (ret == 1) {
|
||||||
|
// "save": save the changes
|
||||||
|
save_it = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (ret != 2) {
|
||||||
|
// "cancel" or "ESC" */
|
||||||
|
return false; // we back doing nothing
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// "discard"
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does we need to save the sprite?
|
||||||
|
if (save_it) {
|
||||||
|
Command* save_command =
|
||||||
|
CommandsModule::instance()->getCommandByName(CommandId::SaveFile);
|
||||||
|
ctx->executeCommand(save_command);
|
||||||
|
|
||||||
|
try_again = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
try_again = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy the sprite (locking it as writer)
|
||||||
|
DocumentDestroyer destroyer(
|
||||||
|
static_cast<app::Context*>(m_document->context()), m_document);
|
||||||
|
|
||||||
|
StatusBar::instance()
|
||||||
|
->setStatusText(0, "Sprite '%s' closed.",
|
||||||
|
m_document->name().c_str());
|
||||||
|
|
||||||
|
destroyer.destroyDocument();
|
||||||
|
|
||||||
|
// At this point the view is already destroyed
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocumentView::onTabPopup(Workspace* workspace)
|
||||||
|
{
|
||||||
|
Menu* menu = AppMenus::instance()->getDocumentTabPopupMenu();
|
||||||
|
if (!menu)
|
||||||
|
return;
|
||||||
|
|
||||||
UIContext* context = UIContext::instance();
|
UIContext* context = UIContext::instance();
|
||||||
context->setActiveView(this);
|
context->setActiveView(this);
|
||||||
context->updateFlags();
|
context->updateFlags();
|
||||||
|
|
||||||
Command* close_file_cmd =
|
menu->showPopup(ui::get_mouse_position());
|
||||||
CommandsModule::instance()->getCommandByName(CommandId::CloseFile);
|
|
||||||
|
|
||||||
context->executeCommand(close_file_cmd, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DocumentView::onProcessMessage(Message* msg)
|
bool DocumentView::onProcessMessage(Message* msg)
|
||||||
|
|
|
@ -49,7 +49,8 @@ namespace app {
|
||||||
WorkspaceView* cloneWorkspaceView() override;
|
WorkspaceView* cloneWorkspaceView() override;
|
||||||
void onWorkspaceViewSelected() override;
|
void onWorkspaceViewSelected() override;
|
||||||
void onClonedFrom(WorkspaceView* from) override;
|
void onClonedFrom(WorkspaceView* from) override;
|
||||||
void onCloseView(Workspace* workspace) override;
|
bool onCloseView(Workspace* workspace) override;
|
||||||
|
void onTabPopup(Workspace* workspace) override;
|
||||||
|
|
||||||
// DocumentObserver implementation
|
// DocumentObserver implementation
|
||||||
void onGeneralUpdate(doc::DocumentEvent& ev) override;
|
void onGeneralUpdate(doc::DocumentEvent& ev) override;
|
||||||
|
|
|
@ -11,9 +11,11 @@
|
||||||
|
|
||||||
#include "app/ui/home_view.h"
|
#include "app/ui/home_view.h"
|
||||||
|
|
||||||
|
#include "app/app_menus.h"
|
||||||
#include "app/ui/skin/skin_theme.h"
|
#include "app/ui/skin/skin_theme.h"
|
||||||
#include "app/ui/workspace.h"
|
#include "app/ui/workspace.h"
|
||||||
#include "ui/label.h"
|
#include "ui/label.h"
|
||||||
|
#include "ui/system.h"
|
||||||
#include "ui/textbox.h"
|
#include "ui/textbox.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
|
||||||
|
@ -59,9 +61,19 @@ void HomeView::onClonedFrom(WorkspaceView* from)
|
||||||
ASSERT(false); // Never called
|
ASSERT(false); // Never called
|
||||||
}
|
}
|
||||||
|
|
||||||
void HomeView::onCloseView(Workspace* workspace)
|
bool HomeView::onCloseView(Workspace* workspace)
|
||||||
{
|
{
|
||||||
workspace->removeView(this);
|
workspace->removeView(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HomeView::onTabPopup(Workspace* workspace)
|
||||||
|
{
|
||||||
|
Menu* menu = AppMenus::instance()->getTabPopupMenu();
|
||||||
|
if (!menu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
menu->showPopup(ui::get_mouse_position());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HomeView::onWorkspaceViewSelected()
|
void HomeView::onWorkspaceViewSelected()
|
||||||
|
|
|
@ -33,7 +33,8 @@ namespace app {
|
||||||
ui::Widget* getContentWidget() override { return this; }
|
ui::Widget* getContentWidget() override { return this; }
|
||||||
WorkspaceView* cloneWorkspaceView() override;
|
WorkspaceView* cloneWorkspaceView() override;
|
||||||
void onClonedFrom(WorkspaceView* from) override;
|
void onClonedFrom(WorkspaceView* from) override;
|
||||||
void onCloseView(Workspace* workspace) override;
|
bool onCloseView(Workspace* workspace) override;
|
||||||
|
void onTabPopup(Workspace* workspace) override;
|
||||||
void onWorkspaceViewSelected() override;
|
void onWorkspaceViewSelected() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -288,45 +288,33 @@ void MainWindow::onActiveViewChange()
|
||||||
layout();
|
layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons)
|
void MainWindow::onSelectTab(Tabs* tabs, TabView* tabView)
|
||||||
{
|
{
|
||||||
if (!tabView)
|
if (!tabView)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WorkspaceView* workspaceView = dynamic_cast<WorkspaceView*>(tabView);
|
WorkspaceView* view = dynamic_cast<WorkspaceView*>(tabView);
|
||||||
if (m_workspace->activeView() != workspaceView)
|
if (m_workspace->activeView() != view)
|
||||||
m_workspace->setActiveView(workspaceView);
|
m_workspace->setActiveView(view);
|
||||||
|
|
||||||
DocumentView* docView = dynamic_cast<DocumentView*>(workspaceView);
|
|
||||||
if (!docView)
|
|
||||||
return;
|
|
||||||
|
|
||||||
UIContext* context = UIContext::instance();
|
|
||||||
context->setActiveView(docView);
|
|
||||||
context->updateFlags();
|
|
||||||
|
|
||||||
// Right-button: popup-menu
|
|
||||||
if (buttons & kButtonRight) {
|
|
||||||
Menu* popup_menu = AppMenus::instance()->getDocumentTabPopupMenu();
|
|
||||||
if (popup_menu != NULL) {
|
|
||||||
popup_menu->showPopup(ui::get_mouse_position());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Middle-button: close the sprite
|
|
||||||
else if (buttons & kButtonMiddle) {
|
|
||||||
docView->onCloseView(m_workspace);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::clickClose(Tabs* tabs, TabView* tabView)
|
void MainWindow::onCloseTab(Tabs* tabs, TabView* tabView)
|
||||||
{
|
{
|
||||||
WorkspaceView* view = dynamic_cast<WorkspaceView*>(tabView);
|
WorkspaceView* view = dynamic_cast<WorkspaceView*>(tabView);
|
||||||
ASSERT(view);
|
ASSERT(view);
|
||||||
if (view)
|
if (view)
|
||||||
view->onCloseView(m_workspace);
|
m_workspace->closeView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::mouseOverTab(Tabs* tabs, TabView* tabView)
|
void MainWindow::onContextMenuTab(Tabs* tabs, TabView* tabView)
|
||||||
|
{
|
||||||
|
WorkspaceView* view = dynamic_cast<WorkspaceView*>(tabView);
|
||||||
|
ASSERT(view);
|
||||||
|
if (view)
|
||||||
|
view->onTabPopup(m_workspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onMouseOverTab(Tabs* tabs, TabView* tabView)
|
||||||
{
|
{
|
||||||
// Note: tabView can be NULL
|
// Note: tabView can be NULL
|
||||||
if (DocumentView* docView = dynamic_cast<DocumentView*>(tabView)) {
|
if (DocumentView* docView = dynamic_cast<DocumentView*>(tabView)) {
|
||||||
|
@ -339,7 +327,7 @@ void MainWindow::mouseOverTab(Tabs* tabs, TabView* tabView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::isModified(Tabs* tabs, TabView* tabView)
|
bool MainWindow::onIsModified(Tabs* tabs, TabView* tabView)
|
||||||
{
|
{
|
||||||
if (DocumentView* docView = dynamic_cast<DocumentView*>(tabView)) {
|
if (DocumentView* docView = dynamic_cast<DocumentView*>(tabView)) {
|
||||||
Document* document = docView->getDocument();
|
Document* document = docView->getDocument();
|
||||||
|
|
|
@ -64,10 +64,11 @@ namespace app {
|
||||||
void popTimeline();
|
void popTimeline();
|
||||||
|
|
||||||
// TabsDelegate implementation.
|
// TabsDelegate implementation.
|
||||||
void clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons) override;
|
void onSelectTab(Tabs* tabs, TabView* tabView) override;
|
||||||
void clickClose(Tabs* tabs, TabView* tabView) override;
|
void onCloseTab(Tabs* tabs, TabView* tabView) override;
|
||||||
void mouseOverTab(Tabs* tabs, TabView* tabView) override;
|
void onContextMenuTab(Tabs* tabs, TabView* tabView) override;
|
||||||
bool isModified(Tabs* tabs, TabView* tabView) override;
|
void onMouseOverTab(Tabs* tabs, TabView* tabView) override;
|
||||||
|
bool onIsModified(Tabs* tabs, TabView* tabView) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool onProcessMessage(ui::Message* msg) override;
|
bool onProcessMessage(ui::Message* msg) override;
|
||||||
|
|
|
@ -105,7 +105,11 @@ void Tabs::removeTab(TabView* tabView)
|
||||||
m_hot = nullptr;
|
m_hot = nullptr;
|
||||||
|
|
||||||
if (m_selected == tab) {
|
if (m_selected == tab) {
|
||||||
|
if (tab == m_list.back())
|
||||||
|
selectPreviousTab();
|
||||||
|
else
|
||||||
selectNextTab();
|
selectNextTab();
|
||||||
|
|
||||||
if (m_selected == tab)
|
if (m_selected == tab)
|
||||||
m_selected = nullptr;
|
m_selected = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +123,7 @@ void Tabs::removeTab(TabView* tabView)
|
||||||
m_removedTab = tab;
|
m_removedTab = tab;
|
||||||
|
|
||||||
if (m_delegate)
|
if (m_delegate)
|
||||||
tab->modified = m_delegate->isModified(this, tabView);
|
tab->modified = m_delegate->onIsModified(this, tabView);
|
||||||
tab->view = nullptr; // The view will be destroyed after Tabs::removeTab() anyway
|
tab->view = nullptr; // The view will be destroyed after Tabs::removeTab() anyway
|
||||||
|
|
||||||
// Next tab in the list
|
// Next tab in the list
|
||||||
|
@ -185,7 +189,7 @@ void Tabs::selectNextTab()
|
||||||
if (it != currentTabIt) {
|
if (it != currentTabIt) {
|
||||||
selectTabInternal(*it);
|
selectTabInternal(*it);
|
||||||
if (m_delegate)
|
if (m_delegate)
|
||||||
m_delegate->clickTab(this, m_selected->view, kButtonLeft);
|
m_delegate->onSelectTab(this, m_selected->view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +209,7 @@ void Tabs::selectPreviousTab()
|
||||||
if (it != currentTabIt) {
|
if (it != currentTabIt) {
|
||||||
selectTabInternal(*it);
|
selectTabInternal(*it);
|
||||||
if (m_delegate)
|
if (m_delegate)
|
||||||
m_delegate->clickTab(this, m_selected->view, kButtonLeft);
|
m_delegate->onSelectTab(this, m_selected->view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,7 +259,7 @@ bool Tabs::onProcessMessage(Message* msg)
|
||||||
if (m_selected && m_delegate &&
|
if (m_selected && m_delegate &&
|
||||||
!m_clickedCloseButton &&
|
!m_clickedCloseButton &&
|
||||||
mouseMsg->left()) {
|
mouseMsg->left()) {
|
||||||
m_delegate->clickTab(this, m_selected->view, mouseMsg->buttons());
|
m_delegate->onSelectTab(this, m_selected->view);
|
||||||
}
|
}
|
||||||
|
|
||||||
captureMouse();
|
captureMouse();
|
||||||
|
@ -267,11 +271,11 @@ bool Tabs::onProcessMessage(Message* msg)
|
||||||
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
||||||
|
|
||||||
if (m_delegate && m_selected && m_selected == m_hot) {
|
if (m_delegate && m_selected && m_selected == m_hot) {
|
||||||
if (m_hotCloseButton && m_clickedCloseButton) {
|
if (mouseMsg->middle() || (m_hotCloseButton && m_clickedCloseButton)) {
|
||||||
m_delegate->clickClose(this, m_selected->view);
|
m_delegate->onCloseTab(this, m_selected->view);
|
||||||
}
|
}
|
||||||
else if (!mouseMsg->left()) {
|
else if (mouseMsg->right()) {
|
||||||
m_delegate->clickTab(this, m_selected->view, mouseMsg->buttons());
|
m_delegate->onContextMenuTab(this, m_selected->view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +515,7 @@ void Tabs::drawTab(Graphics* g, const gfx::Rect& _box, Tab* tab, int dy,
|
||||||
|
|
||||||
if (m_delegate) {
|
if (m_delegate) {
|
||||||
if (tab->view)
|
if (tab->view)
|
||||||
tab->modified = m_delegate->isModified(this, tab->view);
|
tab->modified = m_delegate->onIsModified(this, tab->view);
|
||||||
|
|
||||||
if (tab->modified &&
|
if (tab->modified &&
|
||||||
(!hover || !m_hotCloseButton)) {
|
(!hover || !m_hotCloseButton)) {
|
||||||
|
@ -588,7 +592,7 @@ void Tabs::calculateHot()
|
||||||
m_hotCloseButton = hotCloseButton;
|
m_hotCloseButton = hotCloseButton;
|
||||||
|
|
||||||
if (m_delegate)
|
if (m_delegate)
|
||||||
m_delegate->mouseOverTab(this, m_hot ? m_hot->view: NULL);
|
m_delegate->onMouseOverTab(this, m_hot ? m_hot->view: NULL);
|
||||||
|
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,17 +45,20 @@ namespace app {
|
||||||
public:
|
public:
|
||||||
virtual ~TabsDelegate() { }
|
virtual ~TabsDelegate() { }
|
||||||
|
|
||||||
// Called when the user presses a mouse button over a tab.
|
// Called when the user selected the tab with the left mouse button.
|
||||||
virtual void clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons) = 0;
|
virtual void onSelectTab(Tabs* tabs, TabView* tabView) = 0;
|
||||||
|
|
||||||
// When the tab close button is pressed.
|
// When the tab close button is pressed (or middle mouse button is used to close it).
|
||||||
virtual void clickClose(Tabs* tabs, TabView* tabView) = 0;
|
virtual void onCloseTab(Tabs* tabs, TabView* tabView) = 0;
|
||||||
|
|
||||||
|
// When the right-click is pressed in the tab.
|
||||||
|
virtual void onContextMenuTab(Tabs* tabs, TabView* tabView) = 0;
|
||||||
|
|
||||||
// Called when the mouse is over a tab (the data can be null if the
|
// Called when the mouse is over a tab (the data can be null if the
|
||||||
// mouse just leave all tabs)
|
// mouse just leave all tabs)
|
||||||
virtual void mouseOverTab(Tabs* tabs, TabView* tabView) = 0;
|
virtual void onMouseOverTab(Tabs* tabs, TabView* tabView) = 0;
|
||||||
|
|
||||||
virtual bool isModified(Tabs* tabs, TabView* tabView) = 0;
|
virtual bool onIsModified(Tabs* tabs, TabView* tabView) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tabs control. Used to show opened documents.
|
// Tabs control. Used to show opened documents.
|
||||||
|
|
|
@ -78,6 +78,11 @@ void Workspace::removeView(WorkspaceView* view)
|
||||||
ActiveViewChanged(); // Fire ActiveViewChanged event
|
ActiveViewChanged(); // Fire ActiveViewChanged event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Workspace::closeView(WorkspaceView* view)
|
||||||
|
{
|
||||||
|
return view->onCloseView(this);
|
||||||
|
}
|
||||||
|
|
||||||
WorkspaceView* Workspace::activeView()
|
WorkspaceView* Workspace::activeView()
|
||||||
{
|
{
|
||||||
ASSERT(m_activePart != NULL);
|
ASSERT(m_activePart != NULL);
|
||||||
|
|
|
@ -30,6 +30,10 @@ namespace app {
|
||||||
void addView(WorkspaceView* view);
|
void addView(WorkspaceView* view);
|
||||||
void removeView(WorkspaceView* view);
|
void removeView(WorkspaceView* view);
|
||||||
|
|
||||||
|
// Closes the given view. Returns false if the user cancels the
|
||||||
|
// operation.
|
||||||
|
bool closeView(WorkspaceView* view);
|
||||||
|
|
||||||
WorkspaceView* activeView();
|
WorkspaceView* activeView();
|
||||||
void setActiveView(WorkspaceView* view);
|
void setActiveView(WorkspaceView* view);
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,9 @@ void WorkspacePart::removeView(WorkspaceView* view)
|
||||||
|
|
||||||
removeChild(view->getContentWidget());
|
removeChild(view->getContentWidget());
|
||||||
|
|
||||||
setActiveView((it != m_views.end() ?
|
setActiveView(
|
||||||
*it : (!m_views.empty() ? m_views.front(): NULL)));
|
(it != m_views.end() ?
|
||||||
|
*it : (!m_views.empty() ? m_views.back(): nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkspacePart::setActiveView(WorkspaceView* view)
|
void WorkspacePart::setActiveView(WorkspaceView* view)
|
||||||
|
|
|
@ -29,7 +29,11 @@ namespace app {
|
||||||
// from the original view.
|
// from the original view.
|
||||||
virtual void onClonedFrom(WorkspaceView* from) = 0;
|
virtual void onClonedFrom(WorkspaceView* from) = 0;
|
||||||
|
|
||||||
virtual void onCloseView(Workspace* workspace) = 0;
|
// Returns true if the view was closed successfully or false if
|
||||||
|
// the user cancels the operation.
|
||||||
|
virtual bool onCloseView(Workspace* workspace) = 0;
|
||||||
|
|
||||||
|
virtual void onTabPopup(Workspace* workspace) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|
|
@ -127,7 +127,7 @@ DocumentView* UIContext::getFirstDocumentView(Document* document) const
|
||||||
{
|
{
|
||||||
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||||
|
|
||||||
for (auto view : *workspace) {
|
for (WorkspaceView* view : *workspace) {
|
||||||
if (DocumentView* docView = dynamic_cast<DocumentView*>(view)) {
|
if (DocumentView* docView = dynamic_cast<DocumentView*>(view)) {
|
||||||
if (docView->getDocument() == document) {
|
if (docView->getDocument() == document) {
|
||||||
return docView;
|
return docView;
|
||||||
|
@ -177,8 +177,7 @@ void UIContext::onRemoveDocument(doc::Document* doc)
|
||||||
DocumentViews docViews;
|
DocumentViews docViews;
|
||||||
|
|
||||||
// Collect all views related to the document.
|
// Collect all views related to the document.
|
||||||
for (Workspace::iterator it=workspace->begin(); it != workspace->end(); ++it) {
|
for (WorkspaceView* view : *workspace) {
|
||||||
WorkspaceView* view = *it;
|
|
||||||
if (DocumentView* docView = dynamic_cast<DocumentView*>(view)) {
|
if (DocumentView* docView = dynamic_cast<DocumentView*>(view)) {
|
||||||
if (docView->getDocument() == doc) {
|
if (docView->getDocument() == doc) {
|
||||||
docViews.push_back(docView);
|
docViews.push_back(docView);
|
||||||
|
@ -186,8 +185,7 @@ void UIContext::onRemoveDocument(doc::Document* doc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DocumentViews::iterator it=docViews.begin(); it != docViews.end(); ++it) {
|
for (DocumentView* docView : docViews) {
|
||||||
DocumentView* docView = *it;
|
|
||||||
workspace->removeView(docView);
|
workspace->removeView(docView);
|
||||||
delete docView;
|
delete docView;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue