// September 2015 // Levee Patroller / Dijk Patrouille // This source file is (c) by Deltares. This source file is open source but only available to select users. Do not redistribute without written permission of Stichting Deltares, Delft, The Netherlands. // This header has been automatically generated. //============================================================================= // In game menu for filling in the questions associated with // a certain signal. Menu's used should be a subclass of this class. // Started from MenuObservationReport. // ------------------------------------------------------------ // Created by Maarten Wesselius // © 2006, GeoDelft // Date Id Modification // ????-??-?? wsl created // 2006-12-01 zmr questionlabels lenght changed // 2007-07-13 wsl added function SaveAnswers // 2007-11-13 zmr added esc functionality and X goes to MenuObservationMain //============================================================================= class MenuSignalQuestions extends GUIPage abstract DependsOn(SignalStringData); var string EN_Title, NL_Title, EN_Finish, NL_Finish, EN_ChosenBefore, NL_ChosenBefore, EN_NoteBook, NL_NoteBook; var SignalStringData DataObject; var int NrQuestions; // number of questions in menu var array EN_QuestionStrings, // one string per question: not all elements used!!! NL_QuestionStrings; var array EN_AnswerStrings; // one set of answer strings per question var array NL_AnswerStrings; // for AnswerStructs, see class SignalStringData var GeoPlayerController GeoPC; var QAHashTable HashTable; var float CheckBoxHeight; var float QuestionHeight; var float MenuHeight, MenuWidth; var float ButtonHGap; var float ButtonVGapSmall; var float ButtonVGapLarge; var float BarHeight; var float BarVPos; var float SButtonSize; var float SButtonVGap; var float SButtonHGap; var float TitleLeftGap; var int HelpMenuOption; function InitComponent(GUIController MyController, GUIComponent MyOwner) { local int q, a, val; local string key; local GUILabel tempLabel; local moCheckBox tempCheckBox; local float lastTop, lastLeft, questionLeft, lastAnswerWidth; Super.InitComponent(MyController, MyOwner); OnKeyEvent = InternalOnKeyEvent; OnClose = InternalOnClose; // initialize GeoPC and adjust language accordingly GeoPC=GeoPlayerController(PlayerOwner()); if(GeoPC!=None) UpdateLanguage(); else log("ERROR WITH TYPE OF GAME"); // Menu Background Controls[0].WinWidth = MenuWidth; Controls[0].WinHeight = MenuHeight; Controls[0].WinLeft = (1 - Controls[0].WinWidth) / 2; Controls[0].WinTop = (1 - Controls[0].WinHeight) / 2; // QuitButton Controls[1].WinTop = 0.5 - (Controls[0].WinHeight / 2) + SButtonVGap; Controls[1].WinLeft = 0.5 + (Controls[0].WinWidth / 2) - SButtonSize - SButtonHGap; Controls[1].WinWidth = SButtonSize; Controls[1].WinHeight = SButtonSize; // HelpButton Controls[2].WinTop = Controls[1].WinTop; Controls[2].WinLeft = Controls[1].WinLeft - SButtonSize - SButtonHGap; Controls[2].WinWidth = SButtonSize; Controls[2].WinHeight = SButtonSize; // FinishButton Controls[3].WinWidth = 0.23; Controls[3].WinHeight = SButtonSize; Controls[3].WinTop = Controls[0].WinTop + Controls[0].WinHeight - SButtonSize - SButtonVGap; Controls[3].WinLeft = Controls[0].WinLeft + Controls[0].WinWidth - TitleLeftGap - Controls[3].WinWidth; // Menu Title Controls[4].WinTop = Controls[1].WinTop; Controls[4].WinLeft = 0.5 - (Controls[0].WinWidth / 2) + TitleLeftGap; Controls[4].WinWidth = 0.5; Controls[4].WinHeight = 0.1; // PreviousButton if(GeoPC.ReportingMode == MODE_CreatingNewObservation || GeoPC.ReportingMode == MODE_EditingFirstReport) { // there is a previous button in these modes Controls[5].WinTop = Controls[3].WinTop; Controls[5].WinLeft = Controls[4].WinLeft; Controls[5].WinWidth = SButtonSize; Controls[5].WinHeight = SButtonSize; } else { Controls[5].setVisibility(false); } // Notebook Button Controls[6].WinWidth = 0.23; Controls[6].WinHeight = SButtonSize; Controls[6].WinTop = Controls[0].WinTop + Controls[0].WinHeight - SButtonSize - SButtonVGap; Controls[6].WinLeft = Controls[0].WinLeft + Controls[0].WinWidth - TitleLeftGap - (2 * Controls[3].WinWidth) - SButtonHGap; // Put all the questions with their answers in the standard configuration for(q = 1; q <= nrQuestions; q++) { key = "Q"$q; tempLabel = GUILabel(Controls[HashTable.getValue(key)]); // position the questionlabel if(q == 1) { tempLabel.WinTop = Controls[4].WinTop + Controls[4].WinHeight + ButtonVGapLarge; tempLabel.WinLeft = Controls[4].WinLeft; questionLeft = tempLabel.WinLeft; } else { // all questions after the first tempLabel.WinTop = lastTop + CheckBoxHeight + ButtonVGapLarge; tempLabel.WinLeft = questionLeft; } tempLabel.WinHeight = QuestionHeight; // save this top and left lastTop = tempLabel.WinTop; lastLeft = tempLabel.WinLeft; // position the answerbuttons for(a = 1; a <= ArrayCount(EN_AnswerStrings[q-1].Answers); a++) { key = "Q"$q$"A"$a; val = HashTable.getValue(key); if(val != -1) { tempCheckBox = moCheckBox(Controls[val]); tempCheckBox.WinWidth = getAnswerWidthValue(tempCheckBox.myLabel.Caption); tempCheckBox.WinHeight = CheckBoxHeight; tempCheckBox.myLabel.TextFont = "MidGameButtonFont"; tempCheckBox.myLabel.bAcceptsInput = true; tempCheckBox.myLabel.OnClick = OnAnswerButtonClick; tempCheckBox.myCheckBox.OnClick = OnAnswerButtonClick; if(a == 1) { // first answerbutton tempCheckBox.WinTop = lastTop + QuestionHeight + ButtonVGapSmall; tempCheckBox.WinLeft = questionLeft + ButtonHGap; } else { // answerbuttons after the first tempCheckBox.WinTop = lastTop; tempCheckBox.WinLeft = lastLeft + lastAnswerWidth + ButtonHGap; } // save this top and left lastTop = tempCheckBox.WinTop; lastLeft = tempCheckBox.WinLeft; lastAnswerWidth = tempCheckBox.WinWidth; } }// answer-for-loop }// question-for-loop Controls[0].SetFocus(none); } //============================================================================= // Date Id Modification // 2007-04-05 Zmr Created this header //============================================================================= Event Opened(GUIComponent Sender) { Super.Opened(Sender); bVisible = true; } function float getAnswerWidthValue(string caption) { local float totalWidth, componentWidth, letterWidth; componentWidth = 0.018; letterWidth = 0.008; totalWidth = componentWidth + (Len(caption) - 2) * letterWidth; return totalWidth; } function InitializeHashTable() { // FUNCTIONALITY: initialize the hashtable with the keys (which should be "Q1", "Q1A1", // "Q2", "Q2A3", etc.) and its corresponding values (the index in the controls-array). // subclasses must implement this function, and call it in their // initComponent function before they call the parent initComponent function! } function InitializeCheckedness() { // FUNCTIONALITY: load values from GeoPC.tempSignal and set answerButtons checkedness accordingly // subclasses will have to implement this, because the signal variables and answerbuttons used // are different for each menu } function bool InternalOnKeyEvent(out byte Key, out byte State, float delta) { //must not swallow if( Key == 0x1B) { Controller.ReplaceMenu("GeoSimulator.MenuObservationMain"); } return true; } function InternalOnClose(optional Bool bCanceled) { Super.OnClose(bCanceled); } //============================================================================= // Date Id Modification // 2006-11-20 zmr When going back change reportingmode //============================================================================= function bool InternalOnClick(GUIComponent Sender) { // FUNCTIONALITY: react to mouseclicks on GUIComponents. // subclasses should call this function from their superclass first (handling the standard components and radiobutton-checking), // then add functionality for answerbuttons (which will not be necessary for most subclasses). local int i; local int signalIndex; local PlayerController pc; pc = PlayerOwner(); for(i = 0; i < Controls.length; i++) { if(Sender == Controls[i]) { if(i == 1) { // Quit Button Controller.ReplaceMenu("GeoSimulator.MenuObservationMain"); } else if(i == 2) { //Controller.ReplaceMenu("GeoSimulator.HelpMenuSignalQuestions"); switch(HelpMenuOption) { case 0: Controller.OpenMenu("GeoSimulator.HelpMenuSettlement"); break; case 1: Controller.OpenMenu("GeoSimulator.HelpMenuUprise"); break; case 2: Controller.OpenMenu("GeoSimulator.HelpMenuGrass"); break; case 3: Controller.OpenMenu("GeoSimulator.HelpMenuCrack"); break; case 4: Controller.OpenMenu("GeoSimulator.HelpMenuHorizontalMovement"); break; case 5: Controller.OpenMenu("GeoSimulator.HelpMenuRipPitching"); break; case 6: Controller.OpenMenu("GeoSimulator.HelpMenuWaterOutflow"); break; case 7: Controller.OpenMenu("GeoSimulator.HelpMenuBioActivity"); break; case 8: Controller.OpenMenu("GeoSimulator.HelpMenuFloatingWaste"); break; case 9: Controller.OpenMenu("GeoSimulator.HelpMenuOverToppingWash"); break; case 10: Controller.OpenMenu("GeoSimulator.HelpMenuLiquefaction"); break; case 11: Controller.OpenMenu("GeoSimulator.HelpMenuHumanActivity"); break; default: Controller.OpenMenu("GeoSimulator.HelpMenuSignalQuestion"); break; } bVisible = false; } else if(i == 3) { // Finish Button // look at current values in answers and save it in GeoPC.NewSignal // then order GeoPC to make/save this NewSignal // then, if needed, save it as an original // then go to the MenuObservations storeAnswerValues(); signalIndex = GeoPC.SaveNewSignal(); if(GeoPC.ReportingMode == MODE_CreatingNewObservation || GeoPC.ReportingMode == MODE_AddingNewReport) { GeoPC.NearbyMarker.SaveSignalOriginal(signalIndex); } Controller.ReplaceMenu("GeoSimulator.MenuObservationMain"); } else if(i == 5) { // Previous Button // look at current values in answers and save it in GeoPC.NewSignal // then go to previous page (with location) storeAnswerValues(); Controller.ReplaceMenu("GeoSimulator.MenuSignalLocation"); } else if(i == 6) { storeAnswerValues(); Controller.OpenMenu("GeoSimulator.MenuNotebook"); bVisible = false; } } } return true; } //============================================================================= // This function is called by function storeAnswerValues of the subclasses. // It checks if Signal theSignal with SignalReport tempSignalReport should be // saved to the corresponding marker, and if so, it saves it in the right // place. // // ============================================================================ // Date Id Modification // 2007-07-13 Wsl Created function //============================================================================= function SaveAnswers(Signal theSignal, SignalReport tempSignalReport) { local int tempIndex; // tempIndex is used to indicate what index the tempSignalReport // should be saved to within theSignal local bool bSaveToNewSignal; // if theSignal should be saved to the red marker afterwards local int tmp1,tmp2; // this one is not really used, but it has to be there as // parameter to SignalReport's isEqual bSaveToNewSignal = true; tempSignalReport.GeoState = GeoPC.GetCurrentFailureState(); log("tempSignalReport.GeoState:"@tempSignalReport.GeoState ); // depending on the mode, it is further checked if theSignal needs to be saved. // tempIndex is set and (if necessary) the signalreport-array extended // note that all booleans in tempSignalReport (bCalled, bChanged, bReported, bApproved) are false by default! Log("1SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); if(GeoPC.ReportingMode == MODE_CreatingNewObservation) { Log("2SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); // new observation made, so add the constructed signalreport at the first place tempIndex = 0; if(!GeoPC.bCreatedNewSignalReport) theSignal.SignalReports.Insert(tempIndex, 1); } else if(GeoPC.ReportingMode == MODE_AddingNewReport) { Log("3SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); // adding a new report to the signal, so compare to previous report to see if anything changed tempIndex = theSignal.SignalReports.length; // compare to previous signalreport to see if they are equal; // if they are, don't save to NewSignal (this is the only case in which theSignal is not saved to NewSignal) if(tempSignalReport.IsEqual(theSignal.SignalReports[tempIndex-1], 0.95,tmp1,tmp2)) { bSaveToNewSignal = false; Log("4SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); } // adding new report, so make a new one in the array where it will be saved to if changed if(bSaveToNewSignal && !GeoPC.bCreatedNewSignalReport) { theSignal.SignalReports.Insert(tempIndex, 1); Log("5SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); } tempSignalReport.bCalled = false; // theSignal.bCalled might have been true from a previous report. Now there is a new report // made, which is not called about yet, so also set theSignal.bCalled to false theSignal.bCalled = false; Log("6SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); } else if (GeoPC.ReportingMode == MODE_EditingFirstReport || GeoPC.ReportingMode == MODE_EditingLaterReport) { Log("7SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); // editing a previously made report. // always save to marker to update new answers and/or bChanged boolean // it will be saved over the last report (because it's only possible to edit the last report) tempIndex = theSignal.SignalReports.length - 1; // if already called about this report, bCalled should also be set to true // in the signalReport, otherwise it should become false tempSignalReport.bCalled = theSignal.bCalled; } // results are saved to NewSignal except if player did not make any changes (when adding new report) if(bSaveToNewSignal) { Log("8SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); // save the current failure state into the signalreport before saving it tempSignalReport.GeoState = GeoPC.GetCurrentFailureState(); // because the signal/report has changed or is completely new, it has to be approved (again) by AC // note that all booleans in tempSignalReport (bCalled, bChanged, bReported, bApproved) are false by default theSignal.bReported = false; theSignal.bApproved = false; // tempIndex is used to indicate what index the tempSignalReport should be saved to theSignal.SignalReports[tempIndex] = tempSignalReport; GeoPC.bCreatedNewSignalReport = true; GeoPC.NewSignal = theSignal; log("saved theSignal to NewSignal"); Log("SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); } Log("9SaveNewSignal + bSaveToNewSignal: "@bSaveToNewSignal); } function bool OnAnswerButtonClick(GUIComponent Sender) { local int q, a, val; local string key; local moCheckBox tempCheckBox; for(q = 1; q <= nrQuestions; q++) { for(a = 1; a <= ArrayCount(EN_AnswerStrings[q-1].Answers); a++) { key = "Q"$q$"A"$a; val = HashTable.getValue(key); if(val != -1) { tempCheckBox = moCheckBox(Controls[val]); if(tempCheckBox.myCheckBox == Sender || tempCheckBox.MyLabel == Sender) { SetRadioButtons(val); } } } } return true; } function SetRadioButtons(int controlsIndex) { local int q, a, val; local string qstring, key; // get question number key = HashTable.getKey(controlsIndex); qstring = Right(Left(key, 2), 1); q = int(qstring); // remove all checked, then check this one for(a = 1; a <= ArrayCount(EN_AnswerStrings[q-1].Answers); a++) { key = "Q"$q$"A"$a; val = HashTable.getValue(key); if(val != -1) { moCheckBox(Controls[val]).Checked(false); } } moCheckBox(Controls[controlsIndex]).Checked(true); } function setQuestionVisibility(int questionNumber, bool bVisible) { local string key; local int a, val; key = "Q"$questionNumber; GUILabel(Controls[HashTable.getValue(key)]).setVisibility(bVisible); for(a = 1; a <= ArrayCount(EN_AnswerStrings[questionNumber-1].Answers); a++) { key = "Q"$questionNumber$"A"$a; val = HashTable.getValue(key); if(val != -1) { moCheckBox(Controls[val]).setVisibility(bVisible); } } } function storeAnswerValues() { // FUNCTIONALITY: look at current values in answers and save it in GeoPC.tempSignal // subclasses will have to implement this, because the answerbuttons and signal properties used // are different for each menu } function UpdateLanguage() { local int s, i, k, val; local array QStrings; local array AStringStructs; local string key; local GUILabel Qlabel; local moCheckBox Abutton; // give dynamic arrays the correct size QStrings.Insert(0, nrQuestions); AStringStructs.Insert(0, nrQuestions); if(GeoPC.Dutch) { GUILabel(Controls[4]).Caption = NL_Title; GUIButton(Controls[3]).Caption = NL_Finish; GUIButton(Controls[6]).Caption = NL_NoteBook; // fill QStrings and AStringStructs with the appropriate strings for(s = 0; s < nrQuestions; s++) { QStrings[s] = NL_QuestionStrings[s]; AStringStructs[s] = NL_AnswerStrings[s]; } } else { GUILabel(Controls[4]).Caption = EN_Title; GUIButton(Controls[3]).Caption = EN_Finish; GUIButton(Controls[6]).Caption = EN_NoteBook; // fill QStrings and AStringStructs with the appropriate strings for(s = 0; s < nrQuestions; s++) { QStrings[s] = EN_QuestionStrings[s]; AStringStructs[s] = EN_AnswerStrings[s]; } } // question labels and labels of answerbuttons for(i = 0; i < NrQuestions; i++) { key = "Q"$(i+1); val = HashTable.getValue(key); if(val != -1) { Qlabel = GUILabel(Controls[val]); Qlabel.Caption = QStrings[i]; // answers for this question for(k = 0; k < ArrayCount(EN_AnswerStrings[i].Answers); k++) { key = "Q"$(i+1)$"A"$(k+1); val = HashTable.getValue(key); if(val != -1) { Abutton = moCheckBox(Controls[val]); Abutton.myLabel.Caption = " " $ AStringStructs[i].Answers[k]; } } } } } defaultproperties { Begin Object Class=GUIButton name=Background bAcceptsInput=false bNeverFocus=true StyleName="GeoCallBar" End Object Controls(0)=GUIButton'Background' Begin Object Class=GUIGFxButton Name=QuitButton Caption="" Graphic=Material'InGameMenuImagesT.NoBackgroundButtons.Closed' Position=ICP_Scaled StyleName="MidGameButton" OnClick=InternalOnClick bNeverFocus=true End Object Controls(1)=GUIButton'QuitButton' Begin Object Class=GUIGFxButton Name=HelpButton Caption="" Graphic=Material'InGameMenuImagesT.NoBackgroundButtons.Questionmark' Position=ICP_Scaled StyleName="MidGameButton" bNeverFocus=true OnClick=InternalOnClick End Object Controls(2)=GUIButton'HelpButton' Begin Object Class=GUIButton Name=FinishButton Caption="***" StyleName="MidGameButton" bNeverFocus=true OnClick=InternalOnClick End Object Controls(3)=GUIButton'FinishButton' Begin Object class=GUILabel Name=MenuTitle Caption="***" TextAlign=TXTA_Left TextColor=(R=255,G=120,B=0,A=255) TextFont="HeaderFont" bMultiLine=true End Object Controls(4)=GUILabel'MenuTitle' Begin Object Class=GUIGFxButton Name=PreviousPage Caption="" Graphic=Material'InGameMenuImagesT.NoBackgroundButtons.Previous' Position=ICP_Scaled StyleName="MidGameButton" bNeverFocus=true OnClick=InternalOnClick End Object Controls(5)=GUIButton'PreviousPage' Begin Object Class=GUIButton Name=NoteBookButton Caption="***" StyleName="MidGameButton" bNeverFocus=true OnClick=InternalOnClick End Object Controls(6)=GUIButton'NoteBookButton' // common properties of all answer buttons Begin Object class=moCheckBox Name=AnswerButton Caption="***" INIOption="@Internal" INIDefault="True" CaptionWidth=1 bSquare=true bFlipped=true bHeightFromComponent=false bNeverFocus=true ComponentJustification=TXTA_Left LabelJustification=TXTA_Right End Object // common properties of all question labels Begin Object class=GUILabel Name=QuestionLabel Caption="***" TextFont="MidGameFont" WinWidth=0.7 End Object CheckBoxHeight=0.03 QuestionHeight=0.02 ButtonHGap=0.03 //0.025 ButtonVGapLarge=0.027 ButtonVGapSmall=0.018 BarHeight=0.21 BarVPos=0.5 SButtonSize=0.06 SButtonHGap=0.02 SButtonVGap=0.02 TitleLeftGap=0.05 NrQuestions=0 OpenSound=sound'RuntimeInterfaceSounds.SelectDshort' bRequire640x480=false bAllowedAsLast=true EN_Finish="Finish observation report" NL_Finish="Maak observatierapport" EN_ChosenBefore="You have chosen: " NL_ChosenBefore="U heeft gekozen: " EN_NoteBook="Notebook" NL_NoteBook="Notitieblok" HelpMenuOption=0 }