Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file lTerm_scroll_impl.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411openLTerm_geomclasst=LTerm_widget_base_impl.tlethbar=0x2550letvbar=0x2551letmap_rangerange1range2offset1=ifrange1=0then0elseletmap_rangerange1range2offset1=max0.(minrange2(range2*.offset1/.range1))inletrndx=int_of_float(x+.0.5)inrnd@@map_range(float_of_intrange1)(float_of_intrange2)(float_of_intoffset1)classadjustment=object(self)(* callbacks *)valoffset_change_callbacks=LTerm_widget_callbacks.create()methodon_offset_change?switch(f:int->unit)=LTerm_widget_callbacks.registerswitchoffset_change_callbacksfvalmutablerange=0valmutableoffset=0methodrange=rangemethodset_range?(trigger_callback=true)r=range<-max0r;self#set_offset~trigger_callbackoffset(* ensure offset is clipped to the new range *)methodoffset=offsetmethodset_offset?(trigger_callback=true)o=leto'=max0(min(range-1)o)inifoffset<>o'thenbeginoffset<-o';iftrigger_callbackthenLTerm_widget_callbacks.exec_callbacksoffset_change_callbackso'endendclassscrollable_adjustment=object(self)inheritadjustmentasadjvalscrollbar_change_callbacks=LTerm_widget_callbacks.create()methodon_scrollbar_change?switch(f:unit->unit)=LTerm_widget_callbacks.registerswitchscrollbar_change_callbacksfmethod!set_offset?(trigger_callback=true)o=adj#set_offset~trigger_callbacko;self#set_scroll_bar_offset(self#scroll_of_windowself#offset)method!set_range?(trigger_callback=true)r=adj#set_range~trigger_callbackr;self#set_scroll_bar_offset(self#scroll_of_windowself#offset)valmutablescroll_window_size=0methodprivatescroll_window_size=scroll_window_sizemethodset_scroll_window_sizes=scroll_window_size<-svalmutablescroll_bar_mode:[`fixedofint|`dynamicofint]=`fixed5methodset_scroll_bar_modem=scroll_bar_mode<-mmethodprivatescroll_bar_size_fixedsize=letwsize=self#scroll_window_sizeinifwsize<=sizethenmax1(wsize-1)elsemax1sizemethodprivatescroll_bar_size_dynamicview_size=ifrange<=1thenself#scroll_window_sizeelseifview_size<=0thenmax1(self#scroll_window_size/max1range)elseletrange=float_of_intrangeinletscroll_size=float_of_int@@self#scroll_window_sizeinletview_size=float_of_intview_sizeinletdoc_size=view_size+.rangeinint_of_float@@scroll_size*.view_size/.doc_sizevalmutablemin_scroll_bar_size:intoption=Nonemethodprivatemin_scroll_bar_size=matchmin_scroll_bar_sizewithNone->1|Some(x)->xmethodset_min_scroll_bar_sizemin=min_scroll_bar_size<-Some(min)valmutablemax_scroll_bar_size:intoption=Nonemethodprivatemax_scroll_bar_size=matchmax_scroll_bar_sizewithNone->self#scroll_window_size|Some(x)->xmethodset_max_scroll_bar_sizemax=max_scroll_bar_size<-Some(max)valmutablescroll_bar_size=0methodprivatescroll_bar_size=letsize=maxself#min_scroll_bar_size@@minself#max_scroll_bar_size@@matchscroll_bar_modewith|`fixedsize->self#scroll_bar_size_fixedsize|`dynamicsize->self#scroll_bar_size_dynamicsizein(ifscroll_bar_size<>sizethenbeginscroll_bar_size<-size;LTerm_widget_callbacks.exec_callbacksscrollbar_change_callbacks()end);sizemethodprivatescroll_bar_steps=self#scroll_window_size-self#scroll_bar_size+1valmutablescroll_bar_offset=0methodprivateset_scroll_bar_offseto=letoffset=max0(min(self#scroll_bar_steps-1)o)in(ifscroll_bar_offset<>offsetthenbeginscroll_bar_offset<-offset;LTerm_widget_callbacks.exec_callbacksscrollbar_change_callbacks()end)methodprivatewindow_of_scrolloffset=map_range(self#scroll_bar_steps-1)(range-1)offsetmethodprivatescroll_of_windowoffset=letoffset=map_range(range-1)(self#scroll_bar_steps-1)offsetinoffsetmethodincr=ifrange>=self#scroll_bar_stepsthenself#window_of_scroll(scroll_bar_offset+1)else(offset+1);methoddecr=ifrange>=self#scroll_bar_stepsthenself#window_of_scroll(scroll_bar_offset-1)else(offset-1);(* mouse click control *)(* scale whole scroll bar area into the number of steps. The scroll
bar will not necessarily end up where clicked. Add a small dead_zone
at far left and right *)methodprivatemouse_scale_ratioscroll=letsteps,_size=self#scroll_bar_steps,self#scroll_bar_sizeinletwsize=self#scroll_window_sizeinletdead_zone=wsize/5in(* ~10% at each end *)map_range(wsize-dead_zone-1)(steps-1)(scroll-dead_zone/2)(* place the middle of the scroll bar at the cursor. Large scroll bars
will reduce the clickable area by their size. *)methodprivatemouse_scale_middlescroll=letsize=self#scroll_bar_sizeinscroll-(size/2)methodprivatemouse_scale_autoscroll=ifself#scroll_bar_size>self#scroll_window_size/2thenself#mouse_scale_ratioscrollelseself#mouse_scale_middlescrollvalmutablemouse_mode:[`middle|`ratio|`auto]=`middlemethodset_mouse_modem=mouse_mode<-mmethodprivatescroll_of_mousescroll=matchmouse_modewith|`middle->self#mouse_scale_middlescroll|`ratio->self#mouse_scale_ratioscroll|`auto->self#mouse_scale_autoscrollmethodmouse_scrollscroll=self#window_of_scroll@@self#scroll_of_mousescrollvalmutablepage_size=-1valmutabledocument_size=-1methodcalculate_rangepage_sizedocument_size=document_size-page_size+1methodprivateupdate_page_and_document_sizespagedoc=ifpage_size<>page||document_size<>docthenbeginpage_size<-page;document_size<-doc;letrange=max0(self#calculate_rangepage_sizedocument_size)inself#set_rangerange;self#set_mouse_mode`auto;self#set_scroll_bar_mode(`dynamicpage_size);endmethodpage_size=page_sizemethodset_page_sizes=self#update_page_and_document_sizessdocument_sizemethoddocument_size=document_sizemethodset_document_sizes=self#update_page_and_document_sizespage_sizesmethodpage_prev=self#offset-page_sizemethodpage_next=self#offset+page_sizemethodget_render_params=scroll_bar_offset,self#scroll_bar_size,self#scroll_window_sizeendclassvirtualscrollbarrcdefault_event_handler(adj:#scrollable_adjustment)=object(self)inherittrcmethod!can_focus=true(* style *)valmutablefocused_style=LTerm_style.nonevalmutableunfocused_style=LTerm_style.nonevalmutablebar_style:[`filled|`outline]=`outlinevalmutableshow_track=falsemethod!update_resources=letrc=self#resource_classandresources=self#resourcesinfocused_style<-LTerm_resources.get_style(rc^".focused")resources;unfocused_style<-LTerm_resources.get_style(rc^".unfocused")resources;bar_style<-(matchLTerm_resources.get(rc^".barstyle")resourceswith|"filled"->`filled|"outline"|""->`outline|style->Printf.ksprintffailwith"invalid scrollbar style %s"style);show_track<-(matchLTerm_resources.get_bool(rc^".track")resourceswith|Some(x)->x|None->false)(* virtual methods needed to abstract over vert/horz scrollbars *)methodvirtualprivatemouse_offset:LTerm_mouse.t->rect->intmethodvirtualprivatescroll_incr_key:LTerm_key.tmethodvirtualprivatescroll_decr_key:LTerm_key.t(* event handling *)methodmouse_eventev=letopenLTerm_mouseinletalloc=self#allocationinmatchevwith|LTerm_event.Mousemwhenm.button=Button1&¬m.control&¬m.shift&¬m.meta->letscroll=self#mouse_offsetmallocinadj#set_offset@@adj#mouse_scrollscroll;true|_->falsemethodscroll_key_event=function|LTerm_event.Keykwhenk=self#scroll_decr_key->adj#set_offsetadj#decr;true|LTerm_event.Keykwhenk=self#scroll_incr_key->adj#set_offsetadj#incr;true|_->false(* drawing *)methodprivatedraw_barctxstylerect=letopenLTerm_drawinlet{cols;rows}=size_of_rectrectinifcols=1||rows=1||bar_style=`filledthenletx=Uchar.of_int@@ifbar_style=`filledthen0x2588elseifcols=1thenvbarelsehbarinforc=rect.col1torect.col2-1doforr=rect.row1torect.row2-1dodraw_charctxrc~style(Zed_char.unsafe_of_uCharx)donedoneelsedraw_framectxrect~styleLight(* auto-draw *)initializeradj#on_scrollbar_change(fun()->self#queue_draw)initializerifdefault_event_handlerthenself#on_event(funev->self#mouse_eventev||self#scroll_key_eventev)endclassvscrollbar?(rc="scrollbar")?(default_event_handler=true)?(width=2)adj=object(self)inheritscrollbarrcdefault_event_handleradjassupermethod!size_request={rows=0;cols=width}methodprivatemouse_offsetmalloc=m.LTerm_mouse.row-alloc.row1valscroll_incr_key=LTerm_key.{control=false;meta=false;shift=true;code=Down}valscroll_decr_key=LTerm_key.{control=false;meta=false;shift=true;code=Up}methodprivatescroll_incr_key=scroll_incr_keymethodprivatescroll_decr_key=scroll_decr_keymethod!set_allocationr=super#set_allocationr;adj#set_scroll_window_size(r.row2-r.row1)method!drawctxfocused=letopenLTerm_drawinletfocus=(self:>t)=focusedinlet{cols;_}=sizectxinletstyle=iffocusthenfocused_styleelseunfocused_styleinfill_stylectxstyle;letoffset,scroll_bar_size,scroll_window_size=adj#get_render_paramsinletrect={row1=offset;col1=0;row2=offset+scroll_bar_size;col2=cols}in(ifshow_trackthendraw_vlinectx0(cols/2)scroll_window_size~styleLight);self#draw_barctxstylerectendclasshscrollbar?(rc="scrollbar")?(default_event_handler=true)?(height=2)adj=object(self)inheritscrollbarrcdefault_event_handleradjassupermethod!size_request={rows=height;cols=0}methodprivatemouse_offsetmalloc=m.LTerm_mouse.col-alloc.col1valscroll_incr_key=LTerm_key.{control=false;meta=false;shift=true;code=Right}valscroll_decr_key=LTerm_key.{control=false;meta=false;shift=true;code=Left}methodprivatescroll_incr_key=scroll_incr_keymethodprivatescroll_decr_key=scroll_decr_keymethod!set_allocationr=super#set_allocationr;adj#set_scroll_window_size(r.col2-r.col1)method!drawctxfocused=letopenLTerm_drawinletfocus=(self:>t)=focusedinlet{rows;_}=sizectxinletstyle=iffocusthenfocused_styleelseunfocused_styleinfill_stylectxstyle;letoffset,scroll_bar_size,scroll_window_size=adj#get_render_paramsinletrect={row1=0;col1=offset;row2=rows;col2=offset+scroll_bar_size}in(ifshow_trackthendraw_hlinectx(rows/2)0scroll_window_size~styleLight);self#draw_barctxstylerectendclassvsliderrng=letadj=newscrollable_adjustmentinobject(self)inheritvscrollbar~rc:"slider"~default_event_handler:false~width:1adjinitializeradj#set_mouse_mode`middle;adj#set_scroll_bar_mode(`fixed1);adj#set_range(max0rng);self#on_event(funev->letopenLTerm_keyinmatchevwith|LTerm_event.Key{control=false;meta=false;shift=true;code=Up}->adj#set_offset(adj#offset-1);true|LTerm_event.Key{control=false;meta=false;shift=true;code=Down}->adj#set_offset(adj#offset+1);true|_->self#mouse_eventev)method!size_request={rows=rng;cols=1}methodoffset=adj#offsetmethodset_offset=adj#set_offsetmethodrange=adj#rangemethodset_range=adj#set_rangemethodon_offset_change=adj#on_offset_changeendclasshsliderrng=letadj=newscrollable_adjustmentinobject(self)inherithscrollbar~rc:"slider"~default_event_handler:false~height:1adjinitializeradj#set_mouse_mode`middle;adj#set_scroll_bar_mode(`fixed1);adj#set_range(max0rng);self#on_event(funev->letopenLTerm_keyinmatchevwith|LTerm_event.Key{control=false;meta=false;shift=true;code=Left}->adj#set_offset(adj#offset-1);true|LTerm_event.Key{control=false;meta=false;shift=true;code=Right}->adj#set_offset(adj#offset+1);true|_->self#mouse_eventev)method!size_request={rows=1;cols=rng}methodoffset=adj#offsetmethodset_offset=adj#set_offsetmethodrange=adj#rangemethodset_range=adj#set_rangemethodon_offset_change=adj#on_offset_changeend