• No results found

Inluppen: exempel på en liten tillämpning. Ett större exempel

N/A
N/A
Protected

Academic year: 2022

Share "Inluppen: exempel på en liten tillämpning. Ett större exempel"

Copied!
6
0
0

Loading.... (view fulltext now)

Full text

(1)

Jozef Swiatycki DSV

Bild 140

Inluppen: exempel på en liten tillämpning

Vandring över skärmen med piltangenterna

När markören hamnar över en ”knapp”

visas knappen med omvänd färg. Om man då trycker på RETURN utförs handlingen (värdet i displayen ökas eller minskas med 1, eller programmet avslutas).

Längst ner en meny: vänster/höger- pilar byter alternativ, RETURN utför handlingen. Om markören finns inom menyn fungerar tangenterna +, - och q som kortkommandon.

Komponenterna behöver inte vara inramade

Obs! Exemplet är mycket enkelt!

Bild 141

Ett större exempel

Komponenterna är inte inramade, spänner över hela fönsterbredden.

Lägg märke till menyns utformning.

(2)

Jozef Swiatycki DSV

Bild 142

Även i Pine beror tangentkommandons betydelse på var markören befinner sig.

Scrollande delfönster o.s.v. är inte så svåra att göra, men de ingår inte i den obligatoriska delen av uppgiften

Samma exempel, annan bildskärmsbild

Bild 143

Åter till det lilla exemplet:

skiss på tillämpningsprogrammet

class Value{

int val;

public:

void oka() { val++; // Visa nya värdet ! } void minska() { val--; // Visa nya värdet ! } }; int main(){

Value v;

Session ses;

// Skapa displayen så att v kan visa värdet där // Skapa knappen för ”öka”, koppla till v.oka

// Skapa knappen för ”minska”, koppla till v.minska // Skapa knappen för ”sluta”, koppla till exit // Skapa menyn

// Skapa menyvalet ”+”, koppla till v.oka // Skapa menyvalet ”-”, koppla till v.minska // Skapa menyvalet ”q”, koppla till exit // Skapa kortkommandot ”+”, koppla till v.oka // Skapa kortkommandot ”-”, koppla till v.minska // Skapa kortkommandot ”q”, koppla till exit ses.run();

}

Tillämpningen anger vid skapandet av skärmobjekten var på skärmen

de skall vara, vad som skall stå i dem o.s.v.

(3)

Jozef Swiatycki DSV

Bild 144

Inlämningsuppgiften

Skapa (början till) ett klassbibliotek med komponenter för sådana tillämpningar

Obligatoriska komponenter:

etikett (label), knapp, editerbar sträng, meny session

Bestäm själva detaljutformningen (inramade eller ej, eller både och, färganvändning osv)

Biblioteket skall vara förberett för utbyggnad, dvs utformat mer generellt än vad som krävs just här

För användaren (tillämpningsprogrammeraren): bekvämt men flexibelt, dvs implementerade defaultbeteenden men möjlighet att ändra

Internt: hög grad av uppdelning, varje klass sköter sina

”naturliga” uppgifter

Bild 145

Tilläggskrav på implementering

Datasamlingar implementerade med STL-behållarklasser

Genomgångar, sökningar osv med generiska algoritmer från standardbiblioteket Adaptorer för funktionsobjekt (bind1st, bind2nd, mem_fun osv) används där det är möjligt, egna funktionsobjekt skapas annars.

Kopplingar till tillämpningsklassers metoder sker genom medlemsfunktions- pekare.

Komponentobjekten hanteras via referensräknande ”pekarklasser”.

Biblioteket reagerar på felaktigheter (överlappande komponenter, komponenter utanför skärmarean osv) genom att generera undantag.

Icke-triviala medlemsfunktioner definieras utanför klassdefinitioner (gäller även mallar). Deklarationer av klasser i headerfiler, definitioner av medlems- funktioner och hjälpfunktioner i implementeringsfiler (gäller inte mallar eller infogade (inline) funktioner).

Hög grad av uppdelning i filer - helst varje klass på egen fil (använd make!).

(4)

Jozef Swiatycki DSV

Bild 146

Förenklingar och önskemål

Förenklingar:

Icke-överlappande komponenter

Önskemål:

Kontroll av vilken komponent markören befinner sig i, kontroll av om komponenter överlappar varandra, eventuell beräkning av position för centrering av text osv är operationer som har att göra med rektanglar. Skapa gärna en klass rektangel med denna funktionalitet som sedan kan användas i komponentklasserna, gröta inte ner komponenterna eller sökfunktionerna med koordinataritmetik.

Bild 147

En möjlig arkitektur för exemplet (instansexempel)

q + -

→←

Knapp

”öka”

Knapp

”minska”

Knapp

”sluta”

”+” ”-” ”q”

Display Meny

Menyvalen Session

öka minska

7

tillämpnings-Ett objekt getCont

run

main v add add remove

setCont content

(5)

Jozef Swiatycki DSV

Bild 148

Förslag till grov klasstruktur

Rectangle

Component

Passive

Menu

Label

Edit_string Button Compund

Session Action_base

Action<>

contains

showerase enter leave handle_event

handle_event show

handle_event get_text

handle_eventshow

handle_eventshow addadd remove

set_textshow

handle_eventshow addadd

getContent setContent

run

perform

perform

Ptr<>

->*

Bild 149

Grov beskrivning av klasser

Rectangle innehåller skärmkoordinater för en rektangulär area och medlemsfunktioner för koordinataritmetik, t.ex. contains() som tar en punkt (kolumn- och radnummer) och returnerar om denna punkt ligger inom dess area. Är mest till för hålla koordinataritmetik separerad från den övriga koden för komponenterna.

Component den egentliga rotklassen i hierarkin. Borde innehålla en rent virtuell medlemsfunktion show() som implementeras i subklasserna och ritar upp komponenten på skärmen; en rent virtuell medlemsfunktion handle_event() som tar en Event-struct (så att komponenten kan se vad det var för tangent och var den trycktes) och returnerar ett booleskt värde (true om komponenten hanterat händelsen, false annars);

två virtuella funktioner enter() och leave() som borde vara implementerade som tomma funktioner men kan överskuggas av subklasser om man vill att något speciellt skall hända när markören flyttas in i komponentens område resp. flyttas ut därifrån. Innehåller även icke-virtuell funktion erase() Passive rotklassen för passiva komponenter, kan implementera handle_event()-medlemsfunktionen så att den

alltid returnerar false - passiva objekt reagerar inte på några händelser Label lövklass, implementerar show() som skriver ut texten på skärmen

Edit_string lövklass, editerbar sträng som implementerar handle_event(): den reagerar på skrivbara tecken genom att lägga in dem i en intern sträng och skriva ut den förändrade strängen på skärmen samt även på delete-tangenten och rubout-tangenten genom att ta bort tecken ur strängen. Den implementerar även show() och har en egen medlemsfunktion get_text(). Denna klass borde implementeras sist.

Button lövklass, implementerar show() och handle_event(): den reagerar på RETURN-tangenten genom att anropa någon medlemsfunktion i något objekt av någon klass i tillämpningen. Måste alltså ha en koppling till tillämpningen (en Action_base *, se nedan Action och Action_base).

(6)

Jozef Swiatycki DSV

Bild 150

Grov beskrivning av klasser, forts.

Compound klassen för sammansatta skärmobjekt. Borde innehålla en datasamling för de ingående skärombjekten (lämpligen en vector med pekare till skärmobjekt) och en datasamling med ”kortkommandon” (lämpligen en map med tangentkoder som nycklar och Action_base-pekare som värden - se Action och Action_base).

Borde ha två funktioner add(): en för att addera komponenter och en för att addera ”kortkommandon”, samt funktionen remove() för borttagning av komponenter.

Implementerar handle_event() genom att gå leta upp den komponent inom vars area händelsen inträffat och anropa dess handle_event(). Om komponenten svarar att den inte hanterar denna händelse (eller om händelsen inträffat utanför någon ingående komponent) så kontrolleras om detta objekt självt kan hantera händelsen (t.ex. genom att titta i ”kortkommando”-samlingen). Medlemsfunktionen show() implementeras genom att gå igenom de ingående komponenterna och anropa deras show().

Menu egentligen ett sammansatt objekt vars ingående komponenter endast kan vara knappar. Dessutom borde piltangenter flytta markören till nästa/föregående knapp och knapparna borde ligga bredvid varandra.

Många tyckte att Meny borde vara en subklass till Compound, men det borde den inte alls. Ett subklass- objekt skall kunna användas i alla de sammanhang där ett basklassobjekt förväntas - till ett Compound- objekt kan man addera godtyckliga komponenter, men det kan man inte till ett Menu-objekt.

Däremot borde Menu implementeras genom att innehålla ett Compound-objekt och de flesta medlems- funktioner i Menu blir nog bara till anrop av motsvarande funktion i det inneslutna Compound-objektet.

En bra sak vore om add-funktionen för knappar i Menu inte tog en färdigskapad knapp utan bara info om vad som skall stå på knappen och vad den skall kopplas till, då kan Menu-objektet räkna ut vilka koordinater nästa knapp i menyn skall ha och skapa knapp-objektet självt, innan det skickas vidare till add() i det inneslutna Compund-objektet. Några design-beslut om hur menyerna skall se ut (stående, liggande, knappstorleken, hur kan tillämpningen styra detta...) måste göras i så fall.

Bild 151

Grov beskrivning av klasser, forts.

Label lövklass, text som visas på skärmen men som inte interagerar med användaren. Programmet skall dock kunna ändra texten.

Session representerar hela terminalskärmen. Innehåller ett sammansatt objekt som i sin tur innehåller skärmobjekten. Har medlemsfunktionerna getContent() för att returnera en”pekare” till det sammansatta objektet och setContent() för att byta ut det mot ett annat.

Tillämpningen skapar ett Session-objekt, adderar komponenter och kortkommandon till dess ”Content”

och anropar sedan funktionen run(). run() innehåller en loop där man läser in nästa händelse och skickar denna händelse till rätt komponent. Förutom händelseinläsning är gången precis som för ett sammansatt objekts händelsehantering.

Action representerar en koppling mellan biblioteksklasser och tillämpningen. Innehåller en pekare till ett objekt Action_base av en tillämpningsklass, en medlemspekare till en medlemsfunktion i denna klass samt medlemsfunktionen

perform() som anropar denna medlemsfunktion hos detta objekt. Eftersom tillämpningsklassen är okänd måste Action vara en mall. Eftersom man vill kunna ha objekt av olika instansieringar av denna mall i samma datasamling (samlingen av kortkommandon i ett Compound-objekt) så bör man skapa en basklass (som inte är en mall) till Action, nämligen Action_base. Denna basklass borde innehålla en virtual-deklaration av medlemsfunktionen perform(). I de övriga biblioteksklasser där man vill ha en koppling till tillämpningars objekt och medlemsfunktioner kan man nu ha en pekare till Action_base, som alltså kan peka ut objekt av olika instansieringar av Action.

Den föreslagna klassen Action representerar en förbindelse med en medlemsfunktion i ett objekt. Man kan tänka sig att en tilläpmning även skulle vilja kunna skapa en koppling mellan bibliotekskomponenter och fristående funktioner i tillämpningen. Vill man förbereda för det kan man göra en specialisering av Action-mallen där typen man specialiserar för är en funktionspekartyp och där Action-klassen innehåller en funktionspekare istället för en objektpekare och en medlemsfunktionspekare.

References

Related documents

• Man kan även låta destruktorn vara privat då förhindras allokering på

Att Stina Fors vid moderns död stod helt utan pengar är troligen också en sanning med modifikation eftersom hon av reportaget att döma bor kvar i det stora huset och dessutom

Vissa undantag (kontrollerade undantag, eller checked exceptions) måste deklareras; om en metod kan kasta ett sådant måste den deklarera det.. Subklasser,

Beskrivs hur patientsäkerhetsarbetet har bedrivits under föregående kalenderår och vilka åtgärder som har vidtagits för att öka patientsäkerheten kopplat till era mål

En del bättre ingår, huvudsakligen * och kvalitén är blandad men även felfria postfriska märken finns.. felfria ostämplade 50 öre och 1 krona

Kommunerna (kommunledning o förvaltning. Eller open space) Institutionerna. Civilsamhället Konstområdena

Absorbenter eller ljuddämpande textilier (ej ordinära gardiner) (i förekommande fall) Skåp för AV-utrustning (i förekommande

Området hyser ett visst biotopvärde, främst genom förekomst av grov ek och asp, samt ett visst artvärde vilket motiverar ett påtagligt