Afgeleide klasse van Listbox, vanuit code het object maken/instantiëren en gebruiken in een VBox

Doel: weergave van de dagen van de week, waarbij iedere dag een reeks waarden bevat (orders). De dagen van een week zijn vertikaal gegroepeerd.

De dag wordt voorgesteld als een soort listbox, met op iedere lijn de weergave van een ordernummer. Maar ik wil niet alle Dag-Listboxen, met steeds dezelfde eigenschappen, op het scherm tekenen.

De orders worden er naartoe “gesleept” (vierkantje op schermafbeelding) en komen in de lijst als je ze loslaat boven de dag (maandag op schermafbeelding).

Als er meer orders in de listbox komen, moet hij “groeien”, dwz de hoogte van de listbox moet groter worden; en omgekeerd moet hij ook kunnen krimpen.

Bovendien: de Dag-Listbox moet meer kunnen dan een listbox, ik maak dus een afgeleide klasse bv myListbox, of zo. Beter: ik noemt die CPlanDay; het geeft de planning voor die dag weer.

VBox ordent een aantal van mijn Listboxes (objecten van CPlanDay) vertikaal tot een week.

Volgende vragen bleven me open toen dat gelukt was:

  • Hoe maak ik een klasse die afgeleid is van een bestaande (Listbox)?
  • Hoe maak ik de objecten van die klasse vanuit code; “on the run”?
  • Hoe kan ik de extra mogelijkheden programmeren?
  • Hoe bereik ik de bestaande mogelijkheden van de ouder-klasse Listbox?

Eerste poging:

De klasse:

' Gambas class file
INHERITS ListBox

STATIC PUBLIC lsbxMinHeight AS Integer = 40
STATIC PUBLIC lsbxMaxHeight AS Integer = 200

STATIC PUBLIC lsbxLineHeight AS Integer = 17
STATIC PUBLIC lsbxFontSize AS Integer = 9

STATIC PUBLIC iMonday AS Integer = 0 
STATIC PUBLIC iTuesday AS Integer = 1
STATIC PUBLIC iWednesday AS Integer = 2
STATIC PUBLIC iThursday AS Integer = 3
STATIC PUBLIC iFriday AS Integer = 4
STATIC PUBLIC iSaturday AS Integer = 5
STATIC PUBLIC iSunday AS Integer = 6

PRIVATE iDay AS Integer = iMonday

PUBLIC SUB _new(OPTIONAL iDayNumber AS Integer)
  
  IF (iDayNumber)
    setDay(iDayNumber)
  ENDIF 
  ME.Font.Size = lsbxFontSize
  ME.Add("I just got birth")
  
END

PUBLIC SUB test()
  
  Message.Info("hello")
  
END


PUBLIC SUB Drag()

  ME.Remove(ME.Index)
  ME.Height = ME.lsbxMinHeight + ME.Count * ME.lsbxLineHeight
  
END 


PUBLIC SUB Drop()

  ME.Add(Drag.Data)
  DEBUG ME.Height & "  " & ME.lsbxMaxHeight
  IF ME.Height < ME.lsbxMaxHeight
    ME.Height = ME.lsbxMinHeight + ME.Count * ME.lsbxLineHeight
  ENDIF 

END 


PUBLIC SUB Mousedrag()

  IF Mouse.Left THEN

    ME.Drag(ME[ME.Index].Text)

  ENDIF 

END


PUBLIC SUB setDay(iDayNumber AS Integer)
  
  IF iDayNumber >= 0
    IF iDayNumber <= 6
      iDay = iDayNumber
    ENDIF 
  ENDIF 
  
END

PUBLIC SUB getDayNumber() AS Integer
  
  RETURN iDay
  
END


PUBLIC SUB getDayName() AS String
  
  SELECT iDay
    CASE iMonday
      RETURN "Monday"
    CASE iTuesday
      RETURN "Tuesday"
    CASE iWednesday
      RETURN "Wednesday"
    CASE iThursday
      RETURN "Thursday"
    CASE iFriday
      RETURN "Friday"
    CASE iSaturday
      RETURN "Saturday"
    CASE iSunday
      RETURN "Sunday"
  END SELECT 
    
END

De form waarin het gebruikt wordt:

...

 DIM lsbxItem AS ListBox
  DIM i AS Integer

  aLine2 = NEW Variant[5]
  
  FOR i = 0 TO 4
    aLine2[i] = NEW CPlanDay(i, VBox2)
    'aLine2[i].Test()
  NEXT 
...

Dat werkt echter nog niet: de dagen worden wel getekend, maar de drag en drop werkt niet (of enkel van de dag weg).

  • Drop is een eigenschap die aangezet moet worden.
  • De hierarchie moet juist aangesproken worden: SUPER keyword voor de parentklasse
  • STATIC moet juist gebruikt worden (zonder "ME" prefix)

Hieronder een uitbreiding:

De klasse CPlanDay:

' Gambas class file
INHERITS ListBox

STATIC PUBLIC lsbxMinHeight AS Integer = 40
STATIC PUBLIC lsbxMaxHeight AS Integer = 200

STATIC PUBLIC lsbxLineHeight AS Integer = 17
STATIC PUBLIC lsbxFontSize AS Integer = 9

STATIC PUBLIC iMonday AS Integer = 0 
STATIC PUBLIC iTuesday AS Integer = 1
STATIC PUBLIC iWednesday AS Integer = 2
STATIC PUBLIC iThursday AS Integer = 3
STATIC PUBLIC iFriday AS Integer = 4
STATIC PUBLIC iSaturday AS Integer = 5
STATIC PUBLIC iSunday AS Integer = 6

PRIVATE iDay AS Integer = iMonday
PRIVATE $hObserver AS Observer
PRIVATE $hDropObserver AS Observer

PUBLIC SUB _new(OPTIONAL iDayNumber AS Integer)
  
  $hObserver = NEW Observer(ME) AS "Observer"
  $hDropObserver = NEW Observer(ME) AS "Dropserver"
    
  IF (iDayNumber)
    setDay(iDayNumber)
  ENDIF 
  ME.Font.Size = lsbxFontSize
  ME.Drop = TRUE
  ME.Height = lsbxMinHeight
'  ME.Add(" - - - - " & ME.getDayName() & " - - - - - ")
  
END

PUBLIC SUB test()
  
  Message.Info("hello")
  
END


PUBLIC SUB Observer_Drag()
   
  ME.Remove(ME.Index)
  SUPER.Height = lsbxMinHeight + SUPER.Count * lsbxLineHeight

END 


PUBLIC SUB Observer_Drop()
  
  SUPER.Add(Drag.Data)
  DEBUG SUPER.Height & "  " & lsbxMaxHeight
  IF SUPER.Height < lsbxMaxHeight
    SUPER.Height = lsbxMinHeight + (ME.Count * lsbxLineHeight)
  ENDIF 

END 


PUBLIC SUB Observer_Mousedrag()

    ME.Drag(ME[ME.Index].Text)
    ME.Remove(ME.Index)

END


PUBLIC SUB setDay(iDayNumber AS Integer)
  
  IF iDayNumber >= 0
    IF iDayNumber <= 6
      iDay = iDayNumber
    ENDIF 
  ENDIF 

END

PUBLIC SUB getDayNumber() AS Integer
  
  RETURN iDay
  
END


PUBLIC SUB getDayName() AS String
  
  SELECT iDay
    CASE iMonday
      RETURN ("Monday")
    CASE iTuesday
      RETURN ("Tuesday")
    CASE iWednesday
      RETURN ("Wednesday")
    CASE iThursday
      RETURN ("Thursday")
    CASE iFriday
      RETURN ("Friday")
    CASE iSaturday
      RETURN ("Saturday")
    CASE iSunday
      RETURN ("Sunday")
  END SELECT 
    
END

De implementatie in gebruik:

...
PUBLIC SUB Form_Open()

  DIM lsbxItem AS ListBox
  DIM i AS Integer
  DIM iWorkingDays AS Integer = 5

  aLine2 = NEW Variant[iWorkingDays]
  
  FOR i = 0 TO (iWorkingDays - 1)

    aLine2[i] = NEW CPlanDay(i, VBox2)

  NEXT 

...