Ported the AboutDialog to C++, thanks @alexrj for the work.

New "configuration" menu over the snapshots, user preferences etc.
This commit is contained in:
bubnikv 2018-04-09 17:03:37 +02:00
parent 601185f113
commit 32c4cddb91
15 changed files with 336 additions and 182 deletions

View File

@ -7,7 +7,6 @@ use File::Basename qw(basename);
use FindBin; use FindBin;
use List::Util qw(first); use List::Util qw(first);
use Slic3r::GUI::2DBed; use Slic3r::GUI::2DBed;
use Slic3r::GUI::AboutDialog;
use Slic3r::GUI::BedShapeDialog; use Slic3r::GUI::BedShapeDialog;
use Slic3r::GUI::ConfigWizard; use Slic3r::GUI::ConfigWizard;
use Slic3r::GUI::Controller; use Slic3r::GUI::Controller;
@ -191,13 +190,6 @@ sub recreate_GUI{
} }
} }
sub about {
my ($self) = @_;
my $about = Slic3r::GUI::AboutDialog->new(undef);
$about->ShowModal;
$about->Destroy;
}
sub system_info { sub system_info {
my ($self) = @_; my ($self) = @_;
my $slic3r_info = Slic3r::slic3r_info(format => 'html'); my $slic3r_info = Slic3r::slic3r_info(format => 'html');

View File

@ -1,122 +0,0 @@
package Slic3r::GUI::AboutDialog;
use strict;
use warnings;
use utf8;
use Wx qw(:font :html :misc :dialog :sizer :systemsettings :frame :id);
use Wx::Event qw(EVT_HTML_LINK_CLICKED EVT_LEFT_DOWN EVT_BUTTON);
use Wx::Print;
use Wx::Html;
use base 'Wx::Dialog';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, -1, 'About Slic3r', wxDefaultPosition, [600, 340], wxCAPTION);
$self->SetBackgroundColour(Wx::wxWHITE);
my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);
$self->SetSizer($hsizer);
# logo
my $logo = Slic3r::GUI::AboutDialog::Logo->new($self, -1, wxDefaultPosition, wxDefaultSize);
$logo->SetBackgroundColour(Wx::wxWHITE);
$hsizer->Add($logo, 0, wxEXPAND | wxLEFT | wxRIGHT, 30);
my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
$hsizer->Add($vsizer, 1, wxEXPAND, 0);
# title
my $title = Wx::StaticText->new($self, -1, $Slic3r::FORK_NAME, wxDefaultPosition, wxDefaultSize);
my $title_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
$title_font->SetWeight(wxFONTWEIGHT_BOLD);
$title_font->SetFamily(wxFONTFAMILY_ROMAN);
$title_font->SetPointSize(24);
$title->SetFont($title_font);
$vsizer->Add($title, 0, wxALIGN_LEFT | wxTOP, 30);
# version
my $version = Wx::StaticText->new($self, -1, "Version $Slic3r::VERSION", wxDefaultPosition, wxDefaultSize);
my $version_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
$version_font->SetPointSize(&Wx::wxMSW ? 9 : 11);
$version->SetFont($version_font);
$vsizer->Add($version, 0, wxALIGN_LEFT | wxBOTTOM, 10);
# text
my $text =
'<html>' .
'<body bgcolor="#ffffff" link="#808080">' .
'<font color="#808080">' .
'Copyright &copy; 2016 Vojtech Bubnik, Prusa Research. <br />' .
'Copyright &copy; 2011-2016 Alessandro Ranellucci. <br />' .
'<a href="http://slic3r.org/">Slic3r</a> is licensed under the ' .
'<a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero General Public License, version 3</a>.' .
'<br /><br /><br />' .
'Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Y. Sapir, Mike Sheldrake and numerous others. ' .
'Manual by Gary Hodgson. Inspired by the RepRap community. <br />' .
'Slic3r logo designed by Corey Daniels, <a href="http://www.famfamfam.com/lab/icons/silk/">Silk Icon Set</a> designed by Mark James. ' .
'</font>' .
'</body>' .
'</html>';
my $html = Wx::HtmlWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER);
my $font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
my $size = &Wx::wxMSW ? 8 : 10;
$html->SetFonts($font->GetFaceName, $font->GetFaceName, [$size, $size, $size, $size, $size, $size, $size]);
$html->SetBorders(2);
$html->SetPage($text);
$vsizer->Add($html, 1, wxEXPAND | wxALIGN_LEFT | wxRIGHT | wxBOTTOM, 20);
EVT_HTML_LINK_CLICKED($self, $html, \&link_clicked);
my $buttons = $self->CreateStdDialogButtonSizer(wxOK);
$self->SetEscapeId(wxID_CLOSE);
EVT_BUTTON($self, wxID_CLOSE, sub {
$self->EndModal(wxID_CLOSE);
$self->Close;
});
$vsizer->Add($buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);
EVT_LEFT_DOWN($self, sub { $self->Close });
EVT_LEFT_DOWN($logo, sub { $self->Close });
return $self;
}
sub link_clicked {
my ($self, $event) = @_;
Wx::LaunchDefaultBrowser($event->GetLinkInfo->GetHref);
$event->Skip(0);
}
package Slic3r::GUI::AboutDialog::Logo;
use Wx qw(:bitmap :dc);
use Wx::Event qw(EVT_PAINT);
use base 'Wx::Panel';
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
$self->{logo} = Wx::Bitmap->new(Slic3r::var("Slic3r_192px.png"), wxBITMAP_TYPE_PNG);
$self->SetMinSize(Wx::Size->new($self->{logo}->GetWidth, $self->{logo}->GetHeight));
EVT_PAINT($self, \&repaint);
return $self;
}
sub repaint {
my ($self, $event) = @_;
my $dc = Wx::PaintDC->new($self);
$dc->SetBackgroundMode(wxTRANSPARENT);
my $size = $self->GetSize;
my $logo_w = $self->{logo}->GetWidth;
my $logo_h = $self->{logo}->GetHeight;
$dc->DrawBitmap($self->{logo}, ($size->GetWidth - $logo_w) / 2, ($size->GetHeight - $logo_h) / 2, 1);
$event->Skip;
}
1;

View File

@ -237,12 +237,6 @@ sub _init_menubar {
$self->repair_stl; $self->repair_stl;
}, undef, 'wrench.png'); }, undef, 'wrench.png');
$fileMenu->AppendSeparator(); $fileMenu->AppendSeparator();
# Cmd+, is standard on OS X - what about other operating systems?
$self->_append_menu_item($fileMenu, L("Preferences…\tCtrl+,"), L('Application preferences'), sub {
# Opening the C++ preferences dialog.
Slic3r::GUI::open_preferences_dialog($self->{preferences_event});
}, wxID_PREFERENCES);
$fileMenu->AppendSeparator();
$self->_append_menu_item($fileMenu, L("&Quit"), L('Quit Slic3r'), sub { $self->_append_menu_item($fileMenu, L("&Quit"), L('Quit Slic3r'), sub {
$self->Close(0); $self->Close(0);
}, wxID_EXIT); }, wxID_EXIT);
@ -348,7 +342,7 @@ sub _init_menubar {
Wx::LaunchDefaultBrowser('http://github.com/prusa3d/slic3r/issues/new'); Wx::LaunchDefaultBrowser('http://github.com/prusa3d/slic3r/issues/new');
}); });
$self->_append_menu_item($helpMenu, L("&About Slic3r"), L('Show about dialog'), sub { $self->_append_menu_item($helpMenu, L("&About Slic3r"), L('Show about dialog'), sub {
wxTheApp->about; Slic3r::GUI::about;
}); });
} }
@ -362,11 +356,9 @@ sub _init_menubar {
$menubar->Append($self->{object_menu}, L("&Object")) if $self->{object_menu}; $menubar->Append($self->{object_menu}, L("&Object")) if $self->{object_menu};
$menubar->Append($windowMenu, L("&Window")); $menubar->Append($windowMenu, L("&Window"));
$menubar->Append($self->{viewMenu}, L("&View")) if $self->{viewMenu}; $menubar->Append($self->{viewMenu}, L("&View")) if $self->{viewMenu};
# Add an optional debug menu # Add a configuration menu.
# (Select application language from the list of installed languages) Slic3r::GUI::add_config_menu($menubar, $self->{preferences_event}, $self->{lang_ch_event});
Slic3r::GUI::add_debug_menu($menubar, $self->{lang_ch_event});
$menubar->Append($helpMenu, L("&Help")); $menubar->Append($helpMenu, L("&Help"));
# Add an optional debug menu. In production code, the add_debug_menu() call should do nothing.
$self->SetMenuBar($menubar); $self->SetMenuBar($menubar);
} }
} }

View File

@ -170,6 +170,8 @@ add_library(libslic3r STATIC
) )
add_library(libslic3r_gui STATIC add_library(libslic3r_gui STATIC
${LIBDIR}/slic3r/GUI/AboutDialog.cpp
${LIBDIR}/slic3r/GUI/AboutDialog.hpp
${LIBDIR}/slic3r/GUI/AppConfig.cpp ${LIBDIR}/slic3r/GUI/AppConfig.cpp
${LIBDIR}/slic3r/GUI/AppConfig.hpp ${LIBDIR}/slic3r/GUI/AppConfig.hpp
${LIBDIR}/slic3r/GUI/BitmapCache.cpp ${LIBDIR}/slic3r/GUI/BitmapCache.cpp
@ -533,13 +535,13 @@ if (SLIC3R_PRUSACONTROL)
set(wxWidgets_UseAlienWx 1) set(wxWidgets_UseAlienWx 1)
if (wxWidgets_UseAlienWx) if (wxWidgets_UseAlienWx)
set(AlienWx_DEBUG 1) set(AlienWx_DEBUG 1)
find_package(AlienWx REQUIRED COMPONENTS base core adv) find_package(AlienWx REQUIRED COMPONENTS base core adv html)
include_directories(${AlienWx_INCLUDE_DIRS}) include_directories(${AlienWx_INCLUDE_DIRS})
#add_compile_options(${AlienWx_CXX_FLAGS}) #add_compile_options(${AlienWx_CXX_FLAGS})
add_definitions(${AlienWx_DEFINITIONS}) add_definitions(${AlienWx_DEFINITIONS})
set(wxWidgets_LIBRARIES ${AlienWx_LIBRARIES}) set(wxWidgets_LIBRARIES ${AlienWx_LIBRARIES})
else () else ()
find_package(wxWidgets REQUIRED COMPONENTS base core adv) find_package(wxWidgets REQUIRED COMPONENTS base core adv html)
include(${wxWidgets_USE_FILE}) include(${wxWidgets_USE_FILE})
endif () endif ()
add_definitions(-DSLIC3R_GUI -DSLIC3R_PRUS) add_definitions(-DSLIC3R_GUI -DSLIC3R_PRUS)

View File

@ -12,7 +12,7 @@ our $VERSION = '0.01';
BEGIN { BEGIN {
if ($^O eq 'MSWin32') { if ($^O eq 'MSWin32') {
eval "use Wx"; eval "use Wx";
# eval "use Wx::Html"; eval "use Wx::Html";
eval "use Wx::Print"; # because of some Wx bug, thread creation fails if we don't have this (looks like Wx::Printout is hard-coded in some thread cleanup code) eval "use Wx::Print"; # because of some Wx bug, thread creation fails if we don't have this (looks like Wx::Printout is hard-coded in some thread cleanup code)
} }
} }

View File

@ -4,6 +4,7 @@
#include "libslic3r.h" #include "libslic3r.h"
#include <string> #include <string>
#include <boost/filesystem/path.hpp>
#include <stdexcept> #include <stdexcept>
namespace Slic3r { namespace Slic3r {
@ -15,6 +16,9 @@ public:
file_parser_error(const std::string &msg, const std::string &file, unsigned long line = 0) : file_parser_error(const std::string &msg, const std::string &file, unsigned long line = 0) :
std::runtime_error(format_what(msg, file, line)), std::runtime_error(format_what(msg, file, line)),
m_message(msg), m_filename(file), m_line(line) {} m_message(msg), m_filename(file), m_line(line) {}
file_parser_error(const std::string &msg, const boost::filesystem::path &file, unsigned long line = 0) :
std::runtime_error(format_what(msg, file.string(), line)),
m_message(msg), m_filename(file.string()), m_line(line) {}
// gcc 3.4.2 complains about lack of throw specifier on compiler // gcc 3.4.2 complains about lack of throw specifier on compiler
// generated dtor // generated dtor
~file_parser_error() throw() {} ~file_parser_error() throw() {}

View File

@ -205,6 +205,22 @@ size_t SnapshotDB::load_db()
return m_snapshots.size(); return m_snapshots.size();
} }
void SnapshotDB::update_slic3r_versions(std::vector<Index> &index_db)
{
for (Snapshot &snapshot : m_snapshots) {
for (Snapshot::VendorConfig &vendor_config : snapshot.vendor_configs) {
auto it = std::find_if(index_db.begin(), index_db.end(), [&vendor_config](const Index &idx) { return idx.vendor() == vendor_config.name; });
if (it != index_db.end()) {
Index::const_iterator it_version = it->find(vendor_config.version);
if (it_version != it->end()) {
vendor_config.min_slic3r_version = it_version->min_slic3r_version;
vendor_config.max_slic3r_version = it_version->max_slic3r_version;
}
}
}
}
}
static void copy_config_dir_single_level(const boost::filesystem::path &path_src, const boost::filesystem::path &path_dst) static void copy_config_dir_single_level(const boost::filesystem::path &path_src, const boost::filesystem::path &path_dst)
{ {
if (! boost::filesystem::is_directory(path_dst) && if (! boost::filesystem::is_directory(path_dst) &&
@ -303,6 +319,26 @@ boost::filesystem::path SnapshotDB::create_db_dir()
return snapshots_dir; return snapshots_dir;
} }
SnapshotDB& SnapshotDB::singleton()
{
static SnapshotDB instance;
bool loaded = false;
if (! loaded) {
try {
loaded = true;
// Load the snapshot database.
instance.load_db();
// Load the vendor specific configuration indices.
std::vector<Index> index_db = Index::load_db();
// Update the min / max slic3r versions compatible with the configurations stored inside the snapshots
// based on the min / max slic3r versions defined by the vendor specific config indices.
instance.update_slic3r_versions(index_db);
} catch (std::exception &ex) {
}
}
return instance;
}
} // namespace Config } // namespace Config
} // namespace GUI } // namespace GUI
} // namespace Slic3r } // namespace Slic3r

View File

@ -6,6 +6,7 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "Version.hpp"
#include "../Utils/Semver.hpp" #include "../Utils/Semver.hpp"
namespace Slic3r { namespace Slic3r {
@ -15,6 +16,8 @@ class AppConfig;
namespace GUI { namespace GUI {
namespace Config { namespace Config {
class Version;
// A snapshot contains: // A snapshot contains:
// Slic3r.ini // Slic3r.ini
// vendor/ // vendor/
@ -75,12 +78,16 @@ public:
class SnapshotDB class SnapshotDB
{ {
public: public:
// Initialize the SnapshotDB singleton instance. Load the database if it has not been loaded yet.
static SnapshotDB& singleton();
typedef std::vector<Snapshot>::const_iterator const_iterator; typedef std::vector<Snapshot>::const_iterator const_iterator;
// Load the snapshot database from the snapshots directory. // Load the snapshot database from the snapshots directory.
// If the snapshot directory or its parent does not exist yet, it will be created. // If the snapshot directory or its parent does not exist yet, it will be created.
// Returns a number of snapshots loaded. // Returns a number of snapshots loaded.
size_t load_db(); size_t load_db();
void update_slic3r_versions(std::vector<Index> &index_db);
// Create a snapshot directory, copy the vendor config bundles, user print/filament/printer profiles, // Create a snapshot directory, copy the vendor config bundles, user print/filament/printer profiles,
// create an index. // create an index.

View File

@ -6,6 +6,8 @@
#include "../../libslic3r/libslic3r.h" #include "../../libslic3r/libslic3r.h"
#include "../../libslic3r/Config.hpp" #include "../../libslic3r/Config.hpp"
#include "../../libslic3r/FileParserError.hpp"
#include "../../libslic3r/Utils.hpp"
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -62,11 +64,12 @@ inline std::string unquote_version_comment(char *value, char *end, const std::st
return svalue; return svalue;
} }
size_t Index::load(const std::string &path) size_t Index::load(const boost::filesystem::path &path)
{ {
m_configs.clear(); m_configs.clear();
m_vendor = path.stem().string();
boost::nowide::ifstream ifs(path); boost::nowide::ifstream ifs(path.string());
std::string line; std::string line;
size_t idx_line = 0; size_t idx_line = 0;
Version ver; Version ver;
@ -96,7 +99,7 @@ size_t Index::load(const std::string &path)
if (semver) if (semver)
throw file_parser_error("Key cannot be a semantic version", path, idx_line); throw file_parser_error("Key cannot be a semantic version", path, idx_line);
// Verify validity of the key / value pair. // Verify validity of the key / value pair.
std::string svalue = unquote_value(left_trim(++ value), end, path, idx_line); std::string svalue = unquote_value(left_trim(++ value), end, path.string(), idx_line);
if (key == "min_sic3r_version" || key == "max_slic3r_version") { if (key == "min_sic3r_version" || key == "max_slic3r_version") {
if (! svalue.empty()) if (! svalue.empty())
semver = Semver::parse(key); semver = Semver::parse(key);
@ -113,13 +116,24 @@ size_t Index::load(const std::string &path)
if (! semver) if (! semver)
throw file_parser_error("Invalid semantic version", path, idx_line); throw file_parser_error("Invalid semantic version", path, idx_line);
ver.config_version = *semver; ver.config_version = *semver;
ver.comment = (end <= key_end) ? "" : unquote_version_comment(value, end, path, idx_line); ver.comment = (end <= key_end) ? "" : unquote_version_comment(value, end, path.string(), idx_line);
m_configs.emplace_back(ver); m_configs.emplace_back(ver);
} }
// Sort the configs by their version.
std::sort(m_configs.begin(), m_configs.end(), [](const Version &v1, const Version &v2) { return v1.config_version < v2.config_version; });
return m_configs.size(); return m_configs.size();
} }
Index::const_iterator Index::find(const Semver &ver)
{
Version key;
key.config_version = ver;
auto it = std::lower_bound(m_configs.begin(), m_configs.end(), key,
[](const Version &v1, const Version &v2) { return v1.config_version < v2.config_version; });
return (it == m_configs.end() || it->config_version == ver) ? it : m_configs.end();
}
Index::const_iterator Index::recommended() const Index::const_iterator Index::recommended() const
{ {
int idx = -1; int idx = -1;
@ -131,6 +145,31 @@ Index::const_iterator Index::recommended() const
return highest; return highest;
} }
std::vector<Index> Index::load_db()
{
boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
boost::filesystem::path vendor_dir = data_dir / "vendor";
std::vector<Index> index_db;
std::string errors_cummulative;
for (auto &dir_entry : boost::filesystem::directory_iterator(vendor_dir))
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".idx")) {
Index idx;
try {
idx.load(dir_entry.path());
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
errors_cummulative += "\n";
continue;
}
index_db.emplace_back(std::move(idx));
}
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
return index_db;
}
} // namespace Config } // namespace Config
} // namespace GUI } // namespace GUI
} // namespace Slic3r } // namespace Slic3r

View File

@ -4,6 +4,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/filesystem.hpp>
#include "../../libslic3r/FileParserError.hpp" #include "../../libslic3r/FileParserError.hpp"
#include "../Utils/Semver.hpp" #include "../Utils/Semver.hpp"
@ -54,17 +56,25 @@ public:
typedef std::vector<Version>::const_iterator const_iterator; typedef std::vector<Version>::const_iterator const_iterator;
// Read a config index file in the simple format described in the Index class comment. // Read a config index file in the simple format described in the Index class comment.
// Throws Slic3r::file_parser_error and the standard std file access exceptions. // Throws Slic3r::file_parser_error and the standard std file access exceptions.
size_t load(const std::string &path); size_t load(const boost::filesystem::path &path);
const std::string& vendor() const { return m_vendor; }
const_iterator begin() const { return m_configs.begin(); } const_iterator begin() const { return m_configs.begin(); }
const_iterator end() const { return m_configs.end(); } const_iterator end() const { return m_configs.end(); }
const_iterator find(const Semver &ver);
const std::vector<Version>& configs() const { return m_configs; } const std::vector<Version>& configs() const { return m_configs; }
// Finds a recommended config to be installed for the current Slic3r version. // Finds a recommended config to be installed for the current Slic3r version.
// Returns configs().end() if such version does not exist in the index. This shall never happen // Returns configs().end() if such version does not exist in the index. This shall never happen
// if the index is valid. // if the index is valid.
const_iterator recommended() const; const_iterator recommended() const;
// Load all vendor specific indices.
// Throws Slic3r::file_parser_error and the standard std file access exceptions.
static std::vector<Index> load_db();
private: private:
std::string m_vendor;
std::vector<Version> m_configs; std::vector<Version> m_configs;
}; };

View File

@ -0,0 +1,125 @@
#include "AboutDialog.hpp"
#include "../../libslic3r/Utils.hpp"
namespace Slic3r {
namespace GUI {
AboutDialogLogo::AboutDialogLogo(wxWindow* parent)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
{
this->SetBackgroundColour(*wxWHITE);
this->logo = wxBitmap(from_u8(Slic3r::var("Slic3r_192px.png")), wxBITMAP_TYPE_PNG);
this->SetMinSize(this->logo.GetSize());
this->Bind(wxEVT_PAINT, &AboutDialogLogo::onRepaint, this);
}
void AboutDialogLogo::onRepaint(wxEvent &event)
{
wxPaintDC dc(this);
dc.SetBackgroundMode(wxTRANSPARENT);
wxSize size = this->GetSize();
int logo_w = this->logo.GetWidth();
int logo_h = this->logo.GetHeight();
dc.DrawBitmap(this->logo, (size.GetWidth() - logo_w)/2, (size.GetHeight() - logo_h)/2, true);
event.Skip();
}
AboutDialog::AboutDialog()
: wxDialog(NULL, wxID_ANY, _(L("About Slic3r")), wxDefaultPosition, wxSize(600, 340), wxCAPTION)
{
this->SetBackgroundColour(*wxWHITE);
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
this->SetSizer(hsizer);
// logo
AboutDialogLogo* logo = new AboutDialogLogo(this);
hsizer->Add(logo, 0, wxEXPAND | wxLEFT | wxRIGHT, 30);
wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
hsizer->Add(vsizer, 1, wxEXPAND, 0);
// title
{
wxStaticText* title = new wxStaticText(this, wxID_ANY, "Slic3r Prusa Edition", wxDefaultPosition, wxDefaultSize);
wxFont title_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
title_font.SetWeight(wxFONTWEIGHT_BOLD);
title_font.SetFamily(wxFONTFAMILY_ROMAN);
title_font.SetPointSize(24);
title->SetFont(title_font);
vsizer->Add(title, 0, wxALIGN_LEFT | wxTOP, 30);
}
// version
{
std::string version_string = _(L("Version ")) + std::string(SLIC3R_VERSION);
wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize);
wxFont version_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
#ifdef __WXMSW__
version_font.SetPointSize(9);
#else
version_font.SetPointSize(11);
#endif
version->SetFont(version_font);
vsizer->Add(version, 0, wxALIGN_LEFT | wxBOTTOM, 10);
}
// text
wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER);
{
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
#ifdef __WXMSW__
int size[] = {8,8,8,8,8,8,8};
#else
int size[] = {11,11,11,11,11,11,11};
#endif
html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
html->SetBorders(2);
const char* text =
"<html>"
"<body bgcolor=\"#ffffff\" link=\"#808080\">"
"<font color=\"#808080\">"
"Copyright &copy; 2016-2018 Prusa Research. <br />"
"Copyright &copy; 2011-2017 Alessandro Ranellucci. <br />"
"<a href=\"http://slic3r.org/\">Slic3r</a> is licensed under the "
"<a href=\"http://www.gnu.org/licenses/agpl-3.0.html\">GNU Affero General Public License, version 3</a>."
"<br /><br /><br />"
"Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik and numerous others. "
"Manual by Gary Hodgson. Inspired by the RepRap community. <br />"
"Slic3r logo designed by Corey Daniels, <a href=\"http://www.famfamfam.com/lab/icons/silk/\">Silk Icon Set</a> designed by Mark James. "
"</font>"
"</body>"
"</html>";
html->SetPage(text);
vsizer->Add(html, 1, wxEXPAND | wxALIGN_LEFT | wxRIGHT | wxBOTTOM, 20);
html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this);
}
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE);
this->SetEscapeId(wxID_CLOSE);
this->Bind(wxEVT_BUTTON, &AboutDialog::onCloseDialog, this, wxID_CLOSE);
vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);
this->Bind(wxEVT_LEFT_DOWN, &AboutDialog::onCloseDialog, this);
logo->Bind(wxEVT_LEFT_DOWN, &AboutDialog::onCloseDialog, this);
html->Bind(wxEVT_LEFT_DOWN, &AboutDialog::onCloseDialog, this);
}
void AboutDialog::onLinkClicked(wxHtmlLinkEvent &event)
{
wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref());
event.Skip(false);
}
void AboutDialog::onCloseDialog(wxEvent &)
{
this->EndModal(wxID_CLOSE);
this->Close();
}
} // namespace GUI
} // namespace Slic3r

View File

@ -0,0 +1,36 @@
#ifndef slic3r_GUI_AboutDialog_hpp_
#define slic3r_GUI_AboutDialog_hpp_
#include "GUI.hpp"
#include <wx/wx.h>
#include <wx/intl.h>
#include <wx/html/htmlwin.h>
namespace Slic3r {
namespace GUI {
class AboutDialogLogo : public wxPanel
{
public:
AboutDialogLogo(wxWindow* parent);
private:
wxBitmap logo;
void onRepaint(wxEvent &event);
};
class AboutDialog : public wxDialog
{
public:
AboutDialog();
private:
void onLinkClicked(wxHtmlLinkEvent &event);
void onCloseDialog(wxEvent &);
};
} // namespace GUI
} // namespace Slic3r
#endif

View File

@ -42,6 +42,7 @@
#include "Tab.hpp" #include "Tab.hpp"
#include "TabIface.hpp" #include "TabIface.hpp"
#include "AboutDialog.hpp"
#include "AppConfig.hpp" #include "AppConfig.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include "Preferences.hpp" #include "Preferences.hpp"
@ -330,32 +331,56 @@ void get_installed_languages(wxArrayString & names,
} }
} }
void add_debug_menu(wxMenuBar *menu, int event_language_change) enum ConfigMenuIDs {
ConfigMenuWizard,
ConfigMenuSnapshots,
ConfigMenuTakeSnapshot,
ConfigMenuUpdate,
ConfigMenuPreferences,
ConfigMenuLanguage,
ConfigMenuCnt,
};
void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_language_change)
{ {
//#if 0
auto local_menu = new wxMenu(); auto local_menu = new wxMenu();
local_menu->Append(wxWindow::NewControlId(1), _(L("Change Application Language"))); wxWindowID config_id_base = wxWindow::NewControlId((int)ConfigMenuCnt);
local_menu->Bind(wxEVT_MENU, [event_language_change](wxEvent&){
wxArrayString names; // Cmd+, is standard on OS X - what about other operating systems?
wxArrayLong identifiers; local_menu->Append(config_id_base + ConfigMenuWizard, _(L("Configuration Wizard\u2026")), _(L("Run configuration wizard")));
get_installed_languages(names, identifiers); local_menu->Append(config_id_base + ConfigMenuSnapshots, _(L("Configuration Snapshots\u2026")), _(L("Inspect / activate configuration snapshots")));
if (select_language(names, identifiers)){ local_menu->Append(config_id_base + ConfigMenuTakeSnapshot, _(L("Take Configuration Snapshot")), _(L("Capture a configuration snapshot")));
save_language(); local_menu->Append(config_id_base + ConfigMenuUpdate, _(L("Check for updates")), _(L("Check for configuration updates")));
show_info(g_wxTabPanel, _(L("Application will be restarted")), _(L("Attention!"))); local_menu->AppendSeparator();
if (event_language_change > 0) { local_menu->Append(config_id_base + ConfigMenuPreferences, _(L("Preferences\u2026\tCtrl+,")), _(L("Application preferences")));
wxCommandEvent event(event_language_change); local_menu->AppendSeparator();
g_wxApp->ProcessEvent(event); local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application Language")));
local_menu->Bind(wxEVT_MENU, [config_id_base, event_language_change, event_preferences_changed](wxEvent &event){
switch (event.GetId() - config_id_base) {
case ConfigMenuPreferences:
{
auto dlg = new PreferencesDialog(g_wxMainFrame, event_preferences_changed);
dlg->ShowModal();
break;
}
case ConfigMenuLanguage:
{
wxArrayString names;
wxArrayLong identifiers;
get_installed_languages(names, identifiers);
if (select_language(names, identifiers)) {
save_language();
show_info(g_wxTabPanel, _(L("Application will be restarted")), _(L("Attention!")));
if (event_language_change > 0) {
wxCommandEvent event(event_language_change);
g_wxApp->ProcessEvent(event);
}
} }
break;
}
} }
}); });
menu->Append(local_menu, _(L("&Localization"))); menu->Append(local_menu, _(L("&Configuration")));
//#endif
}
void open_preferences_dialog(int event_preferences)
{
auto dlg = new PreferencesDialog(g_wxMainFrame, event_preferences);
dlg->ShowModal();
} }
void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed) void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed)
@ -737,4 +762,11 @@ int get_export_option(wxFileDialog* dlg)
return 0; return 0;
} }
void about()
{
AboutDialog dlg;
dlg.ShowModal();
dlg.Destroy();
}
} } } }

View File

@ -82,10 +82,7 @@ wxApp* get_app();
wxColour* get_modified_label_clr(); wxColour* get_modified_label_clr();
wxColour* get_sys_label_clr(); wxColour* get_sys_label_clr();
void add_debug_menu(wxMenuBar *menu, int event_language_change); void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_language_change);
// Create "Preferences" dialog after selecting menu "Preferences" in Perl part
void open_preferences_dialog(int event_preferences);
// Create a new preset tab (print, filament and printer), // Create a new preset tab (print, filament and printer),
void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed); void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed);
@ -134,7 +131,11 @@ ConfigOptionsGroup* get_optgroup();
void add_export_option(wxFileDialog* dlg, const std::string& format); void add_export_option(wxFileDialog* dlg, const std::string& format);
int get_export_option(wxFileDialog* dlg); int get_export_option(wxFileDialog* dlg);
}
} // Display an About dialog
void about();
} // namespace GUI
} // namespace Slic3r
#endif #endif

View File

@ -9,6 +9,9 @@
%package{Slic3r::GUI}; %package{Slic3r::GUI};
void about()
%code{% Slic3r::GUI::about(); %};
void disable_screensaver() void disable_screensaver()
%code{% Slic3r::GUI::disable_screensaver(); %}; %code{% Slic3r::GUI::disable_screensaver(); %};
@ -32,9 +35,9 @@ void set_main_frame(SV *ui)
void set_tab_panel(SV *ui) void set_tab_panel(SV *ui)
%code%{ Slic3r::GUI::set_tab_panel((wxNotebook*)wxPli_sv_2_object(aTHX_ ui, "Wx::Notebook")); %}; %code%{ Slic3r::GUI::set_tab_panel((wxNotebook*)wxPli_sv_2_object(aTHX_ ui, "Wx::Notebook")); %};
void add_debug_menu(SV *ui, int event_language_change) void add_config_menu(SV *ui, int event_preferences_changed, int event_language_change)
%code%{ Slic3r::GUI::add_debug_menu((wxMenuBar*)wxPli_sv_2_object(aTHX_ ui, "Wx::MenuBar"), event_language_change); %}; %code%{ Slic3r::GUI::add_config_menu((wxMenuBar*)wxPli_sv_2_object(aTHX_ ui, "Wx::MenuBar"), event_preferences_changed, event_language_change); %};
void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed) void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed)
%code%{ Slic3r::GUI::create_preset_tabs(no_controller, event_value_change, event_presets_changed); %}; %code%{ Slic3r::GUI::create_preset_tabs(no_controller, event_value_change, event_presets_changed); %};
@ -54,9 +57,6 @@ int combochecklist_get_flags(SV *ui)
void set_app_config(AppConfig *app_config) void set_app_config(AppConfig *app_config)
%code%{ Slic3r::GUI::set_app_config(app_config); %}; %code%{ Slic3r::GUI::set_app_config(app_config); %};
void open_preferences_dialog(int preferences_event)
%code%{ Slic3r::GUI::open_preferences_dialog(preferences_event); %};
void set_preset_bundle(PresetBundle *preset_bundle) void set_preset_bundle(PresetBundle *preset_bundle)
%code%{ Slic3r::GUI::set_preset_bundle(preset_bundle); %}; %code%{ Slic3r::GUI::set_preset_bundle(preset_bundle); %};