/* ** AreaEditor - a program for editing SMAUG and ROM area files. ** Author: Nick Gammon ** http://www.gammon.com.au/ ** See Copyright Notice at the end of AreaEditor.h */ // SkillsListDlg.cpp : implementation file // #include "stdafx.h" #include "AreaEditor.h" #include "SkillsListDlg.h" #include "defaults.h" #include "SkillsSheet.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CSkillsListDlg dialog CSkillsListDlg::CSkillsListDlg(CWnd* pParent /*=NULL*/) : CDialog(CSkillsListDlg::IDD, pParent) { //{{AFX_DATA_INIT(CSkillsListDlg) m_strSkillsCount = _T(""); //}}AFX_DATA_INIT m_last_col = 0; m_reverse = FALSE; } void CSkillsListDlg::DoDataExchange(CDataExchange* pDX) { if (!pDX->m_bSaveAndValidate) m_strSkillsCount.Format ("%i skills/spells/tongues/weapons", App.m_SkillList.GetCount ()); CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSkillsListDlg) DDX_Control(pDX, IDC_SKILLS_LIST, m_ctlSkillsList); DDX_Text(pDX, IDC_SKILL_COUNT, m_strSkillsCount); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CSkillsListDlg, CDialog) //{{AFX_MSG_MAP(CSkillsListDlg) ON_NOTIFY(NM_DBLCLK, IDC_SKILLS_LIST, OnDblclkSkillsList) ON_BN_CLICKED(IDC_ADD, OnAdd) ON_BN_CLICKED(IDC_EDIT, OnEdit) ON_BN_CLICKED(IDC_DELETE, OnDelete) ON_NOTIFY(LVN_COLUMNCLICK, IDC_SKILLS_LIST, OnColumnclickSkillsList) //}}AFX_MSG_MAP ON_MESSAGE(WM_KICKIDLE, OnKickIdle) ON_UPDATE_COMMAND_UI(IDC_EDIT, OnUpdateNeedSelection) ON_UPDATE_COMMAND_UI(IDC_DELETE, OnUpdateNeedSelection) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSkillsListDlg message handlers typedef struct { int sortkey; // which key to use int reverse; // reverse sort or not } t_sort_param; static int CALLBACK CompareFunc ( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { ASSERT (lParamSort != NULL); t_sort_param * psort_param = (t_sort_param *) lParamSort; CSkill * pSkill1 = (CSkill *) lParam1; CSkill * pSkill2 = (CSkill *) lParam2; ASSERT (pSkill1 != NULL); ASSERT (pSkill2 != NULL); int iResult = 0; switch (psort_param->sortkey) { case 3: if (pSkill1->affects.GetCount () < pSkill2->affects.GetCount ()) { iResult = -1; break; } else if (pSkill1->affects.GetCount () > pSkill2->affects.GetCount ()) { iResult = 1; break; } // if affects count is the same, fall through to slot case 2: if (pSkill1->slot < pSkill2->slot) { iResult = -1; break; } else if (pSkill1->slot > pSkill2->slot) { iResult = 1; break; } // note - if slot is same - fall through to type case 0: iResult = stricmp (SkillTypeList.ReturnName (pSkill1->type, false), SkillTypeList.ReturnName (pSkill2->type, false)); if (iResult != 0) break; // note - if type is the same - fall through to name case 1: iResult = pSkill1->name.CompareNoCase (pSkill2->name); break; } // end of switch // if reverse sort wanted, reverse sense of result if (psort_param->reverse) iResult *= -1; return iResult; } // end of CompareFunc void CSkillsListDlg::OnDblclkSkillsList(NMHDR* pNMHDR, LRESULT* pResult) { OnEdit (); *pResult = 0; } BOOL CSkillsListDlg::OnInitDialog() { CDialog::OnInitDialog(); // set list control to display whole row when selected m_ctlSkillsList.SendMessage (LVM_SETEXTENDEDLISTVIEWSTYLE, 0, m_ctlSkillsList.SendMessage (LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0) | LVS_EX_FULLROWSELECT); m_ctlSkillsList.InsertColumn(0, "Type", LVCFMT_LEFT, 80); m_ctlSkillsList.InsertColumn(1, "Name", LVCFMT_LEFT, 150); m_ctlSkillsList.InsertColumn(2, "Slot", LVCFMT_RIGHT, 50); m_ctlSkillsList.InsertColumn(3, "Affects", LVCFMT_RIGHT, 50); RedrawList (); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CSkillsListDlg::OnAdd() { CSkill * skill = new CSkill; CSkillsSheet propSheet (NULL, skill); propSheet.m_skill = skill; propSheet.m_bAdd = true; if (propSheet.DoModal() != IDOK) { delete skill; // don't need it now return; } App.SortSkills (); App.m_SkillList.AddTail (skill); RedrawList (); // in case they renamed it } void CSkillsListDlg::OnEdit() { for (int nIndex = -1; (nIndex = m_ctlSkillsList.GetNextItem(nIndex, LVNI_SELECTED)) != -1; ) { CSkill * skill = (CSkill *) m_ctlSkillsList.GetItemData (nIndex); CSkillsSheet propSheet (NULL, skill); propSheet.m_skill = skill; propSheet.m_bAdd = false; if (propSheet.DoModal() != IDOK) return; RedrawList (); // in case they renamed it } } void CSkillsListDlg::OnDelete() { bool bChanged = false; for (int nIndex = -1; (nIndex = m_ctlSkillsList.GetNextItem(nIndex, LVNI_SELECTED)) != -1; ) { CSkill * skill = (CSkill *) m_ctlSkillsList.GetItemData (nIndex); // ask if they want to delete it if (::AfxMessageBox (CFormat ("OK to delete the %s \"%s\"?", (LPCTSTR) SkillTypeList.ReturnName (skill->type, false), (LPCTSTR) skill->name), MB_ICONQUESTION | MB_YESNO) != IDYES) continue; App.m_SkillList.RemoveAt (App.m_SkillList.Find (skill, NULL)); bChanged = true; } if (bChanged) { App.m_bSkillsDirty = true; RedrawList (); } } void CSkillsListDlg::RedrawList (void) { int nItem = 0; POSITION skillPos; CSkill * skill; m_ctlSkillsList.DeleteAllItems (); for (skillPos = App.m_SkillList.GetHeadPosition (); skillPos; ) { skill = App.m_SkillList.GetNext (skillPos); m_ctlSkillsList.InsertItem (nItem, SkillTypeList.ReturnName (skill->type, false)); m_ctlSkillsList.SetItemText(nItem, 1, skill->name); m_ctlSkillsList.SetItemText(nItem, 2, CFormat ("%i", skill->slot)); m_ctlSkillsList.SetItemText(nItem, 3, CFormat ("%i", skill->affects.GetCount ())); m_ctlSkillsList.SetItemData (nItem, (DWORD) skill); nItem++; } t_sort_param sort_param; sort_param.sortkey = m_last_col; sort_param.reverse = m_reverse; m_ctlSkillsList.SortItems (CompareFunc, (LPARAM) &sort_param); } // end of CSkillsListDlg::RedrawList void CSkillsListDlg::OnColumnclickSkillsList(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; // TODO: Add your control notification handler code here int col = pNMListView->iSubItem; t_sort_param sort_param; if (col == m_last_col) m_reverse = !m_reverse; else m_reverse = FALSE; m_last_col = col; sort_param.sortkey = m_last_col; sort_param.reverse = m_reverse; m_ctlSkillsList.SortItems (CompareFunc, (LPARAM) &sort_param); *pResult = 0; } LRESULT CSkillsListDlg::OnKickIdle(WPARAM, LPARAM) { UpdateDialogControls (AfxGetApp()->m_pMainWnd, false); return 0; } // end of CSkillsListDlg::OnKickIdle void CSkillsListDlg::OnUpdateNeedSelection(CCmdUI* pCmdUI) { pCmdUI->Enable (m_ctlSkillsList.GetFirstSelectedItemPosition () != NULL); } // end of CSkillsListDlg::OnUpdateNeedSelection