PageRenderTime 25ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/QuestTracker.QuestControls/QuestTabControl.cs

#
C# | 580 lines | 457 code | 117 blank | 6 comment | 81 complexity | 2fc899ae1eb19e7542e2abab9cbc0490 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Linq;
  6. using System.Threading;
  7. using System.Windows.Forms;
  8. using QuestTracker.Data;
  9. namespace QuestTracker.QuestControls
  10. {
  11. public partial class QuestTabControl : UserControl
  12. {
  13. public QuestTab QuestTab { get; set; }
  14. public List<QuestControl> QuestControls { get; private set; }
  15. public bool AnyChecked { get; set; }
  16. public bool AllCheckedComplete { get; set; }
  17. public event EventHandler SelectionPluralityChanged;
  18. public event EventHandler QuestSelectionChanged;
  19. private readonly List<QuestGroupControl> questGroupControls;
  20. private QuestGroupControl lastSelectedQuestGroupControl;
  21. private QuestControl lastSelectedQuestControl;
  22. private QuestGroup lastSelectedQuestGroup;
  23. private Quest lastSelectedQuest;
  24. private bool addGroupPresent;
  25. private bool lastShowCompleted;
  26. private bool forcedCollapse;
  27. public QuestGroupControl LastSelectedQuestGroupControl
  28. {
  29. get
  30. {
  31. return lastSelectedQuestGroupControl;
  32. }
  33. set
  34. {
  35. lastSelectedQuestGroupControl = value;
  36. if (value == null)
  37. return;
  38. var questLog = QuestLogControl.GetQuestLog(this);
  39. if (questLog == null)
  40. return;
  41. questLog.LastSelectedQuestGroupControl = value;
  42. questLog.LastSelectedQuestGroup = value.QuestGroup;
  43. questLog.LastSelectedQuestTab = QuestTab;
  44. }
  45. }
  46. public QuestControl LastSelectedQuestControl
  47. {
  48. get
  49. {
  50. return lastSelectedQuestControl;
  51. }
  52. set
  53. {
  54. lastSelectedQuestControl = value;
  55. if (value == null)
  56. return;
  57. var questLog = QuestLogControl.GetQuestLog(this);
  58. if (questLog == null)
  59. return;
  60. questLog.LastSelectedQuestControl = value;
  61. questLog.LastSelectedQuest = value.Quest;
  62. questLog.LastSelectedQuestTab = QuestTab;
  63. }
  64. }
  65. public QuestGroup LastSelectedQuestGroup
  66. {
  67. get { return lastSelectedQuestGroup; }
  68. set
  69. {
  70. lastSelectedQuestGroup = value;
  71. if (value == null)
  72. return;
  73. var lastSelectedQuery = from QuestGroupControl questGroupControl in questGroupControls
  74. where questGroupControl.QuestGroup == lastSelectedQuestGroup
  75. select questGroupControl;
  76. LastSelectedQuestGroupControl = lastSelectedQuery.First();
  77. }
  78. }
  79. public Quest LastSelectedQuest
  80. {
  81. get { return lastSelectedQuest; }
  82. set
  83. {
  84. lastSelectedQuest = value;
  85. if (value == null)
  86. return;
  87. var lastSelectedQuery = from QuestControl questControl in QuestControls
  88. where questControl.Quest == lastSelectedQuest
  89. select questControl;
  90. LastSelectedQuestControl = lastSelectedQuery.First();
  91. }
  92. }
  93. public QuestTabControl()
  94. {
  95. InitializeComponent();
  96. QuestControls = new List<QuestControl>();
  97. questGroupControls = new List<QuestGroupControl>();
  98. }
  99. public void quests_DragOver(object sender, DragEventArgs e)
  100. {
  101. if (!e.Data.GetDataPresent(typeof(QuestGroupControl)))
  102. return;
  103. CollapseAllGroups();
  104. var indicatorY = Cursor.Position.Y - quests.PointToScreen(new Point(0, 0)).Y;
  105. line.Top = Math.Min(Math.Max((indicatorY + 12) / 24 * 24, 0), QuestTab.Groups.Count * 24) - 1;
  106. line.Width = Width;
  107. line.Visible = true;
  108. line.BringToFront();
  109. }
  110. private void quests_DragLeave(object sender, EventArgs e)
  111. {
  112. line.Visible = false;
  113. }
  114. public void quests_DragDrop(object sender, DragEventArgs e)
  115. {
  116. if (!e.Data.GetDataPresent(typeof (QuestGroupControl)))
  117. return;
  118. var data = (QuestGroupControl) e.Data.GetData(typeof (QuestGroupControl));
  119. var questScrollOffset = quests.VerticalScroll.Value;
  120. if (data == null)
  121. return;
  122. var tempQuestControls = new List<QuestGroupControl>();
  123. var controlY = 0;
  124. //Get a list of groups under the destination
  125. for (var i = quests.Controls.Count - 1; i >= 0; i--)
  126. {
  127. if (!(quests.Controls[i] is QuestGroupControl))
  128. continue;
  129. var control = (QuestGroupControl) quests.Controls[i];
  130. controlY = controlY == 0 ? control.PointToScreen(new Point(0, 0)).Y : controlY + 24;
  131. if (controlY <= Cursor.Position.Y - 12)
  132. continue;
  133. if (control != data)
  134. tempQuestControls.Add(control);
  135. }
  136. var questLogControl = QuestLogControl.GetQuestLog(this);
  137. questLogControl.LastSelectedQuestTab.Groups.Remove(data.QuestGroup);
  138. //Remove every group under the destination
  139. foreach (var control in tempQuestControls)
  140. {
  141. QuestTab.Groups.Remove(control.QuestGroup);
  142. }
  143. //Put the groups back in order
  144. QuestTab.Groups.Add(data.QuestGroup);
  145. foreach (var control in tempQuestControls)
  146. {
  147. QuestTab.Groups.Add(control.QuestGroup);
  148. }
  149. line.Visible = false;
  150. questLogControl.RenderLog();
  151. questLogControl.LastSelectedQuestGroup = data.QuestGroup;
  152. IEnumerable<QuestGroupControl> groupControls = from Control control in quests.Controls.Cast<Control>()
  153. where control is QuestGroupControl && ((QuestGroupControl) control).QuestGroup == data.QuestGroup
  154. select (QuestGroupControl) control;
  155. var questGroupControl = groupControls.First();
  156. questLogControl.LastSelectedQuestControl = null;
  157. var lastSelectedQuery = from Control control in questGroupControl.Controls
  158. where control is QuestControl && ((QuestControl)control).Quest == questLogControl.LastSelectedQuest
  159. select (QuestControl)control;
  160. if (lastSelectedQuery.Count() != 0)
  161. {
  162. questLogControl.LastSelectedQuestControl = lastSelectedQuery.First();
  163. questLogControl.LastSelectedQuestControl.SetHighlightedBackcolor();
  164. data.SetNormalBackcolor();
  165. }
  166. else
  167. {
  168. questLogControl.LastSelectedQuest = null;
  169. }
  170. SelectLastSelected();
  171. questGroupControl.selected.Checked = data.selected.Checked;
  172. quests.VerticalScroll.Value = Math.Min(questScrollOffset, quests.VerticalScroll.Maximum);
  173. }
  174. private void quests_DragEnter(object sender, DragEventArgs e)
  175. {
  176. if (e.Data.GetDataPresent(typeof(QuestGroupControl)))
  177. e.Effect = DragDropEffects.Move;
  178. }
  179. private void recurringQuestWorker_DoWork(object sender, DoWorkEventArgs e)
  180. {
  181. CheckRecurringQuests();
  182. }
  183. private void recurringQuestWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
  184. {
  185. RenderTab();
  186. }
  187. public void ChangeSelectedQuest()
  188. {
  189. if (QuestSelectionChanged != null)
  190. QuestSelectionChanged(this, EventArgs.Empty);
  191. }
  192. private void CheckRecurringQuests()
  193. {
  194. while (true)
  195. {
  196. if (QuestTab != null)
  197. {
  198. var refreshLog = false;
  199. foreach (var group in QuestTab.Groups)
  200. {
  201. foreach (var quest in group.Quests.Where(quest => quest.Recurring).Where(quest => quest.Completed).Where(ShouldRecurQuest))
  202. {
  203. RecurQuest(quest);
  204. refreshLog = true;
  205. }
  206. }
  207. if (refreshLog)
  208. recurringQuestWorker.ReportProgress(0);
  209. }
  210. Thread.Sleep(5000);
  211. }
  212. }
  213. private static bool ShouldRecurQuest(Quest quest)
  214. {
  215. var minuteRecurTime = quest.Schedule.Unit == RecurrenceUnit.Minutes && quest.Schedule.StartDate.AddMinutes(quest.Schedule.Frequency) < DateTime.Now;
  216. var hourRecurTime = quest.Schedule.Unit == RecurrenceUnit.Hours && quest.Schedule.StartDate.AddHours(quest.Schedule.Frequency) < DateTime.Now;
  217. var dayRecurTime = quest.Schedule.Unit == RecurrenceUnit.Days && quest.Schedule.StartDate.AddDays(quest.Schedule.Frequency) < DateTime.Now;
  218. return minuteRecurTime || hourRecurTime || dayRecurTime;
  219. }
  220. private static void RecurQuest(Quest quest)
  221. {
  222. quest.Completed = false;
  223. SetNextRecurDate(quest);
  224. }
  225. private static void SetNextRecurDate(Quest quest)
  226. {
  227. if (!quest.Recurring) return;
  228. var timeElapsed = DateTime.Now - quest.Schedule.StartDate;
  229. switch (quest.Schedule.Unit)
  230. {
  231. case RecurrenceUnit.Minutes:
  232. quest.Schedule.StartDate = quest.Schedule.StartDate.AddMinutes((int)timeElapsed.TotalMinutes - ((int)timeElapsed.TotalMinutes % quest.Schedule.Frequency));
  233. break;
  234. case RecurrenceUnit.Hours:
  235. quest.Schedule.StartDate = quest.Schedule.StartDate.AddHours((int)timeElapsed.TotalHours - ((int)timeElapsed.TotalHours % quest.Schedule.Frequency));
  236. break;
  237. case RecurrenceUnit.Days:
  238. quest.Schedule.StartDate = quest.Schedule.StartDate.AddDays((int)timeElapsed.TotalDays - ((int)timeElapsed.TotalDays % quest.Schedule.Frequency));
  239. break;
  240. default:
  241. break;
  242. }
  243. }
  244. public void RenderTab()
  245. {
  246. RenderTab(lastShowCompleted);
  247. }
  248. public void RenderTab(bool showCompleted)
  249. {
  250. lastShowCompleted = showCompleted;
  251. var questScrollOffset = quests.VerticalScroll.Value;
  252. //remove groups that aren't in the log
  253. var controlsToDelete = (from Control questGroupControl in quests.Controls.Cast<Control>()
  254. where questGroupControl is QuestGroupControl && !QuestTab.Groups.Contains(((QuestGroupControl)questGroupControl).QuestGroup)
  255. select (QuestGroupControl)questGroupControl).ToList();
  256. foreach (var questGroupControl in controlsToDelete)
  257. {
  258. foreach (var quest in questGroupControl.QuestControls)
  259. {
  260. QuestControls.Remove(quest);
  261. }
  262. quests.Controls.Remove(questGroupControl);
  263. questGroupControls.Remove(questGroupControl);
  264. }
  265. //add new groups that are in the log
  266. var questGroupsInControls = from Control questGroupControl in quests.Controls.Cast<Control>()
  267. where questGroupControl is QuestGroupControl
  268. select ((QuestGroupControl)questGroupControl).QuestGroup;
  269. var questGroupsToAdd = from QuestGroup questGroup in QuestTab.Groups
  270. where !questGroupsInControls.Contains(questGroup)
  271. select questGroup;
  272. foreach (var questGroupControl in questGroupsToAdd.Select(questGroup => new QuestGroupControl {Dock = DockStyle.Top, QuestGroup = questGroup, TabStop = false, ShowCompleted = showCompleted}))
  273. {
  274. quests.Controls.Add(questGroupControl);
  275. questGroupControls.Add(questGroupControl);
  276. questGroupControl.BringToFront();
  277. }
  278. foreach (var control in questGroupControls)
  279. {
  280. var questGroupControl = control;
  281. questGroupControl.ShowCompleted = showCompleted;
  282. questGroupControl.RenderGroup();
  283. }
  284. if (!addGroupPresent)
  285. {
  286. var addGroup = new AddGroupControl { Dock = DockStyle.Top, TabStop = false };
  287. quests.Controls.Add(addGroup);
  288. addGroupPresent = true;
  289. }
  290. FixZOrder();
  291. var addGroupControl = (from Control addGroup in quests.Controls.Cast<Control>()
  292. where addGroup is AddGroupControl
  293. select (AddGroupControl)addGroup).First();
  294. addGroupControl.BringToFront();
  295. quests.VerticalScroll.Value = Math.Min(questScrollOffset, quests.VerticalScroll.Maximum);
  296. quests.Refresh();
  297. }
  298. private void FixZOrder()
  299. {
  300. var questControlsOrdered = (from QuestGroupControl questGroupControl in quests.Controls.OfType<QuestGroupControl>()
  301. orderby QuestTab.Groups.IndexOf(questGroupControl.QuestGroup) descending
  302. select questGroupControl).ToArray();
  303. var i = -1;
  304. foreach (var questGroupControl in questControlsOrdered)
  305. {
  306. do
  307. {
  308. i++;
  309. } while (!(quests.Controls[i] is QuestGroupControl));
  310. if (quests.Controls[i] != questGroupControl)
  311. quests.Controls.SetChildIndex(questGroupControl, i);
  312. }
  313. }
  314. public void CompleteQuests()
  315. {
  316. if (AnyChecked)
  317. {
  318. if (AllCheckedComplete)
  319. {
  320. foreach (var questControl in QuestControls.Where(questControl => questControl.selected.Checked))
  321. {
  322. questControl.Quest.Completed = false;
  323. questControl.Quest.CompleteDates.RemoveAt(questControl.Quest.CompleteDates.Count - 1);
  324. questControl.selected.Checked = false;
  325. }
  326. }
  327. else
  328. {
  329. foreach (var questControl in QuestControls)
  330. {
  331. if (!questControl.selected.Checked) continue;
  332. var quest = questControl.Quest;
  333. if (!quest.Completed)
  334. {
  335. quest.CompleteDates.Add(DateTime.Now);
  336. quest.Completed = true;
  337. SetNextRecurDate(quest);
  338. }
  339. questControl.selected.Checked = false;
  340. }
  341. }
  342. LastSelectedQuest = null;
  343. RenderTab();
  344. SelectLastSelected();
  345. foreach (var questGroupControl in questGroupControls)
  346. {
  347. questGroupControl.selected.Checked = false;
  348. }
  349. }
  350. else
  351. {
  352. if (LastSelectedQuest != null)
  353. {
  354. if (LastSelectedQuest.Completed)
  355. {
  356. LastSelectedQuest.Completed = false;
  357. LastSelectedQuest.CompleteDates.RemoveAt(LastSelectedQuest.CompleteDates.Count - 1);
  358. }
  359. else
  360. {
  361. LastSelectedQuest.Completed = true;
  362. LastSelectedQuest.CompleteDates.Add(DateTime.Now);
  363. SetNextRecurDate(LastSelectedQuest);
  364. }
  365. LastSelectedQuest = null;
  366. RenderTab();
  367. SelectLastSelected();
  368. }
  369. }
  370. SetSelectionPlurality();
  371. }
  372. public void SelectLastSelected()
  373. {
  374. if (LastSelectedQuestControl != null)
  375. LastSelectedQuestControl.Focus();
  376. else if (LastSelectedQuestGroupControl != null)
  377. LastSelectedQuestGroupControl.Focus();
  378. }
  379. public void DeleteQuests()
  380. {
  381. if (AnyChecked)
  382. {
  383. foreach (var questGroup in questGroupControls)
  384. {
  385. foreach (var questControl in questGroup.QuestControls.Where(questControl => questControl.selected.Checked))
  386. {
  387. questGroup.QuestGroup.Quests.Remove(questControl.Quest);
  388. }
  389. if (questGroup.selected.Checked)
  390. QuestTab.Groups.Remove(questGroup.QuestGroup);
  391. }
  392. RenderTab();
  393. }
  394. else
  395. {
  396. if (lastSelectedQuest != null)
  397. {
  398. lastSelectedQuestGroup.Quests.Remove(lastSelectedQuest);
  399. RenderTab();
  400. }
  401. }
  402. SetSelectionPlurality();
  403. }
  404. public void SetSelectionPlurality()
  405. {
  406. AnyChecked = false;
  407. AllCheckedComplete = true;
  408. foreach (var questControl in QuestControls.Where(questControl => questControl.selected.Checked))
  409. {
  410. AnyChecked = true;
  411. if (!questControl.Quest.Completed)
  412. AllCheckedComplete = false;
  413. }
  414. AnyChecked |= questGroupControls.Where(questGroupControl => questGroupControl.selected.Checked).Any();
  415. if (SelectionPluralityChanged != null)
  416. SelectionPluralityChanged(this, EventArgs.Empty);
  417. }
  418. public static QuestTabControl GetQuestTab(Control control)
  419. {
  420. var retVal = control.Parent;
  421. if (retVal == null) throw new Exception("Could not identify quest log.");
  422. while (!(retVal is QuestTabControl) && retVal.Parent != null)
  423. {
  424. retVal = retVal.Parent;
  425. }
  426. return (QuestTabControl)retVal;
  427. }
  428. public void CollapseAllGroups()
  429. {
  430. foreach (var questGroupControl in quests.Controls.OfType<QuestGroupControl>())
  431. {
  432. questGroupControl.RenderCollapsed();
  433. }
  434. quests.VerticalScroll.Value = 0;
  435. forcedCollapse = true;
  436. }
  437. public void RestoreAllGroups()
  438. {
  439. if (!forcedCollapse)
  440. return;
  441. foreach (var questGroupControl in quests.Controls.OfType<QuestGroupControl>())
  442. {
  443. questGroupControl.RenderCollapseState();
  444. }
  445. forcedCollapse = false;
  446. }
  447. }
  448. public static class TabPageExtensions
  449. {
  450. public static QuestTabControl QuestTabControl(this TabPage questTabPage)
  451. {
  452. //questTabPage can be null during a Drag and Drop operation
  453. if (questTabPage == null)
  454. return null;
  455. if (questTabPage.Controls.Count == 0)
  456. return null;
  457. var questTabControl = (from Control control in questTabPage.Controls.Cast<Control>()
  458. where control is QuestTabControl
  459. select (QuestTabControl)control).First();
  460. return questTabControl;
  461. }
  462. }
  463. }