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