2024-09-29 17:58:05 -03:00
/*
2024-09-30 03:17:31 -03:00
* Copyright 2024 , Santiago Lema < santiago @ lema . org >
2024-09-29 17:58:05 -03:00
* All rights reserved . Distributed under the terms of the MIT license .
*/
# include "MainWindow.h"
2025-05-07 06:56:46 -03:00
static int progressAnim = 0 ;
2025-05-07 02:33:01 -03:00
2024-09-30 03:17:31 -03:00
2024-09-29 17:58:05 -03:00
# include <Application.h>
2024-09-30 03:17:31 -03:00
# include <Button.h>
2024-09-29 17:58:05 -03:00
# include <Catalog.h>
# include <LayoutBuilder.h>
# include <Menu.h>
# include <MenuBar.h>
2025-05-07 03:31:59 -03:00
# include <MimeType.h>
2025-05-07 01:01:00 -03:00
# include <ScrollView.h>
# include <StringView.h>
2025-05-07 06:31:50 -03:00
2024-09-29 17:58:05 -03:00
# include <View.h>
2025-05-07 19:26:56 -03:00
# include <Alert.h>
2025-05-07 06:56:46 -03:00
# include <MessageRunner.h>
2024-09-29 17:58:05 -03:00
2025-05-07 06:31:50 -03:00
# include "Conversation.h"
2024-09-30 03:17:31 -03:00
2024-09-29 17:58:05 -03:00
# undef B_TRANSLATION_CONTEXT
# define B_TRANSLATION_CONTEXT "Window"
MainWindow : : MainWindow ( )
2024-09-30 03:17:31 -03:00
: BWindow ( BRect ( 100 , 100 , 600 , 400 ) , B_TRANSLATE ( " BeDumb " ) , B_TITLED_WINDOW ,
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE ) {
2025-05-07 06:31:50 -03:00
//Without this conversation would never get bmessages from HttpRequest
LockLooper ( ) ;
AddHandler ( _conversation ) ;
UnlockLooper ( ) ;
2024-09-30 03:17:31 -03:00
BMenuBar * menuBar = _BuildMenu ( ) ;
BLayoutBuilder : : Group < > ( this , B_VERTICAL , 0 ) . Add ( menuBar ) . AddGlue ( ) . End ( ) ;
2025-05-07 03:48:23 -03:00
_inputField = new BTextView ( " input_view " , B_WILL_DRAW | B_FOLLOW_ALL ) ;
_inputField - > SetText ( " What is the matrix ? " ) ;
_inputField - > MakeEditable ( true ) ;
_inputField - > MakeSelectable ( true ) ;
_inputField - > SetWordWrap ( true ) ;
2025-05-06 23:26:01 -03:00
_progress = new BStatusBar ( " prog " ) ;
2024-09-30 03:17:31 -03:00
_progress - > SetMaxValue ( 100 ) ;
_progress - > SetTo ( 0 ) ;
2025-05-06 23:26:01 -03:00
_progress - > SetViewColor ( ui_color ( B_PANEL_BACKGROUND_COLOR ) ) ;
2024-09-30 03:17:31 -03:00
2025-05-07 01:01:00 -03:00
BStringView * header = new BStringView ( " biglabel " , " Let's Be Dumber! " ) ;
BFont font ;
header - > GetFont ( & font ) ;
font . SetSize ( 20 ) ;
header - > SetFont ( & font ) ;
2025-05-06 23:26:01 -03:00
// Info view, only one line high
_infoView = new BTextView ( " info " ) ;
2025-05-07 01:01:00 -03:00
_infoView - > SetText ( " ... " ) ;
2025-05-06 23:26:01 -03:00
_infoView - > SetViewColor ( ui_color ( B_PANEL_BACKGROUND_COLOR ) ) ;
_infoView - > MakeEditable ( false ) ;
_infoView - > MakeSelectable ( false ) ;
_infoView - > SetWordWrap ( false ) ;
2025-05-07 01:01:00 -03:00
2025-05-06 23:26:01 -03:00
float lineHeight = _infoView - > LineHeight ( 0 ) ;
_infoView - > SetExplicitMinSize ( BSize ( B_SIZE_UNSET , lineHeight ) ) ;
_infoView - > SetExplicitMaxSize ( BSize ( B_SIZE_UNLIMITED , lineHeight ) ) ;
2025-05-07 03:48:23 -03:00
float askH = lineHeight * 5 ;
2025-05-06 23:26:01 -03:00
_inputField - > SetExplicitMinSize ( BSize ( B_SIZE_UNSET , askH ) ) ;
2024-09-30 03:17:31 -03:00
2025-05-07 02:33:01 -03:00
2024-09-30 03:17:31 -03:00
BButton * sendButton =
2025-05-07 00:28:10 -03:00
new BButton ( " send " , B_TRANSLATE ( " Send " ) , new BMessage ( kSendPrompt ) ,
2024-09-30 03:17:31 -03:00
B_WILL_DRAW | B_NAVIGABLE ) ;
2025-05-07 01:01:00 -03:00
_answerView = new BTextView ( " answer " , B_WILL_DRAW | B_FOLLOW_ALL ) ;
_answerView - > MakeEditable ( false ) ; // Disable editing
_answerView - > MakeSelectable ( true ) ; // Enable text selection
2025-05-07 02:33:01 -03:00
_answerView - > SetWordWrap ( true ) ;
2025-05-07 03:31:59 -03:00
2025-05-07 01:01:00 -03:00
BScrollView * scrollView =
2025-05-07 03:31:59 -03:00
new BScrollView ( " scroll_view " , _answerView , B_FOLLOW_ALL | B_WILL_DRAW , 0 ,
false , true ) ; // horizontal and vertical scrollbars
2025-05-07 01:01:00 -03:00
2024-09-30 03:17:31 -03:00
BLayoutBuilder : : Group < > ( this , B_VERTICAL , 0 )
2025-05-06 23:26:01 -03:00
2025-05-07 01:01:00 -03:00
. AddGlue ( 0.1 )
. Add ( header )
. AddGlue ( 0.1 )
2025-05-06 23:26:01 -03:00
. AddGroup ( B_HORIZONTAL , 0 , 1 )
2024-09-30 03:17:31 -03:00
. Add ( _inputField )
2025-05-06 23:26:01 -03:00
. AddGroup ( B_HORIZONTAL , 0 , 1 )
2024-09-30 03:17:31 -03:00
. Add ( sendButton )
. End ( )
. End ( )
2025-05-07 01:01:00 -03:00
. AddGlue ( 0.1 )
. Add ( scrollView )
2025-05-06 23:26:01 -03:00
. Add ( _progress )
. Add ( _infoView )
2024-09-30 03:17:31 -03:00
. SetInsets ( 5 , 5 , 5 , 5 )
2025-05-06 23:26:01 -03:00
2024-09-30 03:17:31 -03:00
. End ( ) ;
2025-05-07 19:26:56 -03:00
2025-05-07 06:56:46 -03:00
2025-05-07 19:26:56 -03:00
//Just to animate progress
2025-05-07 06:56:46 -03:00
BMessageRunner * runner = new BMessageRunner (
this , // target BHandler
new BMessage ( kPulse ) ,
2025-05-07 07:00:10 -03:00
50000 // interval in μs (0 ms)
2025-05-07 06:56:46 -03:00
) ;
2025-05-07 19:26:56 -03:00
PostMessage ( kCheckKey ) ;
2024-09-30 03:17:31 -03:00
}
2024-09-29 17:58:05 -03:00
2025-05-07 19:26:56 -03:00
void MainWindow : : checkValidKey ( ) {
if ( ! _conversation - > validKey )
{
_infoView - > SetText ( " MISSING API KEY " ) ;
ShowMissingKeyAlertAndQuit ( ) ;
return ;
}
else
2025-05-07 20:13:12 -03:00
{
2025-05-07 19:26:56 -03:00
_infoView - > SetText ( " API Key loaded. " ) ;
2025-05-07 20:13:12 -03:00
_conversation - > loadModels ( ) ;
}
2025-05-07 19:26:56 -03:00
}
void MainWindow : : ShowMissingKeyAlertAndQuit ( )
{
BAlert * alert = new BAlert ( " Missing key file! " , " Create a file named 'openai_key' containing a valid OpenAI Token on one line in \n \n /boot/home/config/settings/openai_key . \n \n Then relaunch the app. \n \n Be aware that this is not a safe storage so don't use valuable keys. " , " Oh, no " , " Sigh " , " Just give up " , B_WIDTH_AS_USUAL , B_WARNING_ALERT ) ;
alert - > SetType ( B_INFO_ALERT ) ;
uint32 result = alert - > Go ( ) ;
PostMessage ( B_QUIT_REQUESTED ) ;
}
2024-09-30 03:17:31 -03:00
MainWindow : : ~ MainWindow ( ) { }
void MainWindow : : MessageReceived ( BMessage * message ) {
2025-05-06 23:26:01 -03:00
2025-05-07 06:31:50 -03:00
switch ( message - > what ) {
2025-05-07 01:01:00 -03:00
2025-05-07 19:26:56 -03:00
case kCheckKey : {
checkValidKey ( ) ;
}
break ;
2025-05-07 06:56:46 -03:00
case kPulse : {
2025-05-07 07:00:10 -03:00
if ( progressAnim > = 1 & & progressAnim < = 85 ) {
2025-05-07 06:56:46 -03:00
_progress - > SetTo ( progressAnim ) ;
progressAnim + + ;
}
}
2025-05-07 19:26:56 -03:00
break ;
2025-05-07 06:56:46 -03:00
// case kMsgNewFile: {
2024-09-30 03:17:31 -03:00
// fSaveMenuItem->SetEnabled(false);
// printf("New\n");
// } break;
// case kMsgOpenFile: {
// fSaveMenuItem->SetEnabled(true);
// printf("Open\n");
// } break;
// case kMsgSaveFile: {
// printf("Save\n");
// } break;
case kSendPrompt : {
2025-05-07 06:31:50 -03:00
_progress - > SetMaxValue ( 100 ) ;
2025-05-07 06:56:46 -03:00
_progress - > SetTo ( 0 ) ;
_answerView - > SetText ( " ... " ) ;
progressAnim = 1 ; //will trigger animation
2024-09-30 03:17:31 -03:00
2025-05-07 06:31:50 -03:00
printf ( " Button Pressed \n " ) ;
_infoView - > SetText ( " Asking... " ) ;
_conversation - > ask ( std : : string ( _inputField - > Text ( ) ) ) ;
2024-09-30 03:17:31 -03:00
2025-05-06 23:26:01 -03:00
} break ;
2025-05-07 06:31:50 -03:00
case kSendReply : {
printf ( " Conversation returned! \n " ) ;
_infoView - > SetText ( " Answer Received " ) ;
2025-05-07 01:01:00 -03:00
2025-05-07 06:56:46 -03:00
progressAnim = 100 ;
2024-09-30 03:17:31 -03:00
2025-05-07 06:31:50 -03:00
const char * text ;
if ( message - > FindString ( " text " , & text ) = = B_OK ) {
2025-05-07 19:26:56 -03:00
// printf("Received text: %s\n", text);
2025-05-07 06:31:50 -03:00
// Do something with text (e.g., set it to a BTextView)
_answerView - > SetText ( text ) ;
} else {
printf ( " No text found in message. \n " ) ;
_answerView - > SetText ( " NO TEXT IN REPLY " ) ;
}
2025-05-07 01:01:00 -03:00
_progress - > SetMaxValue ( 100 ) ;
_progress - > SetTo ( 100 ) ;
2025-05-07 06:31:50 -03:00
2025-05-07 01:01:00 -03:00
} break ;
2025-05-06 23:26:01 -03:00
2024-09-30 03:17:31 -03:00
default : {
2025-05-07 01:01:00 -03:00
// message->PrintToStream();
2025-05-07 06:31:50 -03:00
BHandler : : MessageReceived (
2025-05-07 01:01:00 -03:00
message ) ; // call the parent handler for other messages
2025-05-06 23:26:01 -03:00
// _infoView->SetText(message->FindMessage());
2024-09-30 03:17:31 -03:00
break ;
}
2025-05-06 23:26:01 -03:00
2025-05-07 01:01:00 -03:00
} // end switch
2025-05-06 23:26:01 -03:00
2025-05-07 01:01:00 -03:00
} // end function
2025-05-06 23:26:01 -03:00
2024-09-29 17:58:05 -03:00
2024-09-30 03:17:31 -03:00
BMenuBar * MainWindow : : _BuildMenu ( ) {
2025-05-06 23:26:01 -03:00
2024-09-30 03:17:31 -03:00
BMenuBar * menuBar = new BMenuBar ( " menubar " ) ;
2025-05-07 01:01:00 -03:00
BMenu * menu ;
2024-09-30 03:17:31 -03:00
BMenuItem * item ;
2025-05-07 01:01:00 -03:00
2024-09-30 03:17:31 -03:00
// menu 'File'
menu = new BMenu ( B_TRANSLATE ( " File " ) ) ;
2024-09-29 17:58:05 -03:00
2024-09-30 03:17:31 -03:00
// item = new BMenuItem(B_TRANSLATE("New"), new BMessage(kMsgNewFile), 'N');
// menu->AddItem(item);
2024-09-29 17:58:05 -03:00
2024-09-30 03:17:31 -03:00
// item = new BMenuItem(B_TRANSLATE("Open" B_UTF8_ELLIPSIS),
2025-05-06 23:26:01 -03:00
// new BMessage(kMsgOpenFile), 'O');
2024-09-30 03:17:31 -03:00
// menu->AddItem(item);
2024-09-29 17:58:05 -03:00
2024-09-30 03:17:31 -03:00
// fSaveMenuItem =
// new BMenuItem(B_TRANSLATE("Save"), new BMessage(kMsgSaveFile), 'S');
// fSaveMenuItem->SetEnabled(false);
// menu->AddItem(fSaveMenuItem);
2024-09-29 17:58:05 -03:00
2024-09-30 03:17:31 -03:00
// menu->AddSeparatorItem();
2025-05-07 01:01:00 -03:00
2024-09-30 03:17:31 -03:00
item = new BMenuItem ( B_TRANSLATE ( " About " B_UTF8_ELLIPSIS ) ,
new BMessage ( B_ABOUT_REQUESTED ) ) ;
item - > SetTarget ( be_app ) ;
menu - > AddItem ( item ) ;
2024-09-29 17:58:05 -03:00
2025-05-07 01:01:00 -03:00
item =
new BMenuItem ( B_TRANSLATE ( " Quit " ) , new BMessage ( B_QUIT_REQUESTED ) , ' Q ' ) ;
2024-09-30 03:17:31 -03:00
menu - > AddItem ( item ) ;
2024-09-29 17:58:05 -03:00
2024-09-30 03:17:31 -03:00
menuBar - > AddItem ( menu ) ;
2024-09-29 17:58:05 -03:00
2024-09-30 03:17:31 -03:00
return menuBar ;
2025-05-06 23:26:01 -03:00
}
2025-05-07 02:33:01 -03:00