forked from chrischdi/gphoto2go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
camerawidget.go
240 lines (203 loc) · 5.76 KB
/
camerawidget.go
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
package gphoto2go
// #cgo pkg-config: libgphoto2
// #include <gphoto2.h>
// #include <stdlib.h>
import "C"
import (
"fmt"
"time"
"unsafe"
)
type widgetValueType int
const (
wvtString widgetValueType = iota
wvtNum
wvtDate
wvtWeird
)
// WidgetTypeInfo struct
type WidgetTypeInfo struct {
str string
vtype widgetValueType
enum C.CameraWidgetType
desc string
}
var widgetTypeTable = map[C.CameraWidgetType]WidgetTypeInfo{
C.GP_WIDGET_WINDOW: WidgetTypeInfo{"Window", wvtWeird, C.GP_WIDGET_WINDOW, "Window widget This is the toplevel configuration widget. It should likely contain multiple widget seciton entries"},
C.GP_WIDGET_SECTION: WidgetTypeInfo{"Section", wvtWeird, C.GP_WIDGET_SECTION, "Section widget (think Tab)"},
C.GP_WIDGET_TEXT: WidgetTypeInfo{"Text", wvtString, C.GP_WIDGET_TEXT, "Text widget"},
C.GP_WIDGET_RANGE: WidgetTypeInfo{"Range", wvtNum, C.GP_WIDGET_RANGE, "Slider widget"},
C.GP_WIDGET_TOGGLE: WidgetTypeInfo{"Toggle", wvtNum, C.GP_WIDGET_TOGGLE, "Toggle widget (think check box)"},
C.GP_WIDGET_RADIO: WidgetTypeInfo{"Radio", wvtString, C.GP_WIDGET_RADIO, "Radio button widget"},
C.GP_WIDGET_MENU: WidgetTypeInfo{"Menu", wvtNum, C.GP_WIDGET_MENU, "Menu widget (same as RADIO)"},
C.GP_WIDGET_BUTTON: WidgetTypeInfo{"Button", wvtNum, C.GP_WIDGET_BUTTON, "Button press widget"},
C.GP_WIDGET_DATE: WidgetTypeInfo{"Date", wvtDate, C.GP_WIDGET_DATE, "Date entering widget"},
}
// Str get the widget's type as a string
func (wti *WidgetTypeInfo) Str() string {
return wti.str
}
// CameraWidget struct
type CameraWidget struct {
widget *C.CameraWidget
}
// SetValue func
func (w *CameraWidget) SetValue(v interface{}) error {
switch v.(type) {
case string:
cstr := C.CString(v.(string))
defer C.free(unsafe.Pointer(cstr))
if err := cameraResultToError(C.gp_widget_set_value(w.widget, unsafe.Pointer(cstr))); err != nil {
return err
}
default:
if err := cameraResultToError(C.gp_widget_set_value(w.widget, unsafe.Pointer(&v))); err != nil {
return err
}
}
return nil
}
// Free func
func (w *CameraWidget) Free() {
if err := cameraResultToError(C.gp_widget_free(w.widget)); err != nil {
fmt.Printf("WARNING: error on C.gp_widget_free: %v\n", err)
}
}
//
// getters and setters
//
// Name func
func (w *CameraWidget) Name() (string, error) {
var _name *C.char
defer C.free(unsafe.Pointer(_name))
if err := cameraResultToError(C.gp_widget_get_name(w.widget, &_name)); err != nil {
return "", err
}
return ToString(_name), nil
}
// Value func
func (w *CameraWidget) Value() (interface{}, error) {
var err error
wti, err := w.Type()
if err != nil {
return nil, err
}
switch wti.vtype {
case wvtString:
var val *C.char
defer C.free(unsafe.Pointer(val)) // copied by ToString()
if err := cameraResultToError(C.gp_widget_get_value(w.widget, unsafe.Pointer(&val))); err != nil {
return nil, err
}
return ToString(val), nil
case wvtNum:
var val = new(int)
if err := cameraResultToError(C.gp_widget_get_value(w.widget, unsafe.Pointer(val))); err != nil {
return nil, err
}
return *val, nil
case wvtDate:
var val = new(int64)
if err := cameraResultToError(C.gp_widget_get_value(w.widget, unsafe.Pointer(val))); err != nil {
return nil, err
}
return time.Unix(*val, 0), nil
case wvtWeird:
default:
return "", nil
}
return nil, err
}
// Parent func
func (w *CameraWidget) Parent() (*CameraWidget, error) {
_parent := new(CameraWidget)
if err := cameraResultToError(C.gp_widget_get_parent(w.widget, &_parent.widget)); err != nil {
return nil, err
}
return _parent, nil
}
// Label func
func (w *CameraWidget) Label() (string, error) {
var _label *C.char
defer C.free(unsafe.Pointer(_label))
if err := cameraResultToError(C.gp_widget_get_label(w.widget, &_label)); err != nil {
return "", err
}
return ToString(_label), nil
}
// Type func
func (w *CameraWidget) Type() (*WidgetTypeInfo, error) {
var _type C.CameraWidgetType
if err := cameraResultToError(C.gp_widget_get_type(w.widget, &_type)); err != nil {
return new(WidgetTypeInfo), err
}
widgetTypeInfo := widgetTypeTable[_type]
return &widgetTypeInfo, nil
}
// Readonly func
func (w *CameraWidget) Readonly() (bool, error) {
var _ro C.int
if err := cameraResultToError(C.gp_widget_get_readonly(w.widget, &_ro)); err != nil {
return false, err
}
return _ro == 1, nil
}
// Child func
func (w *CameraWidget) Child(name string) (*CameraWidget, error) {
var child *C.CameraWidget
n := C.CString(name)
defer C.free(unsafe.Pointer(n))
err := cameraResultToError(C.gp_widget_get_child_by_name(w.widget, n, &child))
if err != nil {
C.free(unsafe.Pointer(child))
return nil, fmt.Errorf("error on C.gp_widget_get_child_by_name(%s): %v", name, err)
}
return &CameraWidget{child}, nil
}
// ValueType func
func (w *CameraWidget) ValueType() (string, error) {
wti, err := w.Type()
if err != nil {
return "", err
}
switch wti.vtype {
case wvtString:
return "string", nil
case wvtNum:
return "int", nil
case wvtDate:
return "date", nil
default:
return "weird", nil
}
}
func (w *CameraWidget) choiceCount() (int, error) {
if tipe, err := w.Type(); err == nil {
if tipe.enum != C.GP_WIDGET_RADIO {
return 0, nil
}
} else {
return 0, err
}
numChoices := C.gp_widget_count_choices(w.widget)
if numChoices < 0 {
return 0, cameraResultToError(numChoices)
}
return int(numChoices), nil
}
// Choices func
func (w *CameraWidget) Choices() ([]string, error) {
numChoices, err := w.choiceCount()
if err != nil {
return nil, err
}
choices := make([]string, numChoices)
for idx := 0; idx < numChoices; idx++ {
var val *C.char
if err := cameraResultToError(C.gp_widget_get_choice(w.widget, C.int(idx), &val)); err != nil {
return nil, err
}
choices[idx] = ToString(val) // ToString makes a copy
}
return choices, nil
}