Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file image.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281(*********************************************************************************)(* OCaml-Stk *)(* *)(* Copyright (C) 2023-2024 INRIA All rights reserved. *)(* Author: Maxence Guesdon, INRIA Saclay *)(* *)(* This program is free software; you can redistribute it and/or modify *)(* it under the terms of the GNU General Public License as *)(* published by the Free Software Foundation, version 3 of the License. *)(* *)(* This program is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU General Public License for more details. *)(* *)(* You should have received a copy of the GNU General Public *)(* License along with this program; if not, write to the Free Software *)(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)(* 02111-1307 USA *)(* *)(* As a special exception, you have permission to link this program *)(* with the OCaml compiler and distribute executables, as long as you *)(* follow the requirements of the GNU GPL in regard to all of the *)(* software in the executable aside from the OCaml compiler. *)(* *)(* Contact: Maxence.Guesdon@inria.fr *)(* *)(*********************************************************************************)(** Image widget. *)openTsdlopenTsdl_imageopenMisc(** Property ["image-keep-ratio"] to indicate whether image ratio must be
perserved. Default is [true].
Keeping ratio means that when width is set with
{{!image.set_width}image#set_width}, height of rendered image will
be set accordingly.
If height is set with {{!image.set_height}image#set_height}, width or rendered image
will be set accordingly.
*)letkeep_ratio=Props.(bool_prop~after:[Resize]~default:true~inherited:false"image_keep_ratio")letcss_keep_ratio=Theme.bool_propkeep_ratio(** Property ["image-autosize"] to indicate whether image must fit in
allocated geometry. Default is [false].*)letautosize=Props.(bool_prop~after:[Resize]~default:false~inherited:false"image_autosize")letcss_autosize=Theme.bool_propautosize(** A widget to display an image. *)classimage?classes?name?props?wdata()=object(self)inheritWidget.widget?classes?name?props?wdata()assuper(**/**)valmutablesurface=Nonevalmutableimage_texture=Nonevalmutableratio=Nonevalmutablelast_set=(None:[`W|`H]option)methodkind="image"(**/**)(** {2 Properties} *)methodwidth=self#opt_pProps.widthmethodset_widthw=self#destroy_image_texture;(matchself#keep_ratio,ratiowith|true,Somer->leth=truncate(floatw/.r)inProps.setpropsProps.heighth|_,_->());last_set<-Some`W;self#set_pProps.widthw;self#need_render~layer:self#layergmethodheight=self#opt_pProps.heightmethodset_heighth=self#destroy_image_texture;(matchself#keep_ratio,ratiowith|true,Somer->letw=truncate(floath*.r)inProps.setpropsProps.widthw|_,_->());last_set<-Some`H;self#set_pProps.heighth;self#need_render~layer:self#layergmethodkeep_ratio=self#get_pkeep_ratiomethodset_keep_ratio=self#set_pkeep_ratiomethodautosize=self#get_pautosizemethodset_autosize=self#set_pautosize(**/**)methoddestroy_image_texture=matchimage_texturewith|None->()|Somet->Texture.destroyt;image_texture<-Nonemethod!min_width_=ifself#autosizethen0elsematchself#widthwith|Somex->x|None->matchsurfacewith|None->0|Somes->fst(Tsdl.Sdl.get_surface_sizes)method!min_height_=ifself#autosizethen0elsematchself#heightwith|Somex->x|None->matchsurfacewith|None->0|Somes->snd(Tsdl.Sdl.get_surface_sizes)method!max_width=ifself#autosizethenNoneelseSomeself#min_widthmethod!max_height=ifself#autosizethenNoneelseSomeself#min_height(**/**)(** Returns orignal (width, height) of image, if an image is loaded. *)methodimage_size=Option.mapTsdl.Sdl.get_surface_sizesurface(**/**)methodprivateupdate_from_ratio=matchlast_set,ratiowith|None,_|_,None->()|Some`H,Somer->(matchself#heightwith|None->()|Someh->letw=truncate(floath*.r)inProps.setpropsProps.widthw)|Some`W,Somer->(matchself#widthwith|None->()|Somew->leth=truncate(floatw/.r)inProps.setpropsProps.heighth)methodprivateset_surfaces=self#destroy_surface;surface<-Somes;let(w,h)=Tsdl.Sdl.get_surface_sizesinratio<-Some(floatw/.floath);ifself#keep_ratiothenself#update_from_ratio;self#need_resizemethod!set_geometrygeom=letold_g=ginsuper#set_geometrygeom;matchself#autosizewith|false->()|truewhenold_g=g->()|true->matchself#keep_ratio,ratiowith|false,_->self#set_widthg_inner.w;self#set_heightg_inner.h|_,None->()|true,Somerwhenr>=1.->self#set_widthg_inner.w;Option.iter(funh->ifh>g_inner.hthenself#set_heightg_inner.h)self#height|true,Somer->self#set_heightg_inner.h;Option.iter(funw->ifw>g_inner.wthenself#set_widthg_inner.w)self#width(**/**)(** Load image from rw operations.
Beware that this may be a io-blocking operation. *)methodload_rwrw=matchImage.load_rwrwtruewith|Error(`Msgmsg)->Log.err(funm->m"%s: Could not load image from data: %s"self#memsg)|Oks->Gc.finalise(funs->Tsdl.Sdl.free_surfaces)s;self#set_surfaces(** Load image from file.
Beware that this is a io-blocking operation. *)methodload_filefile=matchImage.loadfilewith|Error(`Msgmsg)->Log.err(funm->m"%s: Could not load image from %S: %s"self#mefilemsg)|Oks->Gc.finalise(funs->Tsdl.Sdl.free_surfaces)s;self#set_surfaces(** Return the (unscaled) image surface, if any.*)methodsurface=surface(**/**)methoddestroy_surface=(matchsurfacewith|None->()|Somes->surface<-None);self#destroy_image_texturemethod!render_me~layerrend~offsetgeom=super#render_with_prepare~layerrend~offsetgeommethod!prepare~(layer:Layer.t)(rend:Sdl.renderer)(geom:G.t)=iflayer=self#get_pProps.layerthen(matchself#image_texturerendwith|None->[%debug"%s#render_me: no texture"self#me];None|Somet->Somet)elseNonemethodprivateimage_texturerend=matchimage_texturewith|None->ifg_inner.w>0&&g_inner.h>0then(matchsurfacewith|None->None|Somes->lett=matchself#width,self#heightwith|None,None->(* no scaling *)Texture.from_surfacerends|_->let(w0,h0)=Tsdl.Sdl.get_surface_sizesinlet>t=Sdl.create_texture_from_surfacerendsinTexture.finalise_sdl_texturet;letw=Option.value~default:w0self#widthinleth=Option.value~default:h0self#heightinTexture.from_scaled_texturerend~w~htinimage_texture<-Somet;image_texture)elseNone|x->xend(** Convenient function to create a {!class-image}.
Optional arguments:
{ul
{- [width] specifies width of rendered image.}
{- [height] specifies height of renderer image.}
{- [file] specifies a file to load an image from.}
{- [keep_ratio] specifies the {!val-keep_ratio} property.}
{- [autosize] specifies the {!val-autosize} property.}
}
See {!Widget.widget_arguments} for other arguments. *)letimage?classes?name?props?wdata?width?height?keep_ratio?autosize?file?pack()=letw=newimage?classes?name?props?wdata()inOption.iterw#set_keep_ratiokeep_ratio;Option.iterw#set_autosizeautosize;Option.iterw#set_widthwidth;Option.iterw#set_heightheight;Option.iterw#load_filefile;Widget.may_pack?packw;w