Last active
December 8, 2021 13:51
-
-
Save xyx0no646/21572495e1dbf006b2506256cbf53106 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// YesNoDialog.tjs - はい/いいえを選択するダイアログボックス | |
// Copyright (C)2001-2006, W.Dee and contributors 改変・配布は自由です | |
// | |
// ■確認ダイアログボックス改造版 | |
// | |
// ◎不定形の確認ダイアログボックスを表示する | |
// ‐ダイアログボックス本体、はい/いいえボタンにはαチャンネルつき画像を用いる | |
// ‐ダイアログボックス本体の画像は不透明度1以上の箇所がくり抜かれた形で表示される | |
// ‐ダイアログボックスにボーダーは付かない | |
// ◎メッセージ、タイトルバーキャプションはセンタリングされる | |
// ◎メッセージは各種マージン(dialogMessageLeft〜dialogMessageHeight)内に | |
// 収まるよう改行される。この領域に収まらないほど長いメッセージを指定した場合、 | |
// メッセージが途中で切れるので注意 | |
// ◎タイトルバーキャプションにはメッセージのような改行処理を施していない。タイトルバー | |
// キャプションの文字列の長さには注意すること(はみ出る) | |
// ◎各種パラメータは、Config_YesNoDialog.tjsのYesNoDialogWindow_config()で変更できる | |
// ◎その他、改造のポイントは☆を含むコメントを参照のこと | |
// | |
class YesNoDialogWindow extends Window | |
{ | |
var yesButton; // [はい] ボタン | |
var noButton; // [いいえ] ボタン | |
var result = false; // no:false yes:true | |
// 以下は定数として扱う:Config_YesNoDialog.tjsのYesNoDialogWindow_config()で変更できる | |
var dialogImage = "dialog_base.png"; // ダイアログボックス本体の画像ファイル | |
var dialogYesButtonImage = "dialog_bt_yes.png"; // [はい]ボタンの画像ファイル | |
var dialogYesButtonLeft = 85; // 同、X座標(ピクセル) | |
var dialogYesButtonTop = 156; // 同、Y座標(ピクセル) | |
var dialogNoButtonImage = "dialog_bt_no.png"; // [いいえ]ボタンの画像ファイル | |
var dialogNoButtonLeft = 210; // 同、X座標(ピクセル) | |
var dialogNoButtonTop = 156; // 同、Y座標(ピクセル) | |
var dialogFontHeight = 18; // メッセージのフォント高さ(ピクセル) | |
var dialogFontFace = "MS Pゴシック"; // メッセージのフォント | |
var dialogFontBold = false; // メッセージを太字にする場合はtrue | |
var dialogFontColor = clBtnText; // メッセージの色(0xRRGGBB形式/色定数) | |
var dialogShadowLevel = 0; // 影の不透明度(0:影なし) | |
var dialogShadowColor = 0x000000; // 影の色(0xRRGGBB形式/色定数) | |
var dialogShadowWidth = 0; // 影の幅(0:シャープ〜ぼける) | |
var dialogShadowOffsetX = 0; // 影の位置のX座標(0:真下) | |
var dialogShadowOffsetY = 0; // 同、Y座標(0:真下) | |
var dialogMessageLeft = 37; // メッセージ描画領域の左上隅X座標(ピクセル) | |
var dialogMessageTop = 63; // 同、Y座標(ピクセル) | |
var dialogMessageWidth = 400 - 37*2; // メッセージ描画領域の最大横幅(ピクセル) | |
var dialogMessageHeight = 210 - 63 - 75; // 同、高さ(ピクセル) | |
var dialogCaptionFontHeight = 18; // タイトルバーキャプションのフォント高さ(ピクセル) | |
var dialogCaptionTop = 18; // 同、Y座標(ピクセル) | |
function YesNoDialogWindow(message, cap) | |
{ | |
super.Window(); | |
if (typeof global.YesNoDialogWindow_config != "undefined") | |
(YesNoDialogWindow_config incontextof this)(); // パラメータを設定 | |
// メインウィンドウから cursor**** の情報をとってくる | |
if(global.Window.mainWindow !== null && | |
typeof global.Window.mainWindow.cursorDefault != "undefined") | |
this.cursorDefault = global.Window.mainWindow.cursorDefault; | |
if(global.Window.mainWindow !== null && | |
typeof global.Window.mainWindow.cursorPointed != "undefined") | |
this.cursorPointed = global.Window.mainWindow.cursorPointed; | |
// 外見の調整 | |
borderStyle = bsNone; // ウィンドウのボーダーをなくす | |
innerSunken = false; // クライアント領域の外見をフラットに(凹ませない) | |
// caption = cap; // ←ウィンドウのボーダーをなくしたため、現在は無意味なコード | |
// プライマリレイヤの作成 | |
add(new Layer(this, null)); | |
primaryLayer.loadImages(dialogImage); // ダイアログボックスの画像ファイルを読み込み | |
primaryLayer.setSizeToImageSize(); // レイヤのサイズを画像ファイルのそれに合わせる | |
setMaskRegion(); // ウィンドウを不定形にする | |
// プライマリのマウスカーソルを設定 | |
if(typeof this.cursorDefault !== "undefined") | |
primaryLayer.cursor = cursorDefault; | |
setInnerSize(primaryLayer.width, primaryLayer.height); | |
// ウィンドウ位置の調整 | |
if(global.Window.mainWindow !== null && global.Window.mainWindow isvalid) | |
{ | |
var win = global.Window.mainWindow; | |
var l, t; | |
l = ((win.width - width)>>1) + win.left; | |
t = ((win.height - height)>>1) + win.top; | |
if(l < 0) l = 0; | |
if(t < 0) t = 0; | |
if(l + width > System.screenWidth) l = System.screenWidth - width; | |
if(t + height > System.screenHeight) t = System.screenHeight - height; | |
setPos(l, t); | |
} | |
else | |
{ | |
setPos((System.screenWidth - width)>>1, (System.screenHeight - height)>>1); | |
} | |
// メッセージの描画 | |
primaryLayer.font.height = dialogFontHeight; // フォント高さを設定 | |
primaryLayer.font.face = dialogFontFace; // フォントを設定 | |
primaryLayer.font.bold = dialogFontBold; // 太字にする場合はtrueを設定する | |
var lines = getLines(message); // メッセージを領域内に収まるよう分割する | |
var y = dialogMessageTop; | |
for (var i = 0; i < lines.count; i++) { // 分割したメッセージを一行ずつ描画する | |
var th = primaryLayer.font.getTextHeight(lines[i]); | |
if (y+th > dialogMessageTop+dialogMessageHeight) { | |
// primaryLayer.hint = message; // ☆ヒントにメッセージを表示させる | |
Debug.notice("YesNoDialogWindow.YesNoDialogWindow(): 表示するメッセージが長すぎます"); | |
break; | |
} | |
var x = dialogMessageLeft + (dialogMessageWidth - primaryLayer.font.getTextWidth(lines[i])) \ 2; | |
primaryLayer.drawText(x, y, lines[i], dialogFontColor, 255, true, | |
dialogShadowLevel, dialogShadowColor, dialogShadowWidth, dialogShadowOffsetX, dialogShadowOffsetY); | |
y += th; | |
} | |
invalidate lines; | |
// キャプションの描画 | |
primaryLayer.font.height = dialogCaptionFontHeight; // フォント高さを設定 | |
var caption_left = (primaryLayer.width - primaryLayer.font.getTextWidth(cap)) \ 2; | |
primaryLayer.drawText(caption_left, dialogCaptionTop, cap, dialogFontColor, 255, true, | |
dialogShadowLevel, dialogShadowColor, dialogShadowWidth, dialogShadowOffsetX, dialogShadowOffsetY); | |
// Yesボタン | |
add(yesButton = new ButtonLayer(this, primaryLayer)); | |
with (yesButton) { | |
.loadImages(dialogYesButtonImage); | |
.top = dialogYesButtonTop; | |
.left = dialogYesButtonLeft; | |
.hitThreshold = 64; | |
.visible = true; | |
} | |
// Noボタン | |
add(noButton = new ButtonLayer(this, primaryLayer)); | |
with (noButton) { | |
.loadImages(dialogNoButtonImage); | |
.top = dialogNoButtonTop; | |
.left = dialogNoButtonLeft; | |
.hitThreshold = 64; | |
.visible = true; | |
} | |
} | |
function finalize() | |
{ | |
super.finalize(...); | |
} | |
function action(ev) | |
{ | |
// action | |
if(ev.type == "onClick") | |
{ | |
if(ev.target == yesButton) | |
{ | |
result = true; | |
close(); | |
} | |
else if(ev.target == noButton) | |
{ | |
result = false; | |
close(); | |
} | |
} | |
else if(ev.type == "onKeyDown" && ev.target === this) | |
{ | |
// パッド入力に対応する処理 | |
switch(ev.key) | |
{ | |
case VK_PADLEFT: | |
yesButton.focus(); | |
break; | |
case VK_PADRIGHT: | |
noButton.focus(); | |
break; | |
case VK_PAD1: | |
if(focusedLayer == yesButton) | |
{ | |
result = true; | |
close(); | |
} | |
else if(focusedLayer == noButton) | |
{ | |
result = false; | |
close(); | |
} | |
break; | |
case VK_PAD2: | |
result = false; | |
close(); | |
break; | |
} | |
} | |
} | |
function onKeyDown(key, shift) | |
{ | |
super.onKeyDown(...); | |
if(key == VK_ESCAPE) | |
{ | |
// ESC キーが押された | |
// 「いいえ」として処理 | |
result = false; | |
close(); | |
} | |
} | |
function getLines(message) | |
{ | |
// ↓あまり効率的なコードではないので、気になる場合は修正すると良い | |
var lines = new Array(); | |
var remainder = message.length; // 残りの文字数 | |
var start = 0; // 行頭のインデックス | |
var num = 1; // message_widthに納まる文字数 | |
while (remainder > 0) { | |
// 幅dialogMessageWidthピクセルに納まる文字数を調べる | |
for (var i = 1; i <= remainder; i++) { | |
if (primaryLayer.font.getTextWidth(message.substr(start,i)) <= dialogMessageWidth) | |
num = i; | |
else | |
break; | |
} | |
// message[start]〜message[start+num]までの文字列を抜き出し、配列に登録 | |
lines.add( message.substr(start,num) ); | |
// 行頭のインデックス、残りの文字数を更新 | |
start += num; | |
remainder -= num; | |
} | |
return lines; | |
} | |
} | |
// Yes か No かはっきりさせる関数 | |
function askYesNo(message, caption = "確認") | |
{ | |
if(typeof(global.KirikiriEmscriptenInterface) == "Object"){ | |
var result = true; | |
try { | |
var js = KirikiriEmscriptenInterface.evalJS('window'); | |
// 一度音を止めます | |
KirikiriEmscriptenInterface.evalJS('Module["SDL2"] && Module["SDL2"].audioContext.suspend()'); | |
try { | |
result = js.confirm(message); | |
} | |
catch(e1){ | |
Debug.notice(e1.message); | |
} | |
// 音を再開させます | |
KirikiriEmscriptenInterface.evalJS('Module["SDL2"] && Module["SDL2"].audioContext.resume()'); | |
} | |
catch(e2){ | |
Debug.notice(e2.message); | |
} | |
return result; | |
} | |
else if (typeof(global.KrkrUIAlert) == "Object"){ | |
return KrkrUIAlert.askYesNo(caption,message); | |
} | |
else{ | |
var win = new YesNoDialogWindow(message, caption); | |
win.showModal(); | |
var res = win.result; | |
invalidate win; | |
return res; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment