KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
Popup_Questionnaire.cpp
이 파일의 문서화 페이지로 가기
1// Copyright (c) 2025 Doppleddiggong. All rights reserved. Unauthorized copying, modification, or distribution of this file, via any medium is strictly prohibited. Proprietary and confidential.
2
3
5
6#include "ALingoPlayerState.h"
7#include "APlayerControl.h"
8#include "GameLogging.h"
11#include "UImageButton.h"
13#include "ULingoGameHelper.h"
14#include "UPopupManager.h"
15#include "Components/Spacer.h"
16#include "Components/VerticalBox.h"
17
18
19UPopup_Questionnaire::UPopup_Questionnaire(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
20{
21 ConstructorHelpers::FClassFinder<UPopup_QuestionnaireItem> questionnaireItemRef(TEXT("/Game/CustomContents/UI/Widgets/Write/WBP_PopupQuestionnaireItem.WBP_PopupQuestionnaireItem_C"));
22 if (questionnaireItemRef.Succeeded())
23 {
24 QuestionnaireItemClass = questionnaireItemRef.Class;
25 }
26}
27
29{
30 Super::NativeConstruct();
31
32 // 버튼 이벤트 바인딩
33 if (Btn_Submit)
34 {
35 Btn_Submit->OnButtonClickedEvent.RemoveDynamic(this, &UPopup_Questionnaire::OnClickSubmit);
36 Btn_Submit->OnButtonClickedEvent.AddDynamic(this, &UPopup_Questionnaire::OnClickSubmit);
37
38 // 초기 상태는 비활성화
39 Btn_Submit->SetIsEnabled(false);
40 }
41}
42
44{
45 // 질문 데이터 저장
47 {
48 lps->WriteQuestionData = QuestionData;
49 }
50 SavedQuestions = QuestionData.question;
51
52 // 기존 항목 제거
53 VerticalBox->ClearChildren();
54 QuestionnaireItems.Empty();
55
56 // 각 질문에 대해 항목 위젯 생성
57 for (int32 i = 0; i < SavedQuestions.Num(); ++i)
58 {
59 const FWriteQuestionData& Data = SavedQuestions[i];
60
61 // 인터뷰 항목 위젯 생성
62 UPopup_QuestionnaireItem* ItemWidget = CreateWidget<UPopup_QuestionnaireItem>(
63 GetWorld(), QuestionnaireItemClass);
64 ItemWidget->InitItem(Data);
65
66 // 답변 상태 변경 델리게이트 바인딩
68
69 // 배열에 저장
70 QuestionnaireItems.Add(ItemWidget);
71
72 VerticalBox->AddChildToVerticalBox(ItemWidget);
73
74 // 마지막 항목이 아니면 Spacer 추가
75 if (i < SavedQuestions.Num() - 1)
76 {
77 USpacer* Spacer = NewObject<USpacer>(this);
78 if (Spacer)
79 {
80 Spacer->SetSize(FVector2D(1.0f, ItemSpacing));
81 VerticalBox->AddChildToVerticalBox(Spacer);
82 }
83 }
84 }
85
86 // 초기 버튼 상태 업데이트
88}
89
91{
92 // PopupManager를 통해 팝업 닫기 (마우스 커서 처리 포함)
93 if (UPopupManager* PopupMgr = UPopupManager::Get(GetWorld()))
94 {
95 PopupMgr->HideCurrentPopup();
96 }
97}
98
100{
101 // 사진 파일 모으기
102 // 네트워크 전송
103 if (auto KLingoNetwork = UKLingoNetworkSystem::Get(GetWorld()))
104 {
105 // Question마다 png파일 1개로 보내기
106 TArray<FString> pngFiles;
107 TArray<FString> targetTexts;
108 for (const auto& question : SavedQuestions)
109 {
110 FString imagePath = WriteImagePath + FString::Printf(TEXT("Answer%d.PNG"), question.Id);
111 PRINTLOG(TEXT("[TEST] RequestOcrExtract - ImagePath: %s"), *imagePath);
112
113 pngFiles.Add(imagePath);
114 targetTexts.Add(question.answer_kor);
115 }
116
117 KLingoNetwork->RequestWriteSubmit(
118 pngFiles,
119 targetTexts,
120 FResponseWriteSubmitDelegate::CreateUObject(this, &UPopup_Questionnaire::OnResponseOcrExtract)
121 );
122
123 OnClickClose();
124 }
125 else
126 {
127 PRINTLOG(TEXT("UKLingoNetworkSystem not found!"));
128 }
129}
130
132{
133 if (bWasSuccessful)
134 {
135 PRINTLOG(TEXT("--- OCR Extract SUCCESS ---"));
136
138 {
139 lps->WriteSubmitResultData = ResponseData;
140 }
141
142 if (auto GS = Cast<ALingoGameState>(GetWorld()->GetGameState()))
143 {
144 // 네트워크 송신 (Host만)
145 if (UKLingoNetworkSystem* KLingoNetwork = UKLingoNetworkSystem::Get(GetWorld()))
146 {
147 FRequestWriteResult WriteRequest;
148 WriteRequest.room_id = GS->GetRoomId();
149 WriteRequest.user_id = Cast<APlayerControl>(GetOwningPlayer())->GetUserId();
150 WriteRequest.scenario_id = 1;
152 WriteRequest.state_type = 0;
153 WriteRequest.result_time = GS->GetTimeTaken();
154 WriteRequest.wrong_idx = GS->WrongReadAnswerList;
155
156 KLingoNetwork->RequestWriteResult(
157 WriteRequest,
158 FResponseWriteResultDelegate::CreateUObject(this, &UPopup_Questionnaire::OnResponseWriteResult)
159 );
160 }
161 }
162 }
163 else
164 {
165 PRINTLOG(TEXT("--- OCR Extract FAILED ---"));
166 }
167}
168
170{
171 if (bWasSuccessful)
172 {
173 PRINTLOG(TEXT("--- OCR Extract SUCCESS ---"));
174
176 if (lps)
177 {
178 lps->WriteWholeResultData = ResponseData;
179 }
180
181 // 피드백 팝업 창 생성
182 if (auto Popup = UPopupManager::ShowPopupAs<UPopup_QuestionnaireResult>(GetWorld(), EPopupType::QuestionnaireResult))
183 {
184 // 팝업 초기화
185 Popup->InitPopup(lps->WriteSubmitResultData, ResponseData);
186
187 PRINTLOG(TEXT("[PopupTester] Result popup opened"));
188 }
189 }
190 else
191 {
192 PRINTLOG(TEXT("--- OCR Extract FAILED ---"));
193 }
194}
195
197{
198 // 항목의 답변 상태가 변경되었으므로 제출 버튼 상태 업데이트
200}
201
203{
204 if (!Btn_Submit)
205 {
206 return;
207 }
208
209 // 모든 항목이 답변되었는지 확인
210 bool bAllAnswered = true;
211 for (const auto& Item : QuestionnaireItems)
212 {
213 if (Item && !Item->IsAnswered())
214 {
215 bAllAnswered = false;
216 break;
217 }
218 }
219
220 // 모든 항목이 답변되었으면 버튼 활성화, 아니면 비활성화
221 Btn_Submit->SetIsEnabled(bAllAnswered);
222}
APlayerControl 선언에 대한 Doxygen 주석을 제공합니다.
YiSan 전반에서 사용하는 공용 인터페이스를 선언합니다.
#define PRINTLOG(fmt,...)
Definition GameLogging.h:30
KLingo API 요청을 담당하는 서브시스템을 선언합니다.
FResponseWriteSubmit WriteSubmitResultData
FResponseWriteResult WriteWholeResultData
KLingo 서버와의 HTTP 요청을 중재하는 게임 인스턴스 서브시스템입니다.
static int32 GetStageTypeIndex(const EQuestType QuestType)
static class ALingoPlayerState * GetLingoPlayerState(const UObject *WorldContextObject)
팝업 관리자
FOnAnswerStateChanged OnAnswerStateChanged
답변 상태 변경 시 호출되는 델리게이트
void InitItem(const FWriteQuestionData &Data)
질문 항목 초기화
virtual void NativeConstruct() override
UPopup_Questionnaire(const FObjectInitializer &ObjectInitializer)
float ItemSpacing
인터뷰 항목 간 간격 (Spacer Height)
void OnResponseOcrExtract(FResponseWriteSubmit &ResponseData, bool bWasSuccessful)
TObjectPtr< class UVerticalBox > VerticalBox
인터뷰 항목들이 추가될 VerticalBox
TObjectPtr< class UImageButton > Btn_Submit
제출 버튼
TArray< FWriteQuestionData > SavedQuestions
저장된 인터뷰 질문 데이터
TSubclassOf< class UPopup_QuestionnaireItem > QuestionnaireItemClass
팝업 내에서 표시될 인터뷰 항목 위젯 클래스
void InitPopup(const FQuestWriteInfo &QuestionData)
팝업 초기화 (필요 시 API 확장)
void UpdateSubmitButtonState()
제출 버튼 활성화 상태 업데이트
void OnItemAnswerStateChanged(bool bIsAnswered)
항목의 답변 상태 변경 콜백
void OnResponseWriteResult(FResponseWriteResult &ResponseData, bool bWasSuccessful)
TArray< TObjectPtr< class UPopup_QuestionnaireItem > > QuestionnaireItems
생성된 설문 항목 위젯들
Write 퀘스트 정보 구조체입니다.
TArray< FWriteQuestionData > question
TArray< int32 > wrong_idx
Write Submit 응답 구조체입니다.
Write 질문 및 정답 구조체입니다.