From f2603e12d7ccee4f6bf0a52b743f10df8c2d6450 Mon Sep 17 00:00:00 2001 From: Joakim Hunskaar <joakim.borge.hunskar@gmail.com> Date: Wed, 1 May 2024 21:52:37 +0200 Subject: [PATCH 1/4] updated all code examples and removed some outdated instructions --- docs/animationwindow/animation.md | 34 ++-- docs/animationwindow/drawing.md | 184 +++++++++--------- docs/animationwindow/gui.md | 93 ++++------ docs/animationwindow/helpers.md | 298 +++++++++++++++--------------- docs/animationwindow/index.md | 33 ++-- docs/animationwindow/input.md | 28 ++- docs/troubleshooting/macos.md | 6 +- docs/troubleshooting/windows.md | 5 +- 8 files changed, 317 insertions(+), 364 deletions(-) diff --git a/docs/animationwindow/animation.md b/docs/animationwindow/animation.md index bbbb101..3dc9640 100644 --- a/docs/animationwindow/animation.md +++ b/docs/animationwindow/animation.md @@ -9,15 +9,13 @@ En animasjon er en rekke bilder som er vist kort etter hverandre, hvor ved Ã¥ be Vi har fram til nÃ¥ bare tegnet enkelte bilder som ikke beveger eller endrer seg, og fordi animasjonen krever at vi tegner flere bilder trenger vi Ã¥ bruke et par andre funksjoner i stede for `wait_for_close()` funksjonen som vi har brukt sÃ¥ langt: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; while(!window.should_close()) { - window.draw_circle({100, 100}, 50, Color::dark_green); + window.draw_circle({100, 100}, 50, TDT4012::Color::dark_green); window.next_frame(); } @@ -38,17 +36,15 @@ Det er to nye funksjoner som brukes i dette eksempelet: Siden det nÃ¥ er mulig Ã¥ tegne flere bilder pÃ¥ rad kan vi prøve Ã¥ lage en enkel animasjon, for eksempel en firkant som beveger mot høyre siden av skjermen. Vi gjør dette ved Ã¥ øke x-koordinatet hver gang vi tegner et nytt bilde: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; int xPosition = 0; while(!window.should_close()) { xPosition = xPosition + 2; - Point position {xPosition, 100}; + TDT4102::Point position {xPosition, 100}; window.draw_rectangle(position, 100, 100); window.next_frame(); @@ -60,15 +56,13 @@ int main() Merk at hele bildet mÃ¥ tegnes pÃ¥ nytt etter hver gang `next_frame()` funksjonen blir kallet. Det er ikke mulig Ã¥ beholde en del av bildet og tegne bare det som endrer seg. -NÃ¥r du kjører eksempelet forsvinner firkanten etterhvert. Vi kan løse dette ved Ã¥ legge til et if setning: +NÃ¥r du kjører eksempelet forsvinner firkanten etterhvert. Vi kan løse dette ved Ã¥ legge til en if setning: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; int xPosition = 0; while(!window.should_close()) { @@ -76,7 +70,7 @@ int main() if(xPosition > 200) { xPosition = 0; } - Point position {xPosition, 100}; + TDT4102::Point position {xPosition, 100}; window.draw_rectangle(position, 100, 100); window.next_frame(); @@ -89,12 +83,10 @@ int main() Og for moro skyld kan vi sørge for at den bare flytter seg nÃ¥r mellomrom pÃ¥ tastaturen holdes ned (du finner mer informasjon om dette pÃ¥ input siden): ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; int xPosition = 0; while(!window.should_close()) { @@ -104,7 +96,7 @@ int main() if(xPosition > 200) { xPosition = 0; } - Point position {xPosition, 100}; + TDT4102::Point position {xPosition, 100}; window.draw_rectangle(position, 100, 100); window.next_frame(); diff --git a/docs/animationwindow/drawing.md b/docs/animationwindow/drawing.md index 8ca10a9..94b6a97 100644 --- a/docs/animationwindow/drawing.md +++ b/docs/animationwindow/drawing.md @@ -4,24 +4,22 @@ ### Vinduets koordinatsystem -Alle former som kan tegnes i vinduet krever at du spesifiserer en posisjon. Koordinater er mÃ¥let relativ til øverst venstre hjørnet i vinduet, hvor x-koordinater øker i høyre retningen og y-koordinater øker nedover. +Alle former som kan tegnes i vinduet krever at du spesifiserer en posisjon. Koordinater er mÃ¥let relativ til øverst venstre hjørnet i vinduet, hvor x-koordinater øker mot høyre og y-koordinater øker nedover. <img src="../../images/window_coordinates.png" alt="Bilde som viser x og y-aksen i vinduet" style="max-width:600px; width:100%;"/> -Du kan ogsÃ¥ bruke følgende programmet for Ã¥ visualisere hvilket koordinat musen din peker til: +Du kan ogsÃ¥ bruke følgende program for Ã¥ visualisere hvilket koordinat musepekeren er pÃ¥: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; while(!window.should_close()) { - Point mouseCoordinates = window.get_mouse_coordinates(); - string coordinateText = to_string(mouseCoordinates.x) + ", " + to_string(mouseCoordinates.y); + TDT4102::Point mouseCoordinates = window.get_mouse_coordinates(); + string coordinateText = std::to_string(mouseCoordinates.x) + ", " + std::to_string(mouseCoordinates.y); window.draw_text(mouseCoordinates, coordinateText); window.next_frame(); @@ -37,23 +35,21 @@ Du kan tenke pÃ¥ vinduet som et slags maleri. Det betyr at nÃ¥r du tegner over n For eksempel, dette er resultatet nÃ¥r rektangelen tegnes først og sirklen sist: -<img src="../../images/draw_order_1.png" alt="Bilde som viser x og y-aksen i vinduet" style="max-width:600px; width:100%;"/> +<img src="../../images/draw_order_1.png" alt="Grønn sirkel over et blÃ¥tt rektangel" style="max-width:600px; width:100%;"/> Og dette er resultatet dersom rektangelen tegnes sist: -<img src="../../images/draw_order_2.png" alt="Bilde som viser x og y-aksen i vinduet" style="max-width:600px; width:100%;"/> +<img src="../../images/draw_order_2.png" alt="BlÃ¥tt rektangel over en grønn sirkel" style="max-width:600px; width:100%;"/> ## Basisformer Om du ønsker Ã¥ teste de kodeeksemplene som er vist, kan du bruke følgende eksempelet hvor du erstatter linjen som er markert: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; // Erstatt denne linjen med eksemplet som du ønsker Ã¥ prøve @@ -66,7 +62,7 @@ int main() For Ã¥ tegne sirkler kan du bruke `draw_circle()` funksjonen. Denne krever et punkt hvor midtpunktet skal tegnes, og en radius som definerer hvor stor den skal være: ```c++ - Point circleOrigin {150, 150}; + TDT4102::Point circleOrigin {150, 150}; int radius = 100; window.draw_circle(circleOrigin, radius); ``` @@ -75,157 +71,157 @@ For Ã¥ tegne sirkler kan du bruke `draw_circle()` funksjonen. Denne krever et pu window.draw_circle({150, 150}, 100); ``` -<img src="../../images/circle_1.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/circle_1.png" alt="Bilde som viser en blÃ¥ sirkel" style="max-width:450px; width:100%;"/> Det er mulig Ã¥ endre pÃ¥ sirklens farge: ```c++ - Point circleOrigin {150, 150}; + TDT4102::Point circleOrigin {150, 150}; int radius = 100; - Color fillColor = Color::dark_orange; + TDT4102::Color fillColor = TDT4102::Color::dark_orange; window.draw_circle(circleOrigin, radius, fillColor); ``` -<img src="../../images/circle_2.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/circle_2.png" alt="Bilde som viser en mørke-oransje sirkel" style="max-width:450px; width:100%;"/> Og en kantlinje med en gitt farge: ```c++ - Point circleOrigin {150, 150}; + TDT4102::Point circleOrigin {150, 150}; int radius = 100; - Color fillColor = Color::dark_orange; - Color borderColor = Color::black; + TDT4102::Color fillColor = TDT4102::Color::dark_orange; + TDT4102::Color borderColor = TDT4102::Color::black; window.draw_circle(circleOrigin, radius, fillColor, borderColor); ``` -<img src="../../images/circle_3.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/circle_3.png" alt="Bilde som viser en mørke-oransje sirkel med svart kantlinje" style="max-width:450px; width:100%;"/> ### Trekanter Trekanter tegnes mellom tre punkt og `draw_triangle()` funksjonen: ```c++ - Point vertex0 {150, 50}; - Point vertex1 {50, 200}; - Point vertex2 {250, 200}; + TDT4102::Point vertex0 {150, 50}; + TDT4102::Point vertex1 {50, 200}; + TDT4102::Point vertex2 {250, 200}; window.draw_triangle(vertex0, vertex1, vertex2); ``` -<img src="../../images/triangle_1.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/triangle_1.png" alt="Bilde som viser en gul trekant" style="max-width:450px; width:100%;"/> Og som før kan fargen endres: ```c++ - Point vertex0 {150, 50}; - Point vertex1 {50, 200}; - Point vertex2 {250, 200}; - Color fillColor = Color::indigo; + TDT4102::Point vertex0 {150, 50}; + TDT4102::Point vertex1 {50, 200}; + TDT4102::Point vertex2 {250, 200}; + TDT4102::Color fillColor = TDT4102::Color::indigo; window.draw_triangle(vertex0, vertex1, vertex2, fillColor); ``` -<img src="../../images/triangle_2.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/triangle_2.png" alt="Bilde som viser en lilla trekant" style="max-width:450px; width:100%;"/> ### Rektangel -Rektangel tegnes pÃ¥ et punkt som tilsvarer øverst venstre hjørnet samt et høyde og bredde. Den tegnes med `draw_rectangle()` funksjonen: +Rektangel tegnes fra et punkt som tilsvarer øverst venstre hjørnet samt høyde og bredde. Den tegnes med `draw_rectangle()` funksjonen: ```c++ - Point topLeftCorner {50, 50}; + TDT4102::Point topLeftCorner {50, 50}; int width = 150; int height = 100; window.draw_rectangle(topLeftCorner, width, height); ``` -<img src="../../images/rectangle_1.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/rectangle_1.png" alt="Bilde som viser et blÃ¥grønt rektangel" style="max-width:450px; width:100%;"/> Som alle andre former kan fargen endres: ```c++ - Point topLeftCorner {50, 50}; + TDT4102::Point topLeftCorner {50, 50}; int width = 150; int height = 100; - Color fillColor = Color::light_sea_green; + TDT4102::Color fillColor = TDT4102::Color::light_sea_green; window.draw_rectangle(topLeftCorner, width, height, fillColor); ``` Og kantfargen kan ogsÃ¥ endres som i sirkler: ```c++ - Point topLeftCorner {50, 50}; + TDT4102::Point topLeftCorner {50, 50}; int width = 150; int height = 100; - Color fillColor = Color::light_sea_green; - Color edgeColor = Color::lime; + TDT4102::Color fillColor = TDT4102::Color::light_sea_green; + TDT4102::Color edgeColor = TDT4102::Color::lime; window.draw_rectangle(topLeftCorner, width, height, fillColor, lime); ``` -<img src="../../images/rectangle_2.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/rectangle_2.png" alt="Bilde som viser et grønt rektangel" style="max-width:450px; width:100%;"/> ### Quad En quad er et rektangel hvor hvert hjørne kan flyttes uavhengig av hverandre. Den tegnes med `draw_quad()` funksjonen: ```c++ - Point vertex0 {180, 80}; - Point vertex1 {50, 120}; - Point vertex2 {120, 250}; - Point vertex3 {250, 180}; + TDT4102::Point vertex0 {180, 80}; + TDT4102::Point vertex1 {50, 120}; + TDT4102::Point vertex2 {120, 250}; + TDT4102::Point vertex3 {250, 180}; window.draw_quad(vertex0, vertex1, vertex2, vertex3); ``` -<img src="../../images/quad_1.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/quad_1.png" alt="Bilde som viser en lyseblÃ¥ quad" style="max-width:450px; width:100%;"/> Fargen kan justeres: ```c++ - Point vertex0 {180, 80}; - Point vertex1 {50, 120}; - Point vertex2 {120, 250}; - Point vertex3 {250, 180}; - Color fillColor = Color::violet; + TDT4102::Point vertex0 {180, 80}; + TDT4102::Point vertex1 {50, 120}; + TDT4102::Point vertex2 {120, 250}; + TDT4102::Point vertex3 {250, 180}; + TDT4102::Color fillColor = TDT4102::Color::violet; window.draw_quad(vertex0, vertex1, vertex2, vertex3, fillColor); ``` -<img src="../../images/quad_2.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/quad_2.png" alt="Bilde som viser en rosa quad" style="max-width:450px; width:100%;"/> ### Linjer Du kan tegne linjer ved Ã¥ bruke `draw_line()` funksjonen. Linjer tegnes mellom to punkt: ```c++ - Point lineStart {50, 50}; - Point lineEnd {280, 290}; + TDT4102::Point lineStart {50, 50}; + TDT4102::Point lineEnd {280, 290}; window.draw_line(lineStart, lineEnd); ``` -<img src="../../images/line_1.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/line_1.png" alt="Bilde som viser en linje" style="max-width:450px; width:100%;"/> I tillegg kan linjens farge endres: ```c++ - Point lineStart {50, 50}; - Point lineEnd {280, 290}; - Color lineColor = Color::firebrick; + TDT4102::Point lineStart {50, 50}; + TDT4102::Point lineEnd {280, 290}; + TDT4102::Color lineColor = TDT4102::Color::firebrick; window.draw_line(lineStart, lineEnd, lineColor); ``` -<img src="../../images/line_2.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/line_2.png" alt="Bilde som viser en linje" style="max-width:450px; width:100%;"/> ### Arc En bue er en sirkel som tegnes delvis, mellom et start og sluttvinkel relativ til sirklens midtpunkt: -<img src="../../images/arc_angles.png" alt="Bilde som viser x og y-aksen i vinduet" style="max-width:600px; width:100%;"/> +<img src="../../images/arc_angles.png" alt="Bilde som viser vinkler" style="max-width:600px; width:100%;"/> Merk at sluttvinkelen mÃ¥ være større enn startvinkelen, og alle vinklene mÃ¥ være mellom 0 og 360 grader. Høyden og bredden spesifiserer sirklens størrelse, og gjør det mulig Ã¥ strekke sirklen: -<img src="../../images/arc_scale.png" alt="Bilde som viser x og y-aksen i vinduet" style="max-width:400px; width:100%;"/> +<img src="../../images/arc_scale.png" alt="Bilde som viser ellipser" style="max-width:400px; width:100%;"/> Med disse parameterene til sammen kan du tegne en bue ved Ã¥ bruke `draw_arc()` funksjonen: ```c++ - Point centerPoint {100, 50}; + TDT4102::Point centerPoint {100, 50}; int width = 200; int height = 370; int startDegree = 270; @@ -238,12 +234,12 @@ Med disse parameterene til sammen kan du tegne en bue ved Ã¥ bruke `draw_arc()` Lik som linjer er det mulig Ã¥ endre fargen: ```c++ - Point centerPoint {100, 50}; + TDT4102::Point centerPoint {100, 50}; int width = 200; int height = 370; int startDegree = 270; int endDegree = 360; - Color lineColor = Color::lime; + TDT4102::Color lineColor = TDT4102::Color::lime; window.draw_arc(centerPoint, width, height, startDegree, endDegree, lineColor); ``` @@ -256,48 +252,48 @@ Lik som linjer er det mulig Ã¥ endre fargen: For Ã¥ tegne tekst i vinduet brukes `draw_text()` funksjonen. Denne tar inn et sted pÃ¥ skjermen, og en tekst streng som skal vises som parametere: ```c++ - Point location {100, 100}; + TDT4102::Point location {100, 100}; string message = "Greetings from outer space!"; window.draw_text(location, message); ``` -<img src="../../images/text_1.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/text_1.png" alt="Bilde som viser tekst" style="max-width:450px; width:100%;"/> Du kan endre fargen pÃ¥ teksten: ```c++ - Point location {100, 100}; + TDT4102::Point location {100, 100}; string message = "Greetings from outer space!"; - Color textColor = Color::deep_skyblue; + TDT4102::Color textColor = TDT4102::Color::deep_skyblue; window.draw_text(location, message, textColor); ``` -<img src="../../images/text_2.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/text_2.png" alt="Bilde som viser blÃ¥ tekst" style="max-width:450px; width:100%;"/> Og størrelsen: ```c++ - Point location {100, 100}; + TDT4102::Point location {100, 100}; string message = "Greetings from outer space!"; - Color textColor = Color::deep_skyblue; + TDT4102::Color textColor = TDT4102::Color::deep_skyblue; int fontSize = 120; window.draw_text(location, message, textColor, fontSize); ``` -<img src="../../images/text_3.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/text_3.png" alt="Bilde som viser stor blÃ¥ tekst" style="max-width:450px; width:100%;"/> Om du ønsker skrifttypen kan du bruke en Font verdi som siste parameter: ```c++ - Point location {100, 100}; - string message = "Greetings from outer space!"; - Color textColor = Color::deep_skyblue; + TDT4102::Point location {100, 100}; + TDT4102::string message = "Greetings from outer space!"; + Color textColor = TDT4102::Color::deep_skyblue; int fontSize = 120; - Font fontFace = Font::times_bold; + TDT4102::Font fontFace = TDT4102::Font::times_bold; window.draw_text(location, message, textColor, fontSize, fontFace); ``` -<img src="../../images/text_4.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:450px; width:100%;"/> +<img src="../../images/text_4.png" alt="Bilde som viser stor blÃ¥ tekst med endret font" style="max-width:450px; width:100%;"/> Her er et oversikt over de forskjellige skrifttyper som er tilgjengelig og hvordan de ser ut: @@ -324,37 +320,35 @@ For Ã¥ kunne tegne et bilde mÃ¥ den lastes inn fra en fil. Finn gjerne et bilde <a title="Dietmar Rabich / Wikimedia Commons / “Dichroitisches Prisma -- 2020 -- 5123â€Â / CC BY-SA 4.0" href="https://commons.wikimedia.org/wiki/File:Dichroitisches_Prisma_--_2020_--_5123.jpg"><img width="256" alt="Dichroitisches Prisma -- 2020 -- 5123" src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/87/Dichroitisches_Prisma_--_2020_--_5123.jpg/512px-Dichroitisches_Prisma_--_2020_--_5123.jpg"></a> -Kopier bildet inn pÃ¥ prosjektet i samme mappen som inneholder «.vscode» og «builddir» mappene: +Kopier bildet inn pÃ¥ prosjektet: <img src="../../images/image_file_view.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:300px; width:100%;"/> Slik laster du inn ditt bilde, og tegner den i vinduet: ```c++ - Point topLeftCorner {50, 100}; - Image image("img.jpg"); + TDT4102::Point topLeftCorner {50, 100}; + TDT4102::Image image("img.jpg"); window.draw_image(topLeftCorner, image); ``` -Om ditt bilde har et annet navn enn «img.jpg» mÃ¥ du endre navnet som er definert i koden slik at den er akkurat det samme som navnet pÃ¥ filen: +Om bilde har et annet navn enn «img.jpg» mÃ¥ du endre navnet som er definert i koden slik at den er akkurat det samme som navnet pÃ¥ filen: -<img src="../../images/image_file_equivalent.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code" style="max-width:600px; width:100%;"/> +<img src="../../images/image_file_equivalent.png" alt="Bilde som viser et JPG fil i arbeidsomrÃ¥det i Visual Studio Code med røde bokser" style="max-width:600px; width:100%;"/> **Merk:** nÃ¥r du skal tegne et bilde i en animasjon bør du ikke laste inn bildet innenfor while løkken. Om du hadde flyttet `image` variablen inn pÃ¥ `while`-løkken, sÃ¥ hadde bildet blitt lastet inn pÃ¥ nytt hver eneste gang et bilde blir tegnet. ```c++ #include "AnimationWindow.h" -#include "std_lib_facilities.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; // VIKTIG: Image variabler bør ikke defineres innenfor while-løkken - Image image("img.jpg"); + TDT4102::Image image("img.jpg"); while(!window.should_close()) { - Point topLeftCorner {50, 100}; + TDT4102::Point topLeftCorner {50, 100}; window.draw_image(topLeftCorner, image); window.next_frame(); } @@ -363,21 +357,19 @@ int main() } ``` -Noen bilder er for stor eller for liten Ã¥ vise i sin orginale størrelse. Det er derfor mulig Ã¥ spesifesere et alternativ størrelse nÃ¥r du skal tegne bildet. For eksempel, her brukes muspekeren til dette: +Noen bilder er for store eller for smÃ¥ i sin orginale størrelse. Det er derfor mulig Ã¥ spesifisere en annen størrelse nÃ¥r du skal tegne bildet. For eksempel, her brukes muspekeren til dette: ```c++ #include "AnimationWindow.h" -#include "std_lib_facilities.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; - Image image("img.jpg"); + TDT4102::Image image("img.jpg"); while(!window.should_close()) { - Point topLeftCorner {0, 0}; - Point mouse = window.get_mouse_coordinates(); + TDT4102::Point topLeftCorner {0, 0}; + TDT4102::Point mouse = window.get_mouse_coordinates(); int imageWidth = mouse.x; int imageHeight = mouse.y; window.draw_image(topLeftCorner, image, imageWidth, imageHeight); diff --git a/docs/animationwindow/gui.md b/docs/animationwindow/gui.md index 2f98467..7f8b870 100644 --- a/docs/animationwindow/gui.md +++ b/docs/animationwindow/gui.md @@ -4,30 +4,28 @@ Grafiske brukergrensesnitt ## Konstruksjon av grafiske grensesnitt -Grafiske grensesnitt bestÃ¥r av en rekke GUI elementer som kalles `widgets`. Dette kan være knapper, tekstfelt eller dropdown lister. +Grafiske grensesnitt bestÃ¥r av en rekke GUI elementer som kalles `widgets`. Dette kan være knapper, tekstfelt eller dropdown-lister. -<img src="../../images/gui.png" alt="Bilde som viser en kurve tegnet med draw_arc funksjonen og endret farge" style="max-width:400px; width:100%;"/> +<img src="../../images/gui.png" alt="Bilde som viser ulike widgets; knapper, tekstfelt og dropdown-liste" style="max-width:400px; width:100%;"/> ## Callback -Et «callback» er en funksjon som kalles etter en spesifikk hendelse har inntruffet. Disse brukes ofte med brukergrensesnitt, for eksempel for Ã¥ spesifisere hva som skal skje etter brukeren har trykket pÃ¥ en knapp. Hvert GUI-element lar deg definere _én_ slik funksjon som blir kjørt etter hver interaksjon. Nøyaktig hvilken interaksjon er avhengig av GUI-elementet. +Et «callback» er en funksjon som kalles etter at en spesifikk hendelse har inntruffet. Disse brukes ofte med brukergrensesnitt, for eksempel for Ã¥ spesifisere hva som skal skje etter brukeren har trykket pÃ¥ en knapp. Hvert GUI-element lar deg definere _én_ slik funksjon som blir kjørt etter hver interaksjon. Nøyaktig hvilken interaksjon er avhengig av GUI-elementet. For Ã¥ vise hvordan man definerer og bruker en callback funksjon, fortsetter vi med samme eksempelet som før: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" #include "widgets/Button.h" -int main() -{ - const Point buttonPosition {100, 100}; +int main() { + const TDT4102::Point buttonPosition {100, 100}; const unsigned int buttonWidth = 100; const unsigned int buttonHeight = 40; const string buttonLabel = "Click me!"; - Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel}; + TDT4102::Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel}; - AnimationWindow window; + TDT4102::AnimationWindow window; window.add(button); window.wait_for_close(); @@ -38,7 +36,6 @@ int main() Vi kan nÃ¥ definere callback funksjonen. Den skal ha ingen parametere, og returnere `void`. Det er mulig Ã¥ definere flere callback funksjoner i en enkelt fil, og navnet pÃ¥ funksjonene er ikke viktig. Flere GUI elementer kan ha samme callback funksjonen. ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" #include "widgets/Button.h" @@ -46,15 +43,14 @@ void callbackFunction() { std::cout << "This is printed when this function is executed." << std::endl; } -int main() -{ - const Point buttonPosition {100, 100}; +int main() { + const TDT4102::Point buttonPosition {100, 100}; const unsigned int buttonWidth = 100; const unsigned int buttonHeight = 40; const string buttonLabel = "Click me!"; - Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel}; + TDT4102::Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel}; - AnimationWindow window; + TDT4102::AnimationWindow window; window.add(button); window.wait_for_close(); @@ -65,7 +61,6 @@ int main() Den siste steget er Ã¥ bruke `callbackFunction()` funksjonen som callback av knappen vi laget tidligere. Vi gjør dette ved Ã¥ bruke `setCallback()` funksjonen, med navn pÃ¥ funksjonen som vi ønsker Ã¥ bruke som parameter: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" #include "widgets/Button.h" @@ -73,15 +68,14 @@ void callbackFunction() { std::cout << "This is printed when this function is executed." << std::endl; } -int main() -{ - const Point buttonPosition {100, 100}; +int main() { + const TDT4102::Point buttonPosition {100, 100}; const unsigned int buttonWidth = 100; const unsigned int buttonHeight = 40; const string buttonLabel = "Click me!"; - Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel}; + TDT4102::Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel}; - AnimationWindow window; + TDT4102::AnimationWindow window; button.setCallback(callbackFunction); window.add(button); window.wait_for_close(); @@ -92,20 +86,20 @@ int main() NÃ¥r vi kjører dette programmet og klikker pÃ¥ knappen ser vi at callback funksjonen skriver ut tekst pÃ¥ skjermen: -<img src="../../images/callback.png" alt="Bilde som viser en kurve tegnet med draw_arc funksjonen og endret farge" style="max-width:800px; width:100%;"/> +<img src="../../images/callback.png" alt="Bilde som viser tekst i terminalen fra callback-funksjonen" style="max-width:800px; width:100%;"/> ### Objekt-orienterte callback funksjoner Dersom man ønsker Ã¥ sette callback-funksjonen til en klassemetode mÃ¥ man bruke `std::bind` for Ã¥ gjøre funksjonen kompatibel. ```c++ -class SuperManWindow : public AnimationWindow { +class SuperManWindow : public TDT4102::AnimationWindow { public: SuperManWindow(); void superCallbackFunction(); void fly(); private: - Button flyButton; + TDT4102::Button flyButton; }; void SuperManWindow::superCallbackFunction() { @@ -144,12 +138,11 @@ Denne funksjonen blir kalt med `true` for Ã¥ vise elementet og med `false` for En knapp er et GUI element som gjør noe nÃ¥r du klikker pÃ¥ den: -<img src="../../images/button.png" alt="Bilde som viser en kurve tegnet med draw_arc funksjonen og endret farge" style="max-width:400px; width:100%;"/> +<img src="../../images/button.png" alt="Bilde som viser en knapp" style="max-width:400px; width:100%;"/> Her er et eksempel som vises hvordan den brukes: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" #include "widgets/Button.h" @@ -157,18 +150,17 @@ void buttonClicked() { std::cout << "Someone clicked on me!" << std::endl; } -int main() -{ - const Point buttonPosition {100, 100}; +int main() { + const TDT4102::Point buttonPosition {100, 100}; const unsigned int buttonWidth = 100; const unsigned int buttonHeight = 40; const string buttonLabel = "Click me!"; - Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel}; + TDT4102::Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel}; - AnimationWindow window; + TDT4102::AnimationWindow window; window.add(button); button.setCallback(buttonClicked); - button.setButtonColor(Color::silver); + button.setButtonColor(TDT4102::Color::silver); window.wait_for_close(); return 0; } @@ -176,43 +168,41 @@ int main() Merk at vi mÃ¥ først inkludere headeren til `TDT4102::Button` klassen ved Ã¥ skrive `#include "widgets/Button.h"` øverst i filen. -Deretter lager vi en knapp ved Ã¥ instansiere `TDT4102::Button` klassen, som har følgende konstruktøren: +Deretter lager vi en knapp ved Ã¥ instansiere `TDT4102::Button` klassen, som har følgende konstruktør: ```c++ -Button(TDT4102::Point location, unsigned int width, unsigned int height, std::string label); +TDT4102::Button(TDT4102::Point location, unsigned int width, unsigned int height, std::string label); ``` -Her definerer `TDT4102::Point location` hvor knappen skal plasseres pÃ¥ skjermen, `width` og `height` størrelsen, og `label` teksten som skal vises pÃ¥ knappen. Vi bruker `add()` og `setCallback()` funksjonene Ã¥ sørge for at knappen blir synlig i vinduet, og at det skjer noe nÃ¥r vi klikker pÃ¥ den. +Her definerer `TDT4102::Point location` hvor knappen skal plasseres pÃ¥ skjermen, `width` og `height` størrelsen, og `label` teksten som skal vises pÃ¥ knappen. Vi bruker `add()` og `setCallback()` funksjonene for Ã¥ sørge at knappen blir synlig i vinduet, og at det skjer noe nÃ¥r vi klikker pÃ¥ den. Callback funksjonen blir kalt hver gang brukeren klikker pÃ¥ knappen. Buttonklassen har diverse funksjoner for Ã¥ endre pÃ¥ utseende. ```c++ void setLabel(std::string newLabel); -void setLabelColor(Color newColor); -void setButtonColor(Color newColor); -void setButtonColorHover(Color newColor); -void setButtonColorActive(Color newColor); +void setLabelColor(TDT4102::Color newColor); +void setButtonColor(TDT4102::Color newColor); +void setButtonColorHover(TDT4102::Color newColor); +void setButtonColorActive(TDT4102::Color newColor); ``` -Du kan endre tekst og tekstfarge med `setLabel` og `setLabelColor`. Du kan endre fargen for knappen med `setButtonColor`, fargen nÃ¥r du har musen over med `setButtonColorHover` og fargen pÃ¥ knappen nÃ¥r den er trykket ned med `setButtonColorActive`. +Du kan endre tekst og tekstfarge med `setLabel` og `setLabelColor`. Du kan endre fargen for knappen med `setButtonColor`, fargen nÃ¥r du har musepekeren over med `setButtonColorHover` og fargen pÃ¥ knappen nÃ¥r den er trykket ned med `setButtonColorActive`. ### Tekst felt ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" #include "widgets/TextInput.h" -TextInput textField {{100, 100}, 300, 30, "This text field is small!"}; +TDT4102::TextInput textField {{100, 100}, 300, 30, "This text field is small!"}; void textFieldChanged() { std::cout << "The text field now contains: " << textField.getText() << std::endl; } -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; window.add(textField); textField.setCallback(textFieldChanged); window.wait_for_close(); @@ -221,19 +211,17 @@ int main() ``` ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" #include "widgets/TextInput.h" -TextInput textField {{100, 100}, 300, 150, "This text field\ncontains more than\none line of text!"}; +TDT4102::TextInput textField {{100, 100}, 300, 150, "This text field\ncontains more than\none line of text!"}; void textFieldChanged() { std::cout << "The text field now contains: " << textField.getText() << std::endl; } -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; window.add(textField); textField.setCallback(textFieldChanged); window.wait_for_close(); @@ -244,12 +232,11 @@ int main() ### Dropdown list ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" #include "widgets/DropdownList.h" std::vector<std::string> options {"Hello", "There", "General", "You", "Are", "A", "Bold", "One"}; -DropdownList list({100, 100}, 300, 30, options); +TDT4102::DropdownList list({100, 100}, 300, 30, options); void handle() { std::cout << "Selected: " << list.getValue() << std::endl; @@ -257,7 +244,7 @@ void handle() { int main() { - AnimationWindow window; + TDT4102::AnimationWindow window; window.add(list); list.setCallback(handle); window.wait_for_close(); diff --git a/docs/animationwindow/helpers.md b/docs/animationwindow/helpers.md index 35ad6e3..fe00494 100644 --- a/docs/animationwindow/helpers.md +++ b/docs/animationwindow/helpers.md @@ -63,153 +63,153 @@ Det er vanligvis langt lettere Ã¥ bruke en forhÃ¥ndsdefinert farge i stedet for <table> <tr><td style="font-weight: bold;">Color verdi</td><td style="font-weight: bold;">Farge</td></tr> -<tr><td>Color::transparent</td><td style="background-color: rgba(0, 0, 0, 1);">(transparant)</td></tr> -<tr><td>Color::black</td><td style="background-color:#000000;"></td></tr> -<tr><td>Color::silver</td><td style="background-color:#c0c0c0;"></td></tr> -<tr><td>Color::gray</td><td style="background-color:#808080;"></td></tr> -<tr><td>Color::white</td><td style="background-color:#ffffff;"></td></tr> -<tr><td>Color::maroon</td><td style="background-color:#800000;"></td></tr> -<tr><td>Color::red</td><td style="background-color:#ff0000;"></td></tr> -<tr><td>Color::purple</td><td style="background-color:#800080;"></td></tr> -<tr><td>Color::magenta</td><td style="background-color:#ff00ff;"></td></tr> -<tr><td>Color::green</td><td style="background-color:#008000;"></td></tr> -<tr><td>Color::lime</td><td style="background-color:#00ff00;"></td></tr> -<tr><td>Color::olive</td><td style="background-color:#808000;"></td></tr> -<tr><td>Color::yellow</td><td style="background-color:#ffff00;"></td></tr> -<tr><td>Color::navy</td><td style="background-color:#000080;"></td></tr> -<tr><td>Color::blue</td><td style="background-color:#0000ff;"></td></tr> -<tr><td>Color::teal</td><td style="background-color:#008080;"></td></tr> -<tr><td>Color::aqua</td><td style="background-color:#00ffff;"></td></tr> -<tr><td>Color::orange</td><td style="background-color:#ffa500;"></td></tr> -<tr><td>Color::alice_blue</td><td style="background-color:#f0f8ff;"></td></tr> -<tr><td>Color::antique_white</td><td style="background-color:#faebd7;"></td></tr> -<tr><td>Color::aquamarine</td><td style="background-color:#7fffd4;"></td></tr> -<tr><td>Color::azure</td><td style="background-color:#f0ffff;"></td></tr> -<tr><td>Color::beige</td><td style="background-color:#f5f5dc;"></td></tr> -<tr><td>Color::bisque</td><td style="background-color:#ffe4c4;"></td></tr> -<tr><td>Color::blanched_almond</td><td style="background-color:#ffebcd;"></td></tr> -<tr><td>Color::blue_violet</td><td style="background-color:#8a2be2;"></td></tr> -<tr><td>Color::brown</td><td style="background-color:#a52a2a;"></td></tr> -<tr><td>Color::burly_wood</td><td style="background-color:#deb887;"></td></tr> -<tr><td>Color::cadet_blue</td><td style="background-color:#5f9ea0;"></td></tr> -<tr><td>Color::chart_reuse</td><td style="background-color:#7fff00;"></td></tr> -<tr><td>Color::chocolate</td><td style="background-color:#d2691e;"></td></tr> -<tr><td>Color::coral</td><td style="background-color:#ff7f50;"></td></tr> -<tr><td>Color::cornflower_blue</td><td style="background-color:#6495ed;"></td></tr> -<tr><td>Color::corn_silk</td><td style="background-color:#fff8dc;"></td></tr> -<tr><td>Color::crimson</td><td style="background-color:#dc143c;"></td></tr> -<tr><td>Color::cyan</td><td style="background-color:#00ffff;"></td></tr> -<tr><td>Color::dark_blue</td><td style="background-color:#00008b;"></td></tr> -<tr><td>Color::dark_cyan</td><td style="background-color:#008b8b;"></td></tr> -<tr><td>Color::dark_goldenrod</td><td style="background-color:#b8860b;"></td></tr> -<tr><td>Color::dark_gray</td><td style="background-color:#a9a9a9;"></td></tr> -<tr><td>Color::dark_green</td><td style="background-color:#006400;"></td></tr> -<tr><td>Color::dark_grey</td><td style="background-color:#a9a9a9;"></td></tr> -<tr><td>Color::dark_khaki</td><td style="background-color:#bdb76b;"></td></tr> -<tr><td>Color::dark_magenta</td><td style="background-color:#8b008b;"></td></tr> -<tr><td>Color::dark_olivegreen</td><td style="background-color:#556b2f;"></td></tr> -<tr><td>Color::dark_orange</td><td style="background-color:#ff8c00;"></td></tr> -<tr><td>Color::dark_orchid</td><td style="background-color:#9932cc;"></td></tr> -<tr><td>Color::dark_red</td><td style="background-color:#8b0000;"></td></tr> -<tr><td>Color::dark_salmon</td><td style="background-color:#e9967a;"></td></tr> -<tr><td>Color::dark_seagreen</td><td style="background-color:#8fbc8f;"></td></tr> -<tr><td>Color::dark_slateblue</td><td style="background-color:#483d8b;"></td></tr> -<tr><td>Color::dark_slategray</td><td style="background-color:#2f4f4f;"></td></tr> -<tr><td>Color::dark_slategrey</td><td style="background-color:#2f4f4f;"></td></tr> -<tr><td>Color::dark_turquoise</td><td style="background-color:#00ced1;"></td></tr> -<tr><td>Color::dark_violet</td><td style="background-color:#9400d3;"></td></tr> -<tr><td>Color::deep_pink</td><td style="background-color:#ff1493;"></td></tr> -<tr><td>Color::deep_skyblue</td><td style="background-color:#00bfff;"></td></tr> -<tr><td>Color::dim_gray</td><td style="background-color:#696969;"></td></tr> -<tr><td>Color::dim_grey</td><td style="background-color:#696969;"></td></tr> -<tr><td>Color::dodger_blue</td><td style="background-color:#1e90ff;"></td></tr> -<tr><td>Color::firebrick</td><td style="background-color:#b22222;"></td></tr> -<tr><td>Color::floral_white</td><td style="background-color:#fffaf0;"></td></tr> -<tr><td>Color::forest_green</td><td style="background-color:#228b22;"></td></tr> -<tr><td>Color::gainsboro</td><td style="background-color:#dcdcdc;"></td></tr> -<tr><td>Color::ghost_white</td><td style="background-color:#f8f8ff;"></td></tr> -<tr><td>Color::gold</td><td style="background-color:#ffd700;"></td></tr> -<tr><td>Color::goldenrod</td><td style="background-color:#daa520;"></td></tr> -<tr><td>Color::green_yellow</td><td style="background-color:#adff2f;"></td></tr> -<tr><td>Color::grey</td><td style="background-color:#808080;"></td></tr> -<tr><td>Color::honeydew</td><td style="background-color:#f0fff0;"></td></tr> -<tr><td>Color::hot_pink</td><td style="background-color:#ff69b4;"></td></tr> -<tr><td>Color::indian_red</td><td style="background-color:#cd5c5c;"></td></tr> -<tr><td>Color::indigo</td><td style="background-color:#4b0082;"></td></tr> -<tr><td>Color::ivory</td><td style="background-color:#fffff0;"></td></tr> -<tr><td>Color::khaki</td><td style="background-color:#f0e68c;"></td></tr> -<tr><td>Color::lavender</td><td style="background-color:#e6e6fa;"></td></tr> -<tr><td>Color::lavender_blush</td><td style="background-color:#fff0f5;"></td></tr> -<tr><td>Color::lawn_green</td><td style="background-color:#7cfc00;"></td></tr> -<tr><td>Color::lemon_chiffon</td><td style="background-color:#fffacd;"></td></tr> -<tr><td>Color::light_blue</td><td style="background-color:#add8e6;"></td></tr> -<tr><td>Color::light_coral</td><td style="background-color:#f08080;"></td></tr> -<tr><td>Color::light_cyan</td><td style="background-color:#e0ffff;"></td></tr> -<tr><td>Color::light_goldenrodyellow</td><td style="background-color:#fafad2;"></td></tr> -<tr><td>Color::light_gray</td><td style="background-color:#d3d3d3;"></td></tr> -<tr><td>Color::light_green</td><td style="background-color:#90ee90;"></td></tr> -<tr><td>Color::light_grey</td><td style="background-color:#d3d3d3;"></td></tr> -<tr><td>Color::light_pink</td><td style="background-color:#ffb6c1;"></td></tr> -<tr><td>Color::light_salmon</td><td style="background-color:#ffa07a;"></td></tr> -<tr><td>Color::light_sea_green</td><td style="background-color:#20b2aa;"></td></tr> -<tr><td>Color::light_sky_blue</td><td style="background-color:#87cefa;"></td></tr> -<tr><td>Color::light_slate_gray</td><td style="background-color:#778899;"></td></tr> -<tr><td>Color::light_slate_grey</td><td style="background-color:#778899;"></td></tr> -<tr><td>Color::light_steel_blue</td><td style="background-color:#b0c4de;"></td></tr> -<tr><td>Color::light_yellow</td><td style="background-color:#ffffe0;"></td></tr> -<tr><td>Color::lime_green</td><td style="background-color:#32cd32;"></td></tr> -<tr><td>Color::linen</td><td style="background-color:#faf0e6;"></td></tr> -<tr><td>Color::medium_aquamarine</td><td style="background-color:#66cdaa;"></td></tr> -<tr><td>Color::medium_blue</td><td style="background-color:#0000cd;"></td></tr> -<tr><td>Color::medium_orchid</td><td style="background-color:#ba55d3;"></td></tr> -<tr><td>Color::medium_purple</td><td style="background-color:#9370db;"></td></tr> -<tr><td>Color::medium_sea_green</td><td style="background-color:#3cb371;"></td></tr> -<tr><td>Color::medium_slate_blue</td><td style="background-color:#7b68ee;"></td></tr> -<tr><td>Color::medium_spring_green</td><td style="background-color:#00fa9a;"></td></tr> -<tr><td>Color::medium_turquoise</td><td style="background-color:#48d1cc;"></td></tr> -<tr><td>Color::medium_violet_red</td><td style="background-color:#c71585;"></td></tr> -<tr><td>Color::midnight_blue</td><td style="background-color:#191970;"></td></tr> -<tr><td>Color::mint_cream</td><td style="background-color:#f5fffa;"></td></tr> -<tr><td>Color::misty_rose</td><td style="background-color:#ffe4e1;"></td></tr> -<tr><td>Color::moccasin</td><td style="background-color:#ffe4b5;"></td></tr> -<tr><td>Color::navajo_white</td><td style="background-color:#ffdead;"></td></tr> -<tr><td>Color::old_lace</td><td style="background-color:#fdf5e6;"></td></tr> -<tr><td>Color::olivedrab</td><td style="background-color:#6b8e23;"></td></tr> -<tr><td>Color::orange_red</td><td style="background-color:#ff4500;"></td></tr> -<tr><td>Color::orchid</td><td style="background-color:#da70d6;"></td></tr> -<tr><td>Color::pale_goldenrod</td><td style="background-color:#eee8aa;"></td></tr> -<tr><td>Color::pale_green</td><td style="background-color:#98fb98;"></td></tr> -<tr><td>Color::pale_turquoise</td><td style="background-color:#afeeee;"></td></tr> -<tr><td>Color::pale_violet_red</td><td style="background-color:#db7093;"></td></tr> -<tr><td>Color::papayawhip</td><td style="background-color:#ffefd5;"></td></tr> -<tr><td>Color::peachpuff</td><td style="background-color:#ffdab9;"></td></tr> -<tr><td>Color::peru</td><td style="background-color:#cd853f;"></td></tr> -<tr><td>Color::pink</td><td style="background-color:#ffc0cb;"></td></tr> -<tr><td>Color::plum</td><td style="background-color:#dda0dd;"></td></tr> -<tr><td>Color::powder_blue</td><td style="background-color:#b0e0e6;"></td></tr> -<tr><td>Color::rosy_brown</td><td style="background-color:#bc8f8f;"></td></tr> -<tr><td>Color::royal_blue</td><td style="background-color:#4169e1;"></td></tr> -<tr><td>Color::saddle_brown</td><td style="background-color:#8b4513;"></td></tr> -<tr><td>Color::salmon</td><td style="background-color:#fa8072;"></td></tr> -<tr><td>Color::sandy_brown</td><td style="background-color:#f4a460;"></td></tr> -<tr><td>Color::sea_green</td><td style="background-color:#2e8b57;"></td></tr> -<tr><td>Color::sea_shell</td><td style="background-color:#fff5ee;"></td></tr> -<tr><td>Color::sienna</td><td style="background-color:#a0522d;"></td></tr> -<tr><td>Color::sky_blue</td><td style="background-color:#87ceeb;"></td></tr> -<tr><td>Color::slate_blue</td><td style="background-color:#6a5acd;"></td></tr> -<tr><td>Color::slate_gray</td><td style="background-color:#708090;"></td></tr> -<tr><td>Color::slate_grey</td><td style="background-color:#708090;"></td></tr> -<tr><td>Color::snow</td><td style="background-color:#fffafa;"></td></tr> -<tr><td>Color::spring_green</td><td style="background-color:#00ff7f;"></td></tr> -<tr><td>Color::steel_blue</td><td style="background-color:#4682b4;"></td></tr> -<tr><td>Color::tan</td><td style="background-color:#d2b48c;"></td></tr> -<tr><td>Color::thistle</td><td style="background-color:#d8bfd8;"></td></tr> -<tr><td>Color::fuchsia</td><td style="background-color:#ff00ff;"></td></tr> -<tr><td>Color::tomato</td><td style="background-color:#ff6347;"></td></tr> -<tr><td>Color::turquoise</td><td style="background-color:#40e0d0;"></td></tr> -<tr><td>Color::violet</td><td style="background-color:#ee82ee;"></td></tr> -<tr><td>Color::wheat</td><td style="background-color:#f5deb3;"></td></tr> -<tr><td>Color::white_smoke</td><td style="background-color:#f5f5f5;"></td></tr> -<tr><td>Color::yellow_green</td><td style="background-color:#9acd32;"></td></tr> -<tr><td>Color::rebecca_purple</td><td style="background-color:#663399;"></td></tr> +<tr><td>TDT4102::Color::transparent</td><td style="background-color: rgba(0, 0, 0, 1);">(transparant)</td></tr> +<tr><td>TDT4102::Color::black</td><td style="background-color:#000000;"></td></tr> +<tr><td>TDT4102::Color::silver</td><td style="background-color:#c0c0c0;"></td></tr> +<tr><td>TDT4102::Color::gray</td><td style="background-color:#808080;"></td></tr> +<tr><td>TDT4102::Color::white</td><td style="background-color:#ffffff;"></td></tr> +<tr><td>TDT4102::Color::maroon</td><td style="background-color:#800000;"></td></tr> +<tr><td>TDT4102::Color::red</td><td style="background-color:#ff0000;"></td></tr> +<tr><td>TDT4102::Color::purple</td><td style="background-color:#800080;"></td></tr> +<tr><td>TDT4102::Color::magenta</td><td style="background-color:#ff00ff;"></td></tr> +<tr><td>TDT4102::Color::green</td><td style="background-color:#008000;"></td></tr> +<tr><td>TDT4102::Color::lime</td><td style="background-color:#00ff00;"></td></tr> +<tr><td>TDT4102::Color::olive</td><td style="background-color:#808000;"></td></tr> +<tr><td>TDT4102::Color::yellow</td><td style="background-color:#ffff00;"></td></tr> +<tr><td>TDT4102::Color::navy</td><td style="background-color:#000080;"></td></tr> +<tr><td>TDT4102::Color::blue</td><td style="background-color:#0000ff;"></td></tr> +<tr><td>TDT4102::Color::teal</td><td style="background-color:#008080;"></td></tr> +<tr><td>TDT4102::Color::aqua</td><td style="background-color:#00ffff;"></td></tr> +<tr><td>TDT4102::Color::orange</td><td style="background-color:#ffa500;"></td></tr> +<tr><td>TDT4102::Color::alice_blue</td><td style="background-color:#f0f8ff;"></td></tr> +<tr><td>TDT4102::Color::antique_white</td><td style="background-color:#faebd7;"></td></tr> +<tr><td>TDT4102::Color::aquamarine</td><td style="background-color:#7fffd4;"></td></tr> +<tr><td>TDT4102::Color::azure</td><td style="background-color:#f0ffff;"></td></tr> +<tr><td>TDT4102::Color::beige</td><td style="background-color:#f5f5dc;"></td></tr> +<tr><td>TDT4102::Color::bisque</td><td style="background-color:#ffe4c4;"></td></tr> +<tr><td>TDT4102::Color::blanched_almond</td><td style="background-color:#ffebcd;"></td></tr> +<tr><td>TDT4102::Color::blue_violet</td><td style="background-color:#8a2be2;"></td></tr> +<tr><td>TDT4102::Color::brown</td><td style="background-color:#a52a2a;"></td></tr> +<tr><td>TDT4102::Color::burly_wood</td><td style="background-color:#deb887;"></td></tr> +<tr><td>TDT4102::Color::cadet_blue</td><td style="background-color:#5f9ea0;"></td></tr> +<tr><td>TDT4102::Color::chart_reuse</td><td style="background-color:#7fff00;"></td></tr> +<tr><td>TDT4102::Color::chocolate</td><td style="background-color:#d2691e;"></td></tr> +<tr><td>TDT4102::Color::coral</td><td style="background-color:#ff7f50;"></td></tr> +<tr><td>TDT4102::Color::cornflower_blue</td><td style="background-color:#6495ed;"></td></tr> +<tr><td>TDT4102::Color::corn_silk</td><td style="background-color:#fff8dc;"></td></tr> +<tr><td>TDT4102::Color::crimson</td><td style="background-color:#dc143c;"></td></tr> +<tr><td>TDT4102::Color::cyan</td><td style="background-color:#00ffff;"></td></tr> +<tr><td>TDT4102::Color::dark_blue</td><td style="background-color:#00008b;"></td></tr> +<tr><td>TDT4102::Color::dark_cyan</td><td style="background-color:#008b8b;"></td></tr> +<tr><td>TDT4102::Color::dark_goldenrod</td><td style="background-color:#b8860b;"></td></tr> +<tr><td>TDT4102::Color::dark_gray</td><td style="background-color:#a9a9a9;"></td></tr> +<tr><td>TDT4102::Color::dark_green</td><td style="background-color:#006400;"></td></tr> +<tr><td>TDT4102::Color::dark_grey</td><td style="background-color:#a9a9a9;"></td></tr> +<tr><td>TDT4102::Color::dark_khaki</td><td style="background-color:#bdb76b;"></td></tr> +<tr><td>TDT4102::Color::dark_magenta</td><td style="background-color:#8b008b;"></td></tr> +<tr><td>TDT4102::Color::dark_olivegreen</td><td style="background-color:#556b2f;"></td></tr> +<tr><td>TDT4102::Color::dark_orange</td><td style="background-color:#ff8c00;"></td></tr> +<tr><td>TDT4102::Color::dark_orchid</td><td style="background-color:#9932cc;"></td></tr> +<tr><td>TDT4102::Color::dark_red</td><td style="background-color:#8b0000;"></td></tr> +<tr><td>TDT4102::Color::dark_salmon</td><td style="background-color:#e9967a;"></td></tr> +<tr><td>TDT4102::Color::dark_seagreen</td><td style="background-color:#8fbc8f;"></td></tr> +<tr><td>TDT4102::Color::dark_slateblue</td><td style="background-color:#483d8b;"></td></tr> +<tr><td>TDT4102::Color::dark_slategray</td><td style="background-color:#2f4f4f;"></td></tr> +<tr><td>TDT4102::Color::dark_slategrey</td><td style="background-color:#2f4f4f;"></td></tr> +<tr><td>TDT4102::Color::dark_turquoise</td><td style="background-color:#00ced1;"></td></tr> +<tr><td>TDT4102::Color::dark_violet</td><td style="background-color:#9400d3;"></td></tr> +<tr><td>TDT4102::Color::deep_pink</td><td style="background-color:#ff1493;"></td></tr> +<tr><td>TDT4102::Color::deep_skyblue</td><td style="background-color:#00bfff;"></td></tr> +<tr><td>TDT4102::Color::dim_gray</td><td style="background-color:#696969;"></td></tr> +<tr><td>TDT4102::Color::dim_grey</td><td style="background-color:#696969;"></td></tr> +<tr><td>TDT4102::Color::dodger_blue</td><td style="background-color:#1e90ff;"></td></tr> +<tr><td>TDT4102::Color::firebrick</td><td style="background-color:#b22222;"></td></tr> +<tr><td>TDT4102::Color::floral_white</td><td style="background-color:#fffaf0;"></td></tr> +<tr><td>TDT4102::Color::forest_green</td><td style="background-color:#228b22;"></td></tr> +<tr><td>TDT4102::Color::gainsboro</td><td style="background-color:#dcdcdc;"></td></tr> +<tr><td>TDT4102::Color::ghost_white</td><td style="background-color:#f8f8ff;"></td></tr> +<tr><td>TDT4102::Color::gold</td><td style="background-color:#ffd700;"></td></tr> +<tr><td>TDT4102::Color::goldenrod</td><td style="background-color:#daa520;"></td></tr> +<tr><td>TDT4102::Color::green_yellow</td><td style="background-color:#adff2f;"></td></tr> +<tr><td>TDT4102::Color::grey</td><td style="background-color:#808080;"></td></tr> +<tr><td>TDT4102::Color::honeydew</td><td style="background-color:#f0fff0;"></td></tr> +<tr><td>TDT4102::Color::hot_pink</td><td style="background-color:#ff69b4;"></td></tr> +<tr><td>TDT4102::Color::indian_red</td><td style="background-color:#cd5c5c;"></td></tr> +<tr><td>TDT4102::Color::indigo</td><td style="background-color:#4b0082;"></td></tr> +<tr><td>TDT4102::Color::ivory</td><td style="background-color:#fffff0;"></td></tr> +<tr><td>TDT4102::Color::khaki</td><td style="background-color:#f0e68c;"></td></tr> +<tr><td>TDT4102::Color::lavender</td><td style="background-color:#e6e6fa;"></td></tr> +<tr><td>TDT4102::Color::lavender_blush</td><td style="background-color:#fff0f5;"></td></tr> +<tr><td>TDT4102::Color::lawn_green</td><td style="background-color:#7cfc00;"></td></tr> +<tr><td>TDT4102::Color::lemon_chiffon</td><td style="background-color:#fffacd;"></td></tr> +<tr><td>TDT4102::Color::light_blue</td><td style="background-color:#add8e6;"></td></tr> +<tr><td>TDT4102::Color::light_coral</td><td style="background-color:#f08080;"></td></tr> +<tr><td>TDT4102::Color::light_cyan</td><td style="background-color:#e0ffff;"></td></tr> +<tr><td>TDT4102::Color::light_goldenrodyellow</td><td style="background-color:#fafad2;"></td></tr> +<tr><td>TDT4102::Color::light_gray</td><td style="background-color:#d3d3d3;"></td></tr> +<tr><td>TDT4102::Color::light_green</td><td style="background-color:#90ee90;"></td></tr> +<tr><td>TDT4102::Color::light_grey</td><td style="background-color:#d3d3d3;"></td></tr> +<tr><td>TDT4102::Color::light_pink</td><td style="background-color:#ffb6c1;"></td></tr> +<tr><td>TDT4102::Color::light_salmon</td><td style="background-color:#ffa07a;"></td></tr> +<tr><td>TDT4102::Color::light_sea_green</td><td style="background-color:#20b2aa;"></td></tr> +<tr><td>TDT4102::Color::light_sky_blue</td><td style="background-color:#87cefa;"></td></tr> +<tr><td>TDT4102::Color::light_slate_gray</td><td style="background-color:#778899;"></td></tr> +<tr><td>TDT4102::Color::light_slate_grey</td><td style="background-color:#778899;"></td></tr> +<tr><td>TDT4102::Color::light_steel_blue</td><td style="background-color:#b0c4de;"></td></tr> +<tr><td>TDT4102::Color::light_yellow</td><td style="background-color:#ffffe0;"></td></tr> +<tr><td>TDT4102::Color::lime_green</td><td style="background-color:#32cd32;"></td></tr> +<tr><td>TDT4102::Color::linen</td><td style="background-color:#faf0e6;"></td></tr> +<tr><td>TDT4102::Color::medium_aquamarine</td><td style="background-color:#66cdaa;"></td></tr> +<tr><td>TDT4102::Color::medium_blue</td><td style="background-color:#0000cd;"></td></tr> +<tr><td>TDT4102::Color::medium_orchid</td><td style="background-color:#ba55d3;"></td></tr> +<tr><td>TDT4102::Color::medium_purple</td><td style="background-color:#9370db;"></td></tr> +<tr><td>TDT4102::Color::medium_sea_green</td><td style="background-color:#3cb371;"></td></tr> +<tr><td>TDT4102::Color::medium_slate_blue</td><td style="background-color:#7b68ee;"></td></tr> +<tr><td>TDT4102::Color::medium_spring_green</td><td style="background-color:#00fa9a;"></td></tr> +<tr><td>TDT4102::Color::medium_turquoise</td><td style="background-color:#48d1cc;"></td></tr> +<tr><td>TDT4102::Color::medium_violet_red</td><td style="background-color:#c71585;"></td></tr> +<tr><td>TDT4102::Color::midnight_blue</td><td style="background-color:#191970;"></td></tr> +<tr><td>TDT4102::Color::mint_cream</td><td style="background-color:#f5fffa;"></td></tr> +<tr><td>TDT4102::Color::misty_rose</td><td style="background-color:#ffe4e1;"></td></tr> +<tr><td>TDT4102::Color::moccasin</td><td style="background-color:#ffe4b5;"></td></tr> +<tr><td>TDT4102::Color::navajo_white</td><td style="background-color:#ffdead;"></td></tr> +<tr><td>TDT4102::Color::old_lace</td><td style="background-color:#fdf5e6;"></td></tr> +<tr><td>TDT4102::Color::olivedrab</td><td style="background-color:#6b8e23;"></td></tr> +<tr><td>TDT4102::Color::orange_red</td><td style="background-color:#ff4500;"></td></tr> +<tr><td>TDT4102::Color::orchid</td><td style="background-color:#da70d6;"></td></tr> +<tr><td>TDT4102::Color::pale_goldenrod</td><td style="background-color:#eee8aa;"></td></tr> +<tr><td>TDT4102::Color::pale_green</td><td style="background-color:#98fb98;"></td></tr> +<tr><td>TDT4102::Color::pale_turquoise</td><td style="background-color:#afeeee;"></td></tr> +<tr><td>TDT4102::Color::pale_violet_red</td><td style="background-color:#db7093;"></td></tr> +<tr><td>TDT4102::Color::papayawhip</td><td style="background-color:#ffefd5;"></td></tr> +<tr><td>TDT4102::Color::peachpuff</td><td style="background-color:#ffdab9;"></td></tr> +<tr><td>TDT4102::Color::peru</td><td style="background-color:#cd853f;"></td></tr> +<tr><td>TDT4102::Color::pink</td><td style="background-color:#ffc0cb;"></td></tr> +<tr><td>TDT4102::Color::plum</td><td style="background-color:#dda0dd;"></td></tr> +<tr><td>TDT4102::Color::powder_blue</td><td style="background-color:#b0e0e6;"></td></tr> +<tr><td>TDT4102::Color::rosy_brown</td><td style="background-color:#bc8f8f;"></td></tr> +<tr><td>TDT4102::Color::royal_blue</td><td style="background-color:#4169e1;"></td></tr> +<tr><td>TDT4102::Color::saddle_brown</td><td style="background-color:#8b4513;"></td></tr> +<tr><td>TDT4102::Color::salmon</td><td style="background-color:#fa8072;"></td></tr> +<tr><td>TDT4102::Color::sandy_brown</td><td style="background-color:#f4a460;"></td></tr> +<tr><td>TDT4102::Color::sea_green</td><td style="background-color:#2e8b57;"></td></tr> +<tr><td>TDT4102::Color::sea_shell</td><td style="background-color:#fff5ee;"></td></tr> +<tr><td>TDT4102::Color::sienna</td><td style="background-color:#a0522d;"></td></tr> +<tr><td>TDT4102::Color::sky_blue</td><td style="background-color:#87ceeb;"></td></tr> +<tr><td>TDT4102::Color::slate_blue</td><td style="background-color:#6a5acd;"></td></tr> +<tr><td>TDT4102::Color::slate_gray</td><td style="background-color:#708090;"></td></tr> +<tr><td>TDT4102::Color::slate_grey</td><td style="background-color:#708090;"></td></tr> +<tr><td>TDT4102::Color::snow</td><td style="background-color:#fffafa;"></td></tr> +<tr><td>TDT4102::Color::spring_green</td><td style="background-color:#00ff7f;"></td></tr> +<tr><td>TDT4102::Color::steel_blue</td><td style="background-color:#4682b4;"></td></tr> +<tr><td>TDT4102::Color::tan</td><td style="background-color:#d2b48c;"></td></tr> +<tr><td>TDT4102::Color::thistle</td><td style="background-color:#d8bfd8;"></td></tr> +<tr><td>TDT4102::Color::fuchsia</td><td style="background-color:#ff00ff;"></td></tr> +<tr><td>TDT4102::Color::tomato</td><td style="background-color:#ff6347;"></td></tr> +<tr><td>TDT4102::Color::turquoise</td><td style="background-color:#40e0d0;"></td></tr> +<tr><td>TDT4102::Color::violet</td><td style="background-color:#ee82ee;"></td></tr> +<tr><td>TDT4102::Color::wheat</td><td style="background-color:#f5deb3;"></td></tr> +<tr><td>TDT4102::Color::white_smoke</td><td style="background-color:#f5f5f5;"></td></tr> +<tr><td>TDT4102::Color::yellow_green</td><td style="background-color:#9acd32;"></td></tr> +<tr><td>TDT4102::Color::rebecca_purple</td><td style="background-color:#663399;"></td></tr> </table> diff --git a/docs/animationwindow/index.md b/docs/animationwindow/index.md index e676e80..f0a54e0 100644 --- a/docs/animationwindow/index.md +++ b/docs/animationwindow/index.md @@ -1,27 +1,24 @@ # AnimationWindow -AnimationWindow er grafikkbiblioteket vi bruker i faget, bÃ¥de i øvingene og pÃ¥ eksamen. Den brukes Ã¥ tegne enkle former som sirkler og linjer, og Ã¥ lage enkle grafiske brukergrensesnitt (GUI). +AnimationWindow er grafikkbiblioteket vi bruker i faget, bÃ¥de i øvingene og pÃ¥ eksamen. Det brukes til Ã¥ tegne enkle former som sirkler og linjer, og Ã¥ lage enkle grafiske brukergrensesnitt (GUI). ## Opprett et nytt vindu -For Ã¥ kunne Ã¥pne et AnimationWindow vindu er det nødvendig Ã¥ inkludere et par filer. Det gjør du ved Ã¥ lime inn disse linjene helt øverst i .cpp filen der du ønsker Ã¥ bruke AnimationWindow: +For Ã¥ kunne Ã¥pne et AnimationWindow vindu er det nødvendig Ã¥ inkludere header-filen `AnimationWindow.h` øverst i .cpp filen der du ønsker Ã¥ bruke AnimationWindow: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" ``` -Ved Ã¥ inkludere disse sÃ¥kalte «header» filene forteller du C++ hva et AnimationWindow er, og lar deg bruke det i programmet ditt. Vi kommer til Ã¥ forklare nærmere hvordan header filer fungerer i forelesningene. +Ved Ã¥ inkludere denne sÃ¥kalte «header» filen forteller du C++ hva et AnimationWindow er, og lar deg bruke det i programmet ditt. Vi kommer til Ã¥ forklare nærmere hvordan header filer fungerer i forelesningene. Her er et eksempelprogram som Ã¥pner et vindu: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; window.wait_for_close(); return 0; } @@ -32,15 +29,15 @@ int main() I dette programmet er det to linjer som er relevant: ```c++ - AnimationWindow window; + TDT4102::AnimationWindow window; window.wait_for_close(); ``` -Den første linjen oppretter vinduet ved Ã¥ deklarere en variabel med datatype «AnimationWindow». For Ã¥ forstÃ¥ meningen med den andre linjen, prøv Ã¥ fjerne den og kjøre programmet. Noen gang sÃ¥ skjer det ingenting, mens andre ganger vises et vindu i en kort periode. Dette skjer fordi programmet fortsetter Ã¥ kjøre etter vi oppretter `window` variabelen, og siden den har nÃ¥ kommet til slutten av `main()` funksjonen, avsluttes programmet som lukker vinduet automatisk. Vi mÃ¥ derfor sørge for at programmet venter fram til brukeren lukker vinduet, som vi kan gjøre ved Ã¥ bruke `wait_for_close()` funksjonen. +Den første linjen oppretter vinduet ved Ã¥ deklarere en variabel med datatype «TDT4102::AnimationWindow». For Ã¥ forstÃ¥ meningen med den andre linjen, prøv Ã¥ fjerne den og kjøre programmet. Noen gang sÃ¥ skjer det ingenting, mens andre ganger vises et vindu i en kort periode. Dette skjer fordi programmet fortsetter Ã¥ kjøre etter vi oppretter `window` variabelen, og siden den har nÃ¥ kommet til slutten av `main()` funksjonen, avsluttes programmet som lukker vinduet automatisk. Vi mÃ¥ derfor sørge for at programmet venter fram til brukeren lukker vinduet, som vi kan gjøre ved Ã¥ bruke `wait_for_close()` funksjonen. ## Lukke et vindu -Du kan lukke vinduet ved Ã¥ kalle medlemsfunksjonen `close()`. Dette kan for eksempel brukes i en callback funksjon til en quit knapp. +Du kan lukke vinduet ved Ã¥ kalle medlemsfunksjonen `close()`. Dette kan for eksempel brukes i en callback funksjon til en quit-knapp. ## Endre vinduets standardverdier @@ -52,10 +49,8 @@ Plassering pÃ¥ skjermen oppgis som x og y koordinat i piksler, mÃ¥lt fra vinduet ```c++ #include "AnimationWindow.h" -#include "std_lib_facilities.h" -int main() -{ +int main() { int windowPositionX = 300; int windowPositionY = 100; AnimationWindow window(windowPositionX, windowPositionY); @@ -75,10 +70,8 @@ Vinduets størrelse defineres som bredde og høyde: ```c++ #include "AnimationWindow.h" -#include "std_lib_facilities.h" -int main() -{ +int main() { int windowPositionX = 300; int windowPositionY = 100; int windowWidth = 500; @@ -102,15 +95,13 @@ Hvis du har bÃ¥de definert vinduets posisjon og størrelsen har du mulighet Ã¥ e ```c++ #include "AnimationWindow.h" -#include "std_lib_facilities.h" -int main() -{ +int main() { int windowPositionX = 300; int windowPositionY = 100; int windowWidth = 500; int windowHeight = 100; - string windowTitle = "Alternate window title"; + std::string windowTitle = "Alternate window title"; AnimationWindow window(windowPositionX, windowPositionY, windowWidth, windowHeight, windowTitle); window.wait_for_close(); diff --git a/docs/animationwindow/input.md b/docs/animationwindow/input.md index de95f47..5123b33 100644 --- a/docs/animationwindow/input.md +++ b/docs/animationwindow/input.md @@ -7,23 +7,21 @@ For Ã¥ finne ut hvor i vinduet musen befinner seg brukes det `get_mouse_coordinates()` funksjonen: ```c++ -TDT4102::Point AnimationWindow::get_mouse_coordinates(); +TDT4102::Point TDT4102::AnimationWindow::get_mouse_coordinates(); ``` -Merk at `AnimationWindow::` betyr at funksjonen er et medlemsfunksjon av `AnimationWindow` klassen. Funksjonen returnerer en instans av `Point` som representerer koordinatene hvor musen peker til relativ til øverst venstre hjørnet av vinduet (akkurat det samme koordinatsystem som brukes til tegning). Her er et eksempel som visualiserer koordinatene musene peker pÃ¥: +Merk at `AnimationWindow::` betyr at funksjonen er et medlemsfunksjon av `TDT4102::AnimationWindow` klassen. Funksjonen returnerer en instans av `TDT4102::Point` som representerer koordinatene hvor musen peker til relativ til øverst venstre hjørnet av vinduet (akkurat det samme koordinatsystem som brukes til tegning). Her er et eksempel som visualiserer koordinatene musene peker pÃ¥: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; while(!window.should_close()) { - Point mouseCoordinates = window.get_mouse_coordinates(); + TDT4102::Point mouseCoordinates = window.get_mouse_coordinates(); - string coordinateText = to_string(mouseCoordinates.x) + ", " + to_string(mouseCoordinates.y); + std::string coordinateText = std::to_string(mouseCoordinates.x) + ", " + std::to_string(mouseCoordinates.y); window.draw_text(mouseCoordinates, coordinateText); window.next_frame(); @@ -36,8 +34,8 @@ int main() Du kan sjekke om høyre eller venstre musetast er trykket ned med: ```c++ -bool AnimationWindow::is_left_mouse_button_down() const; -bool AnimationWindow::is_right_mouse_button_down() const; +bool TDT4102::AnimationWindow::is_left_mouse_button_down() const; +bool TDT4102::AnimationWindow::is_right_mouse_button_down() const; ``` @@ -48,18 +46,16 @@ Funksjonen returnerer `true` dersom musetasten er nede. For Ã¥ benytte deg av tastaturet kan du bruke `is_key_down()` funksjonen: ```c++ -bool AnimationWindow::is_key_down(KeyboardKey key); +bool TDT4102::AnimationWindow::is_key_down(KeyboardKey key); ``` `is_key_down()` funksjonen tar inn en tast pÃ¥ tastaturet som parameter, og returnerer `true` nÃ¥r tasten holdes ned, og ellers `false`. Tasten defineres som et verdi av `KeyboardKey`. For eksempel, her brukes R tasten Ã¥ endre fargen pÃ¥ et rektangel: ```c++ -#include "std_lib_facilities.h" #include "AnimationWindow.h" -int main() -{ - AnimationWindow window; +int main() { + TDT4102::AnimationWindow window; while(!window.should_close()) { bool rKeyIsPressed = window.is_key_down(KeyboardKey::R); @@ -84,6 +80,8 @@ Det finnes mange forskjellige taster som kan brukes i programmet. Her er et over <table> <tr><td style="font-weight: bold;">Tast</td><td style="font-weight: bold;">KeyboardKey verdi</td></tr> <tr><td>Bokstavtaster</td><td><code>KeyboardKey::A</code> til <code>KeyboardKey::Z</code></td></tr> +<tr><td>Norske bokstavtaster</td><td><code>KeyboardKey::AA</code><br> +<code>KeyBoardKey::AE</code><br><code>KeyboardKey::OO</code></td></tr> <tr><td>Talltaster</td><td><code>KeyboardKey::KEY_0</code> til <code>KeyboardKey::KEY_9</code></td></tr> <tr><td>Numpad: talltaster</td><td><code>KeyboardKey::NUMPAD_0</code> til <code>KeyboardKey::NUMPAD_9</code></td></tr> <tr><td>Numpad: spesialtaster</td><td><code>KeyboardKey::NUMPAD_COMMA</code><br> diff --git a/docs/troubleshooting/macos.md b/docs/troubleshooting/macos.md index 4dd30c6..3b92475 100644 --- a/docs/troubleshooting/macos.md +++ b/docs/troubleshooting/macos.md @@ -3,17 +3,13 @@ Det kan skje noe galt under installering eller under kjøring av et prosjekt. Under er det listet et par ting det kan være lurt Ã¥ sjekke hvis det dukker opp feilmeldinger pÃ¥ MacOS. Et generelt tips er Ã¥ kjøre `TDT4102: Force refresh of the course content` og `TDT4102: Perform health check of the setup` fra kommandopaletten for en kjapp sjekk av oppsettet. Hvis dette ikke løser problemet, og noe fortsatt er galt, gÃ¥ gjennom punktene under. -### Tillatelser - -Ã…pne Innstillinger og gÃ¥ inn i Generelt > Personvern og sikkerhet > Utviklerverktøy. BÃ¥de VS Code og Terminal trenger tillatelse til Ã¥ kjøre programvare, hvis en eller begge mangler sÃ¥ legg de til med `+` nede i venstre hjørne. - ### Filsti og mappe Pass pÃ¥ at mappen/prosjektet du jobber i ikke er syncet med en skytjeneste som ICloud, OneDrive, DropBox, Google Drive etc. Sjekk ogsÃ¥ at filstien ikke inneholder æøå og spesielle symboler som mellomrom, $, % o.l. Bindestrek og understrek gÃ¥r fint. ### Homebrew og XCode -Ã…pne Terminal og kjør `brew doctor`. Dersom noe feil, start fra toppen og kjør kommandoene som Homebrew foreslÃ¥r. Hvis Homebrew klager pÃ¥ versjonen av Mac'en, oppdater den. Hvis Homebrew klager pÃ¥ versjonen av `XCode` eller `Command Line Tools`, kjør `xcode-select -p` og lim inn filstien etter `sudo rm -rf `. Dette avinstallerer XCode og dette mÃ¥ installeres pÃ¥ nytt. Dette kan gjøres med `TDT4102: Install required tools` fra kommandopaletten i VS Code. +Ã…pne Terminal og kjør `brew doctor`. Dersom noe er feil, start fra toppen og kjør kommandoene som Homebrew foreslÃ¥r. Hvis Homebrew klager pÃ¥ versjonen av Mac'en, oppdater den. Hvis Homebrew klager pÃ¥ versjonen av `XCode` eller `Command Line Tools`, kjør `xcode-select -p` og lim inn filstien etter `sudo rm -rf `. Dette avinstallerer XCode og dette mÃ¥ installeres pÃ¥ nytt. Dette kan gjøres med `TDT4102: Install required tools` fra kommandopaletten i VS Code. ### Kjøring av program diff --git a/docs/troubleshooting/windows.md b/docs/troubleshooting/windows.md index 8180216..e5626ec 100644 --- a/docs/troubleshooting/windows.md +++ b/docs/troubleshooting/windows.md @@ -4,7 +4,7 @@ Det kan skje noe galt under installering eller under kjøring av et prosjekt. Un ### Meson og MinGW -Meson skal ligge under `C:\Program Files` og MinGW skal ligge under `C:\`. Hvis noen av mappene mangler, kjør `TDT4102: Install required tools`. +Meson skal ligge under `C:\Program Files` og TDT4102-mingw64 skal ligge under `C:\`. Hvis noen av mappene mangler, kjør `TDT4102: Install required tools`. ### Systemmiljøvariabler og PATH @@ -15,9 +15,6 @@ BÃ¥de Meson og MinGW mÃ¥ ligge pÃ¥ PATH og systemmiljøvariablene mÃ¥ være rikt Pass pÃ¥ at mappen/prosjektet du jobber i ikke er syncet med en skytjeneste som OneDrive, DropBox, Google Drive etc. Sjekk ogsÃ¥ at filstien ikke inneholder æøå og spesielle symboler som mellomrom, $, % o.l. Bindestrek og understrek gÃ¥r fint. -### Mappen `resources` er korrekt pakket ut -Ã…pne Kjør-menyen med Windows+r og skriv inn "%appdata%\Code\User\globalStorage\tdt4102ntnu.tdt4102-tools". Der skal det ligge en mappe som heter `resources`, hvis den heter noe mer enn bare `resources` sÃ¥ slett mappen og kjør `TDT1402: Force refresh of course content`. - ### Piazza Hvis ingen av punktene hjalp, sjekk om noen har spurt om noe lignende pÃ¥ Piazza eller lag et eget innlegg. \ No newline at end of file -- GitLab From 4b38882256babf418397df719d65a456d19e4873 Mon Sep 17 00:00:00 2001 From: Joakim Hunskaar <joakim.borge.hunskar@gmail.com> Date: Sat, 15 Jun 2024 17:55:14 +0200 Subject: [PATCH 2/4] renamed files and small cleanup in other files --- docs/animationwindow/{helpers.md => color.md} | 6 +++--- docs/animationwindow/gui.md | 2 -- docs/animationwindow/input.md | 2 +- docs/animationwindow/{index.md => window.md} | 0 mkdocs.yml | 4 ++-- 5 files changed, 6 insertions(+), 8 deletions(-) rename docs/animationwindow/{helpers.md => color.md} (96%) rename docs/animationwindow/{index.md => window.md} (100%) diff --git a/docs/animationwindow/helpers.md b/docs/animationwindow/color.md similarity index 96% rename from docs/animationwindow/helpers.md rename to docs/animationwindow/color.md index fe00494..f7c3c49 100644 --- a/docs/animationwindow/helpers.md +++ b/docs/animationwindow/color.md @@ -32,7 +32,7 @@ Klikk her Ã¥ velge farge: } function startup() { - colorPicker = document.getElementById("colorPicker"); + const colorPicker = document.getElementById("colorPicker"); colorPicker.addEventListener("change", colourSelectionChanged, false); colorPicker.setValue("#399AD5"); } @@ -48,7 +48,7 @@ Du kan enten lagre fargen i en egen variabel: Eller bruke verdien direkte, for eksempel som verdi av en funksjonsparameter: <div class="highlight"><pre id="__code_1"><span></span><button class="md-clipboard md-icon" title="Copy to clipboard" data-clipboard-target="#__code_1 > code"></button><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="n">TDT4102</span><span class="o">::</span><span class="n">Color</span><span class="p">(</span><span class="mi" id="red1">100</span><span class="p">,</span><span class="w"> </span><span class="mi" id="green1">100</span><span class="p">,</span><span class="w"> </span><span class="mi" id="blue1">100</span><span class="p">)</span><span class="w"></span></code></pre></div> -Farger kan representeres pÃ¥ forskjellige mÃ¥ter. Den mest vanlige formen er RGB verdier (Rødt, Grønt, og BlÃ¥tt), og blandes i forskjellige mengder for Ã¥ forme ønskede fargen. Disse pleier Ã¥ være verdier mellom 0 og 255 for hver farge-kanal, og det er de som brukes i de Color verdiene overfor. Prøv Ã¥ velge hvit og deretter svart, og se hva som skjer med de RGB-verdiene! +Farger kan representeres pÃ¥ forskjellige mÃ¥ter. Det mest vanlige formatet er RGB (Rødt, Grønt, BlÃ¥tt). De ulike kanalene blandes i forskjellige mengder for Ã¥ lage farger. Disse pleier Ã¥ være verdier mellom 0 og 255 og det er de som brukes i Color-klassen. Prøv Ã¥ velge hvit og deretter svart, og se hva som skjer med RGB-verdiene! <div class="highlight"><pre id="__code_3"><span></span><button class="md-clipboard md-icon" title="Copy to clipboard" data-clipboard-target="#__code_3 > code"></button><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">redChannel</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi" id="red2">0</span><span class="p">;</span><span class="w"></span> <a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">greenChannel</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi" id="green2">0</span><span class="p">;</span><span class="w"></span> @@ -59,7 +59,7 @@ Farger kan representeres pÃ¥ forskjellige mÃ¥ter. Den mest vanlige formen er RGB ## ForhÃ¥ndsdefinerte farger -Det er vanligvis langt lettere Ã¥ bruke en forhÃ¥ndsdefinert farge i stedet for Ã¥ mÃ¥tte lete etter RGB verdier (bleh) eller lignende. Derfor har vi forhÃ¥ndsdefinert en rekke farger for dere. De fargeverdiene du kan velge fra er vist i tabellen under. +Det er vanligvis lettere Ã¥ bruke en forhÃ¥ndsdefinert farge i stedet for Ã¥ mÃ¥tte lete etter RGB verdier. Derfor har vi forhÃ¥ndsdefinert en rekke farger. Fargeverdiene du kan velge fra er vist i tabellen under. <table> <tr><td style="font-weight: bold;">Color verdi</td><td style="font-weight: bold;">Farge</td></tr> diff --git a/docs/animationwindow/gui.md b/docs/animationwindow/gui.md index 7f8b870..43f7166 100644 --- a/docs/animationwindow/gui.md +++ b/docs/animationwindow/gui.md @@ -1,7 +1,5 @@ # Grafiske Brukergrensesnitt (GUI) -Grafiske brukergrensesnitt - ## Konstruksjon av grafiske grensesnitt Grafiske grensesnitt bestÃ¥r av en rekke GUI elementer som kalles `widgets`. Dette kan være knapper, tekstfelt eller dropdown-lister. diff --git a/docs/animationwindow/input.md b/docs/animationwindow/input.md index 5123b33..99831a4 100644 --- a/docs/animationwindow/input.md +++ b/docs/animationwindow/input.md @@ -46,7 +46,7 @@ Funksjonen returnerer `true` dersom musetasten er nede. For Ã¥ benytte deg av tastaturet kan du bruke `is_key_down()` funksjonen: ```c++ -bool TDT4102::AnimationWindow::is_key_down(KeyboardKey key); +bool TDT4102::AnimationWindow::is_key_down(KeyboardKey key) const; ``` `is_key_down()` funksjonen tar inn en tast pÃ¥ tastaturet som parameter, og returnerer `true` nÃ¥r tasten holdes ned, og ellers `false`. Tasten defineres som et verdi av `KeyboardKey`. For eksempel, her brukes R tasten Ã¥ endre fargen pÃ¥ et rektangel: diff --git a/docs/animationwindow/index.md b/docs/animationwindow/window.md similarity index 100% rename from docs/animationwindow/index.md rename to docs/animationwindow/window.md diff --git a/mkdocs.yml b/mkdocs.yml index ff47a96..c3c92b8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -44,12 +44,12 @@ markdown_extensions: nav: - Home: index.md - AnimationWindow: - - Ã…pne et nytt vindu: animationwindow/index.md + - Ã…pne et nytt vindu: animationwindow/window.md - Tegning: animationwindow/drawing.md - Animasjon: animationwindow/animation.md - Input med mus og tastatur: animationwindow/input.md - Grafiske brukergrensesnitt (GUI): animationwindow/gui.md - - Color-klassen: animationwindow/helpers.md + - Color-klassen: animationwindow/color.md - Installering: - Windows: installing/windows.md - MacOS: installing/macos.md -- GitLab From 51b1e84afa4abf169fab96ac403eaf67816659af Mon Sep 17 00:00:00 2001 From: Joakim Hunskaar <joakim.borge.hunskar@gmail.com> Date: Sun, 16 Jun 2024 18:54:32 +0200 Subject: [PATCH 3/4] more text on gui, removed obsolete instructions from linux and win --- docs/animationwindow/gui.md | 20 +++++++++++--------- docs/installing/linux.md | 2 -- docs/uninstalling/windows.md | 6 ------ 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/docs/animationwindow/gui.md b/docs/animationwindow/gui.md index 43f7166..5bdbc43 100644 --- a/docs/animationwindow/gui.md +++ b/docs/animationwindow/gui.md @@ -119,18 +119,14 @@ SuperManWindow::SuperManWindow() ## GUI Elementer -Hvert GUI element som kan brukes i en AnimationWindow er definert i sin egen klasse. Det vil si at nÃ¥r du for eksempel ønsker Ã¥ vise en knapp i vinduet, lager du en instans av `TDT4102::Button` klassen. I tillegg er det nødvendig Ã¥ legge til knappen i vinduet ved Ã¥ bruke medlemsfunksjonen: +Hvert GUI element som kan brukes i `TDT4102::AnimationWindow` er definert i sin egen klasse som arver fra `TDT4102::Widget`. GUI elementer som støttes er `TDT4102::Button` , `TDT4102::TextInput` og `TDT4102::DropdownList`. Hvis du for eksempel ønsker Ã¥ vise en knapp i vinduet, lager du en instans av `TDT4102::Button` klassen og legger den til i vinduet ved Ã¥ bruke medlemsfunksjonen: ```c++ -void AnimationWindow::add(TDT4102::Widget &widgetToAdd); +void TDT4102::AnimationWindow::add(TDT4102::Widget &widgetToAdd); ``` -Alle GUI elementer arver fra typen `Widget`. `Widget` har en funksjon for Ã¥ gjemme eller vise GUI elementene: +Hvis du ikke ønsker Ã¥ vise knappen med en gang, kan du kalle pÃ¥ funksjonen `setVisible(bool isVisible)` med `false` pÃ¥ knapp-variabelen for Ã¥ skjule elementet. Bruk `true` for Ã¥ vise elementet. -```c++ -void Widget::setVisible(bool isVisible); -``` -Denne funksjonen blir kalt med `true` for Ã¥ vise elementet og med `false` for Ã¥ skjule elementet. ### Knapp @@ -187,7 +183,9 @@ void setButtonColorActive(TDT4102::Color newColor); Du kan endre tekst og tekstfarge med `setLabel` og `setLabelColor`. Du kan endre fargen for knappen med `setButtonColor`, fargen nÃ¥r du har musepekeren over med `setButtonColorHover` og fargen pÃ¥ knappen nÃ¥r den er trykket ned med `setButtonColorActive`. -### Tekst felt +### Tekstfelt + +Et tekstfelt er et GUI element hvor man kan skrive inn tekst. Det er ogsÃ¥ mulig Ã¥ hente ut teksten som er i tekstfelet med funksjonen `TDT4102::TextInput::getText()`. ```c++ #include "AnimationWindow.h" @@ -208,6 +206,8 @@ int main() { } ``` +Tekstfeltene kan ogsÃ¥ være over flere linjer: + ```c++ #include "AnimationWindow.h" #include "widgets/TextInput.h" @@ -227,7 +227,9 @@ int main() { } ``` -### Dropdown list +### DropdownList + +Dropdown-liste har en liste med elementer som man kan velge mellom. Det valgte elementet henter vi ut med funksjonen `TDT4102::DropdownList::getValue()`. ```c++ #include "AnimationWindow.h" diff --git a/docs/installing/linux.md b/docs/installing/linux.md index 5f536be..27d9edc 100644 --- a/docs/installing/linux.md +++ b/docs/installing/linux.md @@ -16,8 +16,6 @@ Hvis man har snap installert kan man istedenfor laste ned Visual Studio Code med ## Hurtiginstallasjon -NB! Kun Debian, Ubuntu og derivater er støttet av hurtiginstallasjonsverktøyet - 1. Trykk pÃ¥ ++ctrl+shift+p++ for Ã¥ Ã¥pne kommandopalletten. 2. Skriv inn til du fÃ¥r opp kommandoen: `TDT4102: Install required tools` 3. ++enter++ for Ã¥ kjøre kommandoen diff --git a/docs/uninstalling/windows.md b/docs/uninstalling/windows.md index 1043c53..8f54761 100644 --- a/docs/uninstalling/windows.md +++ b/docs/uninstalling/windows.md @@ -1,17 +1,11 @@ # Avinstallering -Noen ganger kan det være gunstig Ã¥ ha en fresh install. Dessverre stiller ikke alle programmer med kompetente uninstallerere. Dette gjør dette dokumentet et forsøk pÃ¥ Ã¥ fikse. - Data fra extensions ligger under mappen `AppData`, denne er skjult by default. 1. `%appdata%/Code/User/globalStorage/tdt4102ntnu.tdt4102-tools`. Denne mappen MÃ… slettes. 2. `%appdata%/tdt4102`. Hele denne mappen kan trygt slettes. 3. Mer data finnes pÃ¥ `%userprofile%/.vscode/extensions/`. Der skal det ligge en mappe som heter noe med tdt4102 i. Den kan dere slette. -De to siste er ikke sÃ¥ farlig da de ikke brukes av den nye extension. - -**Visual Studio Build Tools** er ikke lengre i bruk sÃ¥ det kan avinstalleres om du ikke bruker det til noe annet. - ### Visual Studio Code VS Code er nesten aldri kilden til problemet da det bare er en teksteditor. Allikevel viser vi hvordan det avinstalleres: -- GitLab From b5a7ddded707f8943984c111ca38f63e4f96bd64 Mon Sep 17 00:00:00 2001 From: Joakim Hunskaar <joakim.borge.hunskar@gmail.com> Date: Mon, 17 Jun 2024 19:58:10 +0200 Subject: [PATCH 4/4] added images for widgets and more text --- docs/animationwindow/gui.md | 12 +++++++++--- docs/images/dropdownlist.png | Bin 0 -> 13994 bytes docs/images/textinput1.png | Bin 0 -> 12935 bytes docs/images/textinput2.png | Bin 0 -> 15932 bytes 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 docs/images/dropdownlist.png create mode 100644 docs/images/textinput1.png create mode 100644 docs/images/textinput2.png diff --git a/docs/animationwindow/gui.md b/docs/animationwindow/gui.md index 5bdbc43..ea72405 100644 --- a/docs/animationwindow/gui.md +++ b/docs/animationwindow/gui.md @@ -185,7 +185,9 @@ Du kan endre tekst og tekstfarge med `setLabel` og `setLabelColor`. Du kan endre ### Tekstfelt -Et tekstfelt er et GUI element hvor man kan skrive inn tekst. Det er ogsÃ¥ mulig Ã¥ hente ut teksten som er i tekstfelet med funksjonen `TDT4102::TextInput::getText()`. +Et tekstfelt er et GUI element hvor man kan skrive inn tekst. Det er ogsÃ¥ mulig Ã¥ hente ut teksten som er i tekstfelet med funksjonen `TDT4102::TextInput::getText()`. For Ã¥ skrive til et tekstfelt bruker vi funksjonen `TDT4102::TextInput::setText(std::string text)`. + +<img src="../../images/textinput1.png" alt="bilde som viser textinput" style="max-width:400px; width:100%;" /> ```c++ #include "AnimationWindow.h" @@ -208,6 +210,8 @@ int main() { Tekstfeltene kan ogsÃ¥ være over flere linjer: +<img src="../../images/textinput2.png" alt="bilde som viser textinput over flere linjer" style="max-width:400px; width:100%;" /> + ```c++ #include "AnimationWindow.h" #include "widgets/TextInput.h" @@ -229,7 +233,9 @@ int main() { ### DropdownList -Dropdown-liste har en liste med elementer som man kan velge mellom. Det valgte elementet henter vi ut med funksjonen `TDT4102::DropdownList::getValue()`. +Dropdown-liste har en liste med elementer som man kan velge mellom. Det valgte elementet henter vi ut med funksjonen `TDT4102::DropdownList::getSelectedValue()`. For Ã¥ endre pÃ¥ elementene i lista, kall pÃ¥ funksjonen `TDT4102::DropdownList::setOptions(std::vector<std::string> &updatedOptionsList)` med en vector som inneholder de nye elementene. + +<img src="../../images/dropdownlist.png" alt="bilde som viser dropdownliste" style="max-width:400px; width:100%;" /> ```c++ #include "AnimationWindow.h" @@ -239,7 +245,7 @@ std::vector<std::string> options {"Hello", "There", "General", "You", "Are", "A" TDT4102::DropdownList list({100, 100}, 300, 30, options); void handle() { - std::cout << "Selected: " << list.getValue() << std::endl; + std::cout << "Selected: " << list.getSelectedValue() << std::endl; } int main() diff --git a/docs/images/dropdownlist.png b/docs/images/dropdownlist.png new file mode 100644 index 0000000000000000000000000000000000000000..bfd84382cdbe0332c9a463ffab36761ea9b17ac8 GIT binary patch literal 13994 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 S`Ut?IEWfoqRd({y&;J`Q+QF;< literal 0 HcmV?d00001 diff --git a/docs/images/textinput1.png b/docs/images/textinput1.png new file mode 100644 index 0000000000000000000000000000000000000000..303c98c3884d75177f2faa785b6a7e22c00c091a GIT binary patch literal 12935 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 literal 0 HcmV?d00001 diff --git a/docs/images/textinput2.png b/docs/images/textinput2.png new file mode 100644 index 0000000000000000000000000000000000000000..e62be7076183fc4b6e658d70db6fdea309eecc8b GIT binary patch literal 15932 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 a_Q#pYYmHKeLqKK>&|i8Vq5t*FcmD?M61&a- literal 0 HcmV?d00001 -- GitLab