Added a custom about box

This commit is contained in:
Gustavo Henrique Santos Souza de Miranda 2025-06-24 20:33:03 -03:00
parent d80d32127d
commit 410e11c6e9
4 changed files with 213 additions and 6 deletions

View File

@ -15,6 +15,8 @@ add_executable(Pilgrim src/main.cpp
src/PilgrimApp.h
src/MainWindow.cpp
src/MainWindow.h
src/AboutDialog.cpp
src/AboutDialog.h
)
target_link_libraries(${PROJECT_NAME} tvision)
if(UNIX)

180
src/AboutDialog.cpp Normal file
View File

@ -0,0 +1,180 @@
// Componentes necessários para a declaração em AboutDialog.h
#define Uses_TDialog
// Componentes necessários para a implementação em AboutDialog.cpp
#define Uses_TStaticText
#define Uses_TButton
#define Uses_TScrollBar
#define Uses_TEditor
#define Uses_TRect
#define Uses_TView
#define Uses_TWindowInit // TDialog herda dele, então é bom ter.
#define Uses_TEvent
#define Uses_TKeys
#define Uses_TScreen
// 2. AGORA INCLUA SEU CABEÇALHO.
// Ele irá puxar <tvision/tv.h> com todas as definições acima ativadas.
#include "AboutDialog.h"
// Outras inclusões C++ padrão
#include <cstring> // Para strlen
#include <fstream> // Para leitura de arquivo
#include <sstream> // Para stringstream
#include <iostream> // Para cerr
// Função para fazer wrap do texto
std::string wrapText(const std::string& text, int maxWidth) {
std::string result;
std::istringstream iss(text);
std::string line;
while (std::getline(iss, line)) {
if (line.length() <= maxWidth) {
result += line + "\n";
} else {
// Fazer wrap da linha
std::string currentLine;
std::istringstream wordStream(line);
std::string word;
while (wordStream >> word) {
if (currentLine.length() + word.length() + 1 <= maxWidth) {
if (!currentLine.empty()) currentLine += " ";
currentLine += word;
} else {
if (!currentLine.empty()) {
result += currentLine + "\n";
currentLine = word;
} else {
// Palavra muito longa, quebrar
result += word.substr(0, maxWidth) + "\n";
currentLine = word.substr(maxWidth);
}
}
}
if (!currentLine.empty()) {
result += currentLine + "\n";
}
}
}
return result;
}
TAboutDialog::TAboutDialog() :
TWindowInit(&TAboutDialog::initFrame),
TDialog(TRect(0, 0, 100, 30), "About Pilgrim")
{
// Centralizar o diálogo programaticamente
int x = (TScreen::screenWidth - 100) / 2;
int y = (TScreen::screenHeight - 30) / 2;
moveTo(x, y);
insert(new TStaticText(TRect(40, 1, 60, 2), "P I L G R I M"));
insert(new TStaticText(TRect(35, 2, 65, 3), "Digital Travel Journal"));
insert(new TStaticText(TRect(41, 3, 59, 4), "Version 1.0 - 2025"));
insert(new TStaticText(TRect(2, 4, 98, 5),
"══════════════════════════════════════════════════════════════════════════════════════════════"));
const char* developerInfo =
"Developed by: Gustavo H. S. S. M.\n"
"GitHub: https://github.com/gmbrax\n"
"Git: https://git.gustavomiranda.xyz";
insert(new TStaticText(TRect(3, 6, 97, 10), developerInfo));
insert(new TStaticText(TRect(3, 11, 20, 12), "License:"));
// Criar apenas scrollbar vertical
TScrollBar* vScrollBar = new TScrollBar(TRect(96, 12, 97, 23));
insert(vScrollBar);
// Criar TEditor para mostrar a licença com scroll vertical apenas - área maior
TEditor* editor = new TEditor(TRect(3, 12, 96, 23), nullptr, vScrollBar, nullptr, 10000);
// Tentar ler o arquivo LICENSE
std::string licenseContent;
std::ifstream licenseFile;
// Tentar diferentes caminhos possíveis para o arquivo LICENSE
const char* possiblePaths[] = {
"LICENSE",
"../LICENSE",
"../../LICENSE",
"./LICENSE"
};
bool fileFound = false;
for (const char* path : possiblePaths) {
licenseFile.open(path);
if (licenseFile.is_open()) {
std::stringstream buffer;
buffer << licenseFile.rdbuf();
licenseContent = buffer.str();
licenseFile.close();
fileFound = true;
break;
}
}
if (!fileFound) {
// Fallback se não conseguir ler o arquivo
licenseContent = "Error loading LICENSE file.\n\n"
"Copyright (c) 2025 GHMiranda.\n\n"
"This software is distributed under the BSD license terms.\n\n"
"Redistribution and use in source and binary forms, with or without\n"
"modification, are permitted provided that the following conditions\n"
"are met:\n\n"
"1. Redistributions of source code must retain the above copyright\n"
" notice, this list of conditions and the following disclaimer.\n\n"
"2. Redistributions in binary form must reproduce the above copyright\n"
" notice, this list of conditions and the following disclaimer in\n"
" the documentation and/or other materials provided with the\n"
" distribution.\n\n"
"3. Neither the name of the copyright holder nor the names of its\n"
" contributors may be used to endorse or promote products derived\n"
" from this software without specific prior written permission.\n\n"
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n"
"FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"
"COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n"
"INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n"
"BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"
"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n"
"CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"
"LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n"
"ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n"
"POSSIBILITY OF SUCH DAMAGE.";
}
// Adicionar informações sobre bibliotecas utilizadas
licenseContent += "\n\n────────────────────────────────────────────────────────────────────────────\n\n";
licenseContent += "USED LIBRARIES:\n\n";
licenseContent += "• Turbo Vision (Magiblot fork)\n";
licenseContent += " Modern port of Borland's Turbo Vision library\n";
licenseContent += " GitHub: https://github.com/magiblot/tvision";
// Fazer wrap do texto para caber na largura do editor (93 caracteres)
std::string wrappedText = wrapText(licenseContent, 93);
editor->insertText(wrappedText.c_str(), wrappedText.length(), true);
editor->setState(sfCursorVis, false); // Desabilitar cursor
editor->setState(sfActive, false); // Desabilitar edição
insert(editor);
insert(new TButton(TRect(45, 27, 55, 29), "~O~K", cmOK, bfDefault));
}
void TAboutDialog::handleEvent(TEvent& event) {
TDialog::handleEvent(event);
if (event.what == evKeyDown) {
switch (event.keyDown.keyCode) {
case kbAltX:
case kbEsc:
close();
clearEvent(event);
break;
}
}
}

28
src/AboutDialog.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef ABOUTDIALOG_H
#define ABOUTDIALOG_H
// Passo 1: Defina TODOS os componentes da TVision necessários para esta janela aqui.
#define Uses_TDialog
#define Uses_TStaticText
#define Uses_TButton
#define Uses_TScrollBar
#define Uses_TEditor
#define Uses_TRect
#define Uses_TView
#define Uses_TWindowInit
#define Uses_TEvent
#define Uses_TKeys
#define Uses_TScreen
// Passo 2: Agora, inclua os cabeçalhos necessários.
#include <tvision/tv.h>
// Passo 3: Defina a sua classe.
class TAboutDialog : public TDialog
{
public:
TAboutDialog();
void handleEvent(TEvent& event) override;
};
#endif // ABOUTDIALOG_H

View File

@ -1,4 +1,5 @@
#include "PilgrimApp.h"
#include "AboutDialog.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
@ -119,12 +120,8 @@ void PilgrimApp::cascade() {
}
void PilgrimApp::about() {
messageBox("\003Pilgrim v1.0\n\n"
"\003Aplicação de demonstração\n"
"\003usando Turbo Vision\n\n"
"\003Desenvolvido com C++\n"
"\003e biblioteca TUI moderna",
mfInformation | mfOKButton);
TAboutDialog* dialog = new TAboutDialog();
deskTop->insert(dialog);
}
void PilgrimApp::dosShell() {