Finish refactoring of platform code.
This commit finally unifies all main() functions and moves the few remaining application-wide functions where they belong.pull/339/head
parent
350d2ad211
commit
5853fa0421
|
@ -20,10 +20,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
|||
|
||||
if(WIN32)
|
||||
set(util_SOURCES
|
||||
platform/w32util.cpp)
|
||||
platform/utilwin.cpp)
|
||||
else()
|
||||
set(util_SOURCES
|
||||
platform/unixutil.cpp)
|
||||
platform/utilunix.cpp)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
|
@ -102,11 +102,13 @@ else()
|
|||
message(FATAL_ERROR "Unsupported OpenGL version ${OPENGL}")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(platform_SOURCES
|
||||
platform/w32main.cpp
|
||||
platform/guiwin.cpp
|
||||
${gl_SOURCES})
|
||||
${gl_SOURCES}
|
||||
platform/entrygui.cpp)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND platform_SOURCES
|
||||
platform/guiwin.cpp)
|
||||
|
||||
set(platform_LIBRARIES
|
||||
comctl32
|
||||
|
@ -115,16 +117,12 @@ elseif(APPLE)
|
|||
add_compile_options(
|
||||
-fobjc-arc)
|
||||
|
||||
set(platform_SOURCES
|
||||
platform/cocoamain.mm
|
||||
platform/guimac.mm
|
||||
list(APPEND platform_SOURCES
|
||||
render/rendergl.cpp
|
||||
${gl_SOURCES})
|
||||
platform/guimac.mm)
|
||||
else()
|
||||
set(platform_SOURCES
|
||||
platform/gtkmain.cpp
|
||||
platform/guigtk.cpp
|
||||
${gl_SOURCES})
|
||||
list(APPEND platform_SOURCES
|
||||
platform/guigtk.cpp)
|
||||
|
||||
set(platform_LIBRARIES
|
||||
${SPACEWARE_LIBRARIES})
|
||||
|
@ -137,9 +135,9 @@ else()
|
|||
endif()
|
||||
|
||||
set(every_platform_SOURCES
|
||||
platform/w32main.cpp
|
||||
platform/gtkmain.cpp
|
||||
platform/cocoamain.mm)
|
||||
platform/guiwin.cpp
|
||||
platform/guigtk.cpp
|
||||
platform/guimac.mm)
|
||||
|
||||
# solvespace library
|
||||
|
||||
|
@ -362,7 +360,7 @@ target_compile_options(solvespace-headless
|
|||
# solvespace command-line executable
|
||||
|
||||
add_executable(solvespace-cli
|
||||
platform/climain.cpp
|
||||
platform/entrycli.cpp
|
||||
$<TARGET_PROPERTY:resources,EXTRA_SOURCES>)
|
||||
|
||||
target_link_libraries(solvespace-cli
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Our main() function, and Cocoa-specific stuff to set up our windows and
|
||||
// otherwise handle our interface to the operating system. Everything
|
||||
// outside platform/... should be standard C++ and OpenGL.
|
||||
//
|
||||
// Copyright 2015 <whitequark@whitequark.org>
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "solvespace.h"
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
using SolveSpace::dbp;
|
||||
|
||||
/* Miscellanea */
|
||||
|
||||
void SolveSpace::OpenWebsite(const char *url) {
|
||||
[[NSWorkspace sharedWorkspace] openURL:
|
||||
[NSURL URLWithString:[NSString stringWithUTF8String:url]]];
|
||||
}
|
||||
|
||||
std::vector<SolveSpace::Platform::Path> SolveSpace::GetFontFiles() {
|
||||
std::vector<SolveSpace::Platform::Path> fonts;
|
||||
|
||||
NSArray *fontNames = [[NSFontManager sharedFontManager] availableFonts];
|
||||
for(NSString *fontName in fontNames) {
|
||||
CTFontDescriptorRef fontRef =
|
||||
CTFontDescriptorCreateWithNameAndSize ((__bridge CFStringRef)fontName, 10.0);
|
||||
CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute);
|
||||
NSString *fontPath = [NSString stringWithString:[(NSURL *)CFBridgingRelease(url) path]];
|
||||
fonts.push_back(
|
||||
Platform::Path::From([[NSFileManager defaultManager]
|
||||
fileSystemRepresentationWithPath:fontPath]));
|
||||
}
|
||||
|
||||
return fonts;
|
||||
}
|
||||
|
||||
/* Application lifecycle */
|
||||
|
||||
@interface ApplicationDelegate : NSObject<NSApplicationDelegate>
|
||||
- (IBAction)preferences:(id)sender;
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
|
||||
@end
|
||||
|
||||
@implementation ApplicationDelegate
|
||||
- (IBAction)preferences:(id)sender {
|
||||
SolveSpace::SS.TW.GoToScreen(SolveSpace::TextWindow::Screen::CONFIGURATION);
|
||||
SolveSpace::SS.ScheduleShowTW();
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
|
||||
SolveSpace::Platform::Path path = SolveSpace::Platform::Path::From([filename UTF8String]);
|
||||
return SolveSpace::SS.Load(path.Expand(/*fromCurrentDirectory=*/true));
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
||||
[[[NSApp mainWindow] delegate] windowShouldClose:nil];
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
- (void)applicationTerminatePrompt {
|
||||
SolveSpace::SS.MenuFile(SolveSpace::Command::EXIT);
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
ApplicationDelegate *delegate = [[ApplicationDelegate alloc] init];
|
||||
[[NSApplication sharedApplication] setDelegate:delegate];
|
||||
|
||||
[[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:nil topLevelObjects:nil];
|
||||
|
||||
NSArray *languages = [NSLocale preferredLanguages];
|
||||
for(NSString *language in languages) {
|
||||
if(SolveSpace::SetLocale([language UTF8String])) break;
|
||||
}
|
||||
if([languages count] == 0) {
|
||||
SolveSpace::SetLocale("en_US");
|
||||
}
|
||||
|
||||
SolveSpace::Platform::Open3DConnexion();
|
||||
SolveSpace::SS.Init();
|
||||
|
||||
[NSApp run];
|
||||
|
||||
SolveSpace::Platform::Close3DConnexion();
|
||||
SolveSpace::SK.Clear();
|
||||
SolveSpace::SS.Clear();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Our main() function for the graphical interface.
|
||||
//
|
||||
// Copyright 2018 <whitequark@whitequark.org>
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "solvespace.h"
|
||||
#if defined(WIN32)
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
using namespace SolveSpace;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::vector<std::string> args = InitPlatform(argc, argv);
|
||||
|
||||
Platform::InitGui(argc, argv);
|
||||
Platform::Open3DConnexion();
|
||||
SS.Init();
|
||||
|
||||
if(args.size() >= 2) {
|
||||
if(args.size() > 2) {
|
||||
dbp("Only the first file passed on command line will be opened.");
|
||||
}
|
||||
|
||||
SS.Load(Platform::Path::From(args.back()).Expand(/*fromCurrentDirectory=*/true));
|
||||
}
|
||||
|
||||
Platform::RunGui();
|
||||
|
||||
Platform::Close3DConnexion();
|
||||
SS.Clear();
|
||||
|
||||
SK.Clear();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine, INT nCmdShow) {
|
||||
return main(0, NULL);
|
||||
}
|
||||
#endif
|
|
@ -1,140 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Our main() function, and GTK2/3-specific stuff to set up our windows and
|
||||
// otherwise handle our interface to the operating system. Everything
|
||||
// outside platform/... should be standard C++ and OpenGL.
|
||||
//
|
||||
// Copyright 2015 <whitequark@whitequark.org>
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <json-c/json_object.h>
|
||||
#include <json-c/json_util.h>
|
||||
|
||||
#include <glibmm/main.h>
|
||||
#include <glibmm/convert.h>
|
||||
#include <giomm/file.h>
|
||||
#include <gdkmm/cursor.h>
|
||||
#include <gtkmm/cssprovider.h>
|
||||
#include <gtkmm/drawingarea.h>
|
||||
#include <gtkmm/glarea.h>
|
||||
#include <gtkmm/scrollbar.h>
|
||||
#include <gtkmm/entry.h>
|
||||
#include <gtkmm/eventbox.h>
|
||||
#include <gtkmm/hvbox.h>
|
||||
#include <gtkmm/fixed.h>
|
||||
#include <gtkmm/adjustment.h>
|
||||
#include <gtkmm/separatormenuitem.h>
|
||||
#include <gtkmm/menuitem.h>
|
||||
#include <gtkmm/checkmenuitem.h>
|
||||
#include <gtkmm/radiomenuitem.h>
|
||||
#include <gtkmm/radiobuttongroup.h>
|
||||
#include <gtkmm/menu.h>
|
||||
#include <gtkmm/menubar.h>
|
||||
#include <gtkmm/filechooserdialog.h>
|
||||
#include <gtkmm/messagedialog.h>
|
||||
#include <gtkmm/main.h>
|
||||
|
||||
#include <cairomm/xlib_surface.h>
|
||||
#include <pangomm/fontdescription.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include "solvespace.h"
|
||||
#include "config.h"
|
||||
|
||||
namespace SolveSpace {
|
||||
|
||||
void OpenWebsite(const char *url) {
|
||||
gtk_show_uri(Gdk::Screen::get_default()->gobj(), url, GDK_CURRENT_TIME, NULL);
|
||||
}
|
||||
|
||||
/* fontconfig is already initialized by GTK */
|
||||
std::vector<Platform::Path> GetFontFiles() {
|
||||
std::vector<Platform::Path> fonts;
|
||||
|
||||
FcPattern *pat = FcPatternCreate();
|
||||
FcObjectSet *os = FcObjectSetBuild(FC_FILE, (char *)0);
|
||||
FcFontSet *fs = FcFontList(0, pat, os);
|
||||
|
||||
for(int i = 0; i < fs->nfont; i++) {
|
||||
FcChar8 *filenameFC = FcPatternFormat(fs->fonts[i], (const FcChar8*) "%{file}");
|
||||
fonts.push_back(Platform::Path::From((const char *)filenameFC));
|
||||
FcStrFree(filenameFC);
|
||||
}
|
||||
|
||||
FcFontSetDestroy(fs);
|
||||
FcObjectSetDestroy(os);
|
||||
FcPatternDestroy(pat);
|
||||
|
||||
return fonts;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
/* It would in principle be possible to judiciously use
|
||||
Glib::filename_{from,to}_utf8, but it's not really worth
|
||||
the effort.
|
||||
The setlocale() call is necessary for Glib::get_charset()
|
||||
to detect the system character set; otherwise it thinks
|
||||
it is always ANSI_X3.4-1968.
|
||||
We set it back to C after all. */
|
||||
setlocale(LC_ALL, "");
|
||||
if(!Glib::get_charset()) {
|
||||
dbp("Sorry, only UTF-8 locales are supported.");
|
||||
return 1;
|
||||
}
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
/* If we don't do this, gtk_init will set the C standard library
|
||||
locale, and printf will format floats using ",". We will then
|
||||
fail to parse these. Also, many text window lines will become
|
||||
ambiguous. */
|
||||
gtk_disable_setlocale();
|
||||
|
||||
Gtk::Main main(argc, argv);
|
||||
|
||||
// Add our application-specific styles, to override GTK defaults.
|
||||
Glib::RefPtr<Gtk::CssProvider> style_provider = Gtk::CssProvider::create();
|
||||
style_provider->load_from_data(R"(
|
||||
entry {
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
)");
|
||||
Gtk::StyleContext::add_provider_for_screen(Gdk::Screen::get_default(),
|
||||
style_provider,
|
||||
600 /*Gtk::STYLE_PROVIDER_PRIORITY_APPLICATION*/);
|
||||
|
||||
const char* const* langNames = g_get_language_names();
|
||||
while(*langNames) {
|
||||
if(SetLocale(*langNames++)) break;
|
||||
}
|
||||
if(!*langNames) {
|
||||
SetLocale("en_US");
|
||||
}
|
||||
|
||||
SS.Init();
|
||||
|
||||
if(argc >= 2) {
|
||||
if(argc > 2) {
|
||||
dbp("Only the first file passed on command line will be opened.");
|
||||
}
|
||||
|
||||
/* Make sure the argument is valid UTF-8. */
|
||||
Glib::ustring arg(argv[1]);
|
||||
SS.Load(Platform::Path::From(arg).Expand(/*fromCurrentDirectory=*/true));
|
||||
}
|
||||
|
||||
main.run();
|
||||
|
||||
SK.Clear();
|
||||
SS.Clear();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -359,7 +359,12 @@ FileDialogRef CreateSaveFileDialog(WindowRef parentWindow);
|
|||
// Application-wide APIs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Exit();
|
||||
std::vector<Platform::Path> GetFontFiles();
|
||||
void OpenInBrowser(const std::string &url);
|
||||
|
||||
void InitGui(int argc, char **argv);
|
||||
void RunGui();
|
||||
void ExitGui();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
#include <unistd.h>
|
||||
#include <json-c/json_object.h>
|
||||
#include <json-c/json_util.h>
|
||||
#include <glibmm/convert.h>
|
||||
#include <glibmm/main.h>
|
||||
#include <gtkmm/box.h>
|
||||
#include <gtkmm/checkmenuitem.h>
|
||||
#include <gtkmm/cssprovider.h>
|
||||
#include <gtkmm/entry.h>
|
||||
#include <gtkmm/filechooserdialog.h>
|
||||
#include <gtkmm/fixed.h>
|
||||
|
@ -281,7 +283,7 @@ public:
|
|||
MenuItemImplGtk() : gtkMenuItem(this) {}
|
||||
|
||||
void SetAccelerator(KeyboardEvent accel) override {
|
||||
guint accelKey;
|
||||
guint accelKey = 0;
|
||||
if(accel.key == KeyboardEvent::Key::CHARACTER) {
|
||||
if(accel.chr == '\t') {
|
||||
accelKey = GDK_KEY_Tab;
|
||||
|
@ -720,15 +722,14 @@ protected:
|
|||
class GtkWindow : public Gtk::Window {
|
||||
Platform::Window *_receiver;
|
||||
Gtk::VBox _vbox;
|
||||
Gtk::MenuBar *_menu_bar;
|
||||
Gtk::MenuBar *_menu_bar = NULL;
|
||||
Gtk::HBox _hbox;
|
||||
GtkEditorOverlay _editor_overlay;
|
||||
Gtk::VScrollbar _scrollbar;
|
||||
bool _is_fullscreen;
|
||||
bool _is_fullscreen = false;
|
||||
|
||||
public:
|
||||
GtkWindow(Platform::Window *receiver) :
|
||||
_receiver(receiver), _menu_bar(NULL), _editor_overlay(receiver) {
|
||||
GtkWindow(Platform::Window *receiver) : _receiver(receiver), _editor_overlay(receiver) {
|
||||
_hbox.pack_start(_editor_overlay, /*expand=*/true, /*fill=*/true);
|
||||
_hbox.pack_end(_scrollbar, /*expand=*/false, /*fill=*/false);
|
||||
_vbox.pack_end(_hbox, /*expand=*/true, /*fill=*/true);
|
||||
|
@ -926,6 +927,7 @@ public:
|
|||
switch(cursor) {
|
||||
case Cursor::POINTER: gdkCursorType = Gdk::ARROW; break;
|
||||
case Cursor::HAND: gdkCursorType = Gdk::HAND1; break;
|
||||
default: ssassert(false, "Unexpected cursor");
|
||||
}
|
||||
|
||||
auto gdkWindow = gtkWindow.get_gl_widget().get_window();
|
||||
|
@ -1122,9 +1124,9 @@ public:
|
|||
}
|
||||
|
||||
void AddButton(std::string name, Response response, bool isDefault) override {
|
||||
int responseId;
|
||||
int responseId = 0;
|
||||
switch(response) {
|
||||
case Response::NONE: ssassert(false, "Invalid response");
|
||||
case Response::NONE: ssassert(false, "Unexpected response");
|
||||
case Response::OK: responseId = Gtk::RESPONSE_OK; break;
|
||||
case Response::YES: responseId = Gtk::RESPONSE_YES; break;
|
||||
case Response::NO: responseId = Gtk::RESPONSE_NO; break;
|
||||
|
@ -1295,8 +1297,78 @@ FileDialogRef CreateSaveFileDialog(WindowRef parentWindow) {
|
|||
// Application-wide APIs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Exit() {
|
||||
Gtk::Main::quit();
|
||||
std::vector<Platform::Path> GetFontFiles() {
|
||||
std::vector<Platform::Path> fonts;
|
||||
|
||||
// fontconfig is already initialized by GTK
|
||||
FcPattern *pat = FcPatternCreate();
|
||||
FcObjectSet *os = FcObjectSetBuild(FC_FILE, (char *)0);
|
||||
FcFontSet *fs = FcFontList(0, pat, os);
|
||||
|
||||
for(int i = 0; i < fs->nfont; i++) {
|
||||
FcChar8 *filenameFC = FcPatternFormat(fs->fonts[i], (const FcChar8*) "%{file}");
|
||||
fonts.push_back(Platform::Path::From((const char *)filenameFC));
|
||||
FcStrFree(filenameFC);
|
||||
}
|
||||
|
||||
FcFontSetDestroy(fs);
|
||||
FcObjectSetDestroy(os);
|
||||
FcPatternDestroy(pat);
|
||||
|
||||
return fonts;
|
||||
}
|
||||
|
||||
void OpenInBrowser(const std::string &url) {
|
||||
gtk_show_uri(Gdk::Screen::get_default()->gobj(), url.c_str(), GDK_CURRENT_TIME, NULL);
|
||||
}
|
||||
|
||||
Gtk::Main *gtkMain;
|
||||
|
||||
void InitGui(int argc, char **argv) {
|
||||
// It would in principle be possible to judiciously use Glib::filename_{from,to}_utf8,
|
||||
// but it's not really worth the effort.
|
||||
// The setlocale() call is necessary for Glib::get_charset() to detect the system
|
||||
// character set; otherwise it thinks it is always ANSI_X3.4-1968.
|
||||
// We set it back to C after all so that printf() and friends behave in a consistent way.
|
||||
setlocale(LC_ALL, "");
|
||||
if(!Glib::get_charset()) {
|
||||
dbp("Sorry, only UTF-8 locales are supported.");
|
||||
exit(1);
|
||||
}
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
gtkMain = new Gtk::Main(argc, argv, /*set_locale=*/false);
|
||||
|
||||
// Add our application-specific styles, to override GTK defaults.
|
||||
Glib::RefPtr<Gtk::CssProvider> style_provider = Gtk::CssProvider::create();
|
||||
style_provider->load_from_data(R"(
|
||||
entry {
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
)");
|
||||
Gtk::StyleContext::add_provider_for_screen(
|
||||
Gdk::Screen::get_default(), style_provider,
|
||||
600 /*Gtk::STYLE_PROVIDER_PRIORITY_APPLICATION*/);
|
||||
|
||||
// Set locale from user preferences.
|
||||
// This apparently only consults the LANGUAGE environment variable.
|
||||
const char* const* langNames = g_get_language_names();
|
||||
while(*langNames) {
|
||||
if(SetLocale(*langNames++)) break;
|
||||
}
|
||||
if(!*langNames) {
|
||||
SetLocale("en_US");
|
||||
}
|
||||
}
|
||||
|
||||
void RunGui() {
|
||||
gtkMain->run();
|
||||
}
|
||||
|
||||
void ExitGui() {
|
||||
gtkMain->quit();
|
||||
delete gtkMain;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1405,7 +1405,82 @@ FileDialogRef CreateSaveFileDialog(WindowRef parentWindow) {
|
|||
// Application-wide APIs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Exit() {
|
||||
std::vector<Platform::Path> GetFontFiles() {
|
||||
std::vector<SolveSpace::Platform::Path> fonts;
|
||||
|
||||
NSArray *fontNames = [[NSFontManager sharedFontManager] availableFonts];
|
||||
for(NSString *fontName in fontNames) {
|
||||
CTFontDescriptorRef fontRef =
|
||||
CTFontDescriptorCreateWithNameAndSize ((__bridge CFStringRef)fontName, 10.0);
|
||||
CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute);
|
||||
NSString *fontPath = [NSString stringWithString:[(NSURL *)CFBridgingRelease(url) path]];
|
||||
fonts.push_back(
|
||||
Platform::Path::From([[NSFileManager defaultManager]
|
||||
fileSystemRepresentationWithPath:fontPath]));
|
||||
}
|
||||
|
||||
return fonts;
|
||||
}
|
||||
|
||||
void OpenInBrowser(const std::string &url) {
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:Wrap(url)]];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@interface SSApplicationDelegate : NSObject<NSApplicationDelegate>
|
||||
- (IBAction)preferences:(id)sender;
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
|
||||
@end
|
||||
|
||||
@implementation SSApplicationDelegate
|
||||
- (IBAction)preferences:(id)sender {
|
||||
SolveSpace::SS.TW.GoToScreen(SolveSpace::TextWindow::Screen::CONFIGURATION);
|
||||
SolveSpace::SS.ScheduleShowTW();
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
|
||||
SolveSpace::Platform::Path path = SolveSpace::Platform::Path::From([filename UTF8String]);
|
||||
return SolveSpace::SS.Load(path.Expand(/*fromCurrentDirectory=*/true));
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
||||
[[[NSApp mainWindow] delegate] windowShouldClose:nil];
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
- (void)applicationTerminatePrompt {
|
||||
SolveSpace::SS.MenuFile(SolveSpace::Command::EXIT);
|
||||
}
|
||||
@end
|
||||
|
||||
namespace SolveSpace {
|
||||
namespace Platform {
|
||||
|
||||
static SSApplicationDelegate *ssDelegate;
|
||||
|
||||
void InitGui(int argc, char **argv) {
|
||||
ssDelegate = [[SSApplicationDelegate alloc] init];
|
||||
NSApplication.sharedApplication.delegate = ssDelegate;
|
||||
|
||||
[NSBundle.mainBundle loadNibNamed:@"MainMenu" owner:nil topLevelObjects:nil];
|
||||
|
||||
NSArray *languages = NSLocale.preferredLanguages;
|
||||
for(NSString *language in languages) {
|
||||
if(SolveSpace::SetLocale([language UTF8String])) break;
|
||||
}
|
||||
if(languages.count == 0) {
|
||||
SolveSpace::SetLocale("en_US");
|
||||
}
|
||||
}
|
||||
|
||||
void RunGui() {
|
||||
[NSApp run];
|
||||
}
|
||||
|
||||
void ExitGui() {
|
||||
[NSApp setDelegate:nil];
|
||||
[NSApp terminate:nil];
|
||||
}
|
||||
|
|
|
@ -139,27 +139,21 @@ FileDialogRef CreateSaveFileDialog(WindowRef parentWindow) {
|
|||
// Application-wide APIs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Exit() {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dialogs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void OpenWebsite(const char *url) {
|
||||
ssassert(false, "Not implemented");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resources
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
std::vector<Platform::Path> fontFiles;
|
||||
std::vector<Platform::Path> GetFontFiles() {
|
||||
return fontFiles;
|
||||
}
|
||||
|
||||
void OpenInBrowser(const std::string &url) {}
|
||||
|
||||
void InitGui(int argc, char **argv) {}
|
||||
|
||||
void RunGui() {}
|
||||
|
||||
void ExitGui() {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1580,7 +1580,49 @@ FileDialogRef CreateSaveFileDialog(WindowRef parentWindow) {
|
|||
// Application-wide APIs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Exit() {
|
||||
std::vector<Platform::Path> GetFontFiles() {
|
||||
std::vector<Platform::Path> fonts;
|
||||
|
||||
std::wstring fontsDirW(MAX_PATH, '\0');
|
||||
fontsDirW.resize(GetWindowsDirectoryW(&fontsDirW[0], fontsDirW.length()));
|
||||
fontsDirW += L"\\fonts\\";
|
||||
Platform::Path fontsDir = Platform::Path::From(Narrow(fontsDirW));
|
||||
|
||||
WIN32_FIND_DATAW wfd;
|
||||
HANDLE h = FindFirstFileW((fontsDirW + L"*").c_str(), &wfd);
|
||||
while(h != INVALID_HANDLE_VALUE) {
|
||||
fonts.push_back(fontsDir.Join(Narrow(wfd.cFileName)));
|
||||
if(!FindNextFileW(h, &wfd)) break;
|
||||
}
|
||||
|
||||
return fonts;
|
||||
}
|
||||
|
||||
void OpenInBrowser(const std::string &url) {
|
||||
ShellExecuteW(NULL, L"open", Widen(url).c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
void InitGui(int argc, char **argv) {
|
||||
INITCOMMONCONTROLSEX icc;
|
||||
icc.dwSize = sizeof(icc);
|
||||
icc.dwICC = ICC_STANDARD_CLASSES|ICC_BAR_CLASSES;
|
||||
InitCommonControlsEx(&icc);
|
||||
|
||||
if(!SetLocale((uint16_t)GetUserDefaultLCID())) {
|
||||
SetLocale("en_US");
|
||||
}
|
||||
}
|
||||
|
||||
void RunGui() {
|
||||
MSG msg;
|
||||
// The return value of the following functions doesn't indicate success or failure.
|
||||
while(GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
void ExitGui() {
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -439,7 +439,7 @@ bool WriteFile(const Platform::Path &filename, const std::string &data) {
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Loading resources, on Windows.
|
||||
// Loading resources, on Windows
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(WIN32)
|
||||
|
@ -457,7 +457,7 @@ const void *LoadResource(const std::string &name, size_t *size) {
|
|||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Loading resources, on *nix.
|
||||
// Loading resources, on *nix
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
@ -568,5 +568,9 @@ const void *LoadResource(const std::string &name, size_t *size) {
|
|||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Command-line argument handling
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Our WinMain() functions, and Win32-specific stuff to set up our windows
|
||||
// and otherwise handle our interface to the operating system. Everything
|
||||
// outside platform/... should be standard C++ and gl.
|
||||
//
|
||||
// Copyright 2008-2013 Jonathan Westhues.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <time.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "solvespace.h"
|
||||
|
||||
// Include after solvespace.h to avoid identifier clashes.
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <commctrl.h>
|
||||
#include <commdlg.h>
|
||||
|
||||
using Platform::Narrow;
|
||||
using Platform::Widen;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Utility routines
|
||||
//-----------------------------------------------------------------------------
|
||||
void SolveSpace::OpenWebsite(const char *url) {
|
||||
ShellExecuteW((HWND)SS.GW.window->NativePtr(),
|
||||
L"open", Widen(url).c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
std::vector<Platform::Path> SolveSpace::GetFontFiles() {
|
||||
std::vector<Platform::Path> fonts;
|
||||
|
||||
std::wstring fontsDirW(MAX_PATH, '\0');
|
||||
fontsDirW.resize(GetWindowsDirectoryW(&fontsDirW[0], fontsDirW.length()));
|
||||
fontsDirW += L"\\fonts\\";
|
||||
Platform::Path fontsDir = Platform::Path::From(Narrow(fontsDirW));
|
||||
|
||||
WIN32_FIND_DATA wfd;
|
||||
HANDLE h = FindFirstFileW((fontsDirW + L"*").c_str(), &wfd);
|
||||
while(h != INVALID_HANDLE_VALUE) {
|
||||
fonts.push_back(fontsDir.Join(Narrow(wfd.cFileName)));
|
||||
if(!FindNextFileW(h, &wfd)) break;
|
||||
}
|
||||
|
||||
return fonts;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Entry point into the program.
|
||||
//-----------------------------------------------------------------------------
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine, INT nCmdShow)
|
||||
{
|
||||
INITCOMMONCONTROLSEX icc;
|
||||
icc.dwSize = sizeof(icc);
|
||||
icc.dwICC = ICC_STANDARD_CLASSES|ICC_BAR_CLASSES;
|
||||
InitCommonControlsEx(&icc);
|
||||
|
||||
std::vector<std::string> args = InitPlatform(0, NULL);
|
||||
|
||||
// Use the user default locale, then fall back to English.
|
||||
if(!SetLocale((uint16_t)GetUserDefaultLCID())) {
|
||||
SetLocale("en_US");
|
||||
}
|
||||
|
||||
// Call in to the platform-independent code, and let them do their init
|
||||
SS.Init();
|
||||
|
||||
// A filename may have been specified on the command line.
|
||||
if(args.size() >= 2) {
|
||||
SS.Load(Platform::Path::From(args[1]).Expand(/*fromCurrentDirectory=*/true));
|
||||
}
|
||||
|
||||
// And now it's the message loop. All calls in to the rest of the code
|
||||
// will be from the wndprocs.
|
||||
MSG msg;
|
||||
while(GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
// Free the memory we've used; anything that remains is a leak.
|
||||
SK.Clear();
|
||||
SS.Clear();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -271,7 +271,7 @@ void SolveSpaceUI::Exit() {
|
|||
// And the default styles, colors and line widths and such.
|
||||
Style::FreezeDefaultStyles(settings);
|
||||
|
||||
Platform::Exit();
|
||||
Platform::ExitGui();
|
||||
}
|
||||
|
||||
void SolveSpaceUI::ScheduleGenerateAll() {
|
||||
|
@ -907,7 +907,7 @@ void SolveSpaceUI::ShowNakedEdges(bool reportOnlyWhenNotOkay) {
|
|||
void SolveSpaceUI::MenuHelp(Command id) {
|
||||
switch(id) {
|
||||
case Command::WEBSITE:
|
||||
OpenWebsite("http://solvespace.com/helpmenu");
|
||||
Platform::OpenInBrowser("http://solvespace.com/helpmenu");
|
||||
break;
|
||||
|
||||
case Command::ABOUT:
|
||||
|
|
|
@ -142,10 +142,6 @@ extern Platform::Path RecentFile[MAX_RECENT];
|
|||
|
||||
#define AUTOSAVE_EXT "slvs~"
|
||||
|
||||
std::vector<Platform::Path> GetFontFiles();
|
||||
|
||||
void OpenWebsite(const char *url);
|
||||
|
||||
void dbp(const char *str, ...);
|
||||
#define DBPTRI(tri) \
|
||||
dbp("tri: (%.3f %.3f %.3f) (%.3f %.3f %.3f) (%.3f %.3f %.3f)", \
|
||||
|
|
|
@ -88,7 +88,7 @@ void TextWindow::ScreenShowEditView(int link, uint32_t v) {
|
|||
SS.TW.GoToScreen(Screen::EDIT_VIEW);
|
||||
}
|
||||
void TextWindow::ScreenGoToWebsite(int link, uint32_t v) {
|
||||
OpenWebsite("http://solvespace.com/txtlink");
|
||||
Platform::OpenInBrowser("http://solvespace.com/txtlink");
|
||||
}
|
||||
void TextWindow::ShowListOfGroups() {
|
||||
const char *radioTrue = " " RADIO_TRUE " ",
|
||||
|
|
|
@ -56,7 +56,7 @@ TtfFontList::~TtfFontList() {
|
|||
void TtfFontList::LoadAll() {
|
||||
if(loaded) return;
|
||||
|
||||
for(const Platform::Path &font : GetFontFiles()) {
|
||||
for(const Platform::Path &font : Platform::GetFontFiles()) {
|
||||
TtfFont tf = {};
|
||||
tf.fontFile = font;
|
||||
if(tf.LoadFromFile(fontLibrary))
|
||||
|
|
|
@ -15,9 +15,11 @@
|
|||
#endif
|
||||
|
||||
namespace SolveSpace {
|
||||
namespace Platform {
|
||||
// These are defined in headless.cpp, and aren't exposed in solvespace.h.
|
||||
extern std::vector<Platform::Path> fontFiles;
|
||||
}
|
||||
}
|
||||
|
||||
// The paths in __FILE__ are from the build system, but defined(WIN32) returns
|
||||
// the value for the host system.
|
||||
|
@ -338,7 +340,7 @@ int main(int argc, char **argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
fontFiles.push_back(HostRoot().Join("Gentium-R.ttf"));
|
||||
Platform::fontFiles.push_back(HostRoot().Join("Gentium-R.ttf"));
|
||||
|
||||
// Wreck order dependencies between tests!
|
||||
std::random_shuffle(testCasesPtr->begin(), testCasesPtr->end());
|
||||
|
|
Loading…
Reference in New Issue