Video

Upgrades and adds various features to the existing window system within one’s game. This plugin provides additions to the window classes such as open/close callbacks, better stretch control, etc.

Window Upgrade
Version 1.00
SomeRanDev

This plugin requires the Game Upgrade plugin:
http://sumrndm.site/game-upgrade/

Upgrades and adds various features to the existing window system within
one's game. This plugin provides additions to the window classes such as
open/close callbacks, better stretch control, etc.

==============================================================================
Information Window
==============================================================================

Information windows are windows that protray a large amount of information
to the player all at once. These require a bit more set up than Question
Windows, but have even greater power when it comes to giving information.

To start, one must go to the "Info Windows" parameter to setup an Info
Window. An Info Window requires Text, Width, Line Height, and a Default
Font Size. Once these four things have been setup, one may display
that specific Info Window by using the ID listed next to it in the
Plugin Manager's list.

CreateInfoWindow [windowId]

In order to show the Info Window, use this plugin command and place its
window ID next to it. That specific window with the specified information
will be shown.

When customizing the text of the window, one may use text codes. Furthermore,
one may also use a "
" tag to generate a horizontal line.

==============================================================================
Choice Window Creation
==============================================================================

The plugin provides an alternative choice window with more options including
row, column, and alignment control, along with the capability to add an
indefinite number of choices.

In order to set this up, simply use the plugin command:

CreateChoiceWindow [variableId] [choice1, choice2, choice3, ...]

This will create a choice window with the defined choices and have the result
be placed within a variable defined by the "variableId". If the first choice
is chosen, 0 will be placed into that variable. Choice2 will input a value
of 1, choice 3 will be 2, etc.

==============================================================================
Choice Window Setup Data
==============================================================================

In order to customize the columns, rows, and alignment for the Choice
window, the following plugin command must also be used before creation:

SetChoiceWindowData [cols] [rows] [align]

This will set the columns, rows, and alignment respectively.

For example:

SetChoiceWindowData 1 4 right

If you wish to reset the data, you can use the plugin command:

ResetChoiceWindowData

==============================================================================
Question Window Setup Choices
==============================================================================

Questions windows are windows that contain both information and the ability
to select a choice within itself. These are more stylized than normal
choice windows, providing a better alternative for developers in specific
situations.

SetQuestionWindowChoices [choice1, choice2, choice3, ...]

To start, once must call this plugin command to set up the names of the
choices that will be shown on the question window. For example, if someone
wanted to create a "yes"/"no" question, they could do:

SetQuestionWindowChoices Yes, No

==============================================================================
Question Window Setup Data
==============================================================================

In order to customize the columns, rows, and alignment for the Question
window, the following plugin command must also be used before creation:

SetQuestionWindowData [cols] [rows] [align]

This will set the columns, rows, and alignment respectively.

For example:

SetQuestionWindowData 2 2 left

If you wish to reset the data, you can use the plugin command:

ResetQuestionWindowData

==============================================================================
Question Window Creation
==============================================================================

Once the choices are set up, one may call upon the Question window using
this plugin command:

CreateQuestionWindow [variableId] [message]

Once the choices are set up, this plugin command creates the question
window itself. The first input, "variableId", should be a number representing
the ID of the variable the result will be stored in. The result will be
a number value, starting from 0, representing which choice was selected.

Here's an example:

CreateQuestionWindow 3 Do you like cake?

This will create a Question Window that asks, "Do you like Cake?" and stores
the result in variable ID 3. Since we set up 2 choices from before, "Yes"
and "No", the variable will be set to 0 is Yes is chosen, and 1 if No is
chosen.

==============================================================================
End of Help File
==============================================================================

Welcome to the bottom of the Help file.

Thanks for reading!
If you have questions, or if you enjoyed this Plugin, please check
out my YouTube channel!

https://www.youtube.com/c/SumRndmDde

Until next time,
~ SomeRanDev
var SRD = SRD || {};
SRD.WindowUpgrade = SRD.WindowUpgrade || {};

var Imported = Imported || {};
Imported["SumRndmDde Window Upgrade"] = 1.01;

function Window_InfoDisplay() {
	this.initialize.apply(this, arguments);
}

function Window_ChoiceBase() {
	this.initialize.apply(this, arguments);
}

function Window_ChoiceMessage() {
	this.initialize.apply(this, arguments);
}

(function(_) {

"use strict";

//-----------------------------------------------------------------------------
// SRD.Requirements
//-----------------------------------------------------------------------------

_.alertNeedGameUpgrade = function() {
	alert("The 'SRD_GameUpgrade' plugin is required for using the 'SRD_WindowUpgrade' plugin.");
	if(confirm("Do you want to open the download page to 'SRD_GameUpgrade'?")) {
		window.open('http://sumrndm.site/game-upgrade/');
	}
};

if(!Imported["SumRndmDde Game Upgrade"]) {
	_.alertNeedGameUpgrade();
	return;
}

//-----------------------------------------------------------------------------
// SRD.WindowUpgrade
//-----------------------------------------------------------------------------

_.params = SRD.parse(JSON.stringify(PluginManager.parameters('SRD_WindowUpgrade')), true);

//-----------------------------------------------------------------------------
// SRD.PluginCommands
//-----------------------------------------------------------------------------

SRD.PluginCommands['createinfowindow'] = function(args) {
	const id = parseInt(args[0]) - 1;
	const info = _.params['Info Windows'][id];
	if(!info) return;
	const scene = SceneManager.scene;
	const win = new Window_InfoDisplay(info['Text'], info['Width'], info['Line Height'], info['Default Font Size']);
	scene.addWindow(win);
	win.setCloseCallback(function() {
		scene.removeChild(win);
		this.setWaitMode('');
	}.bind(this));
	this.setWaitMode('indefinite');
};

SRD.PluginCommands['setchoicewindowdata'] = function(args) {
	if(!$gameSystem.wu_info.choiceWindowData) {
		$gameSystem.wu_info.choiceWindowData = {};
	}
	if(args[0]) {
		$gameSystem.wu_info.choiceWindowData.cols = parseInt(args[0]);
	}
	if(args[1]) {
		$gameSystem.wu_info.choiceWindowData.rows = parseInt(args[1]);
	}
	if(args[2]) {
		$gameSystem.wu_info.choiceWindowData.align = String(args[2]);
	}
};

SRD.PluginCommands['resetchoicewindowdata'] = function(args) {
	$gameSystem.wu_info.choiceWindowData = {};
};

SRD.PluginCommands['createchoicewindow'] = function(args) {
	if(!$gameSystem.wu_info.choiceWindowData) {
		$gameSystem.wu_info.choiceWindowData = {};
	}
	let argString = '';
	for(let i = 1; i < args.length; i++) {
		argString += args[i] + ' ';
	}
	const choices = argString.split(/\s*,\s*/);
	const varId = parseInt(args[0]);
	const callbacks = [];
	for(let i = 0; i < choices.length; i++) {
		callbacks.push(function() {
			$gameVariables.setValue(varId, i);
			win.close();
		}.bind(this));
	}
	const scene = SceneManager.scene;
	const win = new Window_ChoiceBase(
		choices, 
		callbacks, 
		$gameSystem.wu_info.choiceWindowData
	);
	scene.addWindow(win);
	win.setCloseCallback(function() {
		scene.removeChild(win);
		this.setWaitMode('');
	}.bind(this));
	this.setWaitMode('indefinite');
};

SRD.PluginCommands['setquestionwindowdata'] = function(args) {
	if(!$gameSystem.wu_info.questionWindowData) {
		$gameSystem.wu_info.questionWindowData = {};
	}
	if(args[0]) {
		$gameSystem.wu_info.questionWindowData.cols = parseInt(args[0]);
	}
	if(args[1]) {
		$gameSystem.wu_info.questionWindowData.rows = parseInt(args[1]);
	}
	if(args[2]) {
		$gameSystem.wu_info.questionWindowData.align = String(args[2]);
	}
};

SRD.PluginCommands['resetquestionwindowdata'] = function(args) {
	$gameSystem.wu_info.questionWindowData = {};
};

SRD.PluginCommands['setquestionwindowchoices'] = function(args) {
	let argString = '';
	for(let i = 0; i < args.length; i++) {
		argString += args[i] + ' ';
	}
	$gameSystem.wu_info.questionWindowChoices = argString.split(/\s*,\s*/);
};

SRD.PluginCommands['createquestionwindow'] = function(args) {
	if(!$gameSystem.wu_info.questionWindowChoices) {
		$gameSystem.wu_info.questionWindowChoices = ['Yes', 'No'];
	}
	if(!$gameSystem.wu_info.questionWindowData) {
		$gameSystem.wu_info.questionWindowData = {};
	}
	const varId = parseInt(args[0]);
	let message = '';
	for(let i = 1; i < args.length; i++) {
		message += args[i] + ' ';
	}
	message = JSON.parse("\"" + message + "\"");
	let callbacks = [];
	for(let i = 0; i < $gameSystem.wu_info.questionWindowChoices.length; i++) {
		callbacks.push(function() {
			$gameVariables.setValue(varId, i);
			win.close();
		}.bind(this));
	}
	const scene = SceneManager.scene;
	const win = new Window_ChoiceMessage(
		message, 
		$gameSystem.wu_info.questionWindowChoices, 
		callbacks, 
		$gameSystem.wu_info.questionWindowData
	);
	scene.addWindow(win);
	win.setCloseCallback(function() {
		scene.removeChild(win);
		this.setWaitMode('');
	}.bind(this));
	this.setWaitMode('indefinite');
};

//-----------------------------------------------------------------------------
// Window
//-----------------------------------------------------------------------------

Window.prototype.setTone = function(r, g, b) {
	const tone = this._colorTone;
	if (r !== tone[0] || g !== tone[1] || b !== tone[2]) {
		this._colorTone = [r, g, b];
		this._refreshColorFilter();
	}
};

_.Window__createAllParts = Window.prototype._createAllParts;
Window.prototype._createAllParts = function() {
	_.Window__createAllParts.apply(this, arguments);
	this._createColorFilter();
};

Window.prototype._createColorFilter = function() {
	this._colorFilter = new ToneFilter();
	if(_.params['Tone Options'].Background) {
		this._windowBackSprite.filters = [this._colorFilter];
	}
	if(_.params['Tone Options'].Frame) {
		this._windowFrameSprite.filters = [this._colorFilter];
	}
	if(_.params['Tone Options'].Cursor) {
		this._windowCursorSprite.filters = [this._colorFilter];
	}
	this._refreshColorFilter();
};

Window.prototype._refreshColorFilter = function() {
	this._colorFilter.hue(0);
	this._colorFilter.adjustTone(this._colorTone[0], this._colorTone[1], this._colorTone[2]);
};

Window.prototype._refreshBack = function() {
	var m = this._margin;
	var w = this._width - m * 2;
	var h = this._height - m * 2;
	var bitmap = new Bitmap(w, h);

	this._windowBackSprite.bitmap = bitmap;
	this._windowBackSprite.setFrame(0, 0, w, h);
	this._windowBackSprite.move(m, m);

	if (w > 0 && h > 0 && this._windowskin) {
		var p = 96;
		if(_.params['Stretch Options'].Background) {
			bitmap.blt(this._windowskin, 0, 0, p, p, 0, 0, w, h);
		} else {
			for (var y = 0; y < h; y += p) {
				for (var x = 0; x < w; x += p) {
					bitmap.blt(this._windowskin, 0, 0, p, p, x, y, p, p);
				}
			}
		}
		if(_.params['Stretch Options'].Foreground) {
			bitmap.blt(this._windowskin, 0, p, p, p, 0, 0, w, h);
		} else {
			for (var y = 0; y < h; y += p) {
				for (var x = 0; x < w; x += p) {
					bitmap.blt(this._windowskin, 0, p, p, p, x, y, p, p);
				}
			}
		}
	}
};

if(!_.params['Stretch Options'].Frame) {

Window.prototype._refreshFrame = function() {
	var w = this._width;
	var h = this._height;
	var m = 24;
	var bitmap = new Bitmap(w, h);

	this._windowFrameSprite.bitmap = bitmap;
	this._windowFrameSprite.setFrame(0, 0, w, h);

	if (w > 0 && h > 0 && this._windowskin) {
		var skin = this._windowskin;
		var p = 96;
		var q = 96;
		var oWid = p-m*2;
		var nWid = w-m*2;
		var oHei = p-m*2;
		var nHei = h-m*2;
		var hRep = Math.floor(nWid / oWid);
		var vRep = Math.floor(nHei / oHei);
		var hRem = nWid % oWid;
		var vRem = nHei % oHei;

		for(var i = 0; i < hRep; i++) {
			bitmap.blt(skin, p+m, 0, oWid, m, m + (i*oWid), 0, oWid, m);
		}
		bitmap.blt(skin, p+m, 0, hRem, m, m + (oWid*hRep), 0, hRem, m);

		for(var i = 0; i < hRep; i++) {
			bitmap.blt(skin, p+m, q-m, oWid, m, m + (i*oWid), h-m, oWid, m);
		}
		bitmap.blt(skin, p+m, q-m, hRem, m, m + (oWid*hRep), h-m, hRem, m);

		for(var i = 0; i < vRep; i++) {
			bitmap.blt(skin, p, m, m, oHei, 0, m + (i*oHei), m, oHei);
		}
		bitmap.blt(skin, p, m, m, vRem, 0, m + (vRep*oHei), m, vRem);

		for(var i = 0; i < vRep; i++) {
			bitmap.blt(skin, p+q-m, m, m, oHei, w-m, m + (i*oHei), m, oHei);
		}
		bitmap.blt(skin, p+q-m, m, m, vRem, w-m, m + (vRep*oHei), m, vRem);

		bitmap.blt(skin, p+0, 0+0, m, m, 0, 0, m, m);
		bitmap.blt(skin, p+q-m, 0+0, m, m, w-m, 0, m, m);
		bitmap.blt(skin, p+0, 0+q-m, m, m, 0, h-m, m, m);
		bitmap.blt(skin, p+q-m, 0+q-m, m, m, w-m, h-m, m, m);
	}
};

}

//-----------------------------------------------------------------------------
// WindowLayer
//-----------------------------------------------------------------------------

if(_.params['Mutliple Layers']) {

WindowLayer.prototype = Object.create(PIXI.Container.prototype);

WindowLayer.prototype.initialize = function() {
	PIXI.Container.call(this);
	this._width = 0;
	this._height = 0;
	this.on('removed', this.onRemoveAsAChild);
};

WindowLayer.prototype.onRemoveAsAChild = function() {
	this.removeChildren();
};

WindowLayer.prototype.move = function(x, y, width, height) {
	this.x = x;
	this.y = y;
	this.width = width;
	this.height = height;
};

WindowLayer.prototype.update = function() {
	this.children.forEach(function(child) {
		if (child.update) {
			child.update();
		}
	});
};

}

//-----------------------------------------------------------------------------
// Game_System
//-----------------------------------------------------------------------------

_.Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function() {
    _.Game_System_initialize.apply(this, arguments);
    this.wu_info = {};
};

//-----------------------------------------------------------------------------
// Window_Base
//-----------------------------------------------------------------------------

Window_Base.prototype.standardFontSize = function() {
	return _.params['Window Defaults']['Standard Font Size'];
};

Window_Base.prototype.standardPadding = function() {
	return _.params['Window Defaults']['Standard Padding'];
};

Window_Base.prototype.textPadding = function() {
	return _.params['Window Defaults']['Text Padding'];
};

Window_Base.prototype.standardBackOpacity = function() {
	return _.params['Window Defaults']['Standard Back Opacity'];
};

Window_Base.prototype.translucentOpacity = function() {
	return _.params['Window Defaults']['Translucent Opacity'];
};

Window_Base.prototype.setOpenCallback = function(callback) {
	this._openCallback = callback;
};

Window_Base.prototype.setCloseCallback = function(callback) {
	this._closeCallback = callback;
};

Window_Base.prototype.updateOpen = function() {
	if (this._opening) {
		this.openness += _.params['Window Defaults']['Opening Speed'];
		if (this.isOpen()) {
			this._opening = false;
			if(this._openCallback) {
				this._openCallback();
			}
		}
	}
};

Window_Base.prototype.updateClose = function() {
	if (this._closing) {
		this.openness -= _.params['Window Defaults']['Closing Speed'];
		if (this.isClosed()) {
			this._closing = false;
			if(this._closeCallback) {
				this._closeCallback();
			}
		}
	}
};

if(_.params['Text Colors']['Allow Manual Colors']) {

Window_Base.prototype.textColor = function(n) {
	if(_.params['Text Colors']['Text Color ' + n]) {
		return _.params['Text Colors']['Text Color ' + n];
	}
	return '#000000';
};

}

if(_.params['Game Colors']['Normal Color']) {

Window_Base.prototype.normalColor = function() {
	return _.params['Game Colors']['Normal Color'];
};

}

if(_.params['Game Colors']['System Color']) {

Window_Base.prototype.systemColor = function() {
	return _.params['Game Colors']['System Color'];
};

}

if(_.params['Game Colors']['Crisis Color']) {

Window_Base.prototype.crisisColor = function() {
	return _.params['Game Colors']['Crisis Color'];
};

}

if(_.params['Game Colors']['Death Color']) {

Window_Base.prototype.deathColor = function() {
	return _.params['Game Colors']['Death Color'];
};

}

if(_.params['Game Colors']['Gauge Back Color']) {

Window_Base.prototype.gaugeBackColor = function() {
	return _.params['Game Colors']['Gauge Back Color'];
};

}

if(_.params['Game Colors']['HP Gauge Color 1']) {

Window_Base.prototype.hpGaugeColor1 = function() {
	return _.params['Game Colors']['HP Gauge Color 1'];
};

}

if(_.params['Game Colors']['HP Gauge Color 2']) {

Window_Base.prototype.hpGaugeColor2 = function() {
	return _.params['Game Colors']['HP Gauge Color 2'];
};

}

if(_.params['Game Colors']['MP Gauge Color 1']) {

Window_Base.prototype.mpGaugeColor1 = function() {
	return _.params['Game Colors']['MP Gauge Color 1'];
};

}

if(_.params['Game Colors']['MP Gauge Color 2']) {

Window_Base.prototype.mpGaugeColor2 = function() {
	return _.params['Game Colors']['MP Gauge Color 2'];
};

}

if(_.params['Game Colors']['MP Cost Color']) {

Window_Base.prototype.mpCostColor = function() {
	return _.params['Game Colors']['MP Cost Color'];
};

}

if(_.params['Game Colors']['Power Up Color']) {

Window_Base.prototype.powerUpColor = function() {
	return _.params['Game Colors']['Power Up Color'];
};

}

if(_.params['Game Colors']['Power Down Color']) {

Window_Base.prototype.powerDownColor = function() {
	return _.params['Game Colors']['Power Down Color'];
};

}

if(_.params['Game Colors']['TP Gauge Color 1']) {

Window_Base.prototype.tpGaugeColor1 = function() {
	return _.params['Game Colors']['TP Gauge Color 1'];
};

}

if(_.params['Game Colors']['TP Gauge Color 2']) {

Window_Base.prototype.tpGaugeColor2 = function() {
	return _.params['Game Colors']['TP Gauge Color 2'];
};

}

if(_.params['Game Colors']['TP Cost Color']) {

Window_Base.prototype.tpCostColor = function() {
	return _.params['Game Colors']['TP Cost Color'];
};

}

//-----------------------------------------------------------------------------
// Window_InfoDisplay
//-----------------------------------------------------------------------------

Window_InfoDisplay.prototype = Object.create(Window_Base.prototype);
Window_InfoDisplay.prototype.constructor = Window_InfoDisplay;

Window_InfoDisplay.prototype.initialize = function(info, width, lineHeight, fontSize) {
	this._lines = info.split(/(?:\r\n|\r|\n)/);
	this._lineHeight = lineHeight || 32;
	this._fontSize = fontSize || 28;
	const height = this.createHeight(this._lines);
	this._borderPadding = 12;
	Window_Base.prototype.initialize.call(this, 0, 0, width, height + (this.standardPadding() * 2));
	this.x = (Graphics.boxWidth - this.width) / 2;
	this.y = (Graphics.boxHeight - this.height) / 2;
	this.openness = 0;
	this.refresh();
	this.open();
};

Window_InfoDisplay.prototype.createHeight = function(lines) {
	const lineHeight = this.lineHeight();
	let height = 0;
	for(let i = 0; i < lines.length; i++) {
		if(lines[i].match(/<hr>/)) {
			height += 12;
		} else {
			height += lineHeight;
		}
	}
	return height;
};

Window_InfoDisplay.prototype.standardFontSize = function() {
	return this._fontSize;
};

Window_InfoDisplay.prototype.lineHeight = function() {
	return this._lineHeight;
};

Window_InfoDisplay.prototype.update = function() {
	Window_Base.prototype.update.apply(this, arguments);
	if(this.isOpen()) {
		this.updateInput();
	}
};

Window_InfoDisplay.prototype.updateInput = function() {
	if(Input.isPressed('ok')) {
		this.close();
	}
};

Window_InfoDisplay.prototype.refresh = function() {
	this.contents.clear();
	this.drawLines();
};

Window_InfoDisplay.prototype.drawLines = function() {
	const lines = this._lines;
	const lineHeight = this.lineHeight();
	let yPosition = 0;
	for(let i = 0; i < lines.length; i++) {
		if(lines[i].match(/<hr>/)) {
			this.drawHorzLine(yPosition);
			yPosition += 12;
		} else {
			this.drawTextEx(lines[i], 0, yPosition);
			yPosition += lineHeight;
		}
	}
};

Window_InfoDisplay.prototype.drawHorzLine = function(y) {
	this.contents.fillRect(0, y + (Math.floor(this._borderPadding / 2) - 1), this.contentsWidth(), 2, 'rgba(255, 255, 255, 0.2)');
};

//-----------------------------------------------------------------------------
// Window_ChoiceBase
//-----------------------------------------------------------------------------

Window_ChoiceBase.prototype = Object.create(Window_Command.prototype);
Window_ChoiceBase.prototype.constructor = Window_ChoiceBase;

Window_ChoiceBase.prototype.initialize = function(choices, callbacks, data) {
	this._choices = choices;
	this._callbacks = callbacks;
	this.parseData(data);
	Window_Command.prototype.initialize.call(this, 0, 0);
	this.setupWidth(data ? data.width : null);
	this.x = (Graphics.boxWidth - this.width) / 2;
	this.y = (Graphics.boxHeight - this.height) / 2;
	this.openness = 0;
	this.open();
};

Window_ChoiceBase.prototype.setupWidth = function(width) {
	if(!width) {
		this._width = 0;
		for(let i = 0; i < this._choices.length; i++) {
			const textWidth = this.textWidth(this._choices[i]);
			if(this._width < textWidth) {
				this._width = textWidth * this._columns;
			}
		}
		this._width += (this.standardPadding() * 2) + 48 + (this._columns > 1 ? (this.standardFontSize() * this._columns * 2) : 0);
	} else {
		this._width = width;
	}
	this.width = this.windowWidth();
	this.refresh();
	this.select(0);
};

Window_ChoiceBase.prototype.parseData = function(data) {
	data = data || {};
	this._columns = data.cols || 1;
	this._rows = data.rows || this._choices.length;
	this._alignment = data.align || 'center';
};

Window_ChoiceBase.prototype.windowWidth = function() {
	return this._width || 1;
};

Window_ChoiceBase.prototype.maxItems = function() {
	return this._choices.length;
};

Window_ChoiceBase.prototype.maxCols = function() {
	return this._columns;
};

Window_ChoiceBase.prototype.numVisibleRows = function() {
	return this._rows;
};

Window_ChoiceBase.prototype.itemTextAlign = function() {
	return this._alignment;
};

Window_ChoiceBase.prototype.makeCommandList = function() {
	for(let i = 0; i < this._choices.length; i++) {
		this.addCommand(this._choices[i], String(i));
	}
};

Window_ChoiceBase.prototype.isHorizontal = function() {
	return this.maxCols() > 1;
};

Window_ChoiceBase.prototype.isHandled = function(symbol) {
	return !!this._callbacks[parseInt(symbol)];
};

Window_ChoiceBase.prototype.callHandler = function(symbol) {
	let index = parseInt(symbol);
	if(this._callbacks[index]) {
		this._callbacks[index]();
	}
};

//-----------------------------------------------------------------------------
// Window_ChoiceMessage
//-----------------------------------------------------------------------------

Window_ChoiceMessage.prototype = Object.create(Window_ChoiceBase.prototype);
Window_ChoiceMessage.prototype.constructor = Window_ChoiceMessage;

Window_ChoiceMessage.prototype.initialize = function(message, choices, callbacks, data) {
	this._lines = message.split(/(?:\r\n|\r|\n)/);
	this._borderPadding = 12;
	Window_ChoiceBase.prototype.initialize.call(this, choices, callbacks, data);
};

Window_ChoiceMessage.prototype.setupWidth = function(width) {
	if(!width) {
		this._width = 0;
		for(let i = 0; i < this._lines.length; i++) {
			const textWidth = this.textWidth(this._lines[i]);
			if(this._width < textWidth) {
				this._width = textWidth;
			}
		}
		this._width += (this.standardPadding() * 2);
	} else {
		this._width = width;
	}
	this.width = this.windowWidth();
	this.refresh();
	this.select(0);
};

Window_ChoiceMessage.prototype.parseData = function(data) {
	data = data || {};
	this._columns = data.cols || this._choices.length;
	this._rows = data.rows || 1;
	this._alignment = data.align || 'center';
};

Window_ChoiceMessage.prototype.windowHeight = function() {
	return this.fittingHeight(this._lines.length + this.numVisibleRows()) + this._borderPadding;
};

Window_ChoiceMessage.prototype.itemRect = function(index) {
	const rect = Window_Selectable.prototype.itemRect.apply(this, arguments);
	rect.y += (this.lineHeight() * this._lines.length) + this._borderPadding;
	return rect;
};

Window_ChoiceMessage.prototype.drawAllItems = function() {
	Window_ChoiceBase.prototype.drawAllItems.apply(this, arguments);
	for(let i = 0; i < this._lines.length; i++) {
		this.drawTextEx(this._lines[i], 0, this.lineHeight() * i);
	}
	this.contents.fillRect(0, (this.lineHeight() * (this._lines.length)) + (Math.floor(this._borderPadding / 2) - 1), 
		this.contentsWidth(), 2, 'rgba(255, 255, 255, 0.2)');
};

})(SRD.WindowUpgrade);