2020-01-18 09:38:21 +01:00
/*
* Copyright ( c ) 2018 - 2020 , Andreas Kling < kling @ serenityos . org >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
*
* 1. Redistributions of source code must retain the above copyright notice , this
* list of conditions and the following disclaimer .
*
* 2. Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY ,
* OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2019-06-23 16:35:43 +02:00
# include "QSWidget.h"
2019-12-19 20:39:11 +01:00
# include <AK/URL.h>
2020-02-06 12:07:05 +01:00
# include <LibGfx/Bitmap.h>
2020-02-06 20:33:02 +01:00
# include <LibGUI/MessageBox.h>
# include <LibGUI/Painter.h>
# include <LibGUI/Window.h>
2019-06-23 16:35:43 +02:00
2020-02-02 15:07:41 +01:00
QSWidget : : QSWidget ( GUI : : Widget * parent )
: GUI : : Frame ( parent )
2019-06-23 16:35:43 +02:00
{
2020-02-06 11:56:38 +01:00
set_frame_shape ( Gfx : : FrameShape : : Container ) ;
set_frame_shadow ( Gfx : : FrameShadow : : Sunken ) ;
2019-06-23 16:35:43 +02:00
set_frame_thickness ( 2 ) ;
2019-06-30 17:20:31 +02:00
set_fill_with_background_color ( true ) ;
set_background_color ( Color : : Black ) ;
2019-06-23 16:35:43 +02:00
}
QSWidget : : ~ QSWidget ( )
{
}
2020-02-06 11:56:38 +01:00
void QSWidget : : set_bitmap ( NonnullRefPtr < Gfx : : Bitmap > bitmap )
2019-06-23 16:35:43 +02:00
{
m_bitmap = move ( bitmap ) ;
}
void QSWidget : : relayout ( )
{
2020-02-06 13:32:14 +01:00
Gfx : : Size new_size ;
2019-06-23 16:35:43 +02:00
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 ( ) ;
}
2020-02-02 15:07:41 +01:00
void QSWidget : : resize_event ( GUI : : ResizeEvent & event )
2019-06-23 16:35:43 +02:00
{
relayout ( ) ;
2020-02-02 15:07:41 +01:00
GUI : : Widget : : resize_event ( event ) ;
2019-06-23 16:35:43 +02:00
}
2020-02-02 15:07:41 +01:00
void QSWidget : : paint_event ( GUI : : PaintEvent & event )
2019-06-23 16:35:43 +02:00
{
2020-02-02 15:07:41 +01:00
GUI : : Painter painter ( * this ) ;
2019-06-23 16:35:43 +02:00
painter . add_clip_rect ( event . rect ( ) ) ;
painter . draw_scaled_bitmap ( m_bitmap_rect , * m_bitmap , m_bitmap - > rect ( ) ) ;
}
2020-02-02 15:07:41 +01:00
void QSWidget : : mousedown_event ( GUI : : MouseEvent & event )
2019-06-23 16:35:43 +02:00
{
2020-02-02 15:07:41 +01:00
if ( event . button ( ) ! = GUI : : MouseButton : : Left )
2019-06-23 16:35:43 +02:00
return ;
m_pan_origin = event . position ( ) ;
m_pan_bitmap_origin = m_bitmap_rect . location ( ) ;
}
2020-02-02 15:07:41 +01:00
void QSWidget : : mouseup_event ( GUI : : MouseEvent & event )
2019-06-23 16:35:43 +02:00
{
UNUSED_PARAM ( event ) ;
}
2020-02-02 15:07:41 +01:00
void QSWidget : : mousemove_event ( GUI : : MouseEvent & event )
2019-06-23 16:35:43 +02:00
{
2020-02-02 15:07:41 +01:00
if ( ! ( event . buttons ( ) & GUI : : MouseButton : : Left ) )
2019-06-23 16:35:43 +02:00
return ;
auto delta = event . position ( ) - m_pan_origin ;
m_bitmap_rect . set_location ( m_pan_bitmap_origin . translated ( delta ) ) ;
update ( ) ;
}
2020-02-02 15:07:41 +01:00
void QSWidget : : mousewheel_event ( GUI : : MouseEvent & event )
2019-06-23 16:35:43 +02:00
{
auto old_scale = m_scale ;
2019-06-30 15:01:35 +02:00
auto old_scale_factor = ( float ) m_scale / 100.0f ;
auto zoom_point = event . position ( ) . translated ( - m_bitmap_rect . location ( ) ) ;
zoom_point . set_x ( ( float ) zoom_point . x ( ) / old_scale_factor ) ;
zoom_point . set_y ( ( float ) zoom_point . y ( ) / old_scale_factor ) ;
2019-06-23 16:35:43 +02:00
m_scale + = - event . wheel_delta ( ) * 10 ;
if ( m_scale < 10 )
m_scale = 10 ;
if ( m_scale > 1000 )
m_scale = 1000 ;
relayout ( ) ;
2019-06-30 15:01:35 +02:00
auto new_scale_factor = ( float ) m_scale / 100.0f ;
auto scale_factor_change = new_scale_factor - old_scale_factor ;
2020-02-06 13:08:32 +01:00
m_bitmap_rect . move_by ( - Gfx : : Point ( ( float ) zoom_point . x ( ) * scale_factor_change , ( float ) zoom_point . y ( ) * scale_factor_change ) ) ;
2019-06-23 16:35:43 +02:00
if ( old_scale ! = m_scale ) {
if ( on_scale_change )
on_scale_change ( m_scale ) ;
}
}
2019-12-19 20:39:11 +01:00
void QSWidget : : set_path ( const String & path )
{
m_path = path ;
}
2020-02-02 15:07:41 +01:00
void QSWidget : : drop_event ( GUI : : DropEvent & event )
2019-12-19 20:39:11 +01:00
{
event . accept ( ) ;
window ( ) - > move_to_front ( ) ;
if ( event . data_type ( ) = = " url-list " ) {
auto lines = event . data ( ) . split_view ( ' \n ' ) ;
if ( lines . is_empty ( ) )
return ;
if ( lines . size ( ) > 1 ) {
2020-02-02 15:07:41 +01:00
GUI : : MessageBox : : show ( " QuickShow can only open one file at a time! " , " One at a time please! " , GUI : : MessageBox : : Type : : Error , GUI : : MessageBox : : InputType : : OK , window ( ) ) ;
2019-12-19 20:39:11 +01:00
return ;
}
URL url ( lines [ 0 ] ) ;
2020-02-06 11:56:38 +01:00
auto bitmap = Gfx : : Bitmap : : load_from_file ( url . path ( ) ) ;
2019-12-19 20:39:11 +01:00
if ( ! bitmap ) {
2020-02-02 15:07:41 +01:00
GUI : : MessageBox : : show ( String : : format ( " Failed to open %s " , url . to_string ( ) . characters ( ) ) , " Cannot open image " , GUI : : MessageBox : : Type : : Error , GUI : : MessageBox : : InputType : : OK , window ( ) ) ;
2019-12-19 20:39:11 +01:00
return ;
}
m_path = url . path ( ) ;
m_bitmap = bitmap ;
m_scale = 100 ;
if ( on_scale_change )
on_scale_change ( m_scale ) ;
relayout ( ) ;
m_bitmap_rect . center_within ( rect ( ) ) ;
}
}