diff --git a/.travis.yml b/.travis.yml index 9dbf0369..26d94da9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,3 +25,30 @@ 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 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); } }