1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 20:58:11 +00:00

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.)
This commit is contained in:
Andreas Kling 2019-06-23 16:35:43 +02:00
parent cf0d05d54a
commit eedb4f6b2f
7 changed files with 157 additions and 13 deletions

3
Applications/QuickShow/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.o
*.d
QuickShow

View file

@ -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

View file

@ -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);
}
}

View file

@ -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;
};

View file

@ -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();

View file

@ -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

View file

@ -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"