プログラムな日常>ウェブプログラム作品集>
スクロールバーを作ってみました
(a new class of scrollbars)
sc1
realbase mechanicalbase feedback
 
base(not always valid)
whole
view
largeChange
visual width
visual height
visual location_x
visual location_y
inversed direction

使い方:
解説:

【イベントハンドラの難しさ】

大手ソフト会社の提供するプログラミング言語でスクロールバーが使いにくかったことは、古くからのプログラマーのよく知る事実である(1)。


【1だけの違い】

C# の場合は、各変数に次の対応関係がある

Maximum == Valueの最大値 + LargeChange - 1

今回のツールでは、

whole == base の最大値 + view

なんだ、whole は Maximum+1 のこと、小さな違いではないか、と思われるかも知れません。

確かに小さな違いだが、スクロールの方法を逆にするような場合(オーディオの attenuator のように下から上へと増加させたり、国語の縦書き入力のように、右から左へ延ばすなど) には、古い定義だと混乱する。この対策としては、私は C# でも新たなクラスでラップしたり、Panel を利用して最初から作ったりしている。


【クラス/オブジェクト】

私の場合、javascript の経験は浅く、このブログの「一変数多項式の因数分解(実係数)」が最初の作品であったが、 クラスとオブジェクトに基本別々の名前を振らなければいけないオブジェクト指向と比べると、javascript は爽快な感じがしていた。 これはオブジェクト指向の言語で言うところの static な利用法に限られたからだが、今回初めて javascript でオブジェクトをやった。 a new class of scrollbars という英語のタイトルの通り、プログラムは一つで、今回の場合、9個ものオブジェクトを動かせる。 これは有難いことだが、static がデフォである言語においては、変数、関数共に this. が多用されることがわかった。


【イベントの混乱】

既存のツールでもう一つ引っかかっていたのは、イベントの問題である。 スクロールバーとテキストボックスなど、複数の部品を連携させようという時に、OnValueChanged といったイベントはデータのやり取りが限りなく行われて大変なことになる。 今回、basechangedanyway という標準のイベントの他に、basechangedmechanical という、マウスによる直接の操作が行われた場合に限るイベントを作った。 これは、「噂の伝言はしませんよ」ということであり、「必要と思う人は、必要な場所それぞれに直接伝えてね」という思想である。 basechangedbycode という、set** 関数(setbase, setwhole, setview, setwholeandview)による場合のみのイベントも置いておいた。多分、使われることはないと思うが。


【利用方法】
利用可能な関数は次の通りです。

scroll の関数:
関数文例
new scroll : コンストラクタ html 等で既に定義された領域(div など)を利用してスクロールバーにする。例えば、
const divforscr=document.getElementById("divforscr");  const scr1=new scroll(divforscr, false);
または、id をそのまま指定し、
const scr1=new scroll("divforscr", false);
各引数は、1:消費される領域、2:逆方向(右から、下から) 2 の false は省略可
html 等で既に定義された領域(div など)を「保証人」として、新たなスクロールバーを作る。例えば、
const divmother=document.getElementById("divmother");  const scr1=new scroll(divmother, x, y, w, h, false);
または、id をそのまま指定し、
const scr1=new scroll("divmother", 20, 150, 200, 25, false);
各引数は、1:参照される領域、2:絶対位置x、3:絶対位置y、4:幅、5:高さ、6:逆方向(右から、下から) 6 の false は省略可
getbody : 実体(div)を返すscr1.getbody().addEventListner('basechangedmechanical', ()=>{ ... });
getbase : 値を得るvar b=scr1.getbase();
setbase : 値を設定scr1.setbase(b);
setwhole : 全体を設定scr1.setwhole(wh); // === whole は base の最大値と view との和 !!!
setview : 視野を設定scr1.setview(v);
setwholeandview : 全体と視野を設定scr1.setwholeandview(wh, v);
setlargechange : 大きな変化量を設定scr1.setlargechange(L);
setinverse : 右や下からなら true 設定scr1.setinverse(false);
setx : 位置(x)設定scr1.setx(20)
sety : 位置(y)設定scr1.sety(150)
setxy : 位置(x, y)設定scr1.setxy(x, y)
setw : 幅設定scr1.setw(200)
seth : 高さ設定scr1.seth(25)
setwh : 幅と高さ設定scr1.setwh(w, h)

イベントは次の通り。
scroll のイベント:
イベント伝達の原因文例
basechangedmechanicalマウス操作(スクロールとクリック)のみscr1.getbody().addEventListner('basechangedmechanical', ()=>{ ... });
basechangedanywayマウス操作(スクロールとクリック)および set** 関数 (setbase, setwhole, setview, setwholeandview)scr1.getbody().addEventListner('basechangedanyway', ()=>{ ... });
basechangedbycodeset** 関数 (setbase, setwhole, setview, setwholeandview)のみscr1.getbody().addEventListner('basechangedbycode', ()=>{ ... });

なお、これらイベントは、変更があったという事実を伝えるだけであり、具体的数値は getbase() で持ってくる必要がある。


【ソースコード】

このページのアプリケーションのソースコードは次の通り。


スクロールバー自体のソースコードは次の通り。



参考文献:

1.吉田弘一郎 著、VisualC++によるMFCライブラリの使い方(1994) p.63