[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/scad-mode 4bf29ec9b1 20/47: Add preview
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/scad-mode 4bf29ec9b1 20/47: Add preview |
Date: |
Sat, 12 Nov 2022 13:59:35 -0500 (EST) |
branch: elpa/scad-mode
commit 4bf29ec9b1c5dead6a5e9eea681b007c9f4e853c
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: Daniel Mendler <mail@daniel-mendler.de>
Add preview
The preview is based on https://github.com/zk-phi/scad-preview by @zk-phi
---
README.org | 1 +
scad-mode.el | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 187 insertions(+), 4 deletions(-)
diff --git a/README.org b/README.org
index cc1a12a65b..99333a3963 100644
--- a/README.org
+++ b/README.org
@@ -13,6 +13,7 @@
- Syntax highlighting
- Basic completion function
+- Preview rendered model in separate window
* Installation
diff --git a/scad-mode.el b/scad-mode.el
index eb6ced3bc5..d7ddc5a1f6 100644
--- a/scad-mode.el
+++ b/scad-mode.el
@@ -5,7 +5,7 @@
;; Created: 2010
;; Keywords: languages
;; Homepage: https://github.com/openscad/emacs-scad-mode
-;; Package-Requires: ((emacs "26"))
+;; Package-Requires: ((emacs "26.1"))
;; Version: 92.0
;; This program is free software; you can redistribute it and/or modify
@@ -110,12 +110,29 @@
"SCAD operators."
:type 'list)
+(defcustom scad-preview-camera '(0 0 0 50 0 20 500)
+ "Default parameters for the Gimbal camera."
+ :type '(repeat integer))
+
+(defcustom scad-preview-refresh 1.0
+ "Delay in seconds until updating preview."
+ :type 'number)
+
+(defcustom scad-preview-size '(600 . 600)
+ "Size of preview image."
+ :type '(cons integer integer))
+
+(defcustom scad-preview-colorscheme "Tomorrow"
+ "Colorscheme for rendering preview."
+ :type 'string)
+
(defvar scad-mode-map
(let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-o" #'scad-open-current-buffer)
+ (define-key map "\C-c\C-o" #'scad-open)
+ (define-key map "\C-c\C-p" #'scad-preview)
+ (define-key map "\C-c\C-e" #'scad-export)
(define-key map "\t" #'indent-for-tab-command)
(define-key map "\M-\t" #'completion-at-point)
- ;;(define-key map "\C-c\C-s" #'c-show-syntactic-information) ;; Debugging
info
map)
"Keymap for `scad-mode'.")
@@ -203,10 +220,175 @@ Key bindings:
scad-completions
:exclusive 'no)))
-(defun scad-open-current-buffer ()
+(defun scad-open ()
"Open current buffer with `scad-command'."
(interactive)
(call-process scad-command nil 0 nil (buffer-file-name)))
+(defun scad-export ()
+ "Render and export current SCAD model."
+ (interactive)
+ (compile (concat scad-command
+ " -o " (expand-file-name (read-file-name "Export to: "))
+ " " buffer-file-name)))
+
+(defvar-local scad--preview-buffer nil)
+(defvar-local scad--preview-camera nil)
+(defvar-local scad--preview-process nil)
+(defvar-local scad--preview-size nil)
+(defvar-local scad--preview-status nil)
+(defvar-local scad--preview-timer nil)
+(put 'scad--preview-buffer 'permanent-local t)
+(put 'scad--preview-camera 'permanent-local t)
+(put 'scad--preview-process 'permanent-local t)
+(put 'scad--preview-size 'permanent-local t)
+(put 'scad--preview-status 'permanent-local t)
+(put 'scad--preview-timer 'permanent-local t)
+
+(defvar scad-preview-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "M--") #'scad-preview-size-)
+ (define-key map (kbd "M-+") #'scad-preview-size+)
+ (define-key map "-" #'scad-preview-distance-)
+ (define-key map "+" #'scad-preview-distance+)
+ (define-key map [right] #'scad-preview-rotate-z-)
+ (define-key map [left] #'scad-preview-rotate-z+)
+ (define-key map [up] #'scad-preview-rotate-x+)
+ (define-key map [down] #'scad-preview-rotate-x-)
+ (define-key map [M-left] #'scad-preview-translate-x+)
+ (define-key map [M-right] #'scad-preview-translate-x-)
+ (define-key map [M-up] #'scad-preview-translate-z-)
+ (define-key map [M-down] #'scad-preview-translate-z+)
+ map)
+ "Keymap for SCAD preview buffers.")
+
+(defun scad--preview-status (&optional status)
+ "Update mode line of preview buffer with STATUS."
+ (setq scad--preview-status
+ (concat (apply #'format "[%d %d %d] [%d %d %d] %d"
+ scad--preview-camera)
+ " " status))
+ (force-mode-line-update))
+
+(defun scad-preview ()
+ "Preview SCAD models in real-time within Emacs."
+ (interactive)
+ (setq scad--preview-buffer (if (buffer-live-p scad--preview-buffer)
+ scad--preview-buffer
+ (generate-new-buffer (format "*scad preview:
%s*" (buffer-name)))))
+ (add-hook 'after-change-functions #'scad--preview-change nil 'local)
+ (display-buffer scad--preview-buffer)
+ (let ((orig-buffer (current-buffer)))
+ (with-current-buffer scad--preview-buffer
+ (setq scad--preview-buffer orig-buffer)
+ (add-hook 'kill-buffer-hook #'scad--preview-kill nil t)
+ (scad--preview-reset))))
+
+(defun scad--preview-change (&rest _)
+ "Buffer changed, trigger rerendering."
+ (if (not (buffer-live-p scad--preview-buffer))
+ (remove-hook 'after-change-functions #'scad--preview-change 'local)
+ (let ((buffer scad--preview-buffer))
+ (with-current-buffer buffer
+ (scad--preview-kill)
+ (setq scad--preview-timer
+ (run-with-timer
+ scad-preview-refresh nil
+ (lambda ()
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (setq scad--preview-timer nil)
+ (scad--preview-render))))))))))
+
+;; Based on https://github.com/zk-phi/scad-preview
+(defun scad--preview-render ()
+ "Render image from current buffer."
+ (when (buffer-live-p scad--preview-buffer)
+ (scad--preview-kill)
+ (scad--preview-status "Rendering...")
+ (let* ((infile (make-temp-file "scad-preview-" nil ".scad"))
+ (outfile (concat infile ".png"))
+ (buffer (current-buffer)))
+ (with-current-buffer scad--preview-buffer
+ (save-restriction
+ (widen)
+ (write-region (point-min) (point-max) infile nil 'nomsg)))
+ (setq scad--preview-process
+ (make-process
+ :name scad-command
+ :sentinel (lambda (&rest _)
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (setq scad--preview-process nil)
+ (if (not (ignore-errors
+ (and (file-exists-p outfile)
+ (> (file-attribute-size
(file-attributes outfile)) 0))))
+ (scad--preview-status "Error")
+ (fundamental-mode)
+ (erase-buffer)
+ (insert-file-contents outfile)
+ (let ((inhibit-message t)
+ (message-log-max nil))
+ (scad-preview-mode))
+ (scad--preview-status))))
+ (delete-file outfile)
+ (delete-file infile))
+ :command (list scad-command
+ "-o" outfile
+ "--preview"
+ (format "--imgsize=%d,%d"
+ (car scad--preview-size)
+ (cdr scad--preview-size))
+ (format "--camera=%s"
+ (mapconcat #'number-to-string
scad--preview-camera ","))
+ (format "--colorscheme=%s"
scad-preview-colorscheme)
+ infile))))))
+
+(defun scad--preview-kill ()
+ "Kill current rendering."
+ (when (process-live-p scad--preview-process)
+ (delete-process scad--preview-process)
+ (setq scad--preview-process nil))
+ (when scad--preview-timer
+ (cancel-timer scad--preview-timer)
+ (setq scad--preview-timer nil)))
+
+(define-derived-mode scad-preview-mode image-mode "SCADPreview"
+ "Major mode for SCAD preview buffers."
+ (setq mode-line-format '("" mode-line-buffer-identification (" "
scad--preview-status))
+ revert-buffer-function #'scad--preview-reset))
+
+(defun scad--preview-reset (&rest _)
+ "Reset camera parameters and refresh."
+ (setq scad--preview-camera (copy-sequence scad-preview-camera)
+ scad--preview-size (copy-tree scad-preview-size))
+ (scad--preview-render))
+
+(defun scad--preview-move (idx val)
+ "Increment camera IDX by VAL."
+ (cl-incf (nth idx scad--preview-camera) val)
+ (scad--preview-render))
+
+(defun scad--preview-size (factor)
+ "Resize preview by FACTOR."
+ (setf (car scad--preview-size) (round (* (car scad--preview-size) factor))
+ (cdr scad--preview-size) (round (* (cdr scad--preview-size) factor)))
+ (scad--preview-render))
+
+(defun scad-preview-translate-x+ () (interactive) (scad--preview-move 0 10))
+(defun scad-preview-translate-x- () (interactive) (scad--preview-move 0 -10))
+(defun scad-preview-translate-z+ () (interactive) (scad--preview-move 2 10))
+(defun scad-preview-translate-z- () (interactive) (scad--preview-move 2 -10))
+(defun scad-preview-rotate-x+ () (interactive) (scad--preview-move 3 20))
+(defun scad-preview-rotate-x- () (interactive) (scad--preview-move 3 -20))
+(defun scad-preview-rotate-y+ () (interactive) (scad--preview-move 4 20))
+(defun scad-preview-rotate-y- () (interactive) (scad--preview-move 4 -20))
+(defun scad-preview-rotate-z+ () (interactive) (scad--preview-move 5 20))
+(defun scad-preview-rotate-z- () (interactive) (scad--preview-move 5 -20))
+(defun scad-preview-distance- () (interactive) (scad--preview-move 6 100))
+(defun scad-preview-distance+ () (interactive) (scad--preview-move 6 -100))
+(defun scad-preview-size- () (interactive) (scad--preview-size (/ 1.1)))
+(defun scad-preview-size+ () (interactive) (scad--preview-size 1.1))
+
(provide 'scad-mode)
;;; scad-mode.el ends here
- [nongnu] branch elpa/scad-mode created (now 3076e240bf), ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode e64d93cdb2 02/47: Import scad-mode.el from 63b97a0c6da9ceea215395d9d54dd33187a2299d, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 708d871909 06/47: Use lexical-binding, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 4d92026a1a 07/47: Introduce explicit customization group and linting, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 5dde5cacbf 08/47: Remove scad-prime-dabbrev hack, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode ddd1a64991 11/47: Whitespace, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode f18fb5082d 13/47: Update package header and commentary, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 0cb891b232 18/47: Update commentary, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode b038c79b40 19/47: Rebind keys to support tab completion, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 4bf29ec9b1 20/47: Add preview,
ELPA Syncer <=
- [nongnu] elpa/scad-mode 9c9bb9b5aa 01/47: Initial commit, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode fece897e58 04/47: Delete trailing whitespace, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 25f94cc800 03/47: Require Emacs 26, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 53aba7b6e9 09/47: Fix and simplify completion-at-point-function, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 358573e7aa 12/47: Add basic README, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode fff66878d5 17/47: Cleanup hook handling, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode c09d8f97e8 21/47: Automatic refresh can be disabled, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode d39d19f64f 24/47: Save before opening/exporting, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 56a3af8661 37/47: Update keywords, ELPA Syncer, 2022/11/12
- [nongnu] elpa/scad-mode 710cf2b7ce 45/47: Rename preview output buffer, ELPA Syncer, 2022/11/12