Changeset - r19064:0f7af43d9a9f
[Not reviewed]
master
0 14 3
rubidium - 12 years ago 2012-02-12 10:32:41
rubidium@openttd.org
(svn r23932) -Codechange: split the NewGRF text window into its own source files
17 files changed with 352 insertions and 236 deletions:
0 comments (0 inline, 0 general)
projects/openttd_vs100.vcxproj
Show inline comments
 
@@ -573,6 +573,8 @@
 
    <ClInclude Include="..\src\terraform_gui.h" />
 
    <ClInclude Include="..\src\textbuf_gui.h" />
 
    <ClInclude Include="..\src\texteff.hpp" />
 
    <ClInclude Include="..\src\textfile_gui.h" />
 
    <ClInclude Include="..\src\textfile_type.h" />
 
    <ClInclude Include="..\src\tgp.h" />
 
    <ClInclude Include="..\src\tile_cmd.h" />
 
    <ClInclude Include="..\src\tile_type.h" />
 
@@ -684,6 +686,7 @@
 
    <ClCompile Include="..\src\statusbar_gui.cpp" />
 
    <ClCompile Include="..\src\subsidy_gui.cpp" />
 
    <ClCompile Include="..\src\terraform_gui.cpp" />
 
    <ClCompile Include="..\src\textfile_gui.cpp" />
 
    <ClCompile Include="..\src\timetable_gui.cpp" />
 
    <ClCompile Include="..\src\toolbar_gui.cpp" />
 
    <ClCompile Include="..\src\town_gui.cpp" />
projects/openttd_vs100.vcxproj.filters
Show inline comments
 
@@ -948,6 +948,12 @@
 
    <ClInclude Include="..\src\texteff.hpp">
 
      <Filter>Header Files</Filter>
 
    </ClInclude>
 
    <ClInclude Include="..\src\textfile_gui.h">
 
      <Filter>Header Files</Filter>
 
    </ClInclude>
 
    <ClInclude Include="..\src\textfile_type.h">
 
      <Filter>Header Files</Filter>
 
    </ClInclude>
 
    <ClInclude Include="..\src\tgp.h">
 
      <Filter>Header Files</Filter>
 
    </ClInclude>
 
@@ -1281,6 +1287,9 @@
 
    <ClCompile Include="..\src\terraform_gui.cpp">
 
      <Filter>GUI Source Code</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\textfile_gui.cpp">
 
      <Filter>GUI Source Code</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\timetable_gui.cpp">
 
      <Filter>GUI Source Code</Filter>
 
    </ClCompile>
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -1567,6 +1567,14 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\textfile_gui.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\textfile_type.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tgp.h"
 
				>
 
			</File>
 
@@ -2019,6 +2027,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\textfile_gui.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\timetable_gui.cpp"
 
				>
 
			</File>
projects/openttd_vs90.vcproj
Show inline comments
 
@@ -1564,6 +1564,14 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\textfile_gui.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\textfile_type.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tgp.h"
 
				>
 
			</File>
 
@@ -2016,6 +2024,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\textfile_gui.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\timetable_gui.cpp"
 
				>
 
			</File>
source.list
Show inline comments
 
@@ -306,6 +306,8 @@ tar_type.h
 
terraform_gui.h
 
textbuf_gui.h
 
texteff.hpp
 
textfile_gui.h
 
textfile_type.h
 
tgp.h
 
tile_cmd.h
 
tile_type.h
 
@@ -436,6 +438,7 @@ station_gui.cpp
 
statusbar_gui.cpp
 
subsidy_gui.cpp
 
terraform_gui.cpp
 
textfile_gui.cpp
 
timetable_gui.cpp
 
toolbar_gui.cpp
 
town_gui.cpp
src/newgrf_config.h
Show inline comments
 
@@ -17,6 +17,7 @@
 
#include "core/smallmap_type.hpp"
 
#include "misc/countedptr.hpp"
 
#include "fileio_type.h"
 
#include "textfile_type.h"
 

	
 
/** GRF config bit flags */
 
enum GCF_Flags {
 
@@ -145,18 +146,6 @@ struct GRFTextWrapper : public SimpleCou
 
	~GRFTextWrapper();
 
};
 

	
 
/** Additional text files accompanying NewGRFs */
 
enum TextfileType {
 
	TFT_BEGIN,
 

	
 
	TFT_README = TFT_BEGIN,  ///< NewGRF readme
 
	TFT_CHANGELOG,           ///< NewGRF changelog
 
	TFT_LICENSE,             ///< NewGRF license
 

	
 
	TFT_END,
 
};
 
DECLARE_POSTFIX_INCREMENT(TextfileType)
 

	
 
/** Information about GRF, used in the game and (part of it) in savegames */
 
struct GRFConfig : ZeroedMemoryAllocator {
 
	GRFConfig(const char *filename = NULL);
src/newgrf_gui.cpp
Show inline comments
 
@@ -25,10 +25,10 @@
 
#include "querystring_gui.h"
 
#include "core/geometry_func.hpp"
 
#include "newgrf_text.h"
 
#include "fileio_func.h"
 
#include "fontcache.h"
 
#include "textfile_gui.h"
 

	
 
#include "widgets/newgrf_widget.h"
 
#include "widgets/misc_widget.h"
 

	
 
#include "table/sprites.h"
 

	
 
@@ -465,207 +465,27 @@ static void OpenGRFParameterWindow(GRFCo
 
}
 

	
 
/** Window for displaying the textfile of a NewGRF. */
 
struct NewGRFTextfileWindow : public Window, MissingGlyphSearcher {
 
	const GRFConfig *grf_config;         ///< View the textfile of this GRFConfig.
 
	TextfileType file_type;              ///< Type of textfile to view.
 
	int line_height;                     ///< Height of a line in the display widget.
 
	Scrollbar *vscroll;                  ///< Vertical scrollbar.
 
	Scrollbar *hscroll;                  ///< Horizontal scrollbar.
 
	char *text;                          ///< Lines of text from the NewGRF's textfile.
 
	SmallVector<const char *, 64> lines; ///< #text, split into lines in a table with lines.
 
	uint max_length;                     ///< The longest line in the textfile (in pixels).
 

	
 
	static const int TOP_SPACING    = WD_FRAMETEXT_TOP;    ///< Additional spacing at the top of the #WID_NT_BACKGROUND widget.
 
	static const int BOTTOM_SPACING = WD_FRAMETEXT_BOTTOM; ///< Additional spacing at the bottom of the #WID_NT_BACKGROUND widget.
 

	
 
	NewGRFTextfileWindow(const WindowDesc *desc, const GRFConfig *c, TextfileType file_type) : Window(), grf_config(c), file_type(file_type)
 
	{
 
		this->CreateNestedTree(desc);
 
		this->GetWidget<NWidgetCore>(WID_NT_CAPTION)->SetDataTip(STR_NEWGRF_README_CAPTION + file_type, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
 
		this->vscroll = this->GetScrollbar(WID_NT_VSCROLLBAR);
 
		this->hscroll = this->GetScrollbar(WID_NT_HSCROLLBAR);
 
		this->FinishInitNested(desc);
 

	
 
		this->LoadTextfile();
 
	}
 

	
 
	~NewGRFTextfileWindow()
 
	{
 
		free(this->text);
 
	}
 

	
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
 
	{
 
		switch (widget) {
 
			case WID_NT_BACKGROUND:
 
				this->line_height = FONT_HEIGHT_MONO + 2;
 
				resize->height = this->line_height;
 
struct NewGRFTextfileWindow : public TextfileWindow {
 
	const GRFConfig *grf_config; ///< View the textfile of this GRFConfig.
 

	
 
				size->height = 4 * resize->height + TOP_SPACING + BOTTOM_SPACING; // At least 4 lines are visible.
 
				size->width = max(200u, size->width); // At least 200 pixels wide.
 
				break;
 
		}
 
	}
 

	
 
	virtual void SetStringParameters(int widget) const
 
	NewGRFTextfileWindow(TextfileType file_type, const GRFConfig *c) : TextfileWindow(file_type), grf_config(c)
 
	{
 
		if (widget == WID_NT_CAPTION) SetDParamStr(0, this->grf_config->GetName());
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (widget != WID_NT_BACKGROUND) return;
 

	
 
		int width = r.right - r.left + 1 - WD_BEVEL_LEFT - WD_BEVEL_RIGHT;
 
		int height = r.bottom - r.top + 1 - WD_BEVEL_LEFT - WD_BEVEL_RIGHT;
 
		this->GetWidget<NWidgetCore>(WID_TF_CAPTION)->SetDataTip(STR_NEWGRF_README_CAPTION + file_type, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
 

	
 
		DrawPixelInfo new_dpi;
 
		if (!FillDrawPixelInfo(&new_dpi, r.left + WD_BEVEL_LEFT, r.top, width, height)) return;
 
		DrawPixelInfo *old_dpi = _cur_dpi;
 
		_cur_dpi = &new_dpi;
 

	
 
		int left, right;
 
		if (_current_text_dir == TD_RTL) {
 
			left = width + WD_BEVEL_RIGHT - WD_FRAMETEXT_RIGHT - this->hscroll->GetCount();
 
			right = width + WD_BEVEL_RIGHT - WD_FRAMETEXT_RIGHT - 1 + this->hscroll->GetPosition();
 
		} else {
 
			left = WD_FRAMETEXT_LEFT - WD_BEVEL_LEFT - this->hscroll->GetPosition();
 
			right = WD_FRAMETEXT_LEFT - WD_BEVEL_LEFT + this->hscroll->GetCount() - 1;
 
		}
 
		int top = TOP_SPACING;
 
		for (uint i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->lines.Length(); i++) {
 
			DrawString(left, right, top + i * this->line_height, this->lines[i + this->vscroll->GetPosition()], TC_WHITE, SA_LEFT, false, FS_MONO);
 
		}
 

	
 
		_cur_dpi = old_dpi;
 
	}
 

	
 
	virtual void OnResize()
 
	{
 
		this->vscroll->SetCapacityFromWidget(this, WID_NT_BACKGROUND, TOP_SPACING + BOTTOM_SPACING);
 
		this->hscroll->SetCapacityFromWidget(this, WID_NT_BACKGROUND);
 
		const char *textfile = this->grf_config->GetTextfile(file_type);
 
		this->LoadTextfile(textfile, NEWGRF_DIR);
 
	}
 

	
 
private:
 
	uint search_iterator; ///< Iterator for the font check search.
 

	
 
	/* virtual */ void Reset()
 
	{
 
		this->search_iterator = 0;
 
	}
 

	
 
	FontSize DefaultSize()
 
	{
 
		return FS_MONO;
 
	}
 

	
 
	const char *NextString()
 
	{
 
		if (this->search_iterator >= this->lines.Length()) return NULL;
 

	
 
		return this->lines[this->search_iterator++];
 
	}
 

	
 
	/* virtual */ bool Monospace()
 
	{
 
		return true;
 
	}
 

	
 
	/* virtual */ void SetFontNames(FreeTypeSettings *settings, const char *font_name)
 
	{
 
#ifdef WITH_FREETYPE
 
		strecpy(settings->mono_font, font_name, lastof(settings->mono_font));
 
#endif /* WITH_FREETYPE */
 
	}
 

	
 
	/**
 
	 * Load the NewGRF's textfile text from file, and setup #lines, #max_length, and both scrollbars.
 
	 */
 
	void LoadTextfile()
 
	/* virtual */ void SetStringParameters(int widget) const
 
	{
 
		this->lines.Clear();
 

	
 
		/* Does GRF have a file of the demanded type? */
 
		const char *textfile = this->grf_config->GetTextfile(file_type);
 
		if (textfile == NULL) return;
 

	
 
		/* Get text from file */
 
		size_t filesize;
 
		FILE *handle = FioFOpenFile(textfile, "rb", NEWGRF_DIR, &filesize);
 
		if (handle == NULL) return;
 

	
 
		this->text = ReallocT(this->text, filesize + 1);
 
		size_t read = fread(this->text, 1, filesize, handle);
 
		fclose(handle);
 

	
 
		if (read != filesize) return;
 

	
 
		this->text[filesize] = '\0';
 

	
 
		/* Replace tabs and line feeds with a space since str_validate removes those. */
 
		for (char *p = this->text; *p != '\0'; p++) {
 
			if (*p == '\t' || *p == '\r') *p = ' ';
 
		}
 

	
 
		/* Check for the byte-order-mark, and skip it if needed. */
 
		char *p = this->text + (strncmp("\xEF\xBB\xBF", this->text, 3) == 0 ? 3 : 0);
 

	
 
		/* Make sure the string is a valid UTF-8 sequence. */
 
		str_validate(p, this->text + filesize, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE);
 

	
 
		/* Split the string on newlines. */
 
		*this->lines.Append() = p;
 
		for (; *p != '\0'; p++) {
 
			if (*p == '\n') {
 
				*p = '\0';
 
				*this->lines.Append() = p + 1;
 
			}
 
		}
 

	
 
		CheckForMissingGlyphs(true, this);
 

	
 
		/* Initialize scrollbars */
 
		this->vscroll->SetCount(this->lines.Length());
 

	
 
		this->max_length = 0;
 
		for (uint i = 0; i < this->lines.Length(); i++) {
 
			this->max_length = max(this->max_length, GetStringBoundingBox(this->lines[i], FS_MONO).width);
 
		}
 
		this->hscroll->SetCount(this->max_length + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT);
 
		this->hscroll->SetStepSize(10); // Speed up horizontal scrollbar
 
		if (widget == WID_TF_CAPTION) SetDParamStr(0, this->grf_config->GetName());
 
	}
 
};
 

	
 
static const NWidgetPart _nested_newgrf_textfile_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
 
		NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_NT_CAPTION), SetDataTip(STR_NULL, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 
	EndContainer(),
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_PANEL, COLOUR_MAUVE, WID_NT_BACKGROUND), SetMinimalSize(200, 125), SetResize(1, 12), SetScrollbar(WID_NT_VSCROLLBAR),
 
		EndContainer(),
 
		NWidget(NWID_VERTICAL),
 
			NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_NT_VSCROLLBAR),
 
		EndContainer(),
 
	EndContainer(),
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(NWID_HSCROLLBAR, COLOUR_MAUVE, WID_NT_HSCROLLBAR),
 
		NWidget(WWT_RESIZEBOX, COLOUR_MAUVE),
 
	EndContainer(),
 
};
 

	
 
/** Window definition for the grf textfile window */
 
static const WindowDesc _newgrf_textfile_desc(
 
	WDP_CENTER, 630, 460,
 
	WC_NEWGRF_TEXTFILE, WC_NONE,
 
	WDF_UNCLICK_BUTTONS,
 
	_nested_newgrf_textfile_widgets, lengthof(_nested_newgrf_textfile_widgets)
 
);
 

	
 
void ShowNewGRFTextfileWindow(const GRFConfig *c, TextfileType file_type)
 
void ShowNewGRFTextfileWindow(TextfileType file_type, const GRFConfig *c)
 
{
 
	DeleteWindowByClass(WC_NEWGRF_TEXTFILE);
 
	new NewGRFTextfileWindow(&_newgrf_textfile_desc, c, file_type);
 
	DeleteWindowByClass(WC_TEXTFILE);
 
	new NewGRFTextfileWindow(file_type, c);
 
}
 

	
 
static GRFPresetList _grf_preset_list;
 
@@ -756,7 +576,7 @@ struct NewGRFWindow : public QueryString
 
	~NewGRFWindow()
 
	{
 
		DeleteWindowByClass(WC_GRF_PARAMETERS);
 
		DeleteWindowByClass(WC_NEWGRF_TEXTFILE);
 
		DeleteWindowByClass(WC_TEXTFILE);
 

	
 
		if (this->editable && !this->execute) {
 
			CopyGRFConfigList(this->orig_list, this->actives, true);
 
@@ -962,7 +782,7 @@ struct NewGRFWindow : public QueryString
 
		if (widget >= WID_NS_NEWGRF_TEXTFILE && widget < WID_NS_NEWGRF_TEXTFILE + TFT_END) {
 
			if (this->active_sel == NULL && this->avail_sel == NULL) return;
 

	
 
			ShowNewGRFTextfileWindow(this->active_sel != NULL ? this->active_sel : this->avail_sel, (TextfileType)(widget - WID_NS_NEWGRF_TEXTFILE));
 
			ShowNewGRFTextfileWindow((TextfileType)(widget - WID_NS_NEWGRF_TEXTFILE), this->active_sel != NULL ? this->active_sel : this->avail_sel);
 
			return;
 
		}
 

	
 
@@ -1185,8 +1005,8 @@ struct NewGRFWindow : public QueryString
 
		this->avail_sel = NULL;
 
		this->avail_pos = -1;
 
		this->avails.ForceRebuild();
 
		this->DeleteChildWindows(WC_QUERY_STRING);  // Remove the parameter query window
 
		this->DeleteChildWindows(WC_NEWGRF_TEXTFILE); // Remove the view textfile window
 
		this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window
 
		this->DeleteChildWindows(WC_TEXTFILE);     // Remove the view textfile window
 
	}
 

	
 
	virtual void OnDropdownSelect(int widget, int index)
src/script/api/game/game_window.hpp.sq
Show inline comments
 
@@ -59,7 +59,7 @@ void SQGSWindow_Register(Squirrel *engin
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WC_SET_DATE,                               "WC_SET_DATE");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WC_AI_SETTINGS,                            "WC_AI_SETTINGS");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WC_GRF_PARAMETERS,                         "WC_GRF_PARAMETERS");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WC_NEWGRF_TEXTFILE,                        "WC_NEWGRF_TEXTFILE");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WC_TEXTFILE,                               "WC_TEXTFILE");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WC_TOWN_AUTHORITY,                         "WC_TOWN_AUTHORITY");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WC_VEHICLE_DETAILS,                        "WC_VEHICLE_DETAILS");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WC_VEHICLE_REFIT,                          "WC_VEHICLE_REFIT");
 
@@ -750,10 +750,6 @@ void SQGSWindow_Register(Squirrel *engin
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NP_RESET,                              "WID_NP_RESET");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NP_SHOW_DESCRIPTION,                   "WID_NP_SHOW_DESCRIPTION");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NP_DESCRIPTION,                        "WID_NP_DESCRIPTION");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NT_CAPTION,                            "WID_NT_CAPTION");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NT_BACKGROUND,                         "WID_NT_BACKGROUND");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NT_VSCROLLBAR,                         "WID_NT_VSCROLLBAR");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NT_HSCROLLBAR,                         "WID_NT_HSCROLLBAR");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_PRESET_LIST,                        "WID_NS_PRESET_LIST");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_PRESET_SAVE,                        "WID_NS_PRESET_SAVE");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_PRESET_DELETE,                      "WID_NS_PRESET_DELETE");
 
@@ -782,6 +778,10 @@ void SQGSWindow_Register(Squirrel *engin
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_SHOW_APPLY,                         "WID_NS_SHOW_APPLY");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SP_PROGRESS_BAR,                       "WID_SP_PROGRESS_BAR");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SP_PROGRESS_TEXT,                      "WID_SP_PROGRESS_TEXT");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_CAPTION,                            "WID_TF_CAPTION");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_BACKGROUND,                         "WID_TF_BACKGROUND");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_VSCROLLBAR,                         "WID_TF_VSCROLLBAR");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_HSCROLLBAR,                         "WID_TF_HSCROLLBAR");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_N_PANEL,                               "WID_N_PANEL");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_N_TITLE,                               "WID_N_TITLE");
 
	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_N_HEADLINE,                            "WID_N_HEADLINE");
src/script/api/script_window.hpp
Show inline comments
 
@@ -250,7 +250,7 @@ public:
 
		 * textfile; Window numbers:
 
		 *   - 0 = #NewGRFTextfileWidgets
 
		 */
 
		WC_NEWGRF_TEXTFILE = ::WC_NEWGRF_TEXTFILE,
 
		WC_TEXTFILE = ::WC_TEXTFILE,
 

	
 

	
 
		/**
 
@@ -1671,14 +1671,6 @@ public:
 
		WID_NP_DESCRIPTION                   = ::WID_NP_DESCRIPTION,                   ///< Multi-line description of a parameter.
 
	};
 

	
 
	/** Widgets of the #NewGRFTextfileWindow class. */
 
	enum NewGRFTextfileWidgets {
 
		WID_NT_CAPTION                       = ::WID_NT_CAPTION,                       ///< The caption of the window.
 
		WID_NT_BACKGROUND                    = ::WID_NT_BACKGROUND,                    ///< Panel to draw the textfile on.
 
		WID_NT_VSCROLLBAR                    = ::WID_NT_VSCROLLBAR,                    ///< Vertical scrollbar to scroll through the textfile up-and-down.
 
		WID_NT_HSCROLLBAR                    = ::WID_NT_HSCROLLBAR,                    ///< Horizontal scrollbar to scroll through the textfile left-to-right.
 
	};
 

	
 
	/** Widgets of the #NewGRFWindow class. */
 
	enum NewGRFStateWidgets {
 
		WID_NS_PRESET_LIST                   = ::WID_NS_PRESET_LIST,                   ///< Active NewGRF preset.
 
@@ -1715,6 +1707,14 @@ public:
 
		WID_SP_PROGRESS_TEXT                 = ::WID_SP_PROGRESS_TEXT,                 ///< Text explaining what is happening.
 
	};
 

	
 
	/** Widgets of the #TextfileWindow class. */
 
	enum TextfileWidgets {
 
		WID_TF_CAPTION                       = ::WID_TF_CAPTION,                       ///< The caption of the window.
 
		WID_TF_BACKGROUND                    = ::WID_TF_BACKGROUND,                    ///< Panel to draw the textfile on.
 
		WID_TF_VSCROLLBAR                    = ::WID_TF_VSCROLLBAR,                    ///< Vertical scrollbar to scroll through the textfile up-and-down.
 
		WID_TF_HSCROLLBAR                    = ::WID_TF_HSCROLLBAR,                    ///< Horizontal scrollbar to scroll through the textfile left-to-right.
 
	};
 

	
 
	/** Widgets of the #NewsWindow class. */
 
	enum NewsWidgets {
 
		WID_N_PANEL                          = ::WID_N_PANEL,                          ///< Panel of the window.
src/script/api/template/template_window.hpp.sq
Show inline comments
 
@@ -155,12 +155,12 @@ namespace SQConvert {
 
	template <> inline int Return<ScriptWindow::SpriteAlignerWidgets>(HSQUIRRELVM vm, ScriptWindow::SpriteAlignerWidgets res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline ScriptWindow::NewGRFParametersWidgets GetParam(ForceType<ScriptWindow::NewGRFParametersWidgets>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::NewGRFParametersWidgets)tmp; }
 
	template <> inline int Return<ScriptWindow::NewGRFParametersWidgets>(HSQUIRRELVM vm, ScriptWindow::NewGRFParametersWidgets res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline ScriptWindow::NewGRFTextfileWidgets GetParam(ForceType<ScriptWindow::NewGRFTextfileWidgets>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::NewGRFTextfileWidgets)tmp; }
 
	template <> inline int Return<ScriptWindow::NewGRFTextfileWidgets>(HSQUIRRELVM vm, ScriptWindow::NewGRFTextfileWidgets res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline ScriptWindow::NewGRFStateWidgets GetParam(ForceType<ScriptWindow::NewGRFStateWidgets>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::NewGRFStateWidgets)tmp; }
 
	template <> inline int Return<ScriptWindow::NewGRFStateWidgets>(HSQUIRRELVM vm, ScriptWindow::NewGRFStateWidgets res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline ScriptWindow::ScanProgressWidgets GetParam(ForceType<ScriptWindow::ScanProgressWidgets>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::ScanProgressWidgets)tmp; }
 
	template <> inline int Return<ScriptWindow::ScanProgressWidgets>(HSQUIRRELVM vm, ScriptWindow::ScanProgressWidgets res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline ScriptWindow::TextfileWidgets GetParam(ForceType<ScriptWindow::TextfileWidgets>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::TextfileWidgets)tmp; }
 
	template <> inline int Return<ScriptWindow::TextfileWidgets>(HSQUIRRELVM vm, ScriptWindow::TextfileWidgets res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline ScriptWindow::NewsWidgets GetParam(ForceType<ScriptWindow::NewsWidgets>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::NewsWidgets)tmp; }
 
	template <> inline int Return<ScriptWindow::NewsWidgets>(HSQUIRRELVM vm, ScriptWindow::NewsWidgets res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline ScriptWindow::MessageHistoryWidgets GetParam(ForceType<ScriptWindow::MessageHistoryWidgets>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::MessageHistoryWidgets)tmp; }
src/textfile_gui.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file textfile_gui.cpp Implementation of textfile window. */
 

	
 
#include "stdafx.h"
 
#include "fileio_func.h"
 
#include "fontcache.h"
 
#include "gfx_type.h"
 
#include "gfx_func.h"
 
#include "string_func.h"
 
#include "textfile_gui.h"
 

	
 
#include "widgets/misc_widget.h"
 

	
 
#include "table/strings.h"
 

	
 

	
 
/** Widgets for the textfile window. */
 
static const NWidgetPart _nested_textfile_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
 
		NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_TF_CAPTION), SetDataTip(STR_NULL, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 
	EndContainer(),
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_PANEL, COLOUR_MAUVE, WID_TF_BACKGROUND), SetMinimalSize(200, 125), SetResize(1, 12), SetScrollbar(WID_TF_VSCROLLBAR),
 
		EndContainer(),
 
		NWidget(NWID_VERTICAL),
 
			NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_TF_VSCROLLBAR),
 
		EndContainer(),
 
	EndContainer(),
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(NWID_HSCROLLBAR, COLOUR_MAUVE, WID_TF_HSCROLLBAR),
 
		NWidget(WWT_RESIZEBOX, COLOUR_MAUVE),
 
	EndContainer(),
 
};
 

	
 
/** Window definition for the textfile window */
 
static const WindowDesc _textfile_desc(
 
	WDP_CENTER, 630, 460,
 
	WC_TEXTFILE, WC_NONE,
 
	WDF_UNCLICK_BUTTONS,
 
	_nested_textfile_widgets, lengthof(_nested_textfile_widgets)
 
);
 

	
 
TextfileWindow::TextfileWindow(TextfileType file_type) : Window(), file_type(file_type)
 
{
 
	this->CreateNestedTree(&_textfile_desc);
 
	this->vscroll = this->GetScrollbar(WID_TF_VSCROLLBAR);
 
	this->hscroll = this->GetScrollbar(WID_TF_HSCROLLBAR);
 
	this->FinishInitNested(&_textfile_desc);
 
}
 

	
 
/* virtual */ TextfileWindow::~TextfileWindow()
 
{
 
	free(this->text);
 
}
 

	
 
/* virtual */ void TextfileWindow::UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
 
{
 
	switch (widget) {
 
		case WID_TF_BACKGROUND:
 
			this->line_height = FONT_HEIGHT_MONO + 2;
 
			resize->height = this->line_height;
 

	
 
			size->height = 4 * resize->height + TOP_SPACING + BOTTOM_SPACING; // At least 4 lines are visible.
 
			size->width = max(200u, size->width); // At least 200 pixels wide.
 
			break;
 
	}
 
}
 

	
 
/* virtual */ void TextfileWindow::DrawWidget(const Rect &r, int widget) const
 
{
 
	if (widget != WID_TF_BACKGROUND) return;
 

	
 
	int width = r.right - r.left + 1 - WD_BEVEL_LEFT - WD_BEVEL_RIGHT;
 
	int height = r.bottom - r.top + 1 - WD_BEVEL_LEFT - WD_BEVEL_RIGHT;
 

	
 
	DrawPixelInfo new_dpi;
 
	if (!FillDrawPixelInfo(&new_dpi, r.left + WD_BEVEL_LEFT, r.top, width, height)) return;
 
	DrawPixelInfo *old_dpi = _cur_dpi;
 
	_cur_dpi = &new_dpi;
 

	
 
	int left, right;
 
	if (_current_text_dir == TD_RTL) {
 
		left = width + WD_BEVEL_RIGHT - WD_FRAMETEXT_RIGHT - this->hscroll->GetCount();
 
		right = width + WD_BEVEL_RIGHT - WD_FRAMETEXT_RIGHT - 1 + this->hscroll->GetPosition();
 
	} else {
 
		left = WD_FRAMETEXT_LEFT - WD_BEVEL_LEFT - this->hscroll->GetPosition();
 
		right = WD_FRAMETEXT_LEFT - WD_BEVEL_LEFT + this->hscroll->GetCount() - 1;
 
	}
 
	int top = TOP_SPACING;
 
	for (uint i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->lines.Length(); i++) {
 
		DrawString(left, right, top + i * this->line_height, this->lines[i + this->vscroll->GetPosition()], TC_WHITE, SA_LEFT, false, FS_MONO);
 
	}
 

	
 
	_cur_dpi = old_dpi;
 
}
 

	
 
/* virtual */ void TextfileWindow::OnResize()
 
{
 
	this->vscroll->SetCapacityFromWidget(this, WID_TF_BACKGROUND, TOP_SPACING + BOTTOM_SPACING);
 
	this->hscroll->SetCapacityFromWidget(this, WID_TF_BACKGROUND);
 
}
 

	
 
/* virtual */ void TextfileWindow::Reset()
 
{
 
	this->search_iterator = 0;
 
}
 

	
 
/* virtual */ FontSize TextfileWindow::DefaultSize()
 
{
 
	return FS_MONO;
 
}
 

	
 
/* virtual */ const char *TextfileWindow::NextString()
 
{
 
	if (this->search_iterator >= this->lines.Length()) return NULL;
 

	
 
	return this->lines[this->search_iterator++];
 
}
 

	
 
/* virtual */ bool TextfileWindow::Monospace()
 
{
 
	return true;
 
}
 

	
 
/* virtual */ void TextfileWindow::SetFontNames(FreeTypeSettings *settings, const char *font_name)
 
{
 
#ifdef WITH_FREETYPE
 
	strecpy(settings->mono_font, font_name, lastof(settings->mono_font));
 
#endif /* WITH_FREETYPE */
 
}
 

	
 
/**
 
 * Loads the textfile text from file, and setup #lines, #max_length, and both scrollbars.
 
 */
 
/* virtual */ void TextfileWindow::LoadTextfile(const char *textfile, Subdirectory dir)
 
{
 
	if (textfile == NULL) return;
 

	
 
	this->lines.Clear();
 

	
 
	/* Get text from file */
 
	size_t filesize;
 
	FILE *handle = FioFOpenFile(textfile, "rb", dir, &filesize);
 
	if (handle == NULL) return;
 

	
 
	this->text = ReallocT(this->text, filesize + 1);
 
	size_t read = fread(this->text, 1, filesize, handle);
 
	fclose(handle);
 

	
 
	if (read != filesize) return;
 

	
 
	this->text[filesize] = '\0';
 

	
 
	/* Replace tabs and line feeds with a space since str_validate removes those. */
 
	for (char *p = this->text; *p != '\0'; p++) {
 
		if (*p == '\t' || *p == '\r') *p = ' ';
 
	}
 

	
 
	/* Check for the byte-order-mark, and skip it if needed. */
 
	char *p = this->text + (strncmp("\xEF\xBB\xBF", this->text, 3) == 0 ? 3 : 0);
 

	
 
	/* Make sure the string is a valid UTF-8 sequence. */
 
	str_validate(p, this->text + filesize, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE);
 

	
 
	/* Split the string on newlines. */
 
	*this->lines.Append() = p;
 
	for (; *p != '\0'; p++) {
 
		if (*p == '\n') {
 
			*p = '\0';
 
			*this->lines.Append() = p + 1;
 
		}
 
	}
 

	
 
	CheckForMissingGlyphs(true, this);
 

	
 
	/* Initialize scrollbars */
 
	this->vscroll->SetCount(this->lines.Length());
 

	
 
	this->max_length = 0;
 
	for (uint i = 0; i < this->lines.Length(); i++) {
 
		this->max_length = max(this->max_length, GetStringBoundingBox(this->lines[i], FS_MONO).width);
 
	}
 
	this->hscroll->SetCount(this->max_length + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT);
 
	this->hscroll->SetStepSize(10); // Speed up horizontal scrollbar
 
}
src/textfile_gui.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file textfile_gui.h GUI functions related to textfiles. */
 

	
 
#ifndef TEXTFILE_GUI_H
 
#define TEXTFILE_GUI_H
 

	
 
#include "strings_func.h"
 
#include "textfile_type.h"
 
#include "window_gui.h"
 

	
 
/** Window for displaying a textfile */
 
struct TextfileWindow : public Window, MissingGlyphSearcher {
 
	TextfileType file_type;              ///< Type of textfile to view.
 
	int line_height;                     ///< Height of a line in the display widget.
 
	Scrollbar *vscroll;                  ///< Vertical scrollbar.
 
	Scrollbar *hscroll;                  ///< Horizontal scrollbar.
 
	char *text;                          ///< Lines of text from the NewGRF's textfile.
 
	SmallVector<const char *, 64> lines; ///< #text, split into lines in a table with lines.
 
	uint max_length;                     ///< The longest line in the textfile (in pixels).
 
	uint search_iterator;                ///< Iterator for the font check search.
 

	
 
	static const int TOP_SPACING    = WD_FRAMETEXT_TOP;    ///< Additional spacing at the top of the #WID_TF_BACKGROUND widget.
 
	static const int BOTTOM_SPACING = WD_FRAMETEXT_BOTTOM; ///< Additional spacing at the bottom of the #WID_TF_BACKGROUND widget.
 

	
 
	TextfileWindow(TextfileType file_type);
 
	virtual ~TextfileWindow();
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize);
 
	virtual void DrawWidget(const Rect &r, int widget) const;
 
	virtual void OnResize();
 
	virtual void Reset();
 
	virtual FontSize DefaultSize();
 
	virtual const char *NextString();
 
	virtual bool Monospace();
 
	virtual void SetFontNames(FreeTypeSettings *settings, const char *font_name);
 
	virtual void LoadTextfile(const char *textfile, Subdirectory dir);
 
};
 

	
 
#endif /* TEXTFILE_GUI_H */
src/textfile_type.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file textfile_type.h Types related to textfiles. */
 

	
 
#ifndef TEXTFILE_TYPE_H
 
#define TEXTFILE_TYPE_H
 

	
 
/** Additional text files accompanying Tar archives */
 
enum TextfileType {
 
	TFT_BEGIN,
 

	
 
	TFT_README = TFT_BEGIN, ///< NewGRF readme
 
	TFT_CHANGELOG,          ///< NewGRF changelog
 
	TFT_LICENSE,            ///< NewGRF license
 

	
 
	TFT_END,
 
};
 
DECLARE_POSTFIX_INCREMENT(TextfileType)
 

	
 
#endif /* TEXTFILE_TYPE_H */
src/widgets/misc_widget.h
Show inline comments
 
@@ -45,4 +45,12 @@ enum QueryWidgets {
 
	WID_Q_YES,     ///< No button.
 
};
 

	
 
/** Widgets of the #TextfileWindow class. */
 
enum TextfileWidgets {
 
	WID_TF_CAPTION,    ///< The caption of the window.
 
	WID_TF_BACKGROUND, ///< Panel to draw the textfile on.
 
	WID_TF_VSCROLLBAR, ///< Vertical scrollbar to scroll through the textfile up-and-down.
 
	WID_TF_HSCROLLBAR, ///< Horizontal scrollbar to scroll through the textfile left-to-right.
 
};
 

	
 
#endif /* WIDGETS_MISC_WIDGET_H */
src/widgets/newgrf_widget.h
Show inline comments
 
@@ -13,6 +13,7 @@
 
#define WIDGETS_NEWGRF_WIDGET_H
 

	
 
#include "../newgrf_config.h"
 
#include "../textfile_type.h"
 

	
 
/** Widgets of the #NewGRFParametersWindow class. */
 
enum NewGRFParametersWidgets {
 
@@ -29,14 +30,6 @@ enum NewGRFParametersWidgets {
 
	WID_NP_DESCRIPTION,      ///< Multi-line description of a parameter.
 
};
 

	
 
/** Widgets of the #NewGRFTextfileWindow class. */
 
enum NewGRFTextfileWidgets {
 
	WID_NT_CAPTION,    ///< The caption of the window.
 
	WID_NT_BACKGROUND, ///< Panel to draw the textfile on.
 
	WID_NT_VSCROLLBAR, ///< Vertical scrollbar to scroll through the textfile up-and-down.
 
	WID_NT_HSCROLLBAR, ///< Horizontal scrollbar to scroll through the textfile left-to-right.
 
};
 

	
 
/** Widgets of the #NewGRFWindow class. */
 
enum NewGRFStateWidgets {
 
	WID_NS_PRESET_LIST,       ///< Active NewGRF preset.
src/window.cpp
Show inline comments
 
@@ -999,9 +999,9 @@ static uint GetWindowZPriority(const Win
 
		case WC_CUSTOM_CURRENCY:
 
		case WC_NETWORK_WINDOW:
 
		case WC_GRF_PARAMETERS:
 
		case WC_NEWGRF_TEXTFILE:
 
		case WC_AI_LIST:
 
		case WC_AI_SETTINGS:
 
		case WC_TEXTFILE:
 
			++z_priority;
 

	
 
		case WC_CONSOLE:
src/window_type.h
Show inline comments
 
@@ -179,9 +179,9 @@ enum WindowClass {
 

	
 
	/**
 
	 * textfile; %Window numbers:
 
	 *   - 0 = #NewGRFTextfileWidgets
 
	 *   - 0 = #TextfileWidgets
 
	 */
 
	WC_NEWGRF_TEXTFILE,
 
	WC_TEXTFILE,
 

	
 

	
 
	/**
0 comments (0 inline, 0 general)