//
//	ToolLib_Window.c
//
//	エディター共通処理 - ツールのGUIのウインドウ
//
//	* Tue Apr 18 21:46:46 JST 2017 Naoyuki Sawa
//	- 1st リリース。
//	* Wed Apr 19 22:11:14 JST 2017 Naoyuki Sawa
//	- 「①DxLibに依存しないようにする」と「②C言語でコンパイル出来るようにする」を対応しました。
//	  詳細は、/clip/ToolLib/README.TXT の、同日のコメントを参照して下さい。
//	* Thu Apr 20 21:31:57 JST 2017 Naoyuki Sawa
//	- 当ライブラリが生成するオブジェクトの識別子を、整数ハンドル⇒ポインタに変更しました。
//	  オリジナル版では生成したオブジェクトを固定長配列に格納して管理していたのですが、メモリ節約のためにリストで管理するように変更し、そのためには整数ハンドルよりもポインタの方が都合が良いからです。
//	  尚、フォントハンドルと文字列入力ハンドルは、当ライブラリが生成するオブジェクトではなくバックエンドのオブジェクトなので、今回の変更には関係無く整数ハンドルのままです。
//	* Fri Apr 21 22:01:07 JST 2017 Naoyuki Sawa
//	- ToolWindow_Create()にて、名前が設定されている場合だけ、名前表示部分のスペースを追加するように修正しました。
//	  オリジナル版では、名前が設定されていなくても名前表示部分のスペースを追加しており、上部に余分なスペースが開く問題が有りました。
//	- ToolWindow_Draw()にて、縦方向のスクロールバーを描画する場合は、名前を表示するウインドウ上部もその幅まで広げるように変更しました。
//	  オリジナル版では、縦方向のスクロールバーの有無に関係無く、名前を表示するウインドウ上部は情報表示領域の幅までしか塗り潰しておらず、縦方向のスクロールバーの上部に不自然な空白が生じていました。
//	- ToolWindow_Draw()にて、ウインドウの枠を、名前を表示するウインドウ上部も含めて囲むように変更しました。
//	  オリジナル版では、縦横のスクロールバーは含めて囲むのに、名前を表示するウインドウ上部は含めて囲まないという不自然さが有りました。
//	* Tue May 02 22:54:46 JST 2017 Naoyuki Sawa
//	- 各モジュール内のサイズ定義の倍率を一律で調整出来るように、ToolLib.hにTOOL_SCALEの定義を追加しました。
//	  詳細は、ToolLib.hの同日のコメントを参照して下さい。
//	* Sun May 14 23:23:22 JST 2017 Naoyuki Sawa
//	- ToolWindow_IsAnyHovered(),ToolWindow_IsHovered()関数を追加しました。
//	  詳細は、ToolLib.hの同日のコメントを参照して下さい。
//
#include "clip.h"
//*****************************************************************************
//	定数、マクロ、構造体
//*****************************************************************************
#define TOOL_WINDOW_NAME_HEIGHT		(TOOL_SCALE*(16))	//ツール処理のウインドウの名前表示部分の高さ。
#define TOOL_WINDOW_SCROLLBAR_WIDTH	(TOOL_SCALE*(16))	//ツール処理のウインドウのスクロールバーの幅。
#define TOOL_SCROLLBAR_BUTTON_SIZE	(TOOL_SCALE*(8))	//スクロールバー操作用のボタンのサイズ。
#define TOOL_SCROLLBAR_THUMB_SIZE	(TOOL_SCALE*(8))	//スクロールバーのつまみのサイズ。
#define TOOL_SCROLLBAR_SPEED		(TOOL_SCALE*(180))	//スクロールバーをボタンを押して操作する場合の移動速度。
#define TOOL_DRAWAREA_BASERIGHT_SPACE	(TOOL_SCALE*(20))	//サイズ変更可能な表示領域を使用する場合の表示領域右端から空けるスペースのサイズ。
//-----------------------------------------------------------------------------
//ウインドウ構造体
/*typedef*/ struct _SToolWindow {
	SToolSpaceManage*	TSpaceManage;							//スペース管理情報。
	SToolVisible*		TVisible;							//表示状態情報。
	char*			Name;								//ボタンの名前の文字列が格納されているメモリアドレスを保存しているポインタ。
	RECT			InfoArea;							//ウインドウの情報表示領域。
	SIZE			ClientSize;							//ウインドウのクライアント領域のサイズ。
	int			DrawLeftUpX, DrawLeftUpY;					//ウインドウのクライアント領域の内容を描画する際の基点となる左上座標。(スクロールバーによるウインドウ内情報の表示位置が変更される処理に使用)
	int			HScroll, VScroll;						//表示位置を決定するスクロール座標。
	int			HScrollGrips, VScrollGrips;					//スクロールバーを掴んでいるかどうか。
	int			Visible;							//表示状態。
	double			LastButtonBottomTime;						//最後にボタン押下スクロールをした時間。(単位:秒)
	int			UpButBottom, DownButBottom, LeftButBottom, RightButBottom;	//それぞれ上下左右スクロールボタンが押された状態かどうか。(0以外:押されている,0:押されていない)
	int			UpButIn, DownButIn, LeftButIn, RightButIn;			//それぞれ上下左右スクロールボタンの矩形内にマウスカーソルがあるかどうか。
	SToolSpace		NameSpace;							//名前表示部分のスペース情報。
	SToolSpace		InfoSpace;							//情報表示部分のスペース情報。
	SToolSpace		HScrollBarSpace;						//水平スクロールバーのスペース情報。
} /*SToolWindow*/;
//*****************************************************************************
//	ローカル変数
//*****************************************************************************
static GSList*	g_TWindow;
//*****************************************************************************
//	ローカル関数宣言
//*****************************************************************************
static void ToolWindow_UpdateInfoArea(SToolWindow* TWindow);
static void ToolWindow_Step(SToolWindow* TWindow, double StepTime);
static void ToolWindow_Draw(SToolWindow* TWindow);
//*****************************************************************************
//	アプリケーション用関数
//*****************************************************************************
//ウインドウ情報を作成する。
//[in]
//	TSpaceManage		スペース管理情報。(必要のない場合はNULLを渡す)
//	SpaceLast		残りのスペースを全て使用するかどうか。(0以外を渡すと全て使用する)	(TSpaceManageがNULL以外の場合のみ有効)
//	LockSpace		固定タイプのスペースかどうか。						(TSpaceManageがNULL以外の場合のみ有効)
//	HScrollSpace		水平スクロールバー用のスペースも確保するかどうか。			(TSpaceManageがNULL以外の場合のみ有効)
//	Name			ウインドウの名前。
//	DrawX			ウインドウの左端X座標。
//	DrawY			ウインドウの上端Y座標。							(TSpaceManageがNULLの場合のみ有効)
//	DrawW			ウインドウの幅。							(TSpaceManageがNULLの場合のみ有効)
//	DrawH			ウインドウの高さ。							(TSpaceManageがNULLの場合のみ有効)
//	ClientW			ウインドウのクライアント領域の幅。
//	ClientH			ウインドウのクライアント領域の高さ。
//[out]
//	戻り値			ウインドウ情報。
SToolWindow* ToolWindow_Create(SToolSpaceManage* TSpaceManage, int SpaceLast, int LockSpace, int HScrollSpace, const char* Name, int DrawX, int DrawY, int DrawW, int DrawH, int ClientW, int ClientH) {
	SToolWindow* TWindow;
	//新しいウインドウ情報を格納するためのメモリの確保。
	TWindow = calloc(1, sizeof(SToolWindow));
	if(!TWindow) { DIE(); }
	//確保したメモリ領域を保存。
	g_TWindow = g_slist_append(g_TWindow, TWindow);
	//スペース管理情報を保存。
	TWindow->TSpaceManage = TSpaceManage;
	//スペース管理情報が有効な場合はウインドウのスペース情報を追加する。
	if(TSpaceManage) {
		//名前が設定されている場合は名前表示部分のスペースを追加。
		if(Name) {
			ToolSpaceManage_AddSpace(TSpaceManage,
			                         &TWindow->NameSpace,
			                         TOOL_WINDOW_NAME_HEIGHT,
			                         1);
		}
		//情報表示領域のスペースを追加。
		ToolSpaceManage_AddSpace(TSpaceManage,
		                         &TWindow->InfoSpace,
		                         SpaceLast ? (ToolSpaceManage_GetTotalSpace(TSpaceManage) - ToolSpaceManage_GetNextSpace(TSpaceManage) - TOOL_WINDOW_SCROLLBAR_WIDTH) : DrawH,
		                         LockSpace);
		//水平スクロールバー用のスペースを確保する指定がある場合は水平スクロールバー用のスペースを追加する。
		if(HScrollSpace) {
			ToolSpaceManage_AddSpace(TSpaceManage,
			                         &TWindow->HScrollBarSpace,
			                         TOOL_WINDOW_SCROLLBAR_WIDTH,
			                         1);
		}
	}
	//情報を初期化。
//不要	TWindow->TVisible        = NULL;
	TWindow->InfoArea.left   = DrawX;
	TWindow->InfoArea.right  = DrawX + DrawW;
	if(TWindow->TSpaceManage) {
		TWindow->InfoArea.top = TWindow->InfoSpace.SpaceStart;
	} else {
		TWindow->InfoArea.top = DrawY;
	}
	TWindow->InfoArea.bottom = TWindow->InfoArea.top + DrawH;
	TWindow->ClientSize.cx   = ClientW;
	TWindow->ClientSize.cy   = ClientH;
	ToolWindow_SetName(TWindow, Name);
	TWindow->DrawLeftUpX     = 0;
	TWindow->DrawLeftUpY     = 0;
	TWindow->HScroll         = 0;
	TWindow->VScroll         = 0;
	TWindow->Visible         = 1;
	//ウインドウ情報を返す。
	return TWindow;
}
//-----------------------------------------------------------------------------
//ウインドウ情報を削除する。
//[in]
//	TWindow			ウインドウ情報。
void ToolWindow_Delete(SToolWindow* TWindow) {
	//名前保存用にメモリを確保していた場合は解放。
	free(TWindow->Name);
	//確保していたメモリを解放する。
	g_TWindow = g_slist_remove(g_TWindow, TWindow);
	free(TWindow);
}
//-----------------------------------------------------------------------------
//全てのウインドウ情報を削除する。
void ToolWindow_Delete_All() {
	//有効な全てのウインドウを削除する。
	while(g_TWindow) { ToolWindow_Delete(g_TWindow->data); }
}
//-----------------------------------------------------------------------------
//ウインドウ情報に関連付ける表示状態情報をセットする。
//[in]
//	TWindow			ウインドウ情報。
//	TVisible		表示状態情報。
void ToolWindow_SetVisibleHandle(SToolWindow* TWindow, SToolVisible* TVisible) {
	TWindow->TVisible = TVisible;
}
//-----------------------------------------------------------------------------
//ウインドウ情報を元にSetDrawAreaで描画領域を制限する設定を行う。
//[in]
//	TWindow			ウインドウ情報。
void ToolWindow_SetupDrawArea(SToolWindow* TWindow) {
	//スペース情報が変更されている可能性があるので情報表示領域の更新。
	ToolWindow_UpdateInfoArea(TWindow);
	//SetDrawAreaを使用して実際に描画領域の制限設定を行う。
	ToolFunc_SetDrawArea(TWindow->InfoArea.left,
	                     TWindow->InfoArea.top,
	                     TWindow->InfoArea.right,
	                     TWindow->InfoArea.bottom);
}
//-----------------------------------------------------------------------------
//ウインドウ情報の情報表示領域を取得する。
//[in]
//	TWindow			ウインドウ情報。
//[out]
//	戻り値			描画領域の矩形。
RECT ToolWindow_GetInfoArea(SToolWindow* TWindow) {
	//スペース情報が変更されている可能性があるので情報表示領域の更新。
	ToolWindow_UpdateInfoArea(TWindow);
	return TWindow->InfoArea;
}
//-----------------------------------------------------------------------------
//ウインドウ情報のスクロールバーの状態も考慮したクライアント領域の描画原点となるスクリーン座標を取得する。
//[in]
//	TWindow			ウインドウ情報。
//	x,y			座標を代入する変数のアドレス。(NULL可)
void ToolWindow_GetDrawLeftUpPos(SToolWindow* TWindow, int* x, int* y) {
	//スペース情報が変更されている可能性があるので情報表示領域の更新。
	ToolWindow_UpdateInfoArea(TWindow);
	if(x) { *x = -TWindow->DrawLeftUpX + TWindow->InfoArea.left; }
	if(y) { *y = -TWindow->DrawLeftUpY + TWindow->InfoArea.top;  }
}
//-----------------------------------------------------------------------------
//ウインドウ情報のスクロールバーの状態も考慮したクライアント領域の描画原点となる座標を取得する。
//[in]
//	TWindow			ウインドウ情報。
//	x,y			座標を代入する変数のアドレス。(NULL可)
void ToolWindow_GetClientArea(SToolWindow* TWindow, int* x, int* y) {
	//スペース情報が変更されている可能性があるので情報表示領域の更新。
	ToolWindow_UpdateInfoArea(TWindow);
	if(x) { *x = TWindow->DrawLeftUpX; }
	if(y) { *y = TWindow->DrawLeftUpY; }
}
//-----------------------------------------------------------------------------
//ウインドウ情報のクライアント領域のサイズを設定する。
//[in]
//	TWindow			ウインドウ情報。
//	w,h			新しいクライアント領域のサイズ。
void ToolWindow_SetClientSize(SToolWindow* TWindow, int w, int h) {
	int InfoAreaW, InfoAreaH;
	int ScrollW, ScrollH;
	//スペース情報が変更されている可能性があるので情報表示領域の更新。
	ToolWindow_UpdateInfoArea(TWindow);
	//現在のクライアント領域のサイズと同じ場合は何もせずに終了。
	if((TWindow->ClientSize.cx == w) && (TWindow->ClientSize.cy == h)) { return; }	//ここまで
	//新しいクライアント領域のサイズを保存。
	TWindow->ClientSize.cx = w;
	TWindow->ClientSize.cy = h;
	//情報表示領域の幅と高さを算出。
	InfoAreaW = TWindow->InfoArea.right - TWindow->InfoArea.left;
	InfoAreaH = TWindow->InfoArea.bottom - TWindow->InfoArea.top;
	//スクロールバーの水平移動範囲と垂直移動範囲を算出。
	ScrollW = InfoAreaW - (TOOL_SCROLLBAR_THUMB_SIZE + (TOOL_SCROLLBAR_BUTTON_SIZE * 2));
	ScrollH = InfoAreaH - (TOOL_SCROLLBAR_THUMB_SIZE + (TOOL_SCROLLBAR_BUTTON_SIZE * 2));
	//新しいクライアント領域のサイズが情報表示領域より狭い場合はスクロールバーの位置を調節。
	if(InfoAreaW < TWindow->ClientSize.cx) {
		if((TWindow->DrawLeftUpX + InfoAreaW) > TWindow->ClientSize.cx) { TWindow->DrawLeftUpX = TWindow->ClientSize.cx - InfoAreaW; }
		TWindow->HScroll = TWindow->DrawLeftUpX * ScrollW / (TWindow->ClientSize.cx - InfoAreaW);
	} else {
		TWindow->DrawLeftUpX = 0;
		TWindow->HScroll     = 0;
	}
	if(InfoAreaH < TWindow->ClientSize.cy) {
		if((TWindow->DrawLeftUpY + InfoAreaH) > TWindow->ClientSize.cy) { TWindow->DrawLeftUpY = TWindow->ClientSize.cy - InfoAreaH; }
		TWindow->VScroll = TWindow->DrawLeftUpY * ScrollH / (TWindow->ClientSize.cy - InfoAreaH);
	} else {
		TWindow->DrawLeftUpY = 0;
		TWindow->VScroll     = 0;
	}
}
//-----------------------------------------------------------------------------
//ウインドウ情報の名前を設定する。
//[in]
//	TWindow			ウインドウ情報。
//	Name			名前となる文字列のアドレス。
void ToolWindow_SetName(SToolWindow* TWindow, const char* Name) {
	//既に名前用にメモリを確保していた場合は解放する。
	free(TWindow->Name);
	TWindow->Name = NULL;
	//名前のアドレスが有効な場合はメモリを確保して保存する。
	if(Name) {
		TWindow->Name = strdup(Name);
		if(!TWindow->Name) { DIE(); }
	}
}
//-----------------------------------------------------------------------------
//ウインドウ情報の表示状態を変更する。
//[in]
//	TWindow			ウインドウ情報。
//	Visible			新しい表示状態。
void ToolWindow_SetVisible(SToolWindow* TWindow, int Visible) {
	//新しい表示状態を保存する。
	TWindow->Visible = Visible;
}
//-----------------------------------------------------------------------------
//ウインドウ情報の表示状態を取得する。
//[in]
//	TWindow			ウインドウ情報。(NULL可。NULLが指定されたら常に「0以外:表示」を返す)
//[out]
//	戻り値			表示状態。(0以外:表示,0:非表示)
int ToolWindow_GetVisible(SToolWindow* TWindow) {
	//ウインドウ情報が有効ならば…
	if(TWindow) {
		//表示状態が0の場合は0を返す。
		if(!TWindow->Visible) { return 0; }
		//表示状態情報が登録されていて、且つ表示状態情報の表示状態が0の場合は0を返す。
		if(!ToolVisible_GetVisible(TWindow->TVisible)) { return 0; }
	}
	//ここにきていたら非表示ではないということなので0以外を返す。
	return 1;
}
//-----------------------------------------------------------------------------
//指定の座標がウインドウの情報表示領域に入っているかどうかを調べる。
//[in]
//	TWindow			ウインドウ情報。
//	x,y			ウインドウの描画領域に入っているかどうか調べる座標。
//[out]
//	戻り値			指定の座標がウインドウの描画領域に入っているかどうか。(0以外:入っている,0:入っていない)
int ToolWindow_CheckInfoAreaIn(SToolWindow* TWindow, int x, int y) {
	return ((TWindow->InfoArea.left <= x) && (TWindow->InfoArea.right  >= x)) &&
	       ((TWindow->InfoArea.top  <= y) && (TWindow->InfoArea.bottom >= y));
}
//-----------------------------------------------------------------------------
//全てのウインドウ情報の状態推移処理を行う。
//[in]
//	StepTime		進める時間。(単位:秒)
void ToolWindow_Step_All(double StepTime) {
	GSList* list = g_TWindow;
	while(list) {
		ToolWindow_Step(list->data, StepTime);
		list = list->next;
	}
}
//-----------------------------------------------------------------------------
//全てのウインドウ情報の描画移処理を行う。
void ToolWindow_Draw_All() {
	GSList* list = g_TWindow;
	while(list) {
		ToolWindow_Draw(list->data);
		list = list->next;
	}
}
//-----------------------------------------------------------------------------
//マウスカーソルがいずれかのウインドウの内にあるかどうかをチェックする。
//[out]
//	戻り値			いずれかのウインドウの内にマウスカーソルがあるかどうか。(0以外:内にある,0:外にある)
int ToolWindow_IsAnyHovered() {
	GSList* list = g_TWindow;
	while(list) {
		if(ToolWindow_IsHovered(list->data)) { return 1; }
		list = list->next;
	}
	return 0;
}
//-----------------------------------------------------------------------------
//マウスカーソルがウインドウの内にあるかどうかをチェックする。
//[in]
//	TWindow			ウインドウ情報。
//[out]
//	戻り値			ウインドウの内にマウスカーソルがあるかどうか。(0以外:内にある,0:外にある)
int ToolWindow_IsHovered(SToolWindow* TWindow) {
	int x1, y1, x2, y2;
	//表示状態が0の場合は何もせず終了。
	if(!ToolWindow_GetVisible(TWindow)) { return 0; }	//ここまで
	//スペース情報が変更されている可能性があるので情報表示領域の更新。
	ToolWindow_UpdateInfoArea(TWindow);
	//ウインドウの矩形を取得。
	x1 = TWindow->InfoArea.left;
	y1 = TWindow->InfoArea.top;
	x2 = TWindow->InfoArea.right;
	y2 = TWindow->InfoArea.bottom;
	//クライアント領域の幅が情報表示領域より大きければ、横スクロールバーの分、ウインドウの高さを広げる。
	if((TWindow->InfoArea.right - TWindow->InfoArea.left) < TWindow->ClientSize.cx) { y2 += TOOL_WINDOW_SCROLLBAR_WIDTH; }
	//クライアント領域の高さが情報表示領域より大きければ、縦スクロールバーの分、ウインドウの幅を広げる。
	if((TWindow->InfoArea.bottom - TWindow->InfoArea.top) < TWindow->ClientSize.cy) { x2 += TOOL_WINDOW_SCROLLBAR_WIDTH; }
	//名前が設定されている場合は、タイトルバーの分、ウインドウの高さを広げる。
	if(TWindow->Name) { y1 -= TOOL_WINDOW_NAME_HEIGHT; }
	//マウスカーソルがウインドウの矩形の内にあるかどうかをチェックする。
	return ToolStatic_CheckMouseIn(x1, y1, x2, y2);
}
//*****************************************************************************
//	ローカル関数
//*****************************************************************************
//スペース情報を使用している場合にスペース情報に基づいた情報表示領域の更新を行う。
//[in]
//	TWindow			ウインドウ情報。
static void ToolWindow_UpdateInfoArea(SToolWindow* TWindow) {
	//スペース管理情報が無効な場合は何もしない。
	if(!TWindow->TSpaceManage) { return; }	//ここまで
	//情報表示領域をスペース情報に基づいて算出。
	TWindow->InfoArea.right  = Tool_GetBaseRightX() - TOOL_DRAWAREA_BASERIGHT_SPACE;
	TWindow->InfoArea.top    = TWindow->InfoSpace.SpaceStart;
	TWindow->InfoArea.bottom = TWindow->InfoArea.top + TWindow->InfoSpace.UseSpace;
}
//-----------------------------------------------------------------------------
//ウインドウ情報の状態推移処理を行う。
//[in]
//	TWindow			ウインドウ情報。
//	StepTime		進める時間。(単位:秒)
static void ToolWindow_Step(SToolWindow* TWindow, double StepTime) {
	int MouseX, MouseY;
	int MouseMoveX, MouseMoveY;
	int MouseInput, MouseEdgeInput;
	int InfoAreaW, InfoAreaH;
	int SizeOverX, SizeOverY;
	int ScrollW, ScrollH;
	double DeltaTime;
	int ScrollSize;
	//表示状態が0の場合は何もせず終了。
	if(!ToolWindow_GetVisible(TWindow)) { return; }	//ここまで
	//スペース情報が変更されている可能性があるので情報表示領域の更新。
	ToolWindow_UpdateInfoArea(TWindow);
	//マウスカーソルの位置を取得。
	ToolStatic_GetMousePosition(&MouseX, &MouseY);
	//マウスカーソルの移動量を取得。
	ToolStatic_GetMouseMoveVecter(&MouseMoveX, &MouseMoveY);
	//マウスの入力状態を取得。
	MouseInput     = ToolStatic_GetMouseButton();
	MouseEdgeInput = ToolStatic_GetMouseEdgeButton();
	//情報表示領域の幅と高さを算出。
	InfoAreaW = TWindow->InfoArea.right - TWindow->InfoArea.left;
	InfoAreaH = TWindow->InfoArea.bottom - TWindow->InfoArea.top;
	//クライアント領域のサイズが情報表示領域のサイズより大きいかどうかを調べておく。
	SizeOverX = InfoAreaW < TWindow->ClientSize.cx;
	SizeOverY = InfoAreaH < TWindow->ClientSize.cy;
	//スクロールバーの水平移動範囲と垂直移動範囲を算出。
	ScrollW = InfoAreaW - (TOOL_SCROLLBAR_THUMB_SIZE + (TOOL_SCROLLBAR_BUTTON_SIZE * 2));
	ScrollH = InfoAreaH - (TOOL_SCROLLBAR_THUMB_SIZE + (TOOL_SCROLLBAR_BUTTON_SIZE * 2));
	//スクロールバーの上下左右ボタンの表示領域の中にカーソルがあるかどうかを調べる。
	TWindow->UpButIn    = SizeOverY && ToolStatic_CheckMouseIn(TWindow->InfoArea.right,
	                                                           TWindow->InfoArea.top,
	                                                           TWindow->InfoArea.right  + TOOL_WINDOW_SCROLLBAR_WIDTH,
	                                                           TWindow->InfoArea.top    + TOOL_SCROLLBAR_BUTTON_SIZE);
	TWindow->DownButIn  = SizeOverY && ToolStatic_CheckMouseIn(TWindow->InfoArea.right,
	                                                           TWindow->InfoArea.bottom - TOOL_SCROLLBAR_BUTTON_SIZE,
	                                                           TWindow->InfoArea.right  + TOOL_WINDOW_SCROLLBAR_WIDTH,
	                                                           TWindow->InfoArea.bottom);
	TWindow->LeftButIn  = SizeOverX && ToolStatic_CheckMouseIn(TWindow->InfoArea.left,
	                                                           TWindow->InfoArea.bottom,
	                                                           TWindow->InfoArea.left   + TOOL_SCROLLBAR_BUTTON_SIZE,
	                                                           TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH);
	TWindow->RightButIn = SizeOverX && ToolStatic_CheckMouseIn(TWindow->InfoArea.right  - TOOL_SCROLLBAR_BUTTON_SIZE,
	                                                           TWindow->InfoArea.bottom,
	                                                           TWindow->InfoArea.right,
	                                                           TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH);
	//前回状態推移処理が行われてからの経過時間を算出する。
	DeltaTime = ToolStatic_GetNowTime() - TWindow->LastButtonBottomTime;
	//現在の時間を保存しておく。
	TWindow->LastButtonBottomTime = ToolStatic_GetNowTime();
	//経過時間からスクロールバーが移動する場合の移動量を算出する。
	ScrollSize = DeltaTime * TOOL_SCROLLBAR_SPEED;
	if(!ScrollSize) { ScrollSize = TOOL_SCROLLBAR_SPEED / 60; }
	//マウスの左ボタンが押されていない場合はスクロール関係のフラグを全て初期化して終了。
	if(!(MouseInput & (1<<0)/*MOUSE_INPUT_LEFT*/)) {
		TWindow->HScrollGrips   = 0;
		TWindow->VScrollGrips   = 0;
		TWindow->RightButBottom = 0;
		TWindow->LeftButBottom  = 0;
		TWindow->UpButBottom    = 0;
		TWindow->DownButBottom  = 0;
		return;	//ここまで
	}
	//クライアント領域の横幅が情報表示領域の横幅より大きい場合は横方向のスクロールバーの処理を行う。
	if(SizeOverX) {
		//左ボタンが押された瞬間で、且つスクロールボタンの表示領域内にマウスカーソルがあった場合はスクロールボタンを押しているかどうかのフラグを立てる。
		if(MouseEdgeInput & (1<<0)/*MOUSE_INPUT_LEFT*/) {
			if(TWindow->LeftButIn ) { TWindow->LeftButBottom  = 1; }
			if(TWindow->RightButIn) { TWindow->RightButBottom = 1; }
		}
		//スクロールボタンが押されていた場合はスクロール位置を移動する。
		if(TWindow->LeftButIn || TWindow->RightButIn) {
			if(TWindow->LeftButBottom) {
				TWindow->DrawLeftUpX -= ScrollSize;
				if(TWindow->DrawLeftUpX < 0) { TWindow->DrawLeftUpX = 0; }
				TWindow->HScroll = TWindow->DrawLeftUpX * ScrollW / (TWindow->ClientSize.cx - InfoAreaW);
			} else if(TWindow->RightButBottom) {
				TWindow->DrawLeftUpX += ScrollSize;
				if(TWindow->DrawLeftUpX > (TWindow->ClientSize.cx - InfoAreaW)) { TWindow->DrawLeftUpX = TWindow->ClientSize.cx - InfoAreaW; }
				TWindow->HScroll = TWindow->DrawLeftUpX * ScrollW / (TWindow->ClientSize.cx - InfoAreaW);
			}
		//スクロールバーのつまみを掴んでいる場合はマウスカーソルの移動量にあわせてスクロール位置を移動する。
		} else if(TWindow->HScrollGrips) {
			TWindow->HScroll += MouseMoveX;
			if(TWindow->HScroll <       0) { TWindow->HScroll =       0; }
			if(TWindow->HScroll > ScrollW) { TWindow->HScroll = ScrollW; }
			TWindow->DrawLeftUpX = TWindow->HScroll * (TWindow->ClientSize.cx - InfoAreaW) / ScrollW;
		//スクロールバーの領域内にカーソルがあり、且つ左ボタンが押された瞬間の場合はスクロールバー関係の処理をする。
		} else if((MouseEdgeInput & (1<<0)/*MOUSE_INPUT_LEFT*/) &&
			  (ToolStatic_CheckMouseIn(TWindow->InfoArea.left   + TOOL_SCROLLBAR_BUTTON_SIZE,
			                           TWindow->InfoArea.bottom,
			                           TWindow->InfoArea.right  - TOOL_SCROLLBAR_BUTTON_SIZE,
			                           TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH))) {
			//カーソルの外をクリックした場合は1画面分移動する。
			if(MouseX < (TWindow->InfoArea.left + TOOL_SCROLLBAR_BUTTON_SIZE + TWindow->HScroll)) {
				TWindow->HScroll -= InfoAreaW * ScrollW / TWindow->ClientSize.cx;
				if(TWindow->HScroll < 0) { TWindow->HScroll = 0; }
			} else if(MouseX > (TWindow->InfoArea.left + TOOL_SCROLLBAR_BUTTON_SIZE + TWindow->HScroll + TOOL_SCROLLBAR_THUMB_SIZE)) {
				TWindow->HScroll += InfoAreaW * ScrollW / TWindow->ClientSize.cx;
				if(TWindow->HScroll > ScrollW) { TWindow->HScroll = ScrollW; }
			//つまみをクリックした場合はつまみ掴み状態にする。
			} else {
				TWindow->HScrollGrips = 1;
			}
			//スクロール位置からスクロール位置を考慮した描画基点位置を算出。
			TWindow->DrawLeftUpX = TWindow->HScroll * (TWindow->ClientSize.cx - InfoAreaW) / ScrollW;
		}
	}
	//クライアント領域の縦幅が情報表示領域の縦幅より大きい場合は縦方向のスクロールバーの処理を行う。
	if(SizeOverY) {
		//左ボタンが押された瞬間で、且つスクロールボタンの表示領域内にマウスカーソルがあった場合はスクロールボタンを押しているかどうかのフラグを立てる。
		if(MouseEdgeInput & (1<<0)/*MOUSE_INPUT_LEFT*/) {
			if(TWindow->UpButIn  ) { TWindow->UpButBottom   = 1; }
			if(TWindow->DownButIn) { TWindow->DownButBottom = 1; }
		}
		//スクロールボタンが押されていた場合はスクロール位置を移動する。
		if(TWindow->UpButIn || TWindow->DownButIn) {
			if(TWindow->UpButBottom) {
				TWindow->DrawLeftUpY -= ScrollSize;
				if(TWindow->DrawLeftUpY < 0) { TWindow->DrawLeftUpY = 0; }
				TWindow->VScroll = TWindow->DrawLeftUpY * ScrollH / (TWindow->ClientSize.cy - InfoAreaH);
			} else if(TWindow->DownButBottom) {
				TWindow->DrawLeftUpY += ScrollSize;
				if(TWindow->DrawLeftUpY > (TWindow->ClientSize.cy - InfoAreaH)) { TWindow->DrawLeftUpY = TWindow->ClientSize.cy - InfoAreaH; }
				TWindow->VScroll = TWindow->DrawLeftUpY * ScrollH / (TWindow->ClientSize.cy - InfoAreaH);
			}
		//スクロールバーのつまみを掴んでいる場合はマウスカーソルの移動量にあわせてスクロール位置を移動する。
		} else if(TWindow->VScrollGrips) {
			TWindow->VScroll += MouseMoveY;
			if(TWindow->VScroll <       0) { TWindow->VScroll =       0; }
			if(TWindow->VScroll > ScrollH) { TWindow->VScroll = ScrollH; }
			TWindow->DrawLeftUpY = TWindow->VScroll * (TWindow->ClientSize.cy - InfoAreaH) / ScrollH;
		//スクロールバーの領域内にカーソルがあり、且つ左ボタンが押された瞬間の場合はスクロールバー関係の処理をする。
		} else if((MouseEdgeInput & (1<<0)/*MOUSE_INPUT_LEFT*/) &&
			  ToolStatic_CheckMouseIn(TWindow->InfoArea.right,
			                          TWindow->InfoArea.top    + TOOL_SCROLLBAR_BUTTON_SIZE,
			                          TWindow->InfoArea.right  + TOOL_WINDOW_SCROLLBAR_WIDTH,
			                          TWindow->InfoArea.bottom - TOOL_SCROLLBAR_BUTTON_SIZE)) {
			//つまみの外をクリックした場合は1画面分移動する。
			if(MouseY < (TWindow->InfoArea.top + TOOL_SCROLLBAR_BUTTON_SIZE + TWindow->VScroll)) {
				TWindow->VScroll -= InfoAreaH * ScrollH / TWindow->ClientSize.cy;
				if(TWindow->VScroll < 0) { TWindow->VScroll = 0; }
			} else if(MouseY > (TWindow->InfoArea.top + TOOL_SCROLLBAR_BUTTON_SIZE + TWindow->VScroll + TOOL_SCROLLBAR_THUMB_SIZE)) {
				TWindow->VScroll += InfoAreaH * ScrollH / TWindow->ClientSize.cy;
				if(TWindow->VScroll > ScrollH) { TWindow->VScroll = ScrollH; }
			//つまみをクリックした場合はつまみ掴み状態にする。
			} else {
				TWindow->VScrollGrips = 1;
			}
			//スクロール位置からスクロール位置を考慮した描画基点位置を算出。
			TWindow->DrawLeftUpY = TWindow->VScroll * (TWindow->ClientSize.cy - InfoAreaH) / ScrollH;
		}
	}
}
//-----------------------------------------------------------------------------
//ウインドウ情報を画面に描画する。
//[in]
//	TWindow			ウインドウ情報。
static void ToolWindow_Draw(SToolWindow* TWindow) {
	int InfoAreaW, InfoAreaH;
	int DrawWidth;
	int SizeOverX, SizeOverY;
	int DownButInBottom, UpButInBottom, LeftButInBottom, RightButInBottom;
	//表示状態が0の場合は何もせず終了。
	if(!ToolWindow_GetVisible(TWindow)) { return; }	//ここまで
	//スペース情報が変更されている可能性があるので情報表示領域の更新。
	ToolWindow_UpdateInfoArea(TWindow);
	//スクロールバーのボタンの上にカーソルがあり、且つボタンが押されている状態かどうかを調べておく。
	DownButInBottom  = TWindow->DownButBottom  && TWindow->DownButIn;
	UpButInBottom    = TWindow->UpButBottom    && TWindow->UpButIn;
	LeftButInBottom  = TWindow->LeftButBottom  && TWindow->LeftButIn;
	RightButInBottom = TWindow->RightButBottom && TWindow->RightButIn;
	//情報表示領域の幅と高さを算出。
	InfoAreaW = TWindow->InfoArea.right - TWindow->InfoArea.left;
	InfoAreaH = TWindow->InfoArea.bottom - TWindow->InfoArea.top;
	//クライアント領域のサイズが情報表示領域のサイズより大きいかどうかを調べておく。
	SizeOverX = InfoAreaW < TWindow->ClientSize.cx;
	SizeOverY = InfoAreaH < TWindow->ClientSize.cy;
	//名前が設定されている場合は名前を表示する。
	if(TWindow->Name) {
		//名前を表示するウインドウ上部を描画。
		ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 128);
		ToolFunc_DrawBox(TWindow->InfoArea.left  ,
		                 TWindow->InfoArea.top   - TOOL_WINDOW_NAME_HEIGHT,
		                 TWindow->InfoArea.right + (SizeOverY ? TOOL_WINDOW_SCROLLBAR_WIDTH : 0),
		                 TWindow->InfoArea.top   ,
		                 ToolFunc_GetColor(255,255,255),
		                 1);
		//名前の文字列を描画。
		DrawWidth = ToolFunc_GetDrawStringWidthToHandle(TWindow->Name, -1, ToolStatic_GetButtonFontHandle());
		ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 200);
		ToolFunc_DrawStringToHandle(TWindow->InfoArea.left + (InfoAreaW - DrawWidth) / 2,
		                            TWindow->InfoArea.top - TOOL_WINDOW_NAME_HEIGHT + (TOOL_WINDOW_NAME_HEIGHT - TOOL_FONT_HEIGHT) / 2,
		                            TWindow->Name,
		                            ToolFunc_GetColor(0,0,0),
		                            ToolStatic_GetButtonFontHandle());
	}
	//ウインドウの枠を描画。
	ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 200);
	ToolFunc_DrawBox(TWindow->InfoArea.left   - 1,
	                 TWindow->InfoArea.top    - 1 - (TWindow->Name ? TOOL_WINDOW_NAME_HEIGHT : 0),
	                 TWindow->InfoArea.right  + 1 + (SizeOverY ? TOOL_WINDOW_SCROLLBAR_WIDTH : 0),
	                 TWindow->InfoArea.bottom + 1 + (SizeOverX ? TOOL_WINDOW_SCROLLBAR_WIDTH : 0),
	                 ToolFunc_GetColor(255,255,255),
	                 0);
	ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 64);
	ToolFunc_DrawBox(TWindow->InfoArea.left  ,
	                 TWindow->InfoArea.top   ,
	                 TWindow->InfoArea.right ,
	                 TWindow->InfoArea.bottom,
	                 ToolFunc_GetColor(0,0,0),
	                 1);
	ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 200);
	//クライアント領域の縦幅が情報表示領域の縦幅より大きい場合は縦方向のスクロールバーを描画する。
	if(SizeOverY) {
		//バーの上下移動操作ボタンを描画。
		ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 200);
		ToolFunc_DrawBox(TWindow->InfoArea.right,
		                 TWindow->InfoArea.top,
		                 TWindow->InfoArea.right + TOOL_WINDOW_SCROLLBAR_WIDTH,
		                 TWindow->InfoArea.top   + TOOL_SCROLLBAR_BUTTON_SIZE,
		                 ToolFunc_GetColor(255,255,255),
		                 UpButInBottom);
		ToolFunc_DrawBox(TWindow->InfoArea.right,
		                 TWindow->InfoArea.bottom - TOOL_SCROLLBAR_BUTTON_SIZE,
		                 TWindow->InfoArea.right  + TOOL_WINDOW_SCROLLBAR_WIDTH,
		                 TWindow->InfoArea.bottom,
		                 ToolFunc_GetColor(255,255,255),
		                 DownButInBottom);
		ToolFunc_DrawTriangle(TWindow->InfoArea.right + 2,
		                      TWindow->InfoArea.top   + TOOL_SCROLLBAR_BUTTON_SIZE - 2,
		                      TWindow->InfoArea.right + TOOL_WINDOW_SCROLLBAR_WIDTH / 2,
		                      TWindow->InfoArea.top   + 2,
		                      TWindow->InfoArea.right + TOOL_WINDOW_SCROLLBAR_WIDTH - 2,
		                      TWindow->InfoArea.top   + TOOL_SCROLLBAR_BUTTON_SIZE - 2,
		                      UpButInBottom ? ToolFunc_GetColor(0,0,0) : ToolFunc_GetColor(255,255,255),
		                      1);
		ToolFunc_DrawTriangle(TWindow->InfoArea.right  + 2,
		                      TWindow->InfoArea.bottom - TOOL_SCROLLBAR_BUTTON_SIZE + 2,
		                      TWindow->InfoArea.right  + TOOL_WINDOW_SCROLLBAR_WIDTH / 2,
		                      TWindow->InfoArea.bottom - 2,
		                      TWindow->InfoArea.right  + TOOL_WINDOW_SCROLLBAR_WIDTH - 2,
		                      TWindow->InfoArea.bottom - TOOL_SCROLLBAR_BUTTON_SIZE + 2,
		                      DownButInBottom ? ToolFunc_GetColor(0,0,0) : ToolFunc_GetColor(255,255,255),
		                      1);
		//バーの枠を描画。
		ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 128);
		ToolFunc_DrawBox(TWindow->InfoArea.right,
		                 TWindow->InfoArea.top    + TOOL_SCROLLBAR_BUTTON_SIZE,
		                 TWindow->InfoArea.right  + TOOL_WINDOW_SCROLLBAR_WIDTH,
		                 TWindow->InfoArea.bottom - TOOL_SCROLLBAR_BUTTON_SIZE,
		                 ToolFunc_GetColor(255,255,255),
		                 1);
		//バーの現在のスクロール位置を示すつまみ部分を描画。
		ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 200);
		ToolFunc_DrawBox(TWindow->InfoArea.right,
		                 TWindow->InfoArea.top   + TWindow->VScroll + TOOL_SCROLLBAR_BUTTON_SIZE,
		                 TWindow->InfoArea.right + TOOL_WINDOW_SCROLLBAR_WIDTH,
		                 TWindow->InfoArea.top   + TWindow->VScroll + TOOL_SCROLLBAR_BUTTON_SIZE + TOOL_SCROLLBAR_THUMB_SIZE,
		                 ToolFunc_GetColor(255,255,255),
		                 1);
	}
	//クライアント領域の横幅が情報表示領域の横幅より大きい場合は横方向のスクロールバーを描画する。
	if(SizeOverX) {
		//バーの左右移動操作ボタンを描画。
		ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 200);
		ToolFunc_DrawBox(TWindow->InfoArea.left,
		                 TWindow->InfoArea.bottom,
		                 TWindow->InfoArea.left   + TOOL_SCROLLBAR_BUTTON_SIZE,
		                 TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH,
		                 ToolFunc_GetColor(255,255,255),
		                 LeftButInBottom);
		ToolFunc_DrawBox(TWindow->InfoArea.right  - TOOL_SCROLLBAR_BUTTON_SIZE,
		                 TWindow->InfoArea.bottom,
		                 TWindow->InfoArea.right,
		                 TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH,
		                 ToolFunc_GetColor(255,255,255),
		                 RightButInBottom);
		ToolFunc_DrawTriangle(TWindow->InfoArea.left   + TOOL_SCROLLBAR_BUTTON_SIZE - 2,
		                      TWindow->InfoArea.bottom + 2,
		                      TWindow->InfoArea.left   + 2,
		                      TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH / 2,
		                      TWindow->InfoArea.left   + TOOL_SCROLLBAR_BUTTON_SIZE - 2,
		                      TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH - 2,
		                      LeftButInBottom ? ToolFunc_GetColor(0,0,0) : ToolFunc_GetColor(255,255,255),
		                      1);
		ToolFunc_DrawTriangle(TWindow->InfoArea.right  - TOOL_SCROLLBAR_BUTTON_SIZE + 2,
		                      TWindow->InfoArea.bottom + 2,
		                      TWindow->InfoArea.right  - 2,
		                      TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH / 2,
		                      TWindow->InfoArea.right  - TOOL_SCROLLBAR_BUTTON_SIZE + 2,
		                      TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH - 2,
		                      RightButInBottom ? ToolFunc_GetColor(0,0,0) : ToolFunc_GetColor(255,255,255),
		                      1);
		//バーの枠を描画。
		ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 128);
		ToolFunc_DrawBox(TWindow->InfoArea.left   + TOOL_SCROLLBAR_BUTTON_SIZE,
		                 TWindow->InfoArea.bottom,
		                 TWindow->InfoArea.right  - TOOL_SCROLLBAR_BUTTON_SIZE,
		                 TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH,
		                 ToolFunc_GetColor(255,255,255),
		                 1);
		//バーの現在のスクロール位置を示すつまみ部分を描画。
		ToolFunc_SetDrawBlendMode(1/*DX_BLENDMODE_ALPHA*/, 200);
		ToolFunc_DrawBox(TWindow->InfoArea.left   + TWindow->HScroll + TOOL_SCROLLBAR_BUTTON_SIZE,
		                 TWindow->InfoArea.bottom,
		                 TWindow->InfoArea.left   + TWindow->HScroll + TOOL_SCROLLBAR_BUTTON_SIZE + TOOL_SCROLLBAR_THUMB_SIZE,
		                 TWindow->InfoArea.bottom + TOOL_WINDOW_SCROLLBAR_WIDTH,
		                 ToolFunc_GetColor(255,255,255),
		                 1);
	}
	//描画ブレンドモードを元に戻す。
	ToolFunc_SetDrawBlendMode(0/*DX_BLENDMODE_NOBLEND*/, 0);
}
