4 changed files with 268 additions and 6 deletions
+2
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)
+235
View File
@@ -0,0 +1,235 @@
// 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 0.0.1 - 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\n\n";
licenseContent += "BORLAND INTERNATIONAL DISCLAIMER:\n\n";
licenseContent += "Borland International made the Turbo Vision source code public, accompanied\n";
licenseContent += "by the following disclaimer:\n\n";
licenseContent += "DISCLAIMER AND LIMITATION OF LIABILITY: Borland does not make\n";
licenseContent += "or give any representation or warranty with respect to the\n";
licenseContent += "usefulness or the efficiency of this software, it being\n";
licenseContent += "understood that the degree of success with which equipment,\n";
licenseContent += "software, modifications, and other materials can be applied to\n";
licenseContent += "data processing is dependent upon many factors, many of which\n";
licenseContent += "are not under Borland's control. ACCORDINGLY, THIS SOFTWARE IS\n";
licenseContent += "PROVIDED 'AS IS' WITHOUT EXPRESS OR IMPLIED WARRANTIES,\n";
licenseContent += "INCLUDING NO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n";
licenseContent += "PARTICULAR PURPOSE, OR NONINFRINGEMENT. THIS SOFTWARE IS\n";
licenseContent += "PROVIDED GRATUITOUSLY AND, ACCORDINGLY, BORLAND SHALL NOT BE\n";
licenseContent += "LIABLE UNDER ANY THEORY FOR ANY DAMAGES SUFFERED BY YOU OR ANY\n";
licenseContent += "USER OF THE SOFTWARE. BORLAND WILL NOT SUPPORT THIS SOFTWARE\n";
licenseContent += "AND IS UNDER NO OBLIGATION TO ISSUE UPDATES TO THIS SOFTWARE.\n\n";
licenseContent += "WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, NEITHER\n";
licenseContent += "BORLAND NOR ITS SUPPLIERS SHALL BE LIABLE FOR (a) INCIDENTAL,\n";
licenseContent += "CONSEQUENTIAL, SPECIAL OR INDIRECT DAMAGES OF ANY SORT, WHETHER\n";
licenseContent += "ARISING IN TORT, CONTRACT OR OTHERWISE, EVEN IF BORLAND HAS BEEN\n";
licenseContent += "INFORMED OF THE POSSIBILITY OF SUCH DAMAGES, OR (b) FOR ANY\n";
licenseContent += "CLAIM BY ANY OTHER PARTY. SOME STATES DO NOT ALLOW THE\n";
licenseContent += "EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES,\n";
licenseContent += "SO THIS LIMITATION AND EXCLUSION MAY NOT APPLY TO YOU.\n\n";
licenseContent += "MAGIBLOT MIT LICENSE:\n\n";
licenseContent += "The copyright below applies to the modifications made by magiblot and other\n";
licenseContent += "contributors to the original source code and to the source code that has been\n";
licenseContent += "written from scratch.\n\n";
licenseContent += "MIT License\n\n";
licenseContent += "Copyright 2019-2025 magiblot <magiblot@hotmail.com>\n\n";
licenseContent += "Permission is hereby granted, free of charge, to any person obtaining a copy\n";
licenseContent += "of this software and associated documentation files (the \"Software\"), to deal\n";
licenseContent += "in the Software without restriction, including without limitation the rights\n";
licenseContent += "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n";
licenseContent += "copies of the Software, and to permit persons to whom the Software is\n";
licenseContent += "furnished to do so, subject to the following conditions:\n\n";
licenseContent += "The above copyright notice and this permission notice shall be included in\n";
licenseContent += "all copies or substantial portions of the Software.\n\n";
licenseContent += "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n";
licenseContent += "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n";
licenseContent += "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n";
licenseContent += "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n";
licenseContent += "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n";
licenseContent += "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n";
licenseContent += "SOFTWARE.";
// 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;
}
}
if (event.what == evCommand) {
switch (event.message.command) {
case cmOK:
close();
clearEvent(event);
break;
}
}
}
+28
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
+3 -6
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() {