with Ada.Strings.Wide_Wide_Fixed; use Ada.Strings.Wide_Wide_Fixed; with Sf; with GrafikDatentypen; with SchreibeLogiktask; with LeseLogiktask; with SchreibeGrafiktask; with EingabeAllgemeinLogik; package body ZahleneingabeLogik is function Zahleneingabe (ZahlenMinimumExtern : in ZahlenDatentypen.EigenerInteger; ZahlenMaximumExtern : in ZahlenDatentypen.EigenerInteger; WelcheFrageExtern : in Positive) return SystemRecords.ZahlenEingabeRecord is begin ZahlenString := ZahlenStringLeer; EingegebeneZahl.EingegebeneZahl := 0; WelchesVorzeichen := VorzeichenAnpassen (ZahlenMinimumExtern => ZahlenMinimumExtern, ZahlenMaximumExtern => ZahlenMaximumExtern, PlusMinusExtern => True); -- Hier Sonderwerte setzen und in der Grafik das dann beim Text zusätzlich anzeigen? Oder neben der eingegebenen Zahl? Oder einfach gar nicht? äöü -- Den erlaubten Zahlenbereich mit in den Fragetext schieben? äöü -- LeerWert := MinimumMaximumSetzen (ZahlenMinimumExtern => ZahlenMinimumExtern, -- ZahlenMaximumExtern => ZahlenMaximumExtern); SchreibeGrafiktask.Fragenanzeige (FrageExtern => WelcheFrageExtern); SchreibeGrafiktask.Zahleneingabe (ZahlExtern => EingegebeneZahl.EingegebeneZahl); SchreibeGrafiktask.Eingabeart (EingabeartExtern => GrafikDatentypen.Zahlen_Eingabe_Enum); return ZahlSchleife (ZahlenMinimumExtern => ZahlenMinimumExtern, ZahlenMaximumExtern => ZahlenMaximumExtern); end Zahleneingabe; function ZahlSchleife (ZahlenMinimumExtern : in ZahlenDatentypen.EigenerInteger; ZahlenMaximumExtern : in ZahlenDatentypen.EigenerInteger) return SystemRecords.ZahlenEingabeRecord is begin ZahlenSchleife: loop SchreibeLogiktask.WartenGrafik (ZustandExtern => True); SchreibeGrafiktask.Tasteneingabe (JaNeinExtern => True); EingabeAllgemeinLogik.EingabeAbwarten; Zahlen := LeseLogiktask.Tastaturtaste; case GanzeZahlPrüfung (ZeichenExtern => Zahlen) is when Zahl_Hinzufügen => ZahlHinzufügen (EingegebeneZahlExtern => Zahlen, ZahlenMinimumExtern => ZahlenMinimumExtern, ZahlenMaximumExtern => ZahlenMaximumExtern); when Eingabe_Abbrechen => EingegebeneZahl.ErfolgreichAbbruch := False; exit ZahlenSchleife; when Eingabe_Fertig => if True = MinimumMaximumSetzen (ZahlenMinimumExtern => ZahlenMinimumExtern, ZahlenMaximumExtern => ZahlenMaximumExtern) then EingegebeneZahl.ErfolgreichAbbruch := True; exit ZahlenSchleife; else null; end if; when Zahl_Löschen => ZahlEntfernen; when Vorzeichen_Plus => WelchesVorzeichen := VorzeichenAnpassen (ZahlenMinimumExtern => ZahlenMinimumExtern, ZahlenMaximumExtern => ZahlenMaximumExtern, PlusMinusExtern => True); when Vorzeichen_Minus => WelchesVorzeichen := VorzeichenAnpassen (ZahlenMinimumExtern => ZahlenMinimumExtern, ZahlenMaximumExtern => ZahlenMaximumExtern, PlusMinusExtern => False); when Leer => null; end case; SchreibeGrafiktask.Vorzeicheneingabe (JaNeinExtern => WelchesVorzeichen); SchreibeGrafiktask.Zahleneingabe (ZahlExtern => Natural'Wide_Wide_Value (ZahlenString)); end loop ZahlenSchleife; case EingegebeneZahl.ErfolgreichAbbruch is when True => if WelchesVorzeichen then EingegebeneZahl.EingegebeneZahl := Integer'Wide_Wide_Value (ZahlenString); else EingegebeneZahl.EingegebeneZahl := -Integer'Wide_Wide_Value (ZahlenString); end if; when False => null; end case; EingabeAllgemeinLogik.LeerEingabeartFrage; return EingegebeneZahl; end ZahlSchleife; function VorzeichenAnpassen (ZahlenMinimumExtern : in ZahlenDatentypen.EigenerInteger; ZahlenMaximumExtern : in ZahlenDatentypen.EigenerInteger; PlusMinusExtern : in Boolean) return Boolean is begin if ZahlenMinimumExtern >= 0 then return True; elsif ZahlenMaximumExtern < 0 then return False; else return PlusMinusExtern; end if; end VorzeichenAnpassen; function GanzeZahlPrüfung (ZeichenExtern : in Sf.Window.Keyboard.sfKeyCode) return Zahl_Prüfung_Enum is begin case ZeichenExtern is when Sf.Window.Keyboard.sfKeyNum0 .. Sf.Window.Keyboard.sfKeyNum9 | Sf.Window.Keyboard.sfKeyNumpad0 .. Sf.Window.Keyboard.sfKeyNumpad9 => return Zahl_Hinzufügen; when Sf.Window.Keyboard.sfKeyEscape => return Eingabe_Abbrechen; when Sf.Window.Keyboard.sfKeyDelete | Sf.Window.Keyboard.sfKeyBack => return Zahl_Löschen; when Sf.Window.Keyboard.sfKeyE | Sf.Window.Keyboard.sfKeyEnter => return Eingabe_Fertig; when Sf.Window.Keyboard.sfKeySubtract => return Vorzeichen_Minus; when Sf.Window.Keyboard.sfKeyAdd => return Vorzeichen_Plus; when others => return Leer; end case; end GanzeZahlPrüfung; procedure ZahlHinzufügen (EingegebeneZahlExtern : in Sf.Window.Keyboard.sfKeyCode; ZahlenMinimumExtern : in ZahlenDatentypen.EigenerInteger; ZahlenMaximumExtern : in ZahlenDatentypen.EigenerInteger) is use type Sf.Window.Keyboard.sfKeyCode; begin if ZahlenString = Trim (Source => ZahlenMaximumExtern'Wide_Wide_Image, Side => Ada.Strings.Left) then return; else null; end if; ZahlenNachLinksVerschiebenSchleife: for PositionSchleifenwert in ZahlenString'First + 1 .. ZahlenString'Last loop ZahlenString (PositionSchleifenwert - 1) := ZahlenString (PositionSchleifenwert); end loop ZahlenNachLinksVerschiebenSchleife; if EingegebeneZahlExtern > Sf.Window.Keyboard.sfKeyNum9 then Zwischenspeicher := EingegebeneZahlExtern - Sf.Window.Keyboard.sfKeyNumpad0 + Sf.Window.Keyboard.sfKeyNum0; else Zwischenspeicher := EingegebeneZahlExtern; end if; ZahlenString (ZahlenString'Last) := EingabeZahlenUmwandeln (Zwischenspeicher); if ZahlenString (1) /= '0' then ZahlenString := Trim (Source => ZahlenDatentypen.EigenesPositive'Last'Wide_Wide_Image, Side => Ada.Strings.Left); else ZahlBeschränken (ZahlenMinimumExtern => ZahlenMinimumExtern, ZahlenMaximumExtern => ZahlenMaximumExtern); end if; end ZahlHinzufügen; procedure ZahlBeschränken (ZahlenMinimumExtern : in ZahlenDatentypen.EigenerInteger; ZahlenMaximumExtern : in ZahlenDatentypen.EigenerInteger) is begin StringNachZahl := Natural'Wide_Wide_Value (ZahlenString); if StringNachZahl > ZahlenMaximumExtern and ZahlenMaximumExtern > 0 and WelchesVorzeichen then LeerWert := MinimumMaximumSetzen (ZahlenMinimumExtern => ZahlenMinimumExtern, ZahlenMaximumExtern => ZahlenMaximumExtern); elsif StringNachZahl > -ZahlenMinimumExtern and ZahlenMinimumExtern < 0 and WelchesVorzeichen = False then LeerWert := MinimumMaximumSetzen (ZahlenMinimumExtern => ZahlenMinimumExtern, ZahlenMaximumExtern => ZahlenMaximumExtern); else null; end if; end ZahlBeschränken; procedure ZahlEntfernen is begin ZahlenNachRechtsVerschiebenSchleife: for PositionSchleifenwert in reverse ZahlenString'First + 1 .. ZahlenString'Last loop ZahlenString (PositionSchleifenwert) := ZahlenString (PositionSchleifenwert - 1); end loop ZahlenNachRechtsVerschiebenSchleife; ZahlenString (1) := '0'; end ZahlEntfernen; function MinimumMaximumSetzen (ZahlenMinimumExtern : in ZahlenDatentypen.EigenerInteger; ZahlenMaximumExtern : in ZahlenDatentypen.EigenerInteger) return Boolean is begin StringNachZahl := Natural'Wide_Wide_Value (ZahlenString); case WelchesVorzeichen is when True => if StringNachZahl in ZahlenMinimumExtern .. ZahlenMaximumExtern then null; elsif StringNachZahl > ZahlenMaximumExtern and ZahlenMaximumExtern > 0 then return ZahlenstringLimitieren (ZahlExtern => ZahlenMaximumExtern); elsif StringNachZahl < -ZahlenMaximumExtern and ZahlenMaximumExtern < 0 then WelchesVorzeichen := not WelchesVorzeichen; return ZahlenstringLimitieren (ZahlExtern => -ZahlenMaximumExtern); elsif StringNachZahl < ZahlenMinimumExtern and ZahlenMinimumExtern > 0 then return ZahlenstringLimitieren (ZahlExtern => ZahlenMinimumExtern); elsif StringNachZahl > -ZahlenMinimumExtern and ZahlenMinimumExtern < 0 then WelchesVorzeichen := not WelchesVorzeichen; return ZahlenstringLimitieren (ZahlExtern => -ZahlenMinimumExtern); else null; end if; when False => if -StringNachZahl in ZahlenMinimumExtern .. ZahlenMaximumExtern then null; elsif StringNachZahl < ZahlenMaximumExtern and ZahlenMaximumExtern > 0 then WelchesVorzeichen := not WelchesVorzeichen; return ZahlenstringLimitieren (ZahlExtern => ZahlenMaximumExtern); elsif StringNachZahl > -ZahlenMaximumExtern and ZahlenMaximumExtern < 0 then return ZahlenstringLimitieren (ZahlExtern => -ZahlenMaximumExtern); elsif StringNachZahl < ZahlenMinimumExtern and ZahlenMinimumExtern > 0 then WelchesVorzeichen := not WelchesVorzeichen; return ZahlenstringLimitieren (ZahlExtern => ZahlenMinimumExtern); elsif StringNachZahl > -ZahlenMinimumExtern and ZahlenMinimumExtern < 0 then return ZahlenstringLimitieren (ZahlExtern => -ZahlenMinimumExtern); else null; end if; end case; return True; end MinimumMaximumSetzen; function ZahlenstringLimitieren (ZahlExtern : in ZahlenDatentypen.EigenerInteger) return Boolean is begin AktuelleZahl := Trim (Source => ZahlenDatentypen.EigenerInteger'Wide_Wide_Image (ZahlExtern), Side => Ada.Strings.Left)'Length; ZahlenString := ZahlenStringLeer; ZahlenString (ZahlenString'Last - AktuelleZahl + 1 .. ZahlenString'Last) := Trim (Source => ZahlenDatentypen.EigenerInteger'Wide_Wide_Image (ZahlExtern), Side => Ada.Strings.Left); return False; end ZahlenstringLimitieren; end ZahleneingabeLogik;