mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-30 06:32:42 +00:00
Experimental native gtk3 file dialog
This pull request basicly adds the suport for gtk3 dialogs to she. it is disabled by default and can be enabled with cmake ... -DWITH_GTK_FILE_DIALOG_SUPPORT=ON .. and needs the Experimental option "Use native file dialog" enabled in aseprite enabled. It is currently only available on *nix and has a external dependencie on gtkmm >= 3.16 and glibmm >= 2.45 To have at least backwardcompatibility with ubuntu 15.10 the cmake option -D_WITH_DEPRECATED_GLIB_SUPPORT was added to make use of a deprecated glibmm method. Further testing ist need to see how far this backward compatibility works, as of now ubuntu 12.04 does not seem to work. But as ubuntu 12.04 will reach its end of support this summer and ubuntu 15.04 having passed its end of life in february the question is how far back this support is aimed for. Please enter the commit message for your changes. Lines starting
This commit is contained in:
parent
36eb38a5e7
commit
745fd180d4
@ -35,6 +35,8 @@ project(aseprite C CXX)
|
||||
# CMakeCache.txt)
|
||||
|
||||
option(WITH_WEBP_SUPPORT "Enable support to load/save .webp files" off)
|
||||
option(WITH_GTK_FILE_DIALOG_SUPPORT "Enable support for the experimental native GTK File Dialog" off)
|
||||
option(WITH_DEPRECATED_GLIB_SUPPORT "Enable support for older glib versions" off)
|
||||
|
||||
option(USE_STATIC_LIBC "Use static version of C and C++ runtimes" off)
|
||||
option(USE_SHARED_CURL "Use your installed copy of curl" off)
|
||||
@ -360,6 +362,13 @@ if(UNIX AND NOT APPLE AND NOT BEOS)
|
||||
if(XDGA_FOUND)
|
||||
list(APPEND PLATFORM_LIBS Xxf86dga ${X11_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WITH_GTK_FILE_DIALOG_SUPPORT)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GTKMM gtkmm-3.0)
|
||||
include_directories(${GTKMM_INCLUDE_DIRS})
|
||||
link_directories(${GTKMM_LIBRARY_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# -- Windows --
|
||||
|
@ -97,7 +97,7 @@ if(USE_SKIA_BACKEND)
|
||||
find_library(SKIA_OPENGL_LIBRARY opengl32)
|
||||
find_library(SKIA_LIBEGL_LIBRARY libEGL.dll PATH "${SKIA_BUILD_OUT_DIR}")
|
||||
if(SKIA_LIBEGL_LIBRARY)
|
||||
add_definitions(-DSK_ANGLE=1)
|
||||
add_definitions(-DSK_ANGLE=1)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
@ -193,6 +193,15 @@ if(APPLE)
|
||||
osx/native_dialogs.mm)
|
||||
endif()
|
||||
|
||||
if(WITH_GTK_FILE_DIALOG_SUPPORT AND UNIX AND NOT APPLE AND NOT BEOS)
|
||||
if(WITH_DEPRECATED_GLIB_SUPPORT)
|
||||
add_definitions(-DASEPRITE_DEPRECATED_GLIB_SUPPORT)
|
||||
endif()
|
||||
add_definitions(-DASEPRITE_WITH_GTK_FILE_DIALOG_SUPPORT)
|
||||
list(APPEND SHE_SOURCES
|
||||
gtk/native_dialogs.cpp)
|
||||
endif()
|
||||
|
||||
add_library(she ${SHE_SOURCES})
|
||||
|
||||
target_link_libraries(she
|
||||
@ -210,3 +219,8 @@ if(USE_SKIA_BACKEND)
|
||||
target_link_libraries(she
|
||||
${SKIA_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WITH_GTK_FILE_DIALOG_SUPPORT)
|
||||
target_link_libraries(she
|
||||
${GTKMM_LIBRARIES})
|
||||
endif()
|
||||
|
@ -14,6 +14,9 @@
|
||||
#elif defined(__APPLE__)
|
||||
#include "she/osx/clipboard.h"
|
||||
#include "she/osx/native_dialogs.h"
|
||||
#elif defined(ASEPRITE_WITH_GTK_FILE_DIALOG_SUPPORT) && defined(__linux__)
|
||||
#include "she/clipboard_simple.h"
|
||||
#include "she/gtk/native_dialogs.h"
|
||||
#else
|
||||
#include "she/clipboard_simple.h"
|
||||
#include "she/native_dialogs.h"
|
||||
@ -56,6 +59,9 @@ public:
|
||||
#elif defined(__APPLE__)
|
||||
if (!m_nativeDialogs)
|
||||
m_nativeDialogs = new NativeDialogsOSX();
|
||||
#elif defined(ASEPRITE_WITH_GTK_FILE_DIALOG_SUPPORT) && defined(__linux__)
|
||||
if (!m_nativeDialogs)
|
||||
m_nativeDialogs = new NativeDialogsGTK3();
|
||||
#endif
|
||||
return m_nativeDialogs;
|
||||
}
|
||||
|
176
src/she/gtk/native_dialogs.cpp
Normal file
176
src/she/gtk/native_dialogs.cpp
Normal file
@ -0,0 +1,176 @@
|
||||
// GTK Component of SHE library
|
||||
// Copyright (C) 2016 Gabriel Rauter
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
//disable EMPTY_STRING macro already set in allegro, enabling it at the end of file
|
||||
#pragma push_macro("EMPTY_STRING")
|
||||
#undef EMPTY_STRING
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "she/gtk/native_dialogs.h"
|
||||
|
||||
#include "base/string.h"
|
||||
#include "she/display.h"
|
||||
#include "she/error.h"
|
||||
|
||||
#include <gtkmm/application.h>
|
||||
#include <gtkmm/filechooserdialog.h>
|
||||
#include <gtkmm/button.h>
|
||||
#include <gtkmm/filefilter.h>
|
||||
#include <glibmm/refptr.h>
|
||||
#include <glibmm/miscutils.h>
|
||||
#include <glibmm/fileutils.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace she {
|
||||
|
||||
class FileDialogGTK3 : public FileDialog, public Gtk::FileChooserDialog {
|
||||
public:
|
||||
FileDialogGTK3(Glib::RefPtr<Gtk::Application> app) :
|
||||
Gtk::FileChooserDialog(""), m_app(app), m_cancel(true) {
|
||||
this->add_button("_Cancel", Gtk::RESPONSE_CANCEL);
|
||||
m_ok_button = this->add_button("_Open", Gtk::RESPONSE_OK);
|
||||
this->set_default_response(Gtk::RESPONSE_OK);
|
||||
m_filter_all = Gtk::FileFilter::create();
|
||||
m_filter_all->set_name("All formats");
|
||||
this->set_do_overwrite_confirmation();
|
||||
if (FileDialogGTK3::lastUsedDir().empty()) {
|
||||
#ifdef ASEPRITE_DEPRECATED_GLIB_SUPPORT
|
||||
FileDialogGTK3::lastUsedDir() = Glib::get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS);
|
||||
#else
|
||||
FileDialogGTK3::lastUsedDir() = Glib::get_user_special_dir(Glib::USER_DIRECTORY_DOCUMENTS);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void on_show() override {
|
||||
//setting the filename only works properly when the dialog is shown
|
||||
if (!m_file_name.empty()) {
|
||||
if (this->get_action() == Gtk::FILE_CHOOSER_ACTION_OPEN) {
|
||||
this->set_current_folder(m_file_name);
|
||||
} else {
|
||||
if (Glib::file_test(m_file_name, Glib::FILE_TEST_EXISTS)) {
|
||||
this->set_filename(m_file_name);
|
||||
} else {
|
||||
this->set_current_folder(FileDialogGTK3::lastUsedDir());
|
||||
this->set_current_name(m_file_name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->set_current_folder(FileDialogGTK3::lastUsedDir());
|
||||
}
|
||||
//TODO set position centered to parent window, need she::screen to provide info
|
||||
this->set_position(Gtk::WIN_POS_CENTER);
|
||||
Gtk::FileChooserDialog::on_show();
|
||||
this->raise();
|
||||
}
|
||||
|
||||
void on_response(int response_id) override {
|
||||
switch(response_id) {
|
||||
case(Gtk::RESPONSE_OK): {
|
||||
m_cancel = false;
|
||||
m_file_name = this->get_filename();
|
||||
FileDialogGTK3::lastUsedDir() = this->get_current_folder();
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->hide();
|
||||
}
|
||||
|
||||
void dispose() override {
|
||||
for (auto& window : m_app->get_windows()) {
|
||||
window->close();
|
||||
}
|
||||
m_app->quit();
|
||||
delete this;
|
||||
}
|
||||
|
||||
void toOpenFile() override {
|
||||
this->set_action(Gtk::FILE_CHOOSER_ACTION_OPEN);
|
||||
m_ok_button->set_label("_Open");
|
||||
}
|
||||
|
||||
void toSaveFile() override {
|
||||
this->set_action(Gtk::FILE_CHOOSER_ACTION_SAVE);
|
||||
m_ok_button->set_label("_Save");
|
||||
}
|
||||
|
||||
void setTitle(const std::string& title) override {
|
||||
this->set_title(title);
|
||||
}
|
||||
|
||||
void setDefaultExtension(const std::string& extension) override {
|
||||
m_default_extension = extension;
|
||||
}
|
||||
|
||||
void addFilter(const std::string& extension, const std::string& description) override {
|
||||
auto filter = Gtk::FileFilter::create();
|
||||
filter->set_name(description);
|
||||
filter->add_pattern("*." + extension);
|
||||
m_filter_all->add_pattern("*." + extension);
|
||||
m_filters[extension] = filter;
|
||||
}
|
||||
|
||||
std::string fileName() override {
|
||||
return m_file_name;
|
||||
}
|
||||
|
||||
void setFileName(const std::string& filename) override {
|
||||
m_file_name = filename;
|
||||
}
|
||||
|
||||
bool show(Display* parent) override {
|
||||
//keep pointer on parent display to get information later
|
||||
m_display = parent;
|
||||
|
||||
//add filters in order they will appear
|
||||
this->add_filter(m_filter_all);
|
||||
|
||||
for (const auto& filter : m_filters) {
|
||||
this->add_filter(filter.second) ;
|
||||
if (filter.first.compare(m_default_extension) == 0) {
|
||||
this->set_filter(filter.second);
|
||||
}
|
||||
}
|
||||
|
||||
auto filter_any = Gtk::FileFilter::create();
|
||||
filter_any->set_name("Any files");
|
||||
filter_any->add_pattern("*");
|
||||
this->add_filter(filter_any);
|
||||
|
||||
//Run dialog in context of a gtk application so it can be destroys properly
|
||||
m_app->run(*this);
|
||||
return !m_cancel;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_file_name;
|
||||
std::string m_default_extension;
|
||||
Glib::RefPtr<Gtk::FileFilter> m_filter_all;
|
||||
std::map<std::string, Glib::RefPtr<Gtk::FileFilter>> m_filters;
|
||||
Gtk::Button* m_ok_button;
|
||||
Glib::RefPtr<Gtk::Application> m_app;
|
||||
Display* m_display;
|
||||
bool m_cancel;
|
||||
static std::string& lastUsedDir() { static std::string lastUsedDir; return lastUsedDir; }
|
||||
};
|
||||
|
||||
NativeDialogsGTK3::NativeDialogsGTK3()
|
||||
{
|
||||
}
|
||||
|
||||
FileDialog* NativeDialogsGTK3::createFileDialog()
|
||||
{
|
||||
m_app = Gtk::Application::create();
|
||||
FileDialog* dialog = new FileDialogGTK3(m_app);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
} // namespace she
|
||||
#pragma pop_macro("EMPTY_STRING")
|
32
src/she/gtk/native_dialogs.h
Normal file
32
src/she/gtk/native_dialogs.h
Normal file
@ -0,0 +1,32 @@
|
||||
// GTK Component of SHE library
|
||||
// Copyright (C) 2016 Gabriel Rauter
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
//disable EMPTY_STRING macro already set in allegro, enabling it at the end of file
|
||||
#pragma push_macro("EMPTY_STRING")
|
||||
#undef EMPTY_STRING
|
||||
#ifndef SHE_GTK_NATIVE_DIALOGS_H_INCLUDED
|
||||
#define SHE_GTK_NATIVE_DIALOGS_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "she/native_dialogs.h"
|
||||
|
||||
#include <gtkmm/application.h>
|
||||
#include <glibmm/refptr.h>
|
||||
|
||||
namespace she {
|
||||
|
||||
class NativeDialogsGTK3 : public NativeDialogs {
|
||||
public:
|
||||
NativeDialogsGTK3();
|
||||
FileDialog* createFileDialog() override;
|
||||
private:
|
||||
Glib::RefPtr<Gtk::Application> m_app;
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
||||
#endif
|
||||
#pragma pop_macro("EMPTY_STRING")
|
Loading…
x
Reference in New Issue
Block a user