/* Miranda NG: the free IM client for Microsoft* Windows* Copyright (c) 2012-18 Miranda NG team (https://miranda-ng.org), Copyright (c) 2000-08 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "stdafx.h" void RefreshTree(HWND hwndDlg, HTREEITEM hti); static char* rowOptTmplStr; static ROWCELL* rowOptTmplRoot; static ROWCELL* rowOptTA[100]; wchar_t *types[] = { L"none", L"text1", L"text2", L"text3", L"status", L"avatar", L"extra", L"extra1", L"extra2", L"extra3", L"extra4", L"extra5", L"extra6", L"extra7", L"extra8", L"extra9", L"time", L"space", L"fspace" }; RECT da = { 205, 58, 440, 130 }; // Draw area void rowOptBuildTA(pROWCELL cell, pROWCELL* TA, int* i) { if (!cell) return; TA[(*i)++] = cell; rowOptBuildTA(cell->child, TA, i); rowOptBuildTA(cell->next, TA, i); } void rowOptShowSettings(HWND hwnd) { TVITEM tvi; pROWCELL cell; HTREEITEM node = TreeView_GetSelection(GetDlgItem(hwnd, IDC_ROWTREE)); int param; tvi.hItem = node; tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TreeView_GetItem(GetDlgItem(hwnd, IDC_ROWTREE), &tvi); cell = (pROWCELL)tvi.lParam; if (!tvi.hItem) { EnableWindow(GetDlgItem(hwnd, IDC_CONTTYPE), 0); EnableWindow(GetDlgItem(hwnd, IDC_VALIGN), 0); EnableWindow(GetDlgItem(hwnd, IDC_HALIGN), 0); EnableWindow(GetDlgItem(hwnd, IDC_CONTWIDTH), 0); EnableWindow(GetDlgItem(hwnd, IDC_CONTHEIGHT), 0); EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTWIDTH), 0); EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTHEIGHT), 0); SendDlgItemMessage(hwnd, IDC_SPINCONTWIDTH, UDM_SETPOS, 0, 0); SendDlgItemMessage(hwnd, IDC_SPINCONTHEIGHT, UDM_SETPOS, 0, 0); EnableWindow(GetDlgItem(hwnd, IDC_CONTLAYER), 0); return; } EnableWindow(GetDlgItem(hwnd, IDC_CONTTYPE), 1); EnableWindow(GetDlgItem(hwnd, IDC_VALIGN), 1); EnableWindow(GetDlgItem(hwnd, IDC_HALIGN), 1); EnableWindow(GetDlgItem(hwnd, IDC_CONTLAYER), 1); if (cell->type != TC_SPACE && cell->type != TC_FIXED) { EnableWindow(GetDlgItem(hwnd, IDC_CONTWIDTH), 0); EnableWindow(GetDlgItem(hwnd, IDC_CONTHEIGHT), 0); EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTWIDTH), 0); EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTHEIGHT), 0); SendDlgItemMessage(hwnd, IDC_SPINCONTWIDTH, UDM_SETPOS, 0, 0); SendDlgItemMessage(hwnd, IDC_SPINCONTHEIGHT, UDM_SETPOS, 0, 0); } else { EnableWindow(GetDlgItem(hwnd, IDC_CONTWIDTH), 1); EnableWindow(GetDlgItem(hwnd, IDC_CONTHEIGHT), 1); EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTWIDTH), 1); EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTHEIGHT), 1); SendDlgItemMessage(hwnd, IDC_SPINCONTWIDTH, UDM_SETPOS, 0, MAKELONG(cell->w, 0)); SendDlgItemMessage(hwnd, IDC_SPINCONTHEIGHT, UDM_SETPOS, 0, MAKELONG(cell->h, 0)); } SendDlgItemMessage(hwnd, IDC_CONTTYPE, CB_SETCURSEL, cell->type, 0); switch (cell->valign) { case TC_VCENTER: param = 1; break; case TC_BOTTOM: param = 2; break; default: param = 0; } SendDlgItemMessage(hwnd, IDC_VALIGN, CB_SETCURSEL, param, 0); switch (cell->halign) { case TC_HCENTER: param = 1; break; case TC_RIGHT: param = 2; break; default: param = 0; } SendDlgItemMessage(hwnd, IDC_HALIGN, CB_SETCURSEL, param, 0); CheckDlgButton(hwnd, IDC_CONTLAYER, cell->layer ? BST_CHECKED : BST_UNCHECKED); } void rowOptGenerateTreeView(pROWCELL cell, HTREEITEM node, HWND hwnd) { if (!cell) return; TVINSERTSTRUCT tvis; tvis.hParent = node; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvis.item.stateMask = TVIS_STATEIMAGEMASK; tvis.item.lParam = (LPARAM)cell; switch (cell->cont) { case TC_ROW: tvis.item.pszText = L"Line"; break; case TC_COL: tvis.item.pszText = L"Column"; } tvis.item.iImage = cell->child ? 1 : 2; tvis.item.iSelectedImage = cell->child ? 0 : 2; HTREEITEM pnode = TreeView_InsertItem(hwnd, &tvis); rowOptGenerateTreeView(cell->child, pnode, hwnd); rowOptGenerateTreeView(cell->next, node, hwnd); } int rowOptFillRowTree(HWND hwnd) { TreeView_DeleteAllItems(hwnd); rowOptGenerateTreeView(rowOptTmplRoot, nullptr, hwnd); TreeView_Expand(hwnd, TreeView_GetRoot(hwnd), TVM_EXPAND); return 0; } void rowOptAddContainer(HWND htree, HTREEITEM hti) { TVINSERTSTRUCT tvis; TVITEM tviparent; ROWCELL *cell = nullptr; if (!hti) { if (TreeView_GetRoot(htree)) return; rowAddCell(rowOptTmplRoot, TC_ROW); tvis.hParent = nullptr; tvis.hInsertAfter = TVI_ROOT; tvis.item.pszText = L"Line"; tvis.item.lParam = (LPARAM)rowOptTmplRoot; cell = rowOptTmplRoot; } else { // Get parent item tviparent.hItem = hti; tviparent.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TreeView_GetItem(htree, &tviparent); cell = (pROWCELL)tviparent.lParam; if (cell->cont == TC_ROW) tvis.item.pszText = L"Column"; else tvis.item.pszText = L"Line"; if (cell->child) { cell = cell->child; while (cell->next) cell = cell->next; rowAddCell(cell->next, ((ROWCELL*)tviparent.lParam)->cont == TC_ROW ? TC_COL : TC_ROW); cell = cell->next; } else { rowAddCell(cell->child, ((ROWCELL*)tviparent.lParam)->cont == TC_ROW ? TC_COL : TC_ROW); cell = cell->child; } tvis.hInsertAfter = TVI_LAST; } tvis.item.lParam = (LPARAM)cell; tvis.hParent = hti; tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvis.item.stateMask = TVIS_STATEIMAGEMASK; tvis.item.iImage = 2; tvis.item.iSelectedImage = 2; TreeView_InsertItem(htree, &tvis); TreeView_Expand(htree, hti, TVM_EXPAND); // Change icon at parent item tviparent.iImage = 1; tviparent.iSelectedImage = 0; TreeView_SetItem(htree, &tviparent); int i = 0; memset(rowOptTA, 0, sizeof(rowOptTA)); rowOptBuildTA(rowOptTmplRoot, (pROWCELL*)&rowOptTA, &i); } void rowOptDelContainer(HWND htree, HTREEITEM hti) { HTREEITEM prev = TreeView_GetPrevSibling(htree, hti); HTREEITEM prnt = TreeView_GetParent(htree, hti); TVITEM tvi, tvpi; if (!hti) return; // Get current tree item tvi.hItem = hti; tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TreeView_GetItem(htree, &tvi); tvpi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; if (prev) { tvpi.hItem = prev; TreeView_GetItem(htree, &tvpi); ((pROWCELL)tvpi.lParam)->next = ((pROWCELL)tvi.lParam)->next; } else { if (prnt) { tvpi.hItem = prnt; TreeView_GetItem(htree, &tvpi); ((pROWCELL)tvpi.lParam)->child = ((pROWCELL)tvi.lParam)->next; prev = prnt; } else { tvpi.lParam = 0; rowOptTmplRoot = (pROWCELL)tvpi.lParam; } } ((pROWCELL)tvi.lParam)->next = nullptr; rowDeleteTree((pROWCELL)tvi.lParam); { int i = 0; memset(rowOptTA, 0, sizeof(rowOptTA)); rowOptBuildTA((pROWCELL)tvpi.lParam, (pROWCELL*)&rowOptTA, &i); } TreeView_DeleteItem(htree, hti); // Change icon at parent item if (!prnt || (prnt != prev)) return; if (TreeView_GetChild(htree, prnt)) { tvpi.iImage = 1; tvpi.iSelectedImage = 0; } else { tvpi.iImage = 2; tvpi.iSelectedImage = 2; } TreeView_SetItem(htree, &tvpi); } void RefreshTree(HWND hwndDlg, HTREEITEM hti) { HWND htree = GetDlgItem(hwndDlg, IDC_ROWTREE); pROWCELL cell; TVITEM tvi = { 0 }; if (hti == nullptr) hti = TreeView_GetRoot(htree); while (hti) { tvi.hItem = hti; tvi.mask = TVIF_HANDLE;//|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT; TreeView_GetItem(htree, &tvi); cell = (pROWCELL)tvi.lParam; if (cell) { wchar_t buf[200] = { 0 }; if (!cell->child) { if (cell->type == 0) mir_snwprintf(buf, TranslateT("Empty %s cell"), cell->cont == TC_COL ? TranslateT("column") : TranslateT("line")); else mir_wstrncpy(buf, TranslateW(types[cell->type]), _countof(buf)); } else { if (cell->type == 0) mir_wstrncpy(buf, (cell->cont != TC_COL ? TranslateT("columns") : TranslateT("lines")), _countof(buf)); else mir_snwprintf(buf, TranslateT("%s, contain %s"), TranslateW(types[cell->type]), cell->cont != TC_COL ? TranslateT("columns") : TranslateT("lines")); } if (cell->layer) mir_wstrncat(buf, TranslateT(" layered"), _countof(buf) - mir_wstrlen(buf)); tvi.mask = TVIF_HANDLE | TVIF_TEXT; tvi.pszText = buf; TreeView_SetItem(htree, &tvi); } { HTREEITEM child_hti = TreeView_GetChild(htree, hti); if (child_hti) RefreshTree(hwndDlg, child_hti); } hti = TreeView_GetNextSibling(htree, hti); } RedrawWindow(hwndDlg, nullptr, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN); } INT_PTR CALLBACK DlgTmplEditorOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { int hbuf = 0, seq = 0; HWND htree = GetDlgItem(hwndDlg, IDC_ROWTREE); TranslateDialogDefault(hwndDlg); rowOptTmplStr = db_get_sa(0, "ModernData", "RowTemplate"); if (!rowOptTmplStr) rowOptTmplStr = mir_strdup(""); SendDlgItemMessage(hwndDlg, IDC_SPINCONTWIDTH, UDM_SETRANGE, 0, MAKELONG(999, 0)); SendDlgItemMessage(hwndDlg, IDC_SPINCONTHEIGHT, UDM_SETRANGE, 0, MAKELONG(999, 0)); for (auto &it : types) { int item = SendDlgItemMessage(hwndDlg, IDC_CONTTYPE, CB_ADDSTRING, 0, (LPARAM)TranslateW(it)); SendDlgItemMessage(hwndDlg, IDC_CONTTYPE, CB_SETITEMDATA, item, 0); } SendDlgItemMessage(hwndDlg, IDC_CONTTYPE, CB_SETCURSEL, 0, 0); wchar_t *h_alignment[] = { L"left", L"hCenter", L"right" }; for (auto &it : h_alignment) { int item = SendDlgItemMessage(hwndDlg, IDC_HALIGN, CB_ADDSTRING, 0, (LPARAM)TranslateW(it)); SendDlgItemMessage(hwndDlg, IDC_HALIGN, CB_SETITEMDATA, item, 0); } SendDlgItemMessage(hwndDlg, IDC_HALIGN, CB_SETCURSEL, 0, 0); wchar_t *v_alignment[] = { L"top", L"vCenter", L"bottom" }; for (auto &it : v_alignment) { int item = SendDlgItemMessage(hwndDlg, IDC_VALIGN, CB_ADDSTRING, 0, (LPARAM)TranslateW(it)); SendDlgItemMessage(hwndDlg, IDC_VALIGN, CB_SETITEMDATA, item, 0); } SendDlgItemMessage(hwndDlg, IDC_VALIGN, CB_SETCURSEL, 0, 0); rowDeleteTree(rowOptTmplRoot); rowOptTmplRoot = nullptr; rowParse(rowOptTmplRoot, rowOptTmplRoot, rowOptTmplStr, hbuf, seq, rowOptTA); seq = 0; memset(rowOptTA, 0, sizeof(rowOptTA)); rowOptBuildTA(rowOptTmplRoot, (pROWCELL*)&rowOptTA, &seq); rowOptFillRowTree(htree); RefreshTree(hwndDlg, nullptr); TreeView_SelectItem(GetDlgItem(hwndDlg, IDC_ROWTREE), TreeView_GetRoot(GetDlgItem(hwndDlg, IDC_ROWTREE))); rowOptShowSettings(hwndDlg); } return TRUE; case WM_COMMAND: { HWND htree = GetDlgItem(hwndDlg, IDC_ROWTREE); pROWCELL cell; TVITEM tvi = { 0 }; HTREEITEM hti = TreeView_GetSelection(htree); tvi.hItem = hti; tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TreeView_GetItem(htree, &tvi); cell = (pROWCELL)tvi.lParam; switch (LOWORD(wParam)) { case IDC_CONTTYPE: if (HIWORD(wParam) == CBN_SELENDOK) { int index = SendDlgItemMessage(hwndDlg, IDC_CONTTYPE, CB_GETCURSEL, 0, 0); cell->type = index; RefreshTree(hwndDlg, nullptr); } case IDC_VALIGN: if (HIWORD(wParam) == CBN_SELENDOK) { switch (SendDlgItemMessage(hwndDlg, IDC_VALIGN, CB_GETCURSEL, 0, 0)) { case 0: cell->valign = TC_TOP; break; case 1: cell->valign = TC_VCENTER; break; case 2: cell->valign = TC_BOTTOM; break; } RefreshTree(hwndDlg, nullptr); } case IDC_HALIGN: if (HIWORD(wParam) == CBN_SELENDOK) { switch (SendDlgItemMessage(hwndDlg, IDC_HALIGN, CB_GETCURSEL, 0, 0)) { case 0: cell->halign = TC_LEFT; break; case 1: cell->halign = TC_HCENTER; break; case 2: cell->halign = TC_RIGHT; break; } RefreshTree(hwndDlg, nullptr); } } if (HIWORD(wParam) == BN_CLICKED) { if (lParam == (LPARAM)GetDlgItem(hwndDlg, IDC_ADDCONTAINER)) // Adding new container { rowOptAddContainer(htree, hti); } else if (lParam == (LPARAM)GetDlgItem(hwndDlg, IDC_DELCONTAINER)) // Deleting container { rowOptDelContainer(htree, hti); } else if (lParam == (LPARAM)GetDlgItem(hwndDlg, IDC_CONTUP)) // Moving container to up { RedrawWindow(htree, &da, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN); } RefreshTree(hwndDlg, nullptr); RedrawWindow(GetParent(hwndDlg), nullptr, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN); } return TRUE; } case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case IDC_ROWTREE: if (((LPNMHDR)lParam)->code == NM_SETCURSOR) rowOptShowSettings(hwndDlg); if (((LPNMHDR)lParam)->code == NM_CLICK) RedrawWindow(hwndDlg, &da, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW); break; case 0: // Apply or Ok button is pressed return FALSE; // Temporary break; } return TRUE; case WM_PAINT: if (rowOptTmplRoot) { int i = 0; // Drawning row template at properties page PAINTSTRUCT ps; HDC hdc = BeginPaint(hwndDlg, &ps); TVITEM curItem; curItem.hItem = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_ROWTREE)); curItem.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TreeView_GetItem(GetDlgItem(hwndDlg, IDC_ROWTREE), &curItem); while (rowOptTA[i]) { switch (rowOptTA[i]->type) { case TC_AVATAR: rowOptTA[i]->w = 25; rowOptTA[i]->h = 30; break; case TC_STATUS: case TC_EXTRA1: case TC_EXTRA2: case TC_EXTRA3: case TC_EXTRA4: case TC_EXTRA5: case TC_EXTRA6: case TC_EXTRA7: case TC_EXTRA8: case TC_EXTRA9: rowOptTA[i]->w = 16; rowOptTA[i]->h = 16; break; case TC_EXTRA: rowOptTA[i]->w = 112; rowOptTA[i]->h = 16; break; case TC_TEXT1: case TC_TEXT2: case TC_TEXT3: rowOptTA[i]->w = 200; rowOptTA[i]->h = 16; break; case TC_TIME: rowOptTA[i]->w = 30; rowOptTA[i]->h = 10; default: rowOptTA[i]->w = 0; rowOptTA[i]->h = 0; } i++; } rowSizeWithReposition(rowOptTmplRoot, da.right - da.left); i = -1; while (rowOptTA[++i]) { switch (rowOptTA[i]->type) { case TC_SPACE: case TC_FIXED: case 0: //if (rowOptTA[i] != (pROWCELL)curItem.lParam) continue; } Rectangle(hdc, rowOptTA[i]->r.left + da.left, rowOptTA[i]->r.top + da.top, rowOptTA[i]->r.right + da.left, rowOptTA[i]->r.bottom + da.top); } EndPaint(hwndDlg, &ps); return FALSE; } } return FALSE; }