Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file scroll.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384open!ImportmoduleAdjustment=structtypet={mutablerange:int;mutableoffset:int;mutableon_offset_change:(int->unit[@sexp.opaque])}[@@derivingsexp_of]letcreate()={range=0;offset=0;on_offset_change=(fun_->())}letset_offset?(trigger_callback=true)to=leto'=max0(min(t.range-1)o)inift.offset<>o'then(t.offset<-o';iftrigger_callbackthent.on_offset_changeo');;letset_range?(trigger_callback=true)tr=t.range<-max0r;set_offset~trigger_callbacktt.offset;;endmoduleScroll_bar_mode=structtypet=|Fixedofint|Dynamicofint[@@derivingsexp_of]endmoduleMouse_mode=structtypet=|Middle|Ratio|Auto[@@derivingsexp_of]endletmap_rangerange1range2offset1=ifrange1=0then0else(letmap_rangerange1range2offset1=Float.(max0.(minrange2(range2*.offset1/.range1)))inletrndx=Float.to_int(x+.0.5)inrnd@@map_range(Float.of_intrange1)(Float.of_intrange2)(Float.of_intoffset1));;moduleScrollable=structtypet={adj:Adjustment.t;mutablescroll_window_size:int;mutablescroll_bar_mode:Scroll_bar_mode.t;mutablemin_scroll_bar_size:intoption;mutablemax_scroll_bar_size:intoption;mutablescroll_bar_size:int;mutablescroll_bar_offset:int;mutablemouse_mode:Mouse_mode.t;mutablepage_size:int;mutabledocument_size:int;mutableon_scrollbar_change:(unit->unit[@sexp.opaque])}[@@derivingsexp_of]letcreate()={adj=Adjustment.create();scroll_window_size=0;scroll_bar_mode=Fixed1;min_scroll_bar_size=None;max_scroll_bar_size=None;scroll_bar_size=0;scroll_bar_offset=0;mouse_mode=Middle;page_size=-1;document_size=-1;on_scrollbar_change=Fn.id};;letscroll_bar_stepst=t.scroll_window_size-t.scroll_bar_size+1letset_scroll_bar_offsetto=letoffset=max0(min(scroll_bar_stepst-1)o)inift.scroll_bar_offset<>offsetthen(t.scroll_bar_offset<-offset;t.on_scrollbar_change());;letscroll_of_windowtoffset=letoffset=map_range(t.adj.range-1)(scroll_bar_stepst-1)offsetinoffset;;letset_offset?(trigger_callback=true)to=Adjustment.set_offsett.adj~trigger_callbacko;set_scroll_bar_offsett(scroll_of_windowtt.adj.offset);;letset_range?(trigger_callback=true)tr=Adjustment.set_range~trigger_callbackt.adjr;set_scroll_bar_offsett(scroll_of_windowtt.adj.offset);;letscroll_bar_size_fixedtsize=letwsize=t.scroll_window_sizeinifwsize<=sizethenmax1(wsize-1)elsemax1size;;letscroll_bar_size_dynamictview_size=ift.adj.range<=1thent.scroll_window_sizeelseifview_size<=0thenmax1(t.scroll_window_size/max1t.adj.range)else(letrange=Float.of_intt.adj.rangeinletscroll_size=Float.of_int@@t.scroll_window_sizeinletview_size=Float.of_intview_sizeinletdoc_size=view_size+.rangeinFloat.to_int@@(scroll_size*.view_size/.doc_size));;letmin_scroll_bar_sizet=matcht.min_scroll_bar_sizewith|None->1|Somex->x;;letmax_scroll_bar_sizet=matcht.max_scroll_bar_sizewith|None->t.scroll_window_size|Somex->x;;letscroll_bar_sizet=letsize=max(min_scroll_bar_sizet)@@min(max_scroll_bar_sizet)@@matcht.scroll_bar_modewith|Fixedsize->scroll_bar_size_fixedtsize|Dynamicsize->scroll_bar_size_dynamictsizeinift.scroll_bar_size<>sizethen(t.scroll_bar_size<-size;t.on_scrollbar_change());size;;let_set_scroll_bar_offsetto=letoffset=max0(min(scroll_bar_stepst-1)o)inift.scroll_bar_offset<>offsetthen(t.scroll_bar_offset<-offset;t.on_scrollbar_change());;letwindow_of_scrolltoffset=map_range(scroll_bar_stepst-1)(t.adj.range-1)offset;;let_scroll_of_windowtoffset=letoffset=map_range(t.adj.range-1)(scroll_bar_stepst-1)offsetinoffset;;letincrt=ift.adj.range>=scroll_bar_stepstthenwindow_of_scrollt(t.scroll_bar_offset+1)elset.adj.offset+1;;letdecrt=ift.adj.range>=scroll_bar_stepstthenwindow_of_scrollt(t.scroll_bar_offset-1)elset.adj.offset-1;;letmouse_scale_ratiotscroll=letsteps=scroll_bar_stepstinletwsize=t.scroll_window_sizeinletdead_zone=wsize/5in(* ~10% at each end *)map_range(wsize-dead_zone-1)(steps-1)(scroll-(dead_zone/2));;letmouse_scale_middletscroll=letsize=scroll_bar_sizetinscroll-(size/2);;letmouse_scale_autotscroll=ifscroll_bar_sizet>t.scroll_window_size/2thenmouse_scale_ratiotscrollelsemouse_scale_middletscroll;;letscroll_of_mousetscroll=matcht.mouse_modewith|Middle->mouse_scale_middletscroll|Ratio->mouse_scale_ratiotscroll|Auto->mouse_scale_autotscroll;;letmouse_scrolltscroll=scroll_of_mousetscroll|>window_of_scrolltletcalculate_rangepage_sizedocument_size=document_size-page_size+1letupdate_page_and_document_sizestpagedoc=ift.page_size<>page||t.document_size<>docthen(t.page_size<-page;t.document_size<-doc;letrange=max0(calculate_ranget.page_sizet.document_size)inset_rangetrange;t.mouse_mode<-Auto;t.scroll_bar_mode<-Dynamict.page_size);;let_set_page_sizets=update_page_and_document_sizestst.document_sizelet_set_document_sizets=update_page_and_document_sizestt.page_sizeslet_page_prevt=t.adj.offset-t.page_sizelet_page_nextt=t.adj.offset+t.page_sizeendmoduleScroll_bar_style=structtypet=|Filled|Outline[@@derivingsexp_of]endmoduleOrientation=structtypet=|Horz|Vert[@@derivingsexp_of]endmoduleScrollbar=structtypet={scrollable:Scrollable.t;mutablebar_style:Scroll_bar_style.t;incr_key:(Notty.Unescape.key[@sexp.opaque]);decr_key:(Notty.Unescape.key[@sexp.opaque]);mutablebounds:Draw.rect;orientation:Orientation.t}[@@derivingsexp_of]lethbar=0x2550letvbar=0x2551letfilled=0x2588letmouse_offset(t:t)~row~col=matcht.orientationwith|Horz->col-t.bounds.c|Vert->row-t.bounds.r;;letset_boundst(bounds:Draw.rect)=(matcht.orientationwith|Horz->t.scrollable.scroll_window_size<-bounds.w|Vert->t.scrollable.scroll_window_size<-bounds.h);t.bounds<-bounds;;letcreate?(bar_style=Scroll_bar_style.Filled)~incr_key~decr_key~orientation~bounds()=letscrollable=Scrollable.create()inletscrollbar={scrollable;bar_style;incr_key;decr_key;bounds;orientation}inset_boundsscrollbarbounds;scrollbar;;letkey_eventt(key:Notty.Unescape.key)=ifPoly.equalkeyt.incr_keythen(Scrollable.set_offsett.scrollable(Scrollable.incrt.scrollable);true)elseifPoly.equalkeyt.decr_keythen(Scrollable.set_offsett.scrollable(Scrollable.decrt.scrollable);true)elsefalse;;letmouse_eventt((ev,(col,row),mods):Notty.Unescape.mouse)=matchev,modswith|`Press`Left,[]->letscroll=mouse_offsett~row~colinScrollable.set_offsett.scrollable(Scrollable.mouse_scrollt.scrollablescroll);true|_->false;;letdraw_bar~ctx~style~(bounds:Draw.rect)(t:t)=letcols,rows=bounds.w,bounds.hinletis_filled=matcht.bar_stylewith|Filled->true|Outline->falseinifcols=1||rows=1||is_filledthen(letx=matcht.bar_stylewith|Filled->filled|Outline->ifcols=1thenvbarelsehbarinforc=0tobounds.w-1doforr=0tobounds.h-1doDraw_notty.draw_int~ctx~style~bounds~r~cxdonedone)elseDraw_notty.draw_box~ctx~style~bounds"";;endmoduleVScrollbar=structtypet=Scrollbar.t[@@derivingsexp_of]letcreate(bounds:Draw.rect)=Scrollbar.create~incr_key:(`Arrow`Down,[])~decr_key:(`Arrow`Up,[])~bounds~orientation:Vert();;letdraw~ctx~style(t:t)=letscroll_bar_size=Scrollable.scroll_bar_sizet.scrollableinletscroll_offset=t.scrollable.scroll_bar_offsetinletbounds=t.boundsinDraw_notty.fill~ctx~style~bounds' ';letbounds={Draw.r=bounds.r+scroll_offset;c=bounds.c;h=scroll_bar_size;w=bounds.w}inScrollbar.draw_bar~ctx~style~boundst;;endmoduleHScrollbar=structtypet=Scrollbar.t[@@derivingsexp_of]letcreate(bounds:Draw.rect)=Scrollbar.create~incr_key:(`Arrow`Right,[])~decr_key:(`Arrow`Left,[])~bounds~orientation:Horz();;letdraw~ctx~style(t:t)=letscroll_bar_size=Scrollable.scroll_bar_sizet.scrollableinletscroll_offset=t.scrollable.scroll_bar_offsetinletbounds=t.boundsinDraw_notty.fill~ctx~style~bounds' ';letbounds={Draw.r=bounds.r;c=bounds.c+scroll_offset;h=bounds.h;w=scroll_bar_size}inScrollbar.draw_bar~ctx~style~boundst;;end