fixes resizing issues ins croll view
This commit is contained in:
parent
85be8d6ef4
commit
de3dc540c4
5 changed files with 88 additions and 83 deletions
3
App.cpp
3
App.cpp
|
@ -33,7 +33,8 @@ void App::AboutRequested() {
|
||||||
about->AddDescription(B_TRANSLATE("about_body"));
|
about->AddDescription(B_TRANSLATE("about_body"));
|
||||||
about->AddCopyright(2024, "Santiago Lema");
|
about->AddCopyright(2024, "Santiago Lema");
|
||||||
about->AddText("e-mail me at haiku@lema.org");
|
about->AddText("e-mail me at haiku@lema.org");
|
||||||
about->AddText("or ping me on the fediverse on @santi@go.lema.org");
|
about->AddText("or find me on the fediverse as");
|
||||||
|
about->AddText("@santi@go.lema.org");
|
||||||
|
|
||||||
about->Show();
|
about->Show();
|
||||||
}
|
}
|
||||||
|
|
BIN
DumBer
BIN
DumBer
Binary file not shown.
|
@ -44,7 +44,7 @@ MainWindow::MainWindow()
|
||||||
BLayoutBuilder::Group<>(this, B_VERTICAL, 0).Add(menuBar).AddGlue().End();
|
BLayoutBuilder::Group<>(this, B_VERTICAL, 0).Add(menuBar).AddGlue().End();
|
||||||
|
|
||||||
_inputField = new BTextView("input_view", B_WILL_DRAW | B_FOLLOW_ALL);
|
_inputField = new BTextView("input_view", B_WILL_DRAW | B_FOLLOW_ALL);
|
||||||
_inputField->SetText("What is the matrix ?");
|
_inputField->SetText("What is the matrix... printer ?");
|
||||||
_inputField->MakeEditable(true);
|
_inputField->MakeEditable(true);
|
||||||
_inputField->MakeSelectable(true);
|
_inputField->MakeSelectable(true);
|
||||||
_inputField->SetWordWrap(true);
|
_inputField->SetWordWrap(true);
|
||||||
|
@ -58,11 +58,6 @@ MainWindow::MainWindow()
|
||||||
_progress->SetTo(0);
|
_progress->SetTo(0);
|
||||||
_progress->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
_progress->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
// BStringView *header = new BStringView("biglabel", "Let's Be Dumber!");
|
|
||||||
// BFont font;
|
|
||||||
// header->GetFont(&font);
|
|
||||||
// font.SetSize(20);
|
|
||||||
// header->SetFont(&font);
|
|
||||||
|
|
||||||
// Info view, only one line high
|
// Info view, only one line high
|
||||||
_infoView = new BTextView("info");
|
_infoView = new BTextView("info");
|
||||||
|
@ -72,7 +67,6 @@ MainWindow::MainWindow()
|
||||||
_infoView->MakeSelectable(false);
|
_infoView->MakeSelectable(false);
|
||||||
_infoView->SetWordWrap(false);
|
_infoView->SetWordWrap(false);
|
||||||
|
|
||||||
|
|
||||||
_infoConversation = new BTextView("convers");
|
_infoConversation = new BTextView("convers");
|
||||||
_infoConversation->SetText("(No history)");
|
_infoConversation->SetText("(No history)");
|
||||||
_infoConversation->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
_infoConversation->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
@ -80,7 +74,6 @@ MainWindow::MainWindow()
|
||||||
_infoConversation->MakeSelectable(false);
|
_infoConversation->MakeSelectable(false);
|
||||||
_infoConversation->SetWordWrap(false);
|
_infoConversation->SetWordWrap(false);
|
||||||
|
|
||||||
|
|
||||||
float lineHeight = _infoView->LineHeight(0);
|
float lineHeight = _infoView->LineHeight(0);
|
||||||
_infoView->SetExplicitMinSize(BSize(B_SIZE_UNSET, lineHeight));
|
_infoView->SetExplicitMinSize(BSize(B_SIZE_UNSET, lineHeight));
|
||||||
_infoView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, lineHeight));
|
_infoView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, lineHeight));
|
||||||
|
@ -91,7 +84,6 @@ MainWindow::MainWindow()
|
||||||
float askH = lineHeight * 2;
|
float askH = lineHeight * 2;
|
||||||
_inputField->SetExplicitMinSize(BSize(B_SIZE_UNSET, askH));
|
_inputField->SetExplicitMinSize(BSize(B_SIZE_UNSET, askH));
|
||||||
|
|
||||||
|
|
||||||
_sendButton =
|
_sendButton =
|
||||||
new BButton("send", B_TRANSLATE("Send"), new BMessage(kSendPrompt),
|
new BButton("send", B_TRANSLATE("Send"), new BMessage(kSendPrompt),
|
||||||
B_WILL_DRAW | B_NAVIGABLE);
|
B_WILL_DRAW | B_NAVIGABLE);
|
||||||
|
@ -103,34 +95,37 @@ MainWindow::MainWindow()
|
||||||
_answerView->MakeSelectable(true); // Enable text selection
|
_answerView->MakeSelectable(true); // Enable text selection
|
||||||
_answerView->SetWordWrap(true);
|
_answerView->SetWordWrap(true);
|
||||||
|
|
||||||
_answerView->SetExplicitMinSize(BSize(B_SIZE_UNSET, askH*2));
|
_answerView->SetExplicitMinSize(BSize(B_SIZE_UNSET, askH * 2));
|
||||||
|
|
||||||
BScrollView *scrollView =
|
_answerScrollView =
|
||||||
new BScrollView("scroll_view", _answerView, B_FOLLOW_ALL | B_WILL_DRAW, 0,
|
new BScrollView("scroll_view", _answerView, B_FRAME_EVENTS | B_WILL_DRAW, 0,
|
||||||
false, true); // horizontal and vertical scrollbars
|
false, true, B_FANCY_BORDER); // horizontal and vertical scrollbars
|
||||||
|
|
||||||
|
// Enable correct resizing behavior, otherwise we get no correct scrollbar after resizing
|
||||||
//BView *imageView = new BView("icon_view", B_WILL_DRAW | B_FOLLOW_NONE);
|
_answerView->SetFlags(_answerView->Flags() | B_FULL_UPDATE_ON_RESIZE);
|
||||||
//imageView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
_answerScrollView->SetFlags(_answerView->Flags() | B_FULL_UPDATE_ON_RESIZE);
|
||||||
|
|
||||||
|
|
||||||
BStringView *headerQuestion = new BStringView("questionLabel", "Your question: ");
|
// BView *imageView = new BView("icon_view", B_WILL_DRAW | B_FOLLOW_NONE);
|
||||||
|
// imageView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
|
BStringView *headerQuestion =
|
||||||
|
new BStringView("questionLabel", "Your question: ");
|
||||||
BStringView *headerAnswer = new BStringView("questionAnswer", "Answer: ");
|
BStringView *headerAnswer = new BStringView("questionAnswer", "Answer: ");
|
||||||
|
|
||||||
|
|
||||||
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
|
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
|
||||||
|
|
||||||
.AddGlue(0.1)
|
.AddGlue(0.1)
|
||||||
.Add(headerQuestion)
|
.Add(headerQuestion)
|
||||||
.AddGroup(B_HORIZONTAL, 0, 1)
|
.AddGroup(B_HORIZONTAL, 0, 1)
|
||||||
.Add(_inputField,0.25)
|
.Add(_inputField, 0.25)
|
||||||
.AddGroup(B_HORIZONTAL, 0, 0)
|
.AddGroup(B_HORIZONTAL, 0, 0)
|
||||||
.AddGlue()
|
.AddGlue()
|
||||||
|
|
||||||
.AddGroup(B_VERTICAL, 0, 1)
|
.AddGroup(B_VERTICAL, 0, 1)
|
||||||
// .Add(imageView)
|
// .Add(imageView)
|
||||||
|
|
||||||
// .AddGlue()
|
// .AddGlue()
|
||||||
|
|
||||||
.AddGroup(B_HORIZONTAL, 0, 1) // left-align cnv
|
.AddGroup(B_HORIZONTAL, 0, 1) // left-align cnv
|
||||||
.Add(_infoConversation)
|
.Add(_infoConversation)
|
||||||
|
@ -138,7 +133,6 @@ MainWindow::MainWindow()
|
||||||
.End()
|
.End()
|
||||||
.AddGlue()
|
.AddGlue()
|
||||||
|
|
||||||
|
|
||||||
.AddGroup(B_HORIZONTAL, 0, 1) // left-align _modelField
|
.AddGroup(B_HORIZONTAL, 0, 1) // left-align _modelField
|
||||||
.Add(_modelField)
|
.Add(_modelField)
|
||||||
.AddGlue()
|
.AddGlue()
|
||||||
|
@ -157,7 +151,7 @@ MainWindow::MainWindow()
|
||||||
|
|
||||||
.AddGlue(0.1)
|
.AddGlue(0.1)
|
||||||
.Add(headerAnswer)
|
.Add(headerAnswer)
|
||||||
.Add(scrollView,1)
|
.Add(_answerScrollView, 1)
|
||||||
.Add(_progress)
|
.Add(_progress)
|
||||||
.Add(_infoView)
|
.Add(_infoView)
|
||||||
|
|
||||||
|
@ -165,7 +159,7 @@ MainWindow::MainWindow()
|
||||||
|
|
||||||
.End();
|
.End();
|
||||||
|
|
||||||
// Just to animate progress
|
// Loop Just to animate progress in Bar
|
||||||
BMessageRunner *runner = new BMessageRunner(this, // target BHandler
|
BMessageRunner *runner = new BMessageRunner(this, // target BHandler
|
||||||
new BMessage(kPulse),
|
new BMessage(kPulse),
|
||||||
100000 // interval in μs (0 ms)
|
100000 // interval in μs (0 ms)
|
||||||
|
@ -173,17 +167,13 @@ MainWindow::MainWindow()
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// BBitmap* image = BTranslationUtils::GetBitmapFile("/boot/system/data/icons/hicolor/64x64/apps/kdevelop.png");
|
|
||||||
//imageView->SetViewBitmap(image);
|
|
||||||
|
|
||||||
// imageView->SetViewColor(B_TRANSPARENT_COLOR);
|
|
||||||
|
|
||||||
updateHistoryInfo();
|
updateHistoryInfo();
|
||||||
|
|
||||||
|
|
||||||
PostMessage(kCheckKey);
|
PostMessage(kCheckKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::checkValidKey() {
|
void MainWindow::checkValidKey() {
|
||||||
|
|
||||||
if (!_conversation->validKey) {
|
if (!_conversation->validKey) {
|
||||||
|
@ -240,12 +230,9 @@ void MainWindow::SelectModelByName(const char *targetLabel) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::updateHistoryInfo() {
|
void MainWindow::updateHistoryInfo() {
|
||||||
|
|
||||||
_infoConversation->SetText(_conversation->buildHistoryInfoLine().c_str());
|
_infoConversation->SetText(_conversation->buildHistoryInfoLine().c_str());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::MessageReceived(BMessage *message) {
|
void MainWindow::MessageReceived(BMessage *message) {
|
||||||
|
@ -256,21 +243,17 @@ void MainWindow::MessageReceived(BMessage *message) {
|
||||||
checkValidKey();
|
checkValidKey();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case kClearHistory: {
|
case kClearHistory: {
|
||||||
|
|
||||||
printf("will clear history");
|
printf("will clear history");
|
||||||
_infoView->SetText("Cleared conversation history. Starting new context");
|
_infoView->SetText("Cleared conversation history. Starting new context");
|
||||||
_inputField->SetText("");
|
_inputField->SetText("");
|
||||||
_answerView->SetText("");
|
_answerView->SetText("");
|
||||||
_conversation->ClearHistory();
|
_conversation->ClearHistory();
|
||||||
updateHistoryInfo();
|
updateHistoryInfo();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
||||||
case kModelSelected: {
|
case kModelSelected: {
|
||||||
|
|
||||||
printf("model selected");
|
printf("model selected");
|
||||||
|
@ -394,8 +377,8 @@ void MainWindow::MessageReceived(BMessage *message) {
|
||||||
}
|
}
|
||||||
_progress->SetMaxValue(100);
|
_progress->SetMaxValue(100);
|
||||||
_progress->SetTo(100);
|
_progress->SetTo(100);
|
||||||
|
|
||||||
updateHistoryInfo();
|
updateHistoryInfo();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -442,11 +425,10 @@ BMenuBar *MainWindow::_BuildMenu() {
|
||||||
item =
|
item =
|
||||||
new BMenuItem(B_TRANSLATE("Quit"), new BMessage(B_QUIT_REQUESTED), 'Q');
|
new BMenuItem(B_TRANSLATE("Quit"), new BMessage(B_QUIT_REQUESTED), 'Q');
|
||||||
menu->AddItem(item);
|
menu->AddItem(item);
|
||||||
|
|
||||||
|
|
||||||
menuBar->AddItem(menu);
|
menuBar->AddItem(menu);
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
menu = new BMenu(B_TRANSLATE("History"));
|
menu = new BMenu(B_TRANSLATE("History"));
|
||||||
|
|
||||||
|
@ -454,11 +436,8 @@ BMenuBar *MainWindow::_BuildMenu() {
|
||||||
new BMessage(kClearHistory));
|
new BMessage(kClearHistory));
|
||||||
item->SetTarget(this);
|
item->SetTarget(this);
|
||||||
menu->AddItem(item);
|
menu->AddItem(item);
|
||||||
|
|
||||||
|
|
||||||
menuBar->AddItem(menu);
|
menuBar->AddItem(menu);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return menuBar;
|
return menuBar;
|
||||||
}
|
}
|
||||||
|
|
67
MainWindow.h
67
MainWindow.h
|
@ -5,20 +5,18 @@
|
||||||
#ifndef MAINWINDOW_H
|
#ifndef MAINWINDOW_H
|
||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <MenuField.h>
|
||||||
#include <MenuItem.h>
|
#include <MenuItem.h>
|
||||||
#include <TextControl.h>
|
|
||||||
#include <TextView.h>
|
|
||||||
#include <StatusBar.h>
|
|
||||||
#include <Window.h>
|
|
||||||
#include <String.h>
|
|
||||||
#include <MessageRunner.h>
|
#include <MessageRunner.h>
|
||||||
#include <PopUpMenu.h>
|
#include <PopUpMenu.h>
|
||||||
#include <MenuField.h>
|
#include <StatusBar.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <TextControl.h>
|
||||||
|
#include <TextView.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
#include "Conversation.h"
|
#include "Conversation.h"
|
||||||
|
|
||||||
|
|
||||||
static const uint32 kCheckKey = 'chkk';
|
static const uint32 kCheckKey = 'chkk';
|
||||||
static const uint32 kMsgNewFile = 'fnew';
|
static const uint32 kMsgNewFile = 'fnew';
|
||||||
static const uint32 kMsgOpenFile = 'fopn';
|
static const uint32 kMsgOpenFile = 'fopn';
|
||||||
|
@ -30,10 +28,6 @@ static const uint32 kPulse = 'plse';
|
||||||
static const uint32 kSendPrompt = 'kspt';
|
static const uint32 kSendPrompt = 'kspt';
|
||||||
static const uint32 kQuestionChanged = 'kqch';
|
static const uint32 kQuestionChanged = 'kqch';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow : public BWindow {
|
class MainWindow : public BWindow {
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow();
|
||||||
|
@ -41,30 +35,43 @@ public:
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage *msg);
|
virtual void MessageReceived(BMessage *msg);
|
||||||
|
|
||||||
Conversation* _conversation = new Conversation(this);
|
// Overriding FrameResized to receive notifications on resize
|
||||||
|
void FrameResized(float newWidth, float newHeight) override {
|
||||||
|
printf("Window resized to: Width = %f, Height = %f\n", newWidth, newHeight);
|
||||||
|
// You can add additional handling code here if needed
|
||||||
|
|
||||||
|
// Resize the scroll view if necessary, otherwise we lose scroll ability
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Conversation *_conversation = new Conversation(this);
|
||||||
|
|
||||||
|
void checkValidKey();
|
||||||
|
|
||||||
|
void updateHistoryInfo();
|
||||||
|
|
||||||
void checkValidKey();
|
|
||||||
|
|
||||||
void updateHistoryInfo();
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ShowMissingKeyAlertAndQuit();
|
||||||
|
void SelectModelByName(const char *targetLabel);
|
||||||
|
|
||||||
void ShowMissingKeyAlertAndQuit();
|
bool waitMode = false;
|
||||||
void SelectModelByName(const char* targetLabel);
|
|
||||||
|
|
||||||
bool waitMode = false;
|
|
||||||
BMenuBar *_BuildMenu();
|
BMenuBar *_BuildMenu();
|
||||||
BTextView * _answerView;
|
|
||||||
BTextView * _infoConversation;
|
BTextView *_answerView;
|
||||||
BTextView * _infoView;
|
BScrollView *_answerScrollView;
|
||||||
BTextView* _inputField;
|
|
||||||
BStatusBar* _progress;
|
BTextView *_infoConversation;
|
||||||
BMenuField* _modelField;
|
BTextView *_infoView;
|
||||||
BPopUpMenu* _modelMenu;
|
BTextView *_inputField;
|
||||||
|
BStatusBar *_progress;
|
||||||
|
BMenuField *_modelField;
|
||||||
|
BPopUpMenu *_modelMenu;
|
||||||
BButton *_sendButton;
|
BButton *_sendButton;
|
||||||
|
|
||||||
// BMenuItem *fSaveMenuItem;
|
// BMenuItem *fSaveMenuItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
20
README.md
20
README.md
|
@ -1,3 +1,21 @@
|
||||||
# DumBer
|
# DumBer
|
||||||
|
|
||||||
A simple native Haiku OpenAI / ChatGPT Client
|
## A simple native Haiku OpenAI / ChatGPT Client
|
||||||
|
|
||||||
|
To be able to use this app you need an OpenAI account and to create a token ans save it as one text file in:
|
||||||
|
/boot/home/config/openai_key
|
||||||
|
|
||||||
|
# About code quality
|
||||||
|
|
||||||
|
## This app uses Haiku's Experimental API for higher level network
|
||||||
|
|
||||||
|
I just wanted to learn about Haiku code again. This is probably not the best place to look for examples of good code. I am not a good programmer but it works more or less.
|
||||||
|
|
||||||
|
https://www.haiku-os.org/docs/api/group__netservices.html
|
||||||
|
|
||||||
|
# License notes
|
||||||
|
|
||||||
|
This uses a MIT license because I couldn't think of anything simpler. Do what you want with this.
|
||||||
|
|
||||||
|
This app includes json code by Niels Lohmann.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue