aboutsummaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
Diffstat (limited to 'assets')
0 files changed, 0 insertions, 0 deletions
a id='n62' href='#n62'>62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#pragma once

#include <map>
#include <set>
#include <string>
#include <vector>
#include <iostream>

#include "irrlichttypes_extrabloated.h"
#include "guiScrollBar.h"

class ISimpleTextureSource;

/*
	A table GUI element for GUIFormSpecMenu.

	Sends a EGET_TABLE_CHANGED event to the parent when
	an item is selected or double-clicked.
	Call checkEvent() to get info.

	Credits: The interface and implementation of this class are (very)
	loosely based on the Irrlicht classes CGUITable and CGUIListBox.
	CGUITable and CGUIListBox are licensed under the Irrlicht license;
	they are Copyright (C) 2002-2012 Nikolaus Gebhardt
*/
class GUITable : public gui::IGUIElement
{
public:
	/*
		Stores dynamic data that should be preserved
		when updating a formspec
	*/
	struct DynamicData
	{
		s32 selected = 0;
		s32 scrollpos = 0;
		s32 keynav_time = 0;
		core::stringw keynav_buffer;
		std::set<s32> opened_trees;
	};

	/*
		An option of the form <name>=<value>
	*/
	struct Option
	{
		std::string name;
		std::string value;

		Option(const std::string &name_, const std::string &value_) :
			name(name_),
			value(value_)
		{}
	};

	/*
		A list of options that concern the entire table
	*/
	typedef std::vector<Option> TableOptions;

	/*
		A column with options
	*/
	struct TableColumn
	{
		std::string type;
		std::vector<Option> options;
	};
	typedef std::vector<TableColumn> TableColumns;


	GUITable(gui::IGUIEnvironment *env,
			gui::IGUIElement *parent, s32 id,
			core::rect<s32> rectangle,
			ISimpleTextureSource *tsrc);

	virtual ~GUITable();

	/* Split a string of the form "name=value" into name and value */
	static Option splitOption(const std::string &str);

	/* Set textlist-like options, columns and data */
	void setTextList(const std::vector<std::string> &content,
			bool transparent);

	/* Set generic table options, columns and content */
	// Adds empty strings to end of content if there is an incomplete row
	void setTable(const TableOptions &options,
			const TableColumns &columns,
			std::vector<std::string> &content);

	/* Clear the table */
	void clear();

	/* Get info about last event (string such as "CHG:1:2") */
	// Call this after EGET_TABLE_CHANGED
	std::string checkEvent();

	/* Get index of currently selected row (first=1; 0 if none selected) */
	s32 getSelected() const;

	/* Set currently selected row (first=1; 0 if none selected) */
	// If given index is not visible at the moment, select its parent
	// Autoscroll to make the selected row fully visible
	void setSelected(s32 index);

	//! Sets another skin independent font. If this is set to zero, the button uses the font of the skin.
	virtual void setOverrideFont(gui::IGUIFont *font = nullptr);

	//! Gets the override font (if any)
	virtual gui::IGUIFont *getOverrideFont() const;

	/* Get selection, scroll position and opened (sub)trees */
	DynamicData getDynamicData() const;

	/* Set selection, scroll position and opened (sub)trees */
	void setDynamicData(const DynamicData &dyndata);

	/* Returns "GUITable" */
	virtual const c8* getTypeName() const;

	/* Must be called when position or size changes */
	virtual void updateAbsolutePosition();

	/* Irrlicht draw method */
	virtual void draw();

	/* Irrlicht event handler */
	virtual bool OnEvent(const SEvent &event);

protected:
	enum ColumnType {
		COLUMN_TYPE_TEXT,
		COLUMN_TYPE_IMAGE,
		COLUMN_TYPE_COLOR,
		COLUMN_TYPE_INDENT,
		COLUMN_TYPE_TREE,
	};

	struct Cell {
		s32 xmin;
		s32 xmax;
		s32 xpos;
		ColumnType content_type;
		s32 content_index;
		s32 tooltip_index;
		video::SColor color;
		bool color_defined;
		s32 reported_column;
	};

	struct Row {
		Cell *cells;
		s32 cellcount;
		s32 indent;
		// visible_index >= 0: is index of row in m_visible_rows
		// visible_index == -1: parent open but other ancestor closed
		// visible_index == -2: parent closed
		s32 visible_index;
	};

	// Texture source
	ISimpleTextureSource *m_tsrc;

	// Table content (including hidden rows)
	std::vector<Row> m_rows;
	// Table content (only visible; indices into m_rows)
	std::vector<s32> m_visible_rows;
	bool m_is_textlist = false;
	bool m_has_tree_column = false;

	// Selection status
	s32 m_selected = -1; // index of row (1...n), or 0 if none selected
	s32 m_sel_column = 0;
	bool m_sel_doubleclick = false;

	// Keyboard navigation stuff
	u64 m_keynav_time = 0;
	core::stringw m_keynav_buffer = L"";

	// Drawing and geometry information
	bool m_border = true;
	video::SColor m_color = video::SColor(255, 255, 255, 255);
	video::SColor m_background = video::SColor(255, 0, 0, 0);
	video::SColor m_highlight = video::SColor(255, 70, 100, 50);
	video::SColor m_highlight_text = video::SColor(255, 255, 255, 255);
	s32 m_rowheight = 1;
	gui::IGUIFont *m_font = nullptr;
	GUIScrollBar *m_scrollbar = nullptr;

	// Allocated strings and images
	std::vector<core::stringw> m_strings;
	std::vector<video::ITexture*> m_images;
	std::map<std::string, s32> m_alloc_strings;
	std::map<std::string, s32> m_alloc_images;

	s32 allocString(const std::string &text);
	s32 allocImage(const std::string &imagename);
	void allocationComplete();

	// Helper for draw() that draws a single cell
	void drawCell(const Cell *cell, video::SColor color,
			const core::rect<s32> &rowrect,
			const core::rect<s32> &client_clip);

	// Returns the i-th visible row (NULL if i is invalid)
	const Row *getRow(s32 i) const;

	// Key navigation helper
	bool doesRowStartWith(const Row *row, const core::stringw &str) const;

	// Returns the row at a given screen Y coordinate
	// Returns index i such that m_rows[i] is valid (or -1 on error)
	s32 getRowAt(s32 y, bool &really_hovering) const;

	// Returns the cell at a given screen X coordinate within m_rows[row_i]
	// Returns index j such that m_rows[row_i].cells[j] is valid
	// (or -1 on error)