github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/client/GUI/fields/numeric.go (about) 1 package fields 2 3 import ( 4 "strconv" 5 "time" 6 7 "github.com/therecipe/qt/core" 8 9 rd "github.com/benoitkugler/goACVE/server/core/rawdata" 10 11 "github.com/benoitkugler/goACVE/client/GUI/basic" 12 "github.com/therecipe/qt/widgets" 13 ) 14 15 type Euros struct { 16 *widgets.QDoubleSpinBox 17 } 18 19 func NewEuros(editable bool) Euros { 20 w := Euros{widgets.NewQDoubleSpinBox(nil)} 21 w.SetSuffix("€") 22 w.SetEnabled(editable) 23 w.SetMaximum(1000000) 24 w.SetMinimumWidth(40) 25 w.SetMaximumWidth(90) 26 return w 27 } 28 29 func (f Euros) GetData() rd.Euros { 30 return rd.Euros(f.Value()) 31 } 32 33 func (f Euros) SetData(data rd.Euros) { 34 f.SetValue(float64(data)) 35 } 36 37 type Pourcent struct { 38 *widgets.QSpinBox 39 } 40 41 func NewPourcent(editable bool) Pourcent { 42 w := Pourcent{widgets.NewQSpinBox(nil)} 43 w.SetMaximum(100) 44 w.SetMinimum(0) 45 w.SetSuffix("%") 46 w.SetEnabled(editable) 47 w.SetFixedWidth(80) 48 return w 49 } 50 51 func (f Pourcent) GetData() rd.Pourcent { 52 return rd.Pourcent(f.Value()) 53 } 54 55 func (f Pourcent) SetData(data rd.Pourcent) { 56 f.SetValue(int(data)) 57 } 58 59 type Int struct { 60 *widgets.QSpinBox 61 } 62 63 func NewInt(editable bool) Int { 64 w := Int{widgets.NewQSpinBox(nil)} 65 w.SetEnabled(editable) 66 w.SetMaximum(1000000) 67 w.SetMinimum(0) 68 return w 69 } 70 71 func (f Int) GetData() rd.Int { 72 return rd.Int(f.Value()) 73 } 74 75 func (f Int) SetData(data rd.Int) { 76 f.SetValue(int(data)) 77 } 78 79 type Bool struct { 80 *widgets.QCheckBox 81 } 82 83 func NewBool(editable bool) Bool { 84 w := Bool{widgets.NewQCheckBox(nil)} 85 w.SetEnabled(editable) 86 return w 87 } 88 89 func (f Bool) GetData() rd.Bool { 90 return rd.Bool(f.IsChecked()) 91 } 92 93 func (f Bool) SetData(data rd.Bool) { 94 f.SetChecked(bool(data)) 95 } 96 97 type Date struct { 98 *widgets.QFrame 99 100 jour, mois, annee *widgets.QSpinBox 101 102 // s'ajoute à une année à deux chiffres. ex : 25 -> 1925 (ou 2025) 103 centuryHint int 104 } 105 106 func NewDate(editable bool, centuryHint int) Date { 107 w := Date{ 108 QFrame: basic.Frame(), 109 jour: widgets.NewQSpinBox(nil), 110 mois: widgets.NewQSpinBox(nil), 111 annee: widgets.NewQSpinBox(nil), 112 centuryHint: centuryHint, 113 } 114 layout := widgets.NewQHBoxLayout2(w) 115 layout.SetSpacing(0) 116 layout.SetContentsMargins(0, 0, 0, 0) 117 layout.AddWidget(w.jour, 1, 0) 118 layout.AddWidget(w.mois, 1, 0) 119 layout.AddWidget(w.annee, 2, 0) 120 121 w.jour.SetMinimumWidth(10) 122 w.mois.SetMinimumWidth(10) 123 w.annee.SetMinimumWidth(20) 124 125 w.jour.SetMinimum(1) 126 w.mois.SetMinimum(1) 127 w.annee.SetMinimum(1) 128 129 w.jour.SetMaximum(31) 130 w.mois.SetMaximum(12) 131 w.annee.SetMaximum(2500) 132 133 w.jour.SetToolTip("Jour") 134 w.jour.SetToolTip("Mois") 135 w.jour.SetToolTip("Année") 136 137 w.jour.ConnectEditingFinished(w.validate) 138 w.mois.ConnectEditingFinished(w.validate) 139 w.annee.ConnectEditingFinished(w.validate) 140 w.annee.ConnectValueChanged(w.onChange) 141 w.SetEditable(editable) 142 return w 143 } 144 145 func (f Date) SetEditable(b bool) { 146 f.jour.SetReadOnly(!b) 147 f.mois.SetReadOnly(!b) 148 f.annee.SetReadOnly(!b) 149 } 150 151 func (f Date) ConnectDataChanged(fu func()) { 152 f.jour.ConnectValueChanged(func(_ int) { fu() }) 153 f.mois.ConnectValueChanged(func(_ int) { fu() }) 154 f.annee.ConnectValueChanged(func(_ int) { fu() }) 155 } 156 157 func (f Date) validate() { 158 if f.annee.Value() < 100 { 159 f.annee.SetValue(f.annee.Value() + f.centuryHint) 160 } 161 f.SetData(f.GetData()) 162 } 163 164 func (f Date) onChange(year int) { 165 style := "color : black" 166 if year < 1000 { 167 style = "color : red;" 168 } 169 f.annee.SetStyleSheet(style) 170 } 171 172 func (f Date) GetData() rd.Date { 173 year, month, day := f.annee.Value(), f.mois.Value(), f.jour.Value() 174 return rd.Date(time.Date(year, time.Month(month), day, 175 0, 0, 0, 0, time.UTC)) 176 } 177 178 func (f Date) SetData(data rd.Date) { 179 date := time.Time(data) 180 f.jour.SetValue(date.Day()) 181 f.mois.SetValue(int(date.Month())) 182 f.annee.SetValue(date.Year()) 183 } 184 185 // Plage représente deux dates 186 type Plage struct { 187 *widgets.QFrame 188 189 from Date 190 to Date 191 } 192 193 func newPlageLayout(from, to Date, parent widgets.QWidget_ITF) *widgets.QHBoxLayout { 194 lay := widgets.NewQHBoxLayout2(parent) 195 lay.SetContentsMargins(0, 0, 0, 0) 196 lay.AddWidget(basic.Label("du"), 0, 0) 197 lay.AddWidget(from, 2, 0) 198 lay.AddWidget(basic.Label("au"), 0, 0) 199 lay.AddWidget(to, 2, 0) 200 return lay 201 } 202 203 func NewPlage(editable bool) Plage { 204 m := Plage{QFrame: basic.Frame()} 205 m.from = NewDate(editable, 1900) 206 m.to = NewDate(editable, 1900) 207 newPlageLayout(m.from, m.to, m) 208 return m 209 } 210 211 func (f Plage) Valid() bool { 212 return f.from.GetData().Time().Before(f.to.GetData().Time()) 213 } 214 215 func (f Plage) GetData() rd.Plage { 216 return rd.Plage{ 217 From: f.from.GetData(), 218 To: f.to.GetData(), 219 } 220 } 221 222 func (f Plage) SetData(data rd.Plage) { 223 f.from.SetData(data.From) 224 f.to.SetData(data.To) 225 } 226 227 // SetMonthMode paramètre le widget pour la saisie d'une 228 // plage de mois. 229 func (f Plage) SetMonthMode() { 230 f.from.jour.SetMaximum(28) 231 f.to.jour.SetReadOnly(true) 232 f.from.ConnectDataChanged(func() { 233 f.to.SetData(f.from.GetData()) 234 }) 235 } 236 237 // OptionnalPlage représente une plage optionnelle 238 // avec une valeur par défaut si le champ est vide 239 type OptionnalPlage struct { 240 Plage 241 242 defaut rd.Plage 243 active *widgets.QCheckBox 244 } 245 246 func NewOptionnalPlage(editable bool, defaut rd.Plage) OptionnalPlage { 247 op := OptionnalPlage{Plage: Plage{QFrame: basic.Frame()}, defaut: defaut} 248 op.from = NewDate(editable, 1900) 249 op.to = NewDate(editable, 1900) 250 op.active = widgets.NewQCheckBox2("Actif", nil) 251 op.active.ConnectClicked(func(checked bool) { 252 op.to.SetEnabled(checked) 253 op.from.SetEnabled(checked) 254 }) 255 256 lay := widgets.NewQVBoxLayout2(op) 257 lay.AddWidget(op.active, 1, core.Qt__AlignCenter) 258 lay.AddLayout(newPlageLayout(op.from, op.to, nil), 1) 259 return op 260 } 261 262 func (f OptionnalPlage) GetData() rd.Plage { 263 if f.active.IsChecked() { 264 return f.Plage.GetData() 265 } 266 return rd.Plage{} 267 } 268 269 func (f *OptionnalPlage) SetData(data rd.Plage) { 270 shouldCheked := data != rd.Plage{} 271 if shouldCheked { 272 f.Plage.SetData(data) 273 } else { 274 f.Plage.SetData(f.defaut) 275 } 276 f.active.SetChecked(shouldCheked) 277 f.to.SetEnabled(shouldCheked) 278 f.from.SetEnabled(shouldCheked) 279 } 280 281 type OptionnalBool Enum 282 283 func NewOptionnalBool(editable bool, labelOui, labelNon string) OptionnalBool { 284 enum := NewEnum([]Choice{ 285 {Label: "Indifférent", Field: strconv.Itoa(0)}, 286 {Label: labelOui, Field: strconv.Itoa(int(rd.OBOui))}, 287 {Label: labelNon, Field: strconv.Itoa(int(rd.OBNon))}, 288 }, editable) 289 return OptionnalBool(enum) 290 } 291 292 func (f OptionnalBool) GetData() rd.OptionnalBool { 293 i, _ := strconv.Atoi(Enum(f).GetData()) 294 return rd.OptionnalBool(int8(i)) 295 } 296 297 func (f OptionnalBool) SetData(data rd.OptionnalBool) { 298 Enum(f).SetData(strconv.Itoa(int(data))) 299 } 300 301 type Completion Enum 302 303 type LabelCompletion struct { 304 Label string 305 Completion rd.Completion 306 } 307 308 func NewCompletion(editable bool) Completion { 309 comp := Completion(NewEnum(nil, editable)) 310 comp.Setup([]LabelCompletion{ 311 {Label: "Indifférent", Completion: 0}, 312 {Label: "Non commencé", Completion: rd.NonCommencee}, 313 {Label: "En cours", Completion: rd.EnCours}, 314 {Label: "Complété", Completion: rd.Complete}, 315 }) 316 return comp 317 } 318 319 func (f Completion) Setup(labels []LabelCompletion) { 320 c := make([]Choice, len(labels)) 321 for i, v := range labels { 322 c[i] = Choice{Label: v.Label, Field: strconv.Itoa(int(v.Completion))} 323 } 324 Enum(f).setChoice(c) 325 } 326 327 func (f Completion) GetData() rd.Completion { 328 i, _ := strconv.Atoi(Enum(f).GetData()) 329 return rd.Completion(i) 330 } 331 332 func (f Completion) SetData(data rd.Completion) { 333 Enum(f).SetData(strconv.Itoa(int(data))) 334 }