hrev54951 adds 1 changeset to branch 'master'
old head: a2def606ed45418934a4d17550627c740528a87f
new head: a7cda277319a10f392afa58773b1ba86b54eb6e5
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=a7cda277319a+%5Ea2def606ed45
----------------------------------------------------------------------------
a7cda277319a: Mandelbrot: Implement fullscreen and saving
* Fullscreen view without window border or deskbar
* Save current view as .png
Change-Id: I8abbc7c5dc0af06ee26aa29afdef79a41944438c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/867
Reviewed-by: humdinger <humdingerb@xxxxxxxxx>
Reviewed-by: Ryan Leavengood <leavengood@xxxxxxxxx>
[ kerwizzy <kerwizzy@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev54951
Commit: a7cda277319a10f392afa58773b1ba86b54eb6e5
URL: https://git.haiku-os.org/haiku/commit/?id=a7cda277319a
Author: kerwizzy <kerwizzy@xxxxxxxxx>
Date: Thu Jan 10 01:17:47 2019 UTC
Committer: Niels Sascha Reedijk <niels.reedijk@xxxxxxxxx>
Commit-Date: Mon Feb 8 19:37:10 2021 UTC
----------------------------------------------------------------------------
3 files changed, 204 insertions(+), 11 deletions(-)
src/apps/mandelbrot/FractalEngine.cpp | 2 +-
src/apps/mandelbrot/Jamfile | 2 +-
src/apps/mandelbrot/Mandelbrot.cpp | 211 ++++++++++++++++++++++++++++--
----------------------------------------------------------------------------
diff --git a/src/apps/mandelbrot/FractalEngine.cpp
b/src/apps/mandelbrot/FractalEngine.cpp
index e0927c0549..32e0dd28e0 100644
--- a/src/apps/mandelbrot/FractalEngine.cpp
+++ b/src/apps/mandelbrot/FractalEngine.cpp
@@ -221,7 +221,7 @@ void FractalEngine::Render(double locationX, double
locationY, double size)
fLocationY = locationY;
fSize = size;
- TRACE("Location: %g;%g;%g\n", fLocationX, fLocationY, fSize);
+ TRACE("Location (%%.100g): %.100g;%.100g;%.100g\n", fLocationX,
fLocationY, fSize);
for (uint8 i = 0; i < fThreadCount; i++) {
release_sem(fRenderSem);
diff --git a/src/apps/mandelbrot/Jamfile b/src/apps/mandelbrot/Jamfile
index 690ddce62d..2bf6c7dd7c 100644
--- a/src/apps/mandelbrot/Jamfile
+++ b/src/apps/mandelbrot/Jamfile
@@ -7,7 +7,7 @@ UsePrivateHeaders interface shared system ;
Application Mandelbrot :
Mandelbrot.cpp
FractalEngine.cpp
- : be [ TargetLibsupc++ ] localestub
+ : be [ TargetLibsupc++ ] localestub tracker translation
: Mandelbrot.rdef
;
diff --git a/src/apps/mandelbrot/Mandelbrot.cpp
b/src/apps/mandelbrot/Mandelbrot.cpp
index 9fac754046..ede3da1832 100644
--- a/src/apps/mandelbrot/Mandelbrot.cpp
+++ b/src/apps/mandelbrot/Mandelbrot.cpp
@@ -11,11 +11,23 @@
#include <AboutWindow.h>
#include <Application.h>
#include <Bitmap.h>
+#include <BitmapStream.h>
+#include <String.h>
#include <Catalog.h>
+#include <Directory.h>
+#include <File.h>
+#include <FilePanel.h>
+#include <FindDirectory.h>
#include <MenuBar.h>
+#include <NodeInfo.h>
+#include <Path.h>
+#include <TranslationUtils.h>
+#include <TranslatorRoster.h>
#include <LayoutBuilder.h>
#include <View.h>
#include <Window.h>
+#include <Screen.h>
+#include <ScrollView.h>
#include <algorithm>
@@ -62,7 +74,16 @@ public:
void RedrawFractal();
void UpdateSize();
void CreateDisplayBitmap(uint16 width, uint16 height);
+
+ void StartSave();
+ void WriteImage(entry_ref*, char*);
+ void EndSave();
+
FractalEngine* fFractalEngine;
+ enum {
+ MSG_START_SAVE,
+ MSG_WRITE_IMAGE
+ };
private:
BRect GetDragFrame();
@@ -77,6 +98,10 @@ private:
double fLocationX;
double fLocationY;
double fSize;
+
+ BFilePanel* fSavePanel;
+
+ bool fSaving;
};
@@ -88,7 +113,9 @@ FractalView::FractalView()
fDisplayBitmap(NULL),
fLocationX(0),
fLocationY(0),
- fSize(0.005)
+ fSize(0.005),
+ fSavePanel(NULL),
+ fSaving(false)
{
SetHighColor(make_color(255, 255, 255, 255));
}
@@ -128,15 +155,15 @@ void FractalView::UpdateSize()
TRACE("Update Size\n");
BMessage msg(FractalEngine::MSG_RESIZE);
- uint16 width = (uint16)Frame().Width()+1;
- uint16 height = (uint16)Frame().Height()+1;
+ uint16 width = (uint16)Frame().Width();
+ uint16 height = (uint16)Frame().Height();
msg.AddUInt16("width", width);
msg.AddUInt16("height", height);
- CreateDisplayBitmap(width,height);
+ CreateDisplayBitmap(width, height);
- msg.AddPointer("bitmap",fDisplayBitmap);
+ msg.AddPointer("bitmap", fDisplayBitmap);
fFractalEngine->PostMessage(&msg); // Create the new buffer
}
@@ -287,6 +314,24 @@ void FractalView::MessageReceived(BMessage* msg)
ImportBitsAndInvalidate();
break;
+ case MSG_WRITE_IMAGE: {
+ delete fSavePanel;
+ fSavePanel = NULL;
+
+ entry_ref dirRef;
+ char* name;
+ msg->FindRef("directory", &dirRef);
+ msg->FindString((const char*)"name", (const char**) &name);
+
+ WriteImage(&dirRef, name);
+ break;
+ }
+
+ case B_CANCEL:
+ // image is frozen before the FilePanel is shown
+ EndSave();
+ break;
+
default:
BView::MessageReceived(msg);
break;
@@ -302,6 +347,10 @@ void FractalView::Pulse()
void FractalView::ImportBitsAndInvalidate()
{
+ if (fSaving) {
+ TRACE("Not importing bits because saving.\n");
+ return;
+ }
TRACE("Importing bits...\n");
fFractalEngine->WriteToBitmap(fDisplayBitmap);
@@ -328,6 +377,56 @@ void FractalView::Draw(BRect updateRect)
}
+void FractalView::StartSave() {
+ TRACE("Got to start save\n");
+ fSaving = true;
+
+ BMessenger messenger(this);
+ BMessage message(MSG_WRITE_IMAGE);
+ fSavePanel = new BFilePanel(B_SAVE_PANEL, &messenger, 0, 0, false,
+ &message);
+ BString* filename = new BString();
+ filename->SetToFormat("%g-%g-%g.png", fLocationX, fLocationY, fSize);
+
+ fSavePanel->SetSaveText(filename->String());
+ fSavePanel->Show();
+}
+
+
+void FractalView::WriteImage(entry_ref* dirRef, char* name)
+{
+ TRACE("Got to write save handler\n");
+
+ BFile file;
+ BDirectory parentDir(dirRef);
+ parentDir.CreateFile(name, &file);
+
+ // Write the screenshot bitmap to the file
+ BBitmapStream stream(fDisplayBitmap);
+ BTranslatorRoster* roster = BTranslatorRoster::Default();
+ roster->Translate(&stream, NULL, NULL, &file, B_PNG_FORMAT,
+ B_TRANSLATOR_BITMAP);
+
+ BNodeInfo info(&file);
+ if (info.InitCheck() == B_OK)
+ info.SetType("image/png");
+
+ BBitmap* bitmap;
+ stream.DetachBitmap(&bitmap);
+ // The stream takes over ownership of the bitmap
+
+ // unfreeze the image, image was frozen before invoke of FilePanel
+ EndSave();
+}
+
+
+void FractalView::EndSave()
+{
+ fSaving = false;
+ ImportBitsAndInvalidate();
+}
+
+
// #pragma mark - MandelbrotWindow
@@ -363,14 +462,24 @@ public:
MSG_SUBSAMPLING_1,
MSG_SUBSAMPLING_2,
MSG_SUBSAMPLING_3,
- MSG_SUBSAMPLING_4
+ MSG_SUBSAMPLING_4,
+
+ MSG_TOGGLE_FULLSCREEN
};
MandelbrotWindow(BRect frame);
~MandelbrotWindow() {}
+ void ToggleFullscreen();
+
+ virtual void DispatchMessage(BMessage* message, BHandler* target);
virtual void MessageReceived(BMessage* msg);
virtual bool QuitRequested();
+ bool fFullScreen;
+
+ BMenuBar* fMenuBar;
+ BRect fWindowFrame;
+
private:
FractalView* fFractalView;
};
@@ -382,16 +491,24 @@ MandelbrotWindow::MandelbrotWindow(BRect frame)
B_NORMAL_WINDOW_FEEL, 0L),
fFractalView(new FractalView)
{
- BMenuBar* menuBar = new BMenuBar("MenuBar");
+ fFullScreen = false;
+ fMenuBar = new BMenuBar("MenuBar");
BMenu* setMenu;
BMenu* paletteMenu;
BMenu* iterMenu;
BMenu* subsamplingMenu;
- BLayoutBuilder::Menu<>(menuBar)
+ BLayoutBuilder::Menu<>(fMenuBar)
.AddMenu(B_TRANSLATE("File"))
+ .AddItem(B_TRANSLATE("Save as image" B_UTF8_ELLIPSIS),
+ FractalView::MSG_START_SAVE, 'S')
+ .AddSeparator()
.AddItem(B_TRANSLATE("About"), B_ABOUT_REQUESTED)
.AddItem(B_TRANSLATE("Quit"), B_QUIT_REQUESTED, 'Q')
.End()
+ .AddMenu(B_TRANSLATE("View"))
+ .AddItem(B_TRANSLATE("Full screen"),
MSG_TOGGLE_FULLSCREEN,
+ B_RETURN)
+ .End()
.AddMenu(B_TRANSLATE("Set"))
.GetMenu(setMenu)
.AddItem(B_TRANSLATE("Mandelbrot"), MSG_MANDELBROT_SET)
@@ -442,11 +559,39 @@ MandelbrotWindow::MandelbrotWindow(BRect frame)
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
.SetInsets(0)
- .Add(menuBar)
+ .Add(fMenuBar)
.Add(fFractalView)
.End();
}
+void
+MandelbrotWindow::ToggleFullscreen() {
+ BRect frame;
+ fFullScreen = !fFullScreen;
+ if (fFullScreen) {
+ TRACE("Enabling fullscreen\n");
+ BScreen screen;
+ fWindowFrame = Frame();
+ frame = screen.Frame();
+ frame.top -= fMenuBar->Bounds().Height() + 1;
+
+ SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
+
+ Activate();
+ // make the window frontmost
+ } else {
+ TRACE("Disabling fullscreen\n");
+ frame = fWindowFrame;
+
+ SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
+ }
+
+ MoveTo(frame.left, frame.top);
+ ResizeTo(frame.Width(), frame.Height());
+
+ Layout(false);
+}
+
#define HANDLE_SET(uiwhat, id) \
case uiwhat: { \
@@ -481,6 +626,37 @@ MandelbrotWindow::MandelbrotWindow(BRect frame)
fFractalView->RedrawFractal(); \
break; \
}
+
+
+void
+MandelbrotWindow::DispatchMessage(BMessage* message, BHandler* target)
+{
+ const char* bytes;
+ int32 modifierKeys;
+ if ((message->what == B_KEY_DOWN || message->what ==
B_UNMAPPED_KEY_DOWN)
+ && message->FindString("bytes", &bytes) == B_OK
+ && message->FindInt32("modifiers", &modifierKeys) == B_OK) {
+ if (bytes[0] == B_FUNCTION_KEY) {
+ // Matches WebPositive fullscreen key (F11)
+ int32 key;
+ if (message->FindInt32("key", &key) == B_OK) {
+ switch (key) {
+ case B_F11_KEY: {
+ ToggleFullscreen();
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ BWindow::DispatchMessage(message, target);
+}
+
+
void
MandelbrotWindow::MessageReceived(BMessage* msg)
{
@@ -515,6 +691,15 @@ MandelbrotWindow::MessageReceived(BMessage* msg)
HANDLE_SUBSAMPLING(MSG_SUBSAMPLING_3, 3)
HANDLE_SUBSAMPLING(MSG_SUBSAMPLING_4, 4)
+ case FractalView::MSG_START_SAVE: {
+ fFractalView->StartSave();
+ break;
+ }
+
+ case MSG_TOGGLE_FULLSCREEN:
+ ToggleFullscreen();
+ break;
+
case B_ABOUT_REQUESTED: {
BAboutWindow* wind = new BAboutWindow("Mandelbrot",
"application/x-vnd.Haiku-Mandelbrot");
@@ -530,6 +715,14 @@ MandelbrotWindow::MessageReceived(BMessage* msg)
break;
}
+ case B_KEY_DOWN: {
+ int8 val;
+ if (msg->FindInt8("byte", &val) == B_OK && val == B_ESCAPE
+ && fFullScreen)
+ ToggleFullscreen();
+ break;
+ }
+
default:
BWindow::MessageReceived(msg);
break;