diff --git a/.travis.yml b/.travis.yml
index e3bea58d..6b253be3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,6 +26,33 @@ jobs:
on:
repo: solvespace/solvespace
tags: true
+ - &deploy-snap
+ stage: deploy
+ name: Snap amd64
+ os: linux
+ arch: amd64
+ dist: bionic
+ addons:
+ snaps:
+ - name: snapcraft
+ confinement: classic
+ script: ./.travis/build-snap.sh
+ deploy:
+ - provider: script
+ script: sudo ./.travis/deploy-snap.sh edge
+ skip_cleanup: true
+ on:
+ branch: master
+ tags: false
+ - provider: script
+ script: sudo ./.travis/deploy-snap.sh edge,beta
+ skip_cleanup: true
+ on:
+ branch: master
+ tags: true
+ - <<: *deploy-snap
+ name: Snap arm64
+ arch: arm64
- &linux
stage: deploy
os: linux
diff --git a/.travis/build-snap.sh b/.travis/build-snap.sh
new file mode 100755
index 00000000..634e01c4
--- /dev/null
+++ b/.travis/build-snap.sh
@@ -0,0 +1,4 @@
+#!/bin/sh -xe
+
+sudo apt-get update
+sudo ./pkg/snap/build.sh --destructive-mode
diff --git a/.travis/deploy-snap.sh b/.travis/deploy-snap.sh
new file mode 100755
index 00000000..91674a7c
--- /dev/null
+++ b/.travis/deploy-snap.sh
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+
+channels="$1"
+echo "$SNAP_TOKEN" | snapcraft login --with -
+
+for snap in ./pkg/snap/*.snap; do
+ snapcraft push "$snap" --release "$channels"
+done
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9bfd04d0..d442eee9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,8 +7,10 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
" mkdir build && cd build && cmake ..")
endif()
-cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR)
-cmake_policy(VERSION 3.11)
+cmake_minimum_required(VERSION 3.7.2 FATAL_ERROR)
+if(NOT CMAKE_VERSION VERSION_LESS 3.11.0)
+ cmake_policy(VERSION 3.11.0)
+endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${CMAKE_SOURCE_DIR}/cmake/")
set(CMAKE_CXX_STANDARD 11)
diff --git a/README.md b/README.md
index e878c970..94eb67f3 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,20 @@ the SolveSpace maintainers for each stable release.
[rel]: https://github.com/solvespace/solvespace/releases
+### Via Snap Store
+
+Builds from master are automatically released to the `edge` channel in the Snap Store. Those packages contain the latest improvements, but receive less testing than release builds.
+
+Future official releases will appear in the `stable` channel.
+
+[![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-black.svg)](https://snapcraft.io/solvespace)
+
+Or install from a terminal:
+
+```
+snap install --edge solvespace
+```
+
### Via third-party binary packages
_Third-party_ nightly binary packages for Debian and Ubuntu are available
diff --git a/pkg/snap/snap/snapcraft.yaml b/pkg/snap/snap/snapcraft.yaml
index e17ecda1..940d0837 100644
--- a/pkg/snap/snap/snapcraft.yaml
+++ b/pkg/snap/snap/snapcraft.yaml
@@ -26,9 +26,10 @@ apps:
extensions: [gnome-3-28]
plugs: [opengl, unity7, home, removable-media, gsettings, network]
environment:
- __EGL_VENDOR_LIBRARY_DIRS: $SNAP/usr/share/glvnd/egl_vendor.d
+ __EGL_VENDOR_LIBRARY_DIRS: $SNAP/gnome-platform/usr/share/glvnd/egl_vendor.d:$SNAP/usr/share/glvnd/egl_vendor.d
cli:
command: usr/bin/solvespace-cli
+ extensions: [gnome-3-28]
plugs: [home, removable-media, network]
parts:
@@ -71,6 +72,14 @@ parts:
- libglibmm-2.4-1v5
- libpangomm-1.4-1v5
- libsigc++-2.0-0v5
- - libglew2.0
- - libegl-mesa0
- - libdrm2
+ cleanup:
+ after: [solvespace]
+ plugin: nil
+ build-snaps: [core18, gnome-3-28-1804]
+ override-prime: |
+ # Remove all files from snap that are already included in the base snap or in
+ # any connected content snaps
+ set -eux
+ for snap in "core18" "gnome-3-28-1804"; do # List all content-snaps and base snaps you're using here
+ cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" \;
+ done
diff --git a/res/freedesktop/solvespace-scalable.svg b/res/freedesktop/solvespace-scalable.svg
index 7be996e0..0d060d12 100644
--- a/res/freedesktop/solvespace-scalable.svg
+++ b/res/freedesktop/solvespace-scalable.svg
@@ -5,8 +5,8 @@
-
+
diff --git a/src/constraint.cpp b/src/constraint.cpp
index 8ab76f27..fb5c74cb 100644
--- a/src/constraint.cpp
+++ b/src/constraint.cpp
@@ -196,9 +196,6 @@ void Constraint::MenuConstrain(Command id) {
c.valA = 0;
c.ModifyToSatisfy();
AddConstraint(&c);
- if (SS.immediatelyEditDimension) {
- SS.GW.EditConstraint(c.h);
- }
break;
}
@@ -610,9 +607,6 @@ void Constraint::MenuConstrain(Command id) {
c.ModifyToSatisfy();
AddConstraint(&c);
- if (SS.immediatelyEditDimension) {
- SS.GW.EditConstraint(c.h);
- }
break;
}
@@ -769,6 +763,10 @@ void Constraint::MenuConstrain(Command id) {
}
}
+ if ((id == Command::DISTANCE_DIA || id == Command::ANGLE) && SS.immediatelyEditDimension) {
+ SS.GW.EditConstraint(c.h);
+ }
+
SS.GW.ClearSelection();
}
diff --git a/src/export.cpp b/src/export.cpp
index 621fa2e6..31c6c375 100644
--- a/src/export.cpp
+++ b/src/export.cpp
@@ -917,13 +917,13 @@ void SolveSpaceUI::ExportMeshAsQ3doTo(FILE *f, SMesh *sm) {
}
Vector faceNormal = t.Normal();
- auto a = q3d::Vector3(t.a.x/s, t.a.y/s, t.a.z/s);
- auto b = q3d::Vector3(t.b.x/s, t.b.y/s, t.b.z/s);
- auto c = q3d::Vector3(t.c.x/s, t.c.y/s, t.c.z/s);
- auto fn = q3d::Vector3(faceNormal.x, faceNormal.y, faceNormal.x);
- auto n1 = q3d::Vector3(t.normals[0].x, t.normals[0].y, t.normals[0].z);
- auto n2 = q3d::Vector3(t.normals[1].x, t.normals[1].y, t.normals[1].z);
- auto n3 = q3d::Vector3(t.normals[2].x, t.normals[2].y, t.normals[2].z);
+ auto a = q3d::Vector3((float)(t.a.x/s), (float)(t.a.y/s), (float)(t.a.z/s));
+ auto b = q3d::Vector3((float)(t.b.x/s), (float)(t.b.y/s), (float)(t.b.z/s));
+ auto c = q3d::Vector3((float)(t.c.x/s), (float)(t.c.y/s), (float)(t.c.z/s));
+ auto fn = q3d::Vector3((float)faceNormal.x, (float)faceNormal.y, (float)faceNormal.x);
+ auto n1 = q3d::Vector3((float)t.normals[0].x, (float)t.normals[0].y, (float)t.normals[0].z);
+ auto n2 = q3d::Vector3((float)t.normals[1].x, (float)t.normals[1].y, (float)t.normals[1].z);
+ auto n3 = q3d::Vector3((float)t.normals[2].x, (float)t.normals[2].y, (float)t.normals[2].z);
auto tri = q3d::CreateTriangle(builder, &a, &b, &c, &fn, &n1, &n2, &n3);
materialTriangles[color].push_back(tri);
}
diff --git a/src/platform/guimac.mm b/src/platform/guimac.mm
index a5763c90..cb939cf7 100644
--- a/src/platform/guimac.mm
+++ b/src/platform/guimac.mm
@@ -16,6 +16,7 @@ using namespace SolveSpace;
+ (NSToolTipManager *)sharedToolTipManager;
- (void)setInitialToolTipDelay:(double)delay;
- (void)orderOutToolTip;
+- (void)abortToolTip;
- (void)_displayTemporaryToolTipForView:(id)arg1 withString:(id)arg2;
@end
@@ -909,7 +910,11 @@ public:
NSToolTipManager *nsToolTipManager = [NSToolTipManager sharedToolTipManager];
if(newText.empty()) {
- [nsToolTipManager orderOutToolTip];
+ if ([nsToolTipManager respondsToSelector:@selector(abortToolTip)]) {
+ [nsToolTipManager abortToolTip];
+ } else {
+ [nsToolTipManager orderOutToolTip];
+ }
} else {
[nsToolTipManager _displayTemporaryToolTipForView:ssView withString:Wrap(newText)];
}
diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp
index bd1b42e7..70160bbc 100644
--- a/src/platform/guiwin.cpp
+++ b/src/platform/guiwin.cpp
@@ -73,9 +73,9 @@ namespace Platform {
void CheckLastError(const char *file, int line, const char *function, const char *expr) {
if(GetLastError() != S_OK) {
LPWSTR messageW;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPWSTR)&messageW, 0, NULL);
+ FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPWSTR)&messageW, 0, NULL);
std::string message;
message += ssprintf("File %s, line %u, function %s:\n", file, line, function);
@@ -203,8 +203,8 @@ public:
uint32_t ThawInt(const std::string &key, uint32_t defaultValue) {
DWORD value;
DWORD type, length = sizeof(value);
- LSTATUS result = RegQueryValueEx(GetKey(), &Widen(key)[0], 0,
- &type, (BYTE *)&value, &length);
+ LSTATUS result = RegQueryValueExW(GetKey(), &Widen(key)[0], 0,
+ &type, (BYTE *)&value, &length);
if(result == ERROR_SUCCESS && type == REG_DWORD) {
return value;
}
@@ -219,8 +219,8 @@ public:
double ThawFloat(const std::string &key, double defaultValue) {
double value;
DWORD type, length = sizeof(value);
- LSTATUS result = RegQueryValueEx(GetKey(), &Widen(key)[0], 0,
- &type, (BYTE *)&value, &length);
+ LSTATUS result = RegQueryValueExW(GetKey(), &Widen(key)[0], 0,
+ &type, (BYTE *)&value, &length);
if(result == ERROR_SUCCESS && type == REG_QWORD) {
return value;
}
@@ -237,13 +237,13 @@ public:
std::string ThawString(const std::string &key, const std::string &defaultValue) {
DWORD type, length = 0;
- LSTATUS result = RegQueryValueEx(GetKey(), &Widen(key)[0], 0,
- &type, NULL, &length);
+ LSTATUS result = RegQueryValueExW(GetKey(), &Widen(key)[0], 0,
+ &type, NULL, &length);
if(result == ERROR_SUCCESS && type == REG_SZ) {
std::wstring valueW;
valueW.resize(length / 2 - 1);
- sscheck(RegQueryValueEx(GetKey(), &Widen(key)[0], 0,
- &type, (BYTE *)&valueW[0], &length));
+ sscheck(RegQueryValueExW(GetKey(), &Widen(key)[0], 0,
+ &type, (BYTE *)&valueW[0], &length));
return Narrow(valueW);
}
return defaultValue;
@@ -538,7 +538,7 @@ public:
static bool registered;
if(registered) return;
- WNDCLASSEX wc = {};
+ WNDCLASSEXW wc = {};
wc.cbSize = sizeof(wc);
wc.style = CS_BYTEALIGNCLIENT|CS_BYTEALIGNWINDOW|CS_OWNDC|CS_DBLCLKS;
wc.lpfnWndProc = WndProc;
@@ -549,7 +549,7 @@ public:
IMAGE_ICON, 16, 16, 0);
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.lpszClassName = L"SolveSpace";
- sscheck(RegisterClassEx(&wc));
+ sscheck(RegisterClassExW(&wc));
registered = true;
}
@@ -702,7 +702,7 @@ public:
// The wndproc may be called from within CreateWindowEx, and before we've associated
// the window with the WindowImplWin32. In that case, just defer to the default wndproc.
if(window == NULL) {
- return DefWindowProc(h, msg, wParam, lParam);
+ return DefWindowProcW(h, msg, wParam, lParam);
}
#if defined(HAVE_SPACEWARE)
@@ -999,7 +999,7 @@ public:
sscheck(SetForegroundWindow(hParent));
break;
} else {
- return DefWindowProc(h, msg, wParam, lParam);
+ return DefWindowProcW(h, msg, wParam, lParam);
}
}
@@ -1042,7 +1042,7 @@ public:
}
default:
- return DefWindowProc(h, msg, wParam, lParam);
+ return DefWindowProcW(h, msg, wParam, lParam);
}
return 0;
@@ -1227,7 +1227,7 @@ public:
}
void SetCursor(Cursor cursor) override {
- LPWSTR cursorName;
+ LPWSTR cursorName = IDC_ARROW;
switch(cursor) {
case Cursor::POINTER: cursorName = IDC_ARROW; break;
case Cursor::HAND: cursorName = IDC_HAND; break;
@@ -1389,7 +1389,7 @@ WindowRef CreateWindow(Window::Kind kind, WindowRef parentWindow) {
static HWND hSpaceWareDriverClass;
void Open3DConnexion() {
- HWND hSpaceWareDriverClass = FindWindowW(L"SpaceWare Driver Class", NULL);
+ hSpaceWareDriverClass = FindWindowW(L"SpaceWare Driver Class", NULL);
if(hSpaceWareDriverClass != NULL) {
SiInitialize();
}
diff --git a/src/render/render.h b/src/render/render.h
index 70d5863f..b1692f13 100644
--- a/src/render/render.h
+++ b/src/render/render.h
@@ -285,8 +285,8 @@ public:
const Camera &GetCamera() const override { return camera; }
// ViewportCanvas interface.
- void SetCamera(const Camera &camera) override { this->camera = camera; }
- void SetLighting(const Lighting &lighting) override { this->lighting = lighting; }
+ void SetCamera(const Camera &cam) override { this->camera = cam; }
+ void SetLighting(const Lighting &light) override { this->lighting = light; }
void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override;
void DrawEdges(const SEdgeList &el, hStroke hcs) override;
diff --git a/src/render/rendergl1.cpp b/src/render/rendergl1.cpp
index 3e6feb0b..ef34bc52 100644
--- a/src/render/rendergl1.cpp
+++ b/src/render/rendergl1.cpp
@@ -708,8 +708,8 @@ void OpenGl1Renderer::UpdateProjection() {
UnSelectPrimitive();
glViewport(0, 0,
- camera.width * camera.pixelRatio,
- camera.height * camera.pixelRatio);
+ (GLsizei)(camera.width * camera.pixelRatio),
+ (GLsizei)(camera.height * camera.pixelRatio));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -821,8 +821,8 @@ void OpenGl1Renderer::FinishFrame() {
}
std::shared_ptr OpenGl1Renderer::ReadFrame() {
- int width = camera.width * camera.pixelRatio;
- int height = camera.height * camera.pixelRatio;
+ int width = (int)(camera.width * camera.pixelRatio);
+ int height = (int)(camera.height * camera.pixelRatio);
std::shared_ptr pixmap =
Pixmap::Create(Pixmap::Format::RGB, (size_t)width, (size_t)height);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, &pixmap->data[0]);
diff --git a/src/solvespace.cpp b/src/solvespace.cpp
index 1a1df147..a3a53caa 100644
--- a/src/solvespace.cpp
+++ b/src/solvespace.cpp
@@ -361,7 +361,7 @@ std::string SolveSpaceUI::MmToStringSI(double v, int dim) {
}
v /= pow((viewUnits == Unit::INCHES) ? 25.4 : 1000, dim);
- int vdeg = floor((log10(fabs(v))) / dim);
+ int vdeg = (int)((log10(fabs(v))) / dim);
std::string unit;
if(fabs(v) > 0.0) {
int sdeg = 0;
@@ -371,7 +371,7 @@ std::string SolveSpaceUI::MmToStringSI(double v, int dim) {
: SelectSIPrefixMm(vdeg);
v /= pow(10.0, sdeg * dim);
}
- int pdeg = ceil(log10(fabs(v) + 1e-10));
+ int pdeg = (int)ceil(log10(fabs(v) + 1e-10));
return ssprintf("%#.*g%s%s%s", pdeg + UnitDigitsAfterDecimal(), v,
compact ? "" : " ", unit.c_str(), DimToString(dim));
}
@@ -802,7 +802,6 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
case Command::AREA: {
Group *g = SK.GetGroup(SS.GW.activeGroup);
SS.GW.GroupSelection();
- auto const &gs = SS.GW.gs;
if(gs.faces > 0) {
std::vector faces;
@@ -844,8 +843,8 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
if(gs.n > 0 && gs.n == gs.entities) {
double perimeter = 0.0;
for(int i = 0; i < gs.entities; i++) {
- Entity *e = SK.entity.FindById(gs.entity[i]);
- SEdgeList *el = e->GetOrGenerateEdges();
+ Entity *en = SK.entity.FindById(gs.entity[i]);
+ SEdgeList *el = en->GetOrGenerateEdges();
for(const SEdge &e : el->l) {
perimeter += e.b.Minus(e.a).Magnitude();
}
diff --git a/src/srf/surface.cpp b/src/srf/surface.cpp
index b90fb55f..a61713c3 100644
--- a/src/srf/surface.cpp
+++ b/src/srf/surface.cpp
@@ -646,7 +646,7 @@ void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector
// for testing - hard code the axial distance, and number of sections.
// distance will need to be parameters in the future.
double dist = distf - dists;
- int sections = fabs(anglef - angles) / (PI / 2) + 1;
+ int sections = (int)(fabs(anglef - angles) / (PI / 2) + 1);
double wedge = (anglef - angles) / sections;
if(CheckNormalAxisRelationship(sbls, pt, axis, anglef-angles, distf-dists)) {
diff --git a/src/textscreens.cpp b/src/textscreens.cpp
index 7e942393..1ea8f133 100644
--- a/src/textscreens.cpp
+++ b/src/textscreens.cpp
@@ -604,7 +604,7 @@ void TextWindow::ScreenStepDimGo(int link, uint32_t v) {
if(time - SS.TW.stepDim.time < STEP_MILLIS) {
SS.TW.stepDim.timer->RunAfterNextFrame();
} else {
- SS.TW.stepDim.timer->RunAfter(time - SS.TW.stepDim.time - STEP_MILLIS);
+ SS.TW.stepDim.timer->RunAfter((unsigned)(time - SS.TW.stepDim.time - STEP_MILLIS));
}
SS.TW.stepDim.time = time;
} else {
@@ -758,7 +758,8 @@ void TextWindow::EditControlDone(std::string s) {
Group *g = SK.group.FindByIdNoOops(SS.TW.shown.group);
if(!g) break;
- g->color = RgbaColor::FromFloat(rgb.x, rgb.y, rgb.z, g->color.alphaF());
+ g->color = RgbaColor::FromFloat((float)rgb.x, (float)rgb.y, (float)rgb.z,
+ g->color.alphaF());
SS.MarkGroupDirty(g->h);
SS.GW.ClearSuper();
diff --git a/src/toolbar.cpp b/src/toolbar.cpp
index b1718204..4d0b8839 100644
--- a/src/toolbar.cpp
+++ b/src/toolbar.cpp
@@ -219,7 +219,7 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my, UiCanvas *canvas,
{
if(hitCommand) *hitCommand = icon.command;
if(hitX) *hitX = x - boxhw;
- if(hitY) *hitY = height - (y + boxhw);
+ if(hitY) *hitY = (int)height - (y + boxhw);
}
}