示例#1
0
			/// <summary>
			/// Applied before RefreshRows runs.
			/// </summary>
			internal static bool Prefix(TableScreen __instance) {
				var identities = HashSetPool<IAssignableIdentity, TableScreen>.Allocate();
				var living = Components.LiveMinionIdentities.Items;
				StoredMinionIdentity smi;
				// Living Duplicants
				for (int i = 0; i < living.Count; i++) {
					var dupe = living[i];
					if (dupe != null)
						identities.Add(dupe);
				}
				// Duplicants in vanilla rockets and similar
				foreach (var minionStorage in Components.MinionStorages.Items)
					foreach (var info in minionStorage.GetStoredMinionInfo()) {
						var dupe = info.serializedMinion;
						if (dupe != null && (smi = dupe.Get<StoredMinionIdentity>()) != null)
							__instance.AddRow(smi);
					}
				ClearAndAddRows(__instance, identities);
				// Add the missing rows
				foreach (var missingMinion in identities)
					__instance.AddRow(missingMinion);
				identities.Recycle();
				if (DlcManager.FeatureClusterSpaceEnabled())
					AddDividers(__instance);
				SortRows(__instance);
				__instance.rows_dirty = false;
				return false;
			}
示例#2
0
        private void ImportTables(Department department)
        {
            var fileName = string.Format("{0}/Imports/table{1}.txt", LocalSettings.AppPath, "_" + LocalSettings.CurrentLanguage);

            if (!File.Exists(fileName))
            {
                fileName = string.Format("{0}/Imports/table.txt", LocalSettings.AppPath);
            }

            if (!File.Exists(fileName))
            {
                return;
            }

            var lines = File.ReadAllLines(fileName);
            var items = BatchCreateTables(lines, _workspace);

            _workspace.CommitChanges();

            var screen = new TableScreen {
                Name = Resources.AllTables, ColumnCount = 8
            };

            _workspace.Add(screen);

            foreach (var table in items)
            {
                screen.AddScreenItem(table);
            }

            _workspace.CommitChanges();

            department.TableScreenId = screen.Id;
        }
示例#3
0
		/// <summary>
		/// Sorts the table's rows.
		/// </summary>
		/// <param name="instance">The table screen to sort.</param>
		private static void SortRows(TableScreen instance) {
			var rows = instance.all_sortable_rows;
			bool reversed = instance.sort_is_reversed;
			var comparison = new TableSortComparison(instance.active_sort_method, reversed);
			var dividerIndices = DictionaryPool<int, int, TableScreen>.Allocate();
			var dupesByWorld = DictionaryPool<int, TableRowList.PooledList, TableScreen>.
				Allocate();
			int index = 0;
			var entryList = instance.scroll_content_transform;
			UpdateHeaders(instance, reversed);
			GroupDupesByWorld(rows, dupesByWorld);
			rows.Clear();
			foreach (var pair in dupesByWorld) {
				var list = pair.Value;
				// 1 offset for the item added plus the number of items in this list
				dividerIndices.Add(pair.Key, index);
				index++;
				if (comparison.IsSortable)
					list.Sort(comparison);
				index += list.Count;
				rows.AddRange(list);
				list.Recycle();
			}
			dupesByWorld.Recycle();
			MoveRows(instance, rows, dividerIndices);
			dividerIndices.Recycle();
			// Schedule a freeze
			if (entryList != null && instance.isActiveAndEnabled)
				instance.StartCoroutine(FreezeLayouts(rows));
		}
示例#4
0
		/// <summary>
		/// Adds dividers for each planetoid in the Spaced Out DLC.
		/// </summary>
		/// <param name="instance">The table screen to update.</param>
		private static void AddDividers(TableScreen instance) {
			GameObject target;
			int id;
			var occupiedWorlds = DictionaryPool<int, WorldContainer, TableScreen>.Allocate();
			foreach (int worldId in ClusterManager.Instance.GetWorldIDsSorted())
				instance.AddWorldDivider(worldId);
			// List occupied planets
			foreach (object obj in Components.MinionAssignablesProxy)
				if (obj is MinionAssignablesProxy proxy && proxy != null && (target = proxy.
						GetTargetGameObject()) != null) {
					var world = target.GetMyWorld();
					if (world != null && !occupiedWorlds.ContainsKey(id = world.id))
						occupiedWorlds.Add(id, world);
				}
			foreach (var pair in instance.worldDividers)
				if (pair.Value.TryGetComponent(out HierarchyReferences hr)) {
					var dividerRow = hr.GetReference("NobodyRow");
					id = pair.Key;
					if (occupiedWorlds.TryGetValue(id, out WorldContainer world)) {
						dividerRow.gameObject.SetActive(false);
						pair.Value.SetActive(world.IsDiscovered);
					} else {
						dividerRow.gameObject.SetActive(true);
						pair.Value.SetActive(ClusterManager.Instance.GetWorld(id).IsDiscovered);
					}
				}
			occupiedWorlds.Recycle();
		}
示例#5
0
		/// <summary>
		/// Configures the scroll bars for each row.
		/// </summary>
		/// <param name="row">The row being configured.</param>
		/// <param name="parent">The parent game object of the table row.</param>
		/// <param name="id">The scroller ID to look up.</param>
		/// <param name="widget">The widget to display in this row.</param>
		/// <param name="screen">The parent table screen.</param>
		private static void ConfigureScroller(TableRow row, GameObject parent, string id,
				GameObject widget, TableScreen screen) {
			Transform content;
			ScrollRect sr;
			var scrollers = row.scrollers;
			if (scrollers.TryGetValue(id, out GameObject scrollerGO)) {
				content = scrollerGO.transform;
				if (content.parent.TryGetComponent(out sr))
					sr.horizontalNormalizedPosition = 0.0f;
				widget.transform.SetParent(content);
			} else {
				var prefab = Util.KInstantiateUI(row.scrollerPrefab, parent, true);
				if (prefab.TryGetComponent(out sr)) {
					content = sr.content;
					sr.onValueChanged.AddListener(new ScrollListener(screen, sr).
						OnScroll);
					scrollers.Add(id, content.gameObject);
					// Is it a border?
					var border = content.parent.Find("Border");
					if (border != null)
						row.scrollerBorders.Add(id, border.gameObject);
					sr.horizontalNormalizedPosition = 0.0f;
					widget.transform.SetParent(content);
				}
			}
		}
示例#6
0
		/// <summary>
		/// Configures the row's content, only adding widgets that are new.
		/// </summary>
		/// <param name="row">The row being configured.</param>
		/// <param name="minion">The Duplicant for this row.</param>
		/// <param name="columns">The columns to display.</param>
		/// <param name="screen">The parent table screen.</param>
		private static void ConfigureContent(TableRow row, IAssignableIdentity minion,
				IDictionary<string, TableColumn> columns, TableScreen screen) {
			bool def = row.isDefault;
			var go = row.gameObject;
			row.minion = minion;
			ConfigureImage(row, minion);
			foreach (var pair in columns) {
				var column = pair.Value;
				var widgets = row.widgets;
				string id = column.scrollerID;
				// Columns cannot be deleted in vanilla
				if (!widgets.TryGetValue(column, out GameObject widget)) {
					// Create a new one
					if (minion == null) {
						if (def)
							widget = column.GetDefaultWidget(go);
						else
							widget = column.GetHeaderWidget(go);
					} else
						widget = column.GetMinionWidget(go);
					widgets.Add(column, widget);
					column.widgets_by_row.Add(row, widget);
				}
				// Update the scroller if needed
				if (!string.IsNullOrEmpty(id) && column.screen.column_scrollers.Contains(id))
					ConfigureScroller(row, go, id, widget, screen);
			}
			// Run events after the update is complete
			foreach (var pair in columns) {
				var column = pair.Value;
				if (column.widgets_by_row.TryGetValue(row, out GameObject widget)) {
					string id = column.scrollerID;
					column.on_load_action?.Invoke(minion, widget);
					// Apparently the order just... works out? <shrug>
				}
			}
			if (minion != null)
				go.name = minion.GetProperName();
			else if (def)
				go.name = "defaultRow";
			// "Click to go to Duplicant"
			if (row.selectMinionButton != null)
				row.selectMinionButton.transform.SetAsLastSibling();
			// Update the border sizes
			foreach (var pair in row.scrollerBorders) {
				var border = pair.Value;
				var rt = border.rectTransform();
				float width = rt.rect.width;
				border.transform.SetParent(go.transform);
				rt.anchorMin = rt.anchorMax = Vector2.up;
				rt.sizeDelta = new Vector2(width, 374.0f);
				var scrollRT = row.scrollers[pair.Key].transform.parent.rectTransform();
				Vector3 a = scrollRT.GetLocalPosition();
				a.x -= scrollRT.sizeDelta.x * 0.5f;
				a.y = rt.GetLocalPosition().y - rt.anchoredPosition.y;
				rt.SetLocalPosition(a);
			}
		}
示例#7
0
		/// <summary>
		/// Removes and pools any existing rows. Leaves the default and header row if present,
		/// otherwise creates and adds one when requested.
		/// </summary>
		/// <param name="instance">The table screen to clear.</param>
		/// <param name="toAdd">The Duplicants to be added or updated.</param>
		private static void ClearAndAddRows(TableScreen instance,
				ISet<IAssignableIdentity> toAdd) {
			var columns = instance.columns;
			var hr = instance.header_row;
			List<TableRow> rows = instance.rows, sortableRows = instance.all_sortable_rows;
			int n = rows.Count;
			TableRow defaultRow = null, headerRow = null;
			var newRows = TableRowList.Allocate();
			var deadRows = HashSetPool<TableRow, TableScreen>.Allocate();
			IAssignableIdentity minion;
			for (int i = 0; i < n; i++) {
				var row = rows[i];
				var go = row.gameObject;
				// Do not destroy the default or header; pull out any rows for existing minion
				// identities
				if (row.rowType == TableRow.RowType.Default) {
					ThawLayout(go);
					defaultRow = row;
				} else if (go == hr && hr != null) {
					ThawLayout(go);
					headerRow = row;
				} else if (row.rowType != TableRow.RowType.WorldDivider && (minion = row.
						minion) != null && toAdd.Remove(minion)) {
					ThawLayout(go);
					ConfigureContent(row, minion, columns, instance);
					newRows.Add(row);
				} else
					deadRows.Add(row);
			}
			sortableRows.Clear();
			rows.Clear();
			// Restore cached default and header rows; header first
			if (headerRow != null) {
				ConfigureContent(headerRow, null, columns, instance);
				rows.Add(headerRow);
			} else
				instance.AddRow(null);
			if (defaultRow != null) {
				ConfigureContent(defaultRow, null, columns, instance);
				rows.Add(defaultRow);
			} else if (instance.has_default_duplicant_row)
				instance.AddDefaultRow();
			// Add reused rows, delete removed rows
			sortableRows.AddRange(newRows);
			rows.AddRange(newRows);
			newRows.Recycle();
			TakeOutTrash(instance, deadRows);
			deadRows.Recycle();
		}
示例#8
0
		/// <summary>
		/// Moves the rows and row dividers into their final positions.
		/// </summary>
		/// <param name="instance">The table screen to update.</param>
		/// <param name="rows">The current row list with sorting.</param>
		/// <param name="dividerIndices">The locations of each world divider.</param>
		private static void MoveRows(TableScreen instance, IList<TableRow> rows,
				IDictionary<int, int> dividerIndices) {
			int n = rows.Count;
			var dividers = instance.worldDividers;
			// Sort the rows in the UI
			for (int i = 0; i < n; i++)
				rows[i].transform.SetSiblingIndex(i);
			foreach (var pair in dividerIndices)
				if (dividers.TryGetValue(pair.Key, out GameObject divider))
					// Will not be present in vanilla
					divider.transform.SetSiblingIndex(pair.Value);
			// Move the default row to the beginning
			if (instance.has_default_duplicant_row)
				instance.default_row.transform.SetAsFirstSibling();
		}
示例#9
0
		/// <summary>
		/// Updates the header states to match the sorting state.
		/// </summary>
		/// <param name="instance">The table screen to update.</param>
		/// <param name="reverse">Whether the sorting order is reversed.</param>
		private static void UpdateHeaders(TableScreen instance, bool reverse) {
			var sortColumn = instance.active_sort_column;
			MultiToggle sortToggle;
			foreach (var pair in instance.columns) {
				var tableColumn = pair.Value;
				if (tableColumn != null && (sortToggle = tableColumn.column_sort_toggle) !=
						null) {
					int state = sortToggle.CurrentState;
					if (tableColumn == sortColumn) {
						if (reverse) {
							if (state != 2)
								sortToggle.ChangeState(2);
						} else if (state != 1)
							sortToggle.ChangeState(1);
					} else if (state != 0)
						sortToggle.ChangeState(0);
				}
			}
		}
示例#10
0
		/// <summary>
		/// Disposes and removes the specified rows from the table screen.
		/// </summary>
		/// <param name="instance">The table screen to clean up.</param>
		/// <param name="deadRows">The rows that were removed.</param>
		private static void TakeOutTrash(TableScreen instance, ICollection<TableRow> deadRows)
		{
			var ikr = instance.known_widget_rows;
			// Avoid leaking dead rows
			var deadWidgets = ListPool<GameObject, TableScreen>.Allocate();
			foreach (var pair in ikr)
				if (deadRows.Contains(pair.Value))
					deadWidgets.Add(pair.Key);
			int n = deadWidgets.Count;
			for (int i = 0; i < n; i++)
				ikr.Remove(deadWidgets[i]);
			deadWidgets.Recycle();
			foreach (var row in deadRows)
				row.Clear();
			// Dividers are fairly cheap, destroy and recreate them is easier
			var dividers = instance.worldDividers;
			foreach (var pair in dividers)
				Util.KDestroyGameObject(pair.Value);
			dividers.Clear();
		}
示例#11
0
        public void UpdateTableData(TableScreen selectedTableScreen, int pageNo)
        {
            var set = selectedTableScreen.Tables.Select(x => x.Id);

            if (selectedTableScreen.PageCount > 1)
            {
                set = selectedTableScreen.Tables
                      .OrderBy(x => x.Order)
                      .Skip(pageNo * selectedTableScreen.ItemCountPerPage)
                      .Take(selectedTableScreen.ItemCountPerPage)
                      .Select(x => x.Id);
            }

            var result = Dao.Select <Table, dynamic>(x => new { x.Id, Tid = x.TicketId, Locked = x.IsTicketLocked },
                                                     x => set.Contains(x.Id));

            foreach (var td in result)
            {
                var tid   = td.Id;
                var table = selectedTableScreen.Tables.Single(x => x.Id == tid);
                table.TicketId       = td.Tid;
                table.IsTicketLocked = td.Locked;
            }
        }
示例#12
0
			public ScrollListener(TableScreen screen, ScrollRect scrollRect) {
				this.screen = screen;
				this.scrollRect = scrollRect;
			}
示例#13
0
			/// <summary>
			/// Applied before SortRows runs.
			/// </summary>
			internal static bool Prefix(TableScreen __instance) {
				SortRows(__instance);
				return false;
			}
示例#14
0
 public TableScreenItemViewModel(Table model, TableScreen screen)
     : this(model, screen, null)
 {
 }
示例#15
0
			/// <summary>
			/// Applied before ConfigureContent runs.
			/// </summary>
			internal static bool Prefix(TableRow __instance, IAssignableIdentity minion,
					Dictionary<string, TableColumn> columns, TableScreen screen) {
				ConfigureContent(__instance, minion, columns, screen);
				return false;
			}
示例#16
0
 public TableScreenItemViewModel(Table model, TableScreen screen, ICommand actionCommand)
 {
     _actionCommand = actionCommand;
     _screen        = screen;
     Model          = model;
 }
示例#17
0
 private void OnSelectTableCategoryExecuted(TableScreen obj)
 {
     UpdateTables(obj.Id);
 }