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"
2020-02-06 20:33:02 +01:00
# include <LibGUI/MessageBox.h>
# include <LibGUI/Painter.h>
# include <LibGUI/Window.h>
2020-02-14 13:18:34 +01:00
# include <LibGfx/Bitmap.h>
2020-04-05 13:13:32 +02:00
# include <LibGfx/Palette.h>
2019-06-23 16:35:43 +02:00
2020-02-23 12:07:13 +01:00
QSWidget : : QSWidget ( )
2019-06-23 16:35:43 +02:00
{
2020-04-05 13:13:32 +02:00
set_fill_with_background_color ( false ) ;
2019-06-23 16:35:43 +02:00
}
QSWidget : : ~ QSWidget ( )
{
}
void QSWidget : : relayout ( )
{
2020-04-05 09:26:29 +02:00
if ( m_bitmap . is_null ( ) )
return ;
2019-06-23 16:35:43 +02:00
float scale_factor = ( float ) m_scale / 100.0f ;
2020-04-05 20:25:14 +02:00
Gfx : : Size new_size ;
2019-06-23 16:35:43 +02:00
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 ) ;
2020-04-05 20:25:14 +02:00
Gfx : : Point new_location ;
new_location . set_x ( ( width ( ) / 2 ) - ( new_size . width ( ) / 2 ) - ( m_pan_origin . x ( ) * scale_factor ) ) ;
new_location . set_y ( ( height ( ) / 2 ) - ( new_size . height ( ) / 2 ) - ( m_pan_origin . y ( ) * scale_factor ) ) ;
m_bitmap_rect . set_location ( new_location ) ;
2019-06-23 16:35:43 +02:00
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 ( ) ) ;
2020-04-05 13:13:32 +02:00
painter . fill_rect_with_checkerboard ( rect ( ) , { 8 , 8 } , palette ( ) . base ( ) . darkened ( 0.9 ) , palette ( ) . base ( ) ) ;
2020-04-05 20:25:14 +02:00
if ( ! m_bitmap . is_null ( ) )
painter . draw_scaled_bitmap ( m_bitmap_rect , * m_bitmap , m_bitmap - > rect ( ) ) ;
2019-06-23 16:35:43 +02:00
}
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 ;
2020-04-05 20:25:14 +02:00
m_click_position = event . position ( ) ;
m_saved_pan_origin = m_pan_origin ;
2019-06-23 16:35:43 +02:00
}
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 ;
2020-04-05 20:25:14 +02:00
auto delta = event . position ( ) - m_click_position ;
float scale_factor = ( float ) m_scale / 100.0f ;
m_pan_origin = m_saved_pan_origin . translated (
- delta . x ( ) / scale_factor ,
- delta . y ( ) / scale_factor ) ;
relayout ( ) ;
2019-06-23 16:35:43 +02:00
}
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 ;
2020-04-05 20:25:14 +02:00
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 ;
2020-04-05 20:25:14 +02:00
2019-06-30 15:01:35 +02:00
auto new_scale_factor = ( float ) m_scale / 100.0f ;
2020-04-05 20:25:14 +02:00
auto focus_point = Gfx : : FloatPoint (
m_pan_origin . x ( ) - ( ( float ) event . x ( ) - ( float ) width ( ) / 2.0 ) / old_scale_factor ,
m_pan_origin . y ( ) - ( ( float ) event . y ( ) - ( float ) height ( ) / 2.0 ) / old_scale_factor ) ;
m_pan_origin = Gfx : : FloatPoint (
focus_point . x ( ) - new_scale_factor / old_scale_factor * ( focus_point . x ( ) - m_pan_origin . x ( ) ) ,
focus_point . y ( ) - new_scale_factor / old_scale_factor * ( focus_point . y ( ) - m_pan_origin . y ( ) ) ) ;
relayout ( ) ;
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
2020-04-05 20:25:14 +02:00
void QSWidget : : load_from_file ( const String & path )
2019-12-19 20:39:11 +01:00
{
2020-04-05 20:25:14 +02:00
auto bitmap = Gfx : : Bitmap : : load_from_file ( path ) ;
if ( ! bitmap ) {
GUI : : MessageBox : : show ( String : : format ( " Failed to open %s " , path . characters ( ) ) , " Cannot open image " , GUI : : MessageBox : : Type : : Error , GUI : : MessageBox : : InputType : : OK , window ( ) ) ;
return ;
}
window ( ) - > resize ( bitmap - > size ( ) ) ;
2019-12-19 20:39:11 +01:00
m_path = path ;
2020-04-05 20:25:14 +02:00
m_bitmap = bitmap ;
m_scale = 100 ;
m_pan_origin = { 0 , 0 } ;
if ( on_scale_change )
on_scale_change ( m_scale ) ;
relayout ( ) ;
2019-12-19 20:39:11 +01:00
}
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 ( ) ;
2020-04-05 20:25:14 +02:00
if ( on_drop )
on_drop ( event ) ;
2019-12-19 20:39:11 +01:00
}