This repository has been archived by the owner on Apr 2, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathslider.lisp
159 lines (130 loc) · 5.9 KB
/
slider.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#|
This file is a part of Qtools-UI
(c) 2015 Shirakumo http://tymoon.eu (shinmera@tymoon.eu)
Author: Nicolas Hafner <shinmera@tymoon.eu>
|#
(in-package #:org.shirakumo.qtools.ui)
(named-readtables:in-readtable :qtools)
(defgeneric maximum (slider))
(defgeneric (setf maximum) (maximum slider))
(defgeneric minimum (slider))
(defgeneric (setf minimum) (minimum slider))
(defgeneric stepping (slider))
(defgeneric (setf stepping) (stepping slider))
(defgeneric default (slider))
(defgeneric (setf default) (default slider))
(define-widget double-slider (QSlider input)
((maximum :initarg :maximum :accessor maximum)
(minimum :initarg :minimum :accessor minimum)
(stepping :initarg :stepping :accessor stepping)
(div))
(:default-initargs
:maximum 100.0 :minimum 1.0 :stepping 1.0))
(define-initializer (double-slider setup)
(setf div (let ((str (string-trim "0" (format NIL "~f" stepping))))
(expt 10 (- (length str) (position #\. str) 1))))
(setf (q+:maximum double-slider) (round (* div maximum)))
(setf (q+:minimum double-slider) (round (* div minimum)))
(setf (q+:tick-interval double-slider) (round (* div stepping)))
(setf (q+:orientation double-slider) (q+:qt.horizontal)))
(define-signal (double-slider value-changed) (double))
(define-slot (double-slider update) ((value int))
(declare (connected double-slider (value-changed int)))
(signal! double-slider (value-changed double) (/ value div)))
(define-slot (double-slider released) ()
(declare (connected double-slider (slider-released)))
(signal! double-slider (input-done)))
(defmethod value ((double-slider double-slider))
(/ (q+:value double-slider) (slot-value double-slider 'div)))
(defmethod (setf value) (value (double-slider double-slider))
(with-slots-bound (double-slider double-slider)
(unless (<= minimum value maximum)
(error "~a is not within [~a, ~a]." value minimum maximum))
(setf (q+:value double-slider) (round (* value div)))))
(defmethod (setf maximum) :after (value (double-slider double-slider))
(setf (q+:maximum double-slider) value))
(defmethod (setf minimum) :after (value (double-slider double-slider))
(setf (q+:minimum double-slider) value))
(defmethod (setf stepping) :after (value (double-slider double-slider))
(setf (q+:tick-interval double-slider) (round (* (slot-value double-slider 'div) value))))
(define-widget slider (QWidget input)
((maximum :initarg :maximum :accessor maximum)
(minimum :initarg :minimum :accessor minimum)
(stepping :initarg :stepping :accessor stepping)
(default :initarg :default :accessor default))
(:default-initargs
:maximum 100.0 :minimum 0.0 :stepping 1.0 :default NIL))
(define-signal (slider value-changed) (double))
(define-initializer (slider setup)
(setf (q+:minimum-height slider) 20)
(setf (q+:minimum-width slider) 100)
(setf (q+:maximum-height slider) 40))
(define-subwidget (slider double-slider) (make-instance 'double-slider :maximum maximum :minimum minimum :stepping stepping)
(setf (value double-slider) (or default minimum)))
(define-subwidget (slider spin-box) (q+:make-qdoublespinbox)
(setf (q+:single-step spin-box) stepping)
(setf (q+:maximum spin-box) maximum)
(setf (q+:minimum spin-box) minimum)
(setf (q+:value spin-box) (or default minimum))
(setf (q+:fixed-width spin-box) 70))
(define-subwidget (slider button) (q+:make-qpushbutton)
(setf (q+:text button) (princ-to-string default))
(setf (q+:fixed-width button) 50)
(setf (q+:visible button) (not (null default))))
(define-subwidget (slider layout) (q+:make-qhboxlayout slider)
(setf (q+:spacing layout) 0)
(setf (q+:contents-margins layout) (values 0 0 0 0))
(q+:add-widget layout double-slider 8)
(q+:add-widget layout spin-box 1)
(q+:add-widget layout button 1))
(define-override (slider update) ()
(q+:update double-slider)
(q+:update spin-box)
(q+:update button)
(stop-overriding))
(define-slot (slider update) ((value double))
(declare (connected double-slider (value-changed double)))
(declare (connected spin-box (value-changed double)))
(when (or (/= (value double-slider) value)
(/= (value spin-box) value))
(setf (value slider) value)
(signal! slider (value-changed double) value)))
(define-slot (slider done) ()
(declare (connected double-slider (input-done)))
(declare (connected spin-box (editing-finished)))
(signal! slider (input-done)))
(define-slot (slider reset) ()
(declare (connected button (clicked)))
(setf (value double-slider) default)
(setf (value spin-box) default)
(signal! slider (input-done)))
(defmethod value ((slider slider))
(q+:value (slot-value slider 'spin-box)))
(defmethod (setf value) (value (slider slider))
(with-slots-bound (slider slider)
(unless (<= minimum value maximum)
(error "~a is not within [~a, ~a]." value minimum maximum))
(setf (value spin-box) value)
(setf (value double-slider) value)))
(defmethod (setf maximum) :after (value (slider slider))
(with-slots-bound (slider slider)
(setf (maximum double-slider) value)
(setf (q+:maximum spin-box) value)
(when default (setf (default slider) (min value default)))
(setf (value slider) (min (value slider) value))))
(defmethod (setf minimum) :after (value (slider slider))
(with-slots-bound (slider slider)
(setf (minimum double-slider) value)
(setf (q+:minimum spin-box) value)
(when default (setf (default slider) (max value default)))
(setf (value slider) (max (value slider) value))))
(defmethod (setf stepping) :after (value (slider slider))
(with-slots-bound (slider slider)
(setf (stepping double-slider) value)
(setf (q+:single-step spin-box) stepping)))
(defmethod (setf default) :after (value (slider slider))
(with-slots-bound (slider slider)
(unless (<= minimum value maximum)
(error "~a is not within [~a, ~a]." value minimum maximum))
(setf (q+:text button) (princ-to-string value))
(setf (q+:visible button) (not (null value)))))