summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-06-23 16:35:43 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-06-23 16:35:43 +0200
commiteedb4f6b2f60d1b80aa8d17eaace5d213b7be82d (patch)
treee739acd526099fd4186badd2be9d294a48e82833
parentcf0d05d54a54279cf4f543c4bb9c674c66b54e57 (diff)
downloadserenity-eedb4f6b2f60d1b80aa8d17eaace5d213b7be82d.zip
QuickShow: Allow panning and zooming the image instead of stretching it.
This needs more work and polish, but it's a step in a more pleasant and useful direction. Also turn QuickShow into a fully-fledged "application". (By that, I really just mean giving it its own Applications/ subdirectory.)
-rw-r--r--Applications/QuickShow/.gitignore3
-rw-r--r--Applications/QuickShow/Makefile23
-rw-r--r--Applications/QuickShow/QSWidget.cpp85
-rw-r--r--Applications/QuickShow/QSWidget.h32
-rw-r--r--Applications/QuickShow/main.cpp (renamed from Userland/qs.cpp)24
-rwxr-xr-xKernel/build-root-filesystem.sh2
-rwxr-xr-xKernel/makeall.sh1
7 files changed, 157 insertions, 13 deletions
diff --git a/Applications/QuickShow/.gitignore b/Applications/QuickShow/.gitignore
new file mode 100644
index 0000000000..a16f4d2dda
--- /dev/null
+++ b/Applications/QuickShow/.gitignore
@@ -0,0 +1,3 @@
+*.o
+*.d
+QuickShow
diff --git a/Applications/QuickShow/Makefile b/Applications/QuickShow/Makefile
new file mode 100644
index 0000000000..8fce186807
--- /dev/null
+++ b/Applications/QuickShow/Makefile
@@ -0,0 +1,23 @@
+include ../../Makefile.common
+
+OBJS = \
+ QSWidget.o \
+ main.o
+
+APP = QuickShow
+
+DEFINES += -DUSERLAND
+
+all: $(APP)
+
+$(APP): $(OBJS)
+ $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -lcore -lc
+
+.cpp.o:
+ @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
+
+-include $(OBJS:%.o=%.d)
+
+clean:
+ @echo "CLEAN"; rm -f $(APP) $(OBJS) *.d
+
diff --git a/Applications/QuickShow/QSWidget.cpp b/Applications/QuickShow/QSWidget.cpp
new file mode 100644
index 0000000000..1aa667d03b
--- /dev/null
+++ b/Applications/QuickShow/QSWidget.cpp
@@ -0,0 +1,85 @@
+#include "QSWidget.h"
+#include <LibGUI/GPainter.h>
+#include <SharedGraphics/GraphicsBitmap.h>
+
+QSWidget::QSWidget(GWidget* parent)
+ : GFrame(parent)
+{
+ set_frame_shape(FrameShape::Container);
+ set_frame_shadow(FrameShadow::Sunken);
+ set_frame_thickness(2);
+
+ set_background_color(Color::White);
+}
+
+QSWidget::~QSWidget()
+{
+}
+
+void QSWidget::set_bitmap(NonnullRefPtr<GraphicsBitmap> bitmap)
+{
+ set_fill_with_background_color(bitmap->has_alpha_channel());
+ m_bitmap = move(bitmap);
+}
+
+void QSWidget::relayout()
+{
+ Size new_size;
+ float scale_factor = (float)m_scale / 100.0f;
+ new_size.set_width(m_bitmap->width() * scale_factor);
+ new_size.set_height(m_bitmap->height() * scale_factor);
+ m_bitmap_rect.set_size(new_size);
+ update();
+}
+
+void QSWidget::resize_event(GResizeEvent& event)
+{
+ relayout();
+ GWidget::resize_event(event);
+}
+
+void QSWidget::paint_event(GPaintEvent& event)
+{
+ GPainter painter(*this);
+ painter.add_clip_rect(event.rect());
+
+ painter.draw_scaled_bitmap(m_bitmap_rect, *m_bitmap, m_bitmap->rect());
+}
+
+void QSWidget::mousedown_event(GMouseEvent& event)
+{
+ if (event.button() != GMouseButton::Left)
+ return;
+ m_pan_origin = event.position();
+ m_pan_bitmap_origin = m_bitmap_rect.location();
+}
+
+void QSWidget::mouseup_event(GMouseEvent& event)
+{
+ UNUSED_PARAM(event);
+}
+
+void QSWidget::mousemove_event(GMouseEvent& event)
+{
+ if (!(event.buttons() & GMouseButton::Left))
+ return;
+
+ auto delta = event.position() - m_pan_origin;
+ m_bitmap_rect.set_location(m_pan_bitmap_origin.translated(delta));
+ update();
+}
+
+void QSWidget::mousewheel_event(GMouseEvent& event)
+{
+ auto old_scale = m_scale;
+ m_scale += -event.wheel_delta() * 10;
+ if (m_scale < 10)
+ m_scale = 10;
+ if (m_scale > 1000)
+ m_scale = 1000;
+ relayout();
+ if (old_scale != m_scale) {
+ if (on_scale_change)
+ on_scale_change(m_scale);
+ }
+}
diff --git a/Applications/QuickShow/QSWidget.h b/Applications/QuickShow/QSWidget.h
new file mode 100644
index 0000000000..a4a2f69ff3
--- /dev/null
+++ b/Applications/QuickShow/QSWidget.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <LibGUI/GFrame.h>
+
+class GLabel;
+class QSLabel;
+
+class QSWidget final : public GFrame {
+public:
+ QSWidget(GWidget* parent);
+ virtual ~QSWidget() override;
+
+ void set_bitmap(NonnullRefPtr<GraphicsBitmap>);
+
+ Function<void(int)> on_scale_change;
+
+private:
+ virtual void paint_event(GPaintEvent&) override;
+ virtual void resize_event(GResizeEvent&) override;
+ virtual void mousedown_event(GMouseEvent&) override;
+ virtual void mouseup_event(GMouseEvent&) override;
+ virtual void mousemove_event(GMouseEvent&) override;
+ virtual void mousewheel_event(GMouseEvent&) override;
+
+ void relayout();
+
+ RefPtr<GraphicsBitmap> m_bitmap;
+ Rect m_bitmap_rect;
+ int m_scale { 100 };
+ Point m_pan_origin;
+ Point m_pan_bitmap_origin;
+};
diff --git a/Userland/qs.cpp b/Applications/QuickShow/main.cpp
index f3ab074af9..97f992646a 100644
--- a/Userland/qs.cpp
+++ b/Applications/QuickShow/main.cpp
@@ -1,3 +1,4 @@
+#include "QSWidget.h"
#include <LibGUI/GAction.h>
#include <LibGUI/GApplication.h>
#include <LibGUI/GBoxLayout.h>
@@ -51,24 +52,21 @@ int main(int argc, char** argv)
auto* window = new GWindow;
+ auto update_window_title = [&](int scale) {
+ window->set_title(String::format("QuickShow: %s %s %d%%", path, bitmap->size().to_string().characters(), scale));
+ };
+
window->set_double_buffering_enabled(false);
- window->set_title(String::format("QuickShow: %s %s", path, bitmap->size().to_string().characters()));
+ update_window_title(100);
window->set_rect(200, 200, bitmap->width(), bitmap->height());
- auto* widget = new GWidget;
+ auto* widget = new QSWidget(nullptr);
+ widget->on_scale_change = [&](int scale) {
+ update_window_title(scale);
+ };
+ widget->set_bitmap(*bitmap);
window->set_main_widget(widget);
- if (bitmap->has_alpha_channel()) {
- widget->set_background_color(Color::White);
- widget->set_fill_with_background_color(true);
- }
-
- widget->set_layout(make<GBoxLayout>(Orientation::Vertical));
-
- auto* label = new GLabel(widget);
- label->set_icon(move(bitmap));
- label->set_should_stretch_icon(true);
-
window->set_should_exit_event_loop_on_close(true);
window->show();
diff --git a/Kernel/build-root-filesystem.sh b/Kernel/build-root-filesystem.sh
index 8850ed8b65..2ceb29e49b 100755
--- a/Kernel/build-root-filesystem.sh
+++ b/Kernel/build-root-filesystem.sh
@@ -72,6 +72,7 @@ cp ../Applications/Taskbar/Taskbar mnt/bin/Taskbar
cp ../Applications/Terminal/Terminal mnt/bin/Terminal
cp ../Applications/TextEditor/TextEditor mnt/bin/TextEditor
cp ../Applications/PaintBrush/PaintBrush mnt/bin/PaintBrush
+cp ../Applications/QuickShow/QuickShow mnt/bin/QuickShow
cp ../Demos/HelloWorld/HelloWorld mnt/bin/HelloWorld
cp ../Demos/RetroFetch/RetroFetch mnt/bin/RetroFetch
cp ../Demos/WidgetGallery/WidgetGallery mnt/bin/WidgetGallery
@@ -99,6 +100,7 @@ ln -s VisualBuilder mnt/bin/vb
ln -s WidgetGallery mnt/bin/wg
ln -s TextEditor mnt/bin/te
ln -s PaintBrush mnt/bin/pb
+ln -s QuickShow mnt/bin/qs
echo "done"
# Run local sync script, if it exists
diff --git a/Kernel/makeall.sh b/Kernel/makeall.sh
index 12d5edfb7b..6ab41fec29 100755
--- a/Kernel/makeall.sh
+++ b/Kernel/makeall.sh
@@ -30,6 +30,7 @@ build_targets="$build_targets ../Applications/IRCClient"
build_targets="$build_targets ../Applications/Taskbar"
build_targets="$build_targets ../Applications/Downloader"
build_targets="$build_targets ../Applications/PaintBrush"
+build_targets="$build_targets ../Applications/QuickShow"
build_targets="$build_targets ../DevTools/VisualBuilder"
build_targets="$build_targets ../Games/Minesweeper"
build_targets="$build_targets ../Games/Snake"