146 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C#
		
	
	
	
using Contime.model;
 | 
						|
 | 
						|
namespace Contime.view {
 | 
						|
    public partial class MainForm : Form {
 | 
						|
        // --- Events for the Controller ---
 | 
						|
        public event Action WorkdayStartStopClicked;
 | 
						|
        public event Action TaskStartStopClicked;
 | 
						|
        public event Action GoOutOfContextClicked;
 | 
						|
        public event Action ToggleTaskStatusClicked;
 | 
						|
        public event Action AddTaskClicked;
 | 
						|
        public event Action<long> TaskSelected;
 | 
						|
        public event Action SaveContextClicked;
 | 
						|
        public event Action ExportClicked;
 | 
						|
 | 
						|
        // --- Properties for the Controller ---
 | 
						|
        public string NewTaskName => txtNewTask.Text;
 | 
						|
        public string ContextText { get => txtContext.Text; set => txtContext.Text = value; }
 | 
						|
 | 
						|
        public MainForm() {
 | 
						|
            InitializeComponent();
 | 
						|
        }
 | 
						|
 | 
						|
        // Handles full UI redraws, especially for the task list and summary data
 | 
						|
        public void UpdateView(TimeTrackerModel model) {
 | 
						|
            this.SuspendLayout();
 | 
						|
 | 
						|
            UpdateTaskList(model);
 | 
						|
            UpdateSummaryStats(model);
 | 
						|
            UpdateTimersAndState(model); // Also call the lighter update to ensure consistency
 | 
						|
 | 
						|
            this.ResumeLayout();
 | 
						|
        }
 | 
						|
 | 
						|
        // Handles high-frequency updates (timers, button states)
 | 
						|
        public void UpdateTimersAndState(TimeTrackerModel model) {
 | 
						|
            lblWorkdayTimer.Text = model.WorkdayTime.ToString(@"hh\:mm\:ss");
 | 
						|
            lblTaskTimer.Text = model.ActiveTaskTime.ToString(@"hh\:mm\:ss");
 | 
						|
            lblSelectedTaskTotalTime.Text = model.SelectedTaskTotalTime.ToString(@"hh\:mm\:ss");
 | 
						|
 | 
						|
            lblStatus.Text = GetStatusText(model.CurrentState);
 | 
						|
            lblStatus.ForeColor = GetStatusColor(model.CurrentState);
 | 
						|
 | 
						|
            lblSelectedTask.Text = model.SelectedTask?.Name ?? "None";
 | 
						|
 | 
						|
            // --- Update Button States and Text ---
 | 
						|
            btnWorkdayStartStop.Text = (model.CurrentState == TimeTrackerModel.AppState.Idle) ? "Start Workday" : "Stop Workday";
 | 
						|
            btnWorkdayStartStop.BackColor = (model.CurrentState == TimeTrackerModel.AppState.Idle) ? Color.FromArgb(0, 122, 204) : Color.FromArgb(192, 0, 0);
 | 
						|
 | 
						|
            btnGoOutOfContext.Enabled = model.CurrentState != TimeTrackerModel.AppState.Idle;
 | 
						|
            btnGoOutOfContext.Text = (model.CurrentState == TimeTrackerModel.AppState.OutOfContext) ? "Return to Work" : "Go Out of Context";
 | 
						|
 | 
						|
            bool taskIsSelectedAndOpen = model.SelectedTask != null && model.SelectedTask.Status == "open";
 | 
						|
            bool canStartTask = model.CurrentState == TimeTrackerModel.AppState.WorkdayActive && taskIsSelectedAndOpen;
 | 
						|
            btnTaskStartStop.Enabled = canStartTask || model.CurrentState == TimeTrackerModel.AppState.TaskActive;
 | 
						|
            btnTaskStartStop.Text = (model.CurrentState == TimeTrackerModel.AppState.TaskActive) ? "Stop Task" : "Start Task";
 | 
						|
            btnTaskStartStop.BackColor = (model.CurrentState == TimeTrackerModel.AppState.TaskActive) ? Color.FromArgb(220, 53, 69) : Color.FromArgb(40, 167, 69);
 | 
						|
 | 
						|
            btnToggleTaskStatus.Enabled = model.SelectedTask != null && model.CurrentState != TimeTrackerModel.AppState.TaskActive;
 | 
						|
            btnToggleTaskStatus.Text = model.SelectedTask?.Status == "open" ? "Mark as Finished" : "Re-open Task";
 | 
						|
 | 
						|
            lstTasks.Enabled = model.CurrentState != TimeTrackerModel.AppState.TaskActive;
 | 
						|
 | 
						|
            // Show or hide the 'Out of Context' input fields
 | 
						|
            bool outOfContext = model.CurrentState == TimeTrackerModel.AppState.OutOfContext;
 | 
						|
            txtContext.Visible = outOfContext;
 | 
						|
            btnSaveContext.Visible = outOfContext;
 | 
						|
            if (outOfContext) ContextText = model.OutOfContextReason;
 | 
						|
        }
 | 
						|
 | 
						|
        private void UpdateSummaryStats(TimeTrackerModel model) {
 | 
						|
            lblDayTotal.Text = $"Today: {model.DayTotal:hh\\:mm\\:ss}";
 | 
						|
            lblWeekTotal.Text = $"This Week: {model.WeekTotal:hh\\:mm\\:ss}";
 | 
						|
        }
 | 
						|
 | 
						|
        private void LstTasks_SelectedIndexChanged(object sender, EventArgs e) {
 | 
						|
            if (lstTasks.SelectedItems.Count > 0)
 | 
						|
                TaskSelected?.Invoke((long)lstTasks.SelectedItems[0].Tag);
 | 
						|
            else
 | 
						|
                TaskSelected?.Invoke(-1);
 | 
						|
        }
 | 
						|
 | 
						|
        private void LstTasks_MouseDoubleClick(object sender, MouseEventArgs e) {
 | 
						|
            if (lstTasks.SelectedItems.Count == 1) {
 | 
						|
                var selectedItem = lstTasks.SelectedItems[0];
 | 
						|
                string taskName = selectedItem.SubItems[0].Text;
 | 
						|
                string totalTime = selectedItem.SubItems[1].Text;
 | 
						|
                string status = selectedItem.SubItems[2].Text;
 | 
						|
 | 
						|
                string message = $"Task: {taskName}\nTotal Time: {totalTime}\nStatus: {status}";
 | 
						|
                MessageBox.Show(message, "Task Details", MessageBoxButtons.OK, MessageBoxIcon.Information);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private void UpdateTaskList(TimeTrackerModel model) {
 | 
						|
            lstTasks.SelectedIndexChanged -= LstTasks_SelectedIndexChanged; // Unsubscribe to prevent feedback loop
 | 
						|
 | 
						|
            long? selectedTaskId = model.SelectedTask?.Id;
 | 
						|
            lstTasks.Items.Clear();
 | 
						|
 | 
						|
            foreach (var task in model.Tasks) {
 | 
						|
                var item = new ListViewItem(new[] { task.Name, task.ElapsedTime.ToString(@"hh\:mm\:ss"), task.Status }) {
 | 
						|
                    Tag = task.Id,
 | 
						|
                    ForeColor = task.Status == "closed" ? Color.Gray : Color.White
 | 
						|
                };
 | 
						|
                lstTasks.Items.Add(item);
 | 
						|
                if (task.Id == selectedTaskId) {
 | 
						|
                    item.Selected = true;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            lstTasks.SelectedIndexChanged += LstTasks_SelectedIndexChanged; // Re-subscribe
 | 
						|
        }
 | 
						|
 | 
						|
        private string GetStatusText(TimeTrackerModel.AppState state) {
 | 
						|
            switch (state) {
 | 
						|
                case TimeTrackerModel.AppState.Idle: return "Idle";
 | 
						|
                case TimeTrackerModel.AppState.WorkdayActive: return "Workday Active";
 | 
						|
                case TimeTrackerModel.AppState.TaskActive: return "Task in Progress";
 | 
						|
                case TimeTrackerModel.AppState.OutOfContext: return "Out of Context";
 | 
						|
                default: return "Unknown";
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private Color GetStatusColor(TimeTrackerModel.AppState state) {
 | 
						|
            switch (state) {
 | 
						|
                case TimeTrackerModel.AppState.Idle: return Color.White;
 | 
						|
                case TimeTrackerModel.AppState.WorkdayActive: return Color.LightSkyBlue;
 | 
						|
                case TimeTrackerModel.AppState.TaskActive: return Color.LightGreen;
 | 
						|
                case TimeTrackerModel.AppState.OutOfContext: return Color.Orange;
 | 
						|
                default: return Color.White;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public void ShowNotification(string title, string message) {
 | 
						|
            notifyIcon.BalloonTipTitle = title;
 | 
						|
            notifyIcon.BalloonTipText = message;
 | 
						|
            notifyIcon.ShowBalloonTip(3000);
 | 
						|
        }
 | 
						|
 | 
						|
        private void BtnExport_Click(object sender, EventArgs e) {
 | 
						|
            ExportClicked?.Invoke();
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 |