diff options
author | George Hazan <ghazan@miranda.im> | 2020-01-16 22:03:01 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-01-16 22:03:01 +0300 |
commit | bd00314ec32d42fa09918a8ca274b0707c73ec75 (patch) | |
tree | 586b657b523ade102b92dee5323937e0a1c42d2d /plugins/VoiceService/src/frame.cpp | |
parent | 30b859e8e95b1bb4f5e0d0f9d4d6fa40507fd788 (diff) |
VoiceService: adaptaion of the old plugin written by Pescuma for Miranda NG
Diffstat (limited to 'plugins/VoiceService/src/frame.cpp')
-rw-r--r-- | plugins/VoiceService/src/frame.cpp | 741 |
1 files changed, 741 insertions, 0 deletions
diff --git a/plugins/VoiceService/src/frame.cpp b/plugins/VoiceService/src/frame.cpp new file mode 100644 index 0000000000..a95f04f886 --- /dev/null +++ b/plugins/VoiceService/src/frame.cpp @@ -0,0 +1,741 @@ +/* +Copyright (C) 2005 Ricardo Pescuma Domenecci + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this file; see the file license.txt. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" + +// Prototypes ///////////////////////////////////////////////////////////////////////////////////// + +HWND hwnd_frame = NULL; +HWND hwnd_container = NULL; + +int frame_id = -1; + +static LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +#define H_SPACE 2 + +// Functions ////////////////////////////////////////////////////////////////////////////////////// + +void InitFrames() +{ + if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) { + hwnd_frame = CreateDialogW(g_plugin.getInst(), MAKEINTRESOURCE(IDD_CALLS), g_clistApi.hwndContactList, FrameWndProc); + + CLISTFrame Frame = {}; + Frame.cbSize = sizeof(CLISTFrame); + Frame.szName.w = TranslateT("Voice Calls"); + Frame.hWnd = hwnd_frame; + Frame.align = alBottom; + Frame.Flags = F_VISIBLE | F_NOBORDER | F_LOCKED | F_UNICODE; + Frame.height = 0; + Frame.hIcon = g_plugin.getIcon(IDI_MAIN, true); + + frame_id = CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&Frame, 0); + } +} + +void DeInitFrames() +{ + if (ServiceExists(MS_CLIST_FRAMES_REMOVEFRAME) && frame_id != -1) + CallService(MS_CLIST_FRAMES_REMOVEFRAME, (WPARAM)frame_id, 0); + + if (hwnd_frame != NULL) + DestroyWindow(hwnd_frame); +} + +static int GetMaxLineHeight() +{ + return max(ICON_SIZE, font_max_height) + 1; +} + +BOOL FrameIsFloating(int id) +{ + if (id == -1) + return TRUE; // no frames, always floating + + return CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLOATING, id), 0); +} + +void ResizeFrame(int id, HWND hwnd) +{ + int height = calls.getCount() * GetMaxLineHeight(); + if (height > 0) + height += 2; + + if (CanCallNumber()) { + height += 23 + 2; + + if (SendMessage(GetDlgItem(hwnd, IDC_DIALPAD), BM_GETCHECK, 0, 0) == BST_CHECKED) { + RECT first, last; + GetWindowRect(GetDlgItem(hwnd, IDC_1), &first); + GetWindowRect(GetDlgItem(hwnd, IDC_SHARP), &last); + + height += last.bottom - first.top + 1; + } + } + + if (FrameIsFloating(id)) { + HWND parent = GetParent(hwnd); + if (parent == NULL) + return; + + RECT r_client; + GetClientRect(hwnd, &r_client); + + if (r_client.bottom - r_client.top == height) + return; + + RECT parent_client, parent_window, r_window; + GetClientRect(parent, &parent_client); + GetWindowRect(parent, &parent_window); + GetWindowRect(hwnd, &r_window); + + int diff = (parent_window.bottom - parent_window.top) - (parent_client.bottom - parent_client.top); + if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) + diff += (r_window.top - parent_window.top); + + SetWindowPos(parent, 0, 0, 0, parent_window.right - parent_window.left, height + diff, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); + } + else { + int old_height = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT, id), 0); + if (old_height == height) + return; + + CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT, id), (LPARAM)height); + CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)id, (LPARAM)(FU_TBREDRAW | FU_FMREDRAW | FU_FMPOS)); + } +} + +void ShowFrame(int id, HWND hwnd, int show) +{ + BOOL is_visible = IsWindowVisible(hwnd); + if ((is_visible && show == SW_SHOW) || (!is_visible && show == SW_HIDE)) + return; + + if (ServiceExists(MS_CLIST_FRAMES_SHFRAME) && id != -1) + CallService(MS_CLIST_FRAMES_SHFRAME, (WPARAM)id, 0); + else + ShowWindow(GetParent(hwnd), show); +} + +static int dialCtrls[] = { + IDC_DIALPAD, IDC_NUMBER, IDC_CALL, + IDC_1, IDC_2, IDC_3, + IDC_4, IDC_5, IDC_6, + IDC_7, IDC_8, IDC_9, + IDC_AST, IDC_0, IDC_SHARP +}; + +static wchar_t *lstrtrim(wchar_t *str) +{ + int len = lstrlen(str); + + int i; + for (i = len - 1; i >= 0 && (str[i] == ' ' || str[i] == '\t'); --i); + if (i < len - 1) { + ++i; + str[i] = _T('\0'); + len = i; + } + + for (i = 0; i < len && (str[i] == ' ' || str[i] == '\t'); ++i); + if (i > 0) + memmove(str, &str[i], (len - i + 1) * sizeof(wchar_t)); + + return str; +} + +static void InvalidateAll(HWND hwnd) +{ + InvalidateRect(GetDlgItem(hwnd, IDC_CALLS), NULL, FALSE); + for (int i = 0; i < _countof(dialCtrls); ++i) + InvalidateRect(GetDlgItem(hwnd, dialCtrls[i]), NULL, FALSE); + InvalidateRect(hwnd, NULL, FALSE); + + if (frame_id != -1) + CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)frame_id, (LPARAM)(FU_FMREDRAW)); +} + +static void ShowHideDialpad(HWND hwnd) +{ + SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + + if (!CanCallNumber()) { + for (int i = 0; i < _countof(dialCtrls); ++i) + ShowWindow(GetDlgItem(hwnd, dialCtrls[i]), SW_HIDE); + } + else { + int i; + for (i = 0; i < 3; ++i) + ShowWindow(GetDlgItem(hwnd, dialCtrls[i]), SW_SHOW); + + bool showDialpad = (SendMessage(GetDlgItem(hwnd, IDC_DIALPAD), BM_GETCHECK, 0, 0) == BST_CHECKED); + + for (i = 3; i < _countof(dialCtrls); ++i) + ShowWindow(GetDlgItem(hwnd, dialCtrls[i]), showDialpad ? SW_SHOW : SW_HIDE); + + VoiceCall *talking = NULL; + bool ringing = false; + bool calling = false; + for (i = 0; i < calls.getCount(); i++) { + VoiceCall *call = &calls[i]; + if (call->state == VOICE_STATE_TALKING) + talking = call; + else if (call->state == VOICE_STATE_CALLING) + calling = true; + else if (call->state == VOICE_STATE_RINGING) + ringing = true; + } + + wchar_t number[1024]; + GetDlgItemText(hwnd, IDC_NUMBER, number, _countof(number)); + lstrtrim(number); + + if (ringing && number[0] != 0) { + SetWindowText(GetDlgItem(hwnd, IDC_NUMBER), _T("")); + number[0] = 0; + } + + if (ringing || calling) { + for (i = 0; i < _countof(dialCtrls); ++i) + EnableWindow(GetDlgItem(hwnd, dialCtrls[i]), FALSE); + } + else if (talking) { + if (!showDialpad || !talking->CanSendDTMF()) { + for (i = 0; i < _countof(dialCtrls); ++i) + EnableWindow(GetDlgItem(hwnd, dialCtrls[i]), FALSE); + + EnableWindow(GetDlgItem(hwnd, IDC_DIALPAD), TRUE); + } + else { + for (i = 0; i < _countof(dialCtrls); ++i) + EnableWindow(GetDlgItem(hwnd, dialCtrls[i]), TRUE); + + EnableWindow(GetDlgItem(hwnd, IDC_NUMBER), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_CALL), FALSE); + } + } + else { + for (i = 0; i < _countof(dialCtrls); ++i) + EnableWindow(GetDlgItem(hwnd, dialCtrls[i]), TRUE); + + EnableWindow(GetDlgItem(hwnd, IDC_CALL), CanCall(number)); + } + } + + SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); + + InvalidateAll(hwnd); +} + +static int sttCompareProvidesByDescription(const VoiceProvider *p1, const VoiceProvider *p2) +{ + return lstrcmp(p2->description, p1->description); +} + +static void DrawIconLib(HDC hDC, const RECT &rc, int iconId) +{ + HICON hIcon = g_plugin.getIcon(iconId); + if (hIcon == NULL) + return; + + DrawIconEx(hDC, rc.left, (rc.top + rc.bottom - ICON_SIZE) / 2, hIcon, ICON_SIZE, ICON_SIZE, 0, NULL, DI_NORMAL); + IcoLib_ReleaseIcon(hIcon); +} + +static LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + RECT rc; + + switch (msg) { + case WM_CREATE: + case WM_INITDIALOG: + SendDlgItemMessage(hwnd, IDC_DIALPAD, BUTTONSETASFLATBTN, TRUE, 0); + SendDlgItemMessage(hwnd, IDC_DIALPAD, BUTTONSETASPUSHBTN, TRUE, 0); + SendDlgItemMessageA(hwnd, IDC_DIALPAD, BUTTONADDTOOLTIP, (LPARAM)Translate("Show dialpad"), 0); + SendDlgItemMessage(hwnd, IDC_DIALPAD, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon("vc_dialpad", TRUE)); + + SendDlgItemMessage(hwnd, IDC_CALL, BUTTONSETASFLATBTN, TRUE, 0); + SendDlgItemMessageA(hwnd, IDC_CALL, BUTTONADDTOOLTIP, (LPARAM)Translate("Make call"), 0); + SendDlgItemMessage(hwnd, IDC_CALL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon("vca_call", TRUE)); + + PostMessage(hwnd, WMU_RESIZE_FRAME, 0, 1); + break; + + case WM_SIZE: + SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + GetClientRect(hwnd, &rc); + { + int width = rc.right - rc.left; + int height = rc.bottom - rc.top; + + if (CanCallNumber()) { + bool showDialpad = (SendMessage(GetDlgItem(hwnd, IDC_DIALPAD), BM_GETCHECK, 0, 0) == BST_CHECKED); + + GetWindowRect(hwnd, &rc); + + RECT first = { 0 }, last = { 0 }; + GetWindowRect(GetDlgItem(hwnd, IDC_1), &first); + GetWindowRect(GetDlgItem(hwnd, IDC_SHARP), &last); + + int dialpad_height = last.bottom - first.top; + int dialpad_width = last.right - first.left; + + + int call_height = 23; + int call_width = 25; + int top = height - call_height - 1; + + if (showDialpad) + top -= dialpad_height + 1; + + MoveWindow(GetDlgItem(hwnd, IDC_DIALPAD), 1, top, call_width - 2, call_height, FALSE); + MoveWindow(GetDlgItem(hwnd, IDC_NUMBER), call_width, top, width - 2 * call_width, call_height, FALSE); + MoveWindow(GetDlgItem(hwnd, IDC_CALL), width - call_width, top, call_width, call_height + 1, FALSE); + + int dialpad_top = top + call_height + 1; + int dialpad_left = ((rc.right - rc.left) - dialpad_width) / 2; + int deltaX = dialpad_left - first.left; + int deltaY = dialpad_top - first.top; + for (int i = 3; i < _countof(dialCtrls); ++i) { + GetWindowRect(GetDlgItem(hwnd, dialCtrls[i]), &rc); + MoveWindow(GetDlgItem(hwnd, dialCtrls[i]), rc.left + deltaX, rc.top + deltaY, rc.right - rc.left, rc.bottom - rc.top, FALSE); + } + + height -= call_height + 2; + if (showDialpad) + height -= dialpad_height + 1; + } + + if (height <= 2) { + ShowWindow(GetDlgItem(hwnd, IDC_CALLS), SW_HIDE); + } + else { + MoveWindow(GetDlgItem(hwnd, IDC_CALLS), 1, 1, width - 2, height - 2, FALSE); + ShowWindow(GetDlgItem(hwnd, IDC_CALLS), SW_SHOW); + } + } + SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); + InvalidateAll(hwnd); + break; + + case WMU_REFRESH: + { + HWND list = GetDlgItem(hwnd, IDC_CALLS); + + SendMessage(list, WM_SETREDRAW, FALSE, 0); + SendMessage(list, LB_RESETCONTENT, 0, 0); + for (int i = 0; i < calls.getCount(); i++) { + VoiceCall *call = &calls[i]; + + wchar_t text[512]; + mir_snwprintf(text, _countof(text), _T("%d %s"), call->state, call->displayName); + + int pos = SendMessage(list, LB_ADDSTRING, 0, (LPARAM)text); + if (pos == LB_ERR) + // TODO Show error + continue; + + SendMessage(list, LB_SETITEMDATA, pos, (LPARAM)call); + } + SendMessage(list, WM_SETREDRAW, TRUE, 0); + } + __fallthrough; + + case WMU_RESIZE_FRAME: + ShowHideDialpad(hwnd); + + if (lParam) + SendMessage(hwnd, WM_SIZE, 0, 0); + + if (opts.resize_frame) { + if (calls.getCount() == 0 && !CanCallNumber()) { + ShowFrame(frame_id, hwnd, SW_HIDE); + } + else { + ResizeFrame(frame_id, hwnd); + ShowFrame(frame_id, hwnd, SW_SHOW); + } + } + + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_CALL: + { + wchar_t number[1024]; + GetDlgItemText(hwnd, IDC_NUMBER, number, _countof(number)); + lstrtrim(number); + + LIST<VoiceProvider> candidates(10, &sttCompareProvidesByDescription); + + for (int i = 0; i < modules.getCount(); i++) { + if (!modules[i].CanCall(number)) + continue; + + candidates.insert(&modules[i]); + } + + if (candidates.getCount() < 1) + break; + + int selected; + if (candidates.getCount() == 1) { + selected = 0; + } + else { + HMENU menu = CreatePopupMenu(); + + for (int i = 0; i < candidates.getCount(); ++i) { + wchar_t text[1024]; + mir_snwprintf(text, _countof(text), TranslateT("Call with %s"), candidates[i]->description); + + MENUITEMINFO mii = { 0 }; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_ID | MIIM_TYPE; + mii.fType = MFT_STRING; + mii.dwTypeData = text; + mii.cch = lstrlen(text); + mii.wID = i + 1; + + // TODO: Add icon to menu + + InsertMenuItem(menu, 0, TRUE, &mii); + } + + GetWindowRect(GetDlgItem(hwnd, IDC_CALL), &rc); + + POINT p; + p.x = rc.right; + p.y = rc.bottom + 1; + + selected = TrackPopupMenu(menu, TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_RIGHTALIGN, + p.x, p.y, 0, hwnd, NULL); + + DestroyMenu(menu); + + if (selected == 0) + break; + + selected--; + } + + candidates[selected]->Call(NULL, number); + break; + } + + case IDC_NUMBER: + if (HIWORD(wParam) == EN_CHANGE) + ShowHideDialpad(hwnd); + break; + + case IDC_DIALPAD: + ShowHideDialpad(hwnd); + SendMessage(hwnd, WMU_RESIZE_FRAME, 0, 0); + break; + + case IDC_1: + case IDC_2: + case IDC_3: + case IDC_4: + case IDC_5: + case IDC_6: + case IDC_7: + case IDC_8: + case IDC_9: + case IDC_AST: + case IDC_0: + case IDC_SHARP: + wchar_t text[2]; + switch (LOWORD(wParam)) { + case IDC_1: text[0] = _T('1'); break; + case IDC_2: text[0] = _T('2'); break; + case IDC_3: text[0] = _T('3'); break; + case IDC_4: text[0] = _T('4'); break; + case IDC_5: text[0] = _T('5'); break; + case IDC_6: text[0] = _T('6'); break; + case IDC_7: text[0] = _T('7'); break; + case IDC_8: text[0] = _T('8'); break; + case IDC_9: text[0] = _T('9'); break; + case IDC_AST: text[0] = _T('*'); break; + case IDC_0: text[0] = _T('0'); break; + case IDC_SHARP: text[0] = _T('#'); break; + } + text[1] = 0; + + Skin_PlaySound("voice_dialpad"); + { + VoiceCall *call = GetTalkingCall(); + if (call == NULL) { + SendMessage(GetDlgItem(hwnd, IDC_NUMBER), EM_REPLACESEL, TRUE, (LPARAM)text); + } + else { + wchar_t tmp[1024]; + + GetWindowText(GetDlgItem(hwnd, IDC_NUMBER), tmp, _countof(tmp)); + + tmp[_countof(tmp) - 2] = 0; + lstrcat(tmp, text); + + SetWindowText(GetDlgItem(hwnd, IDC_NUMBER), tmp); + + call->SendDTMF(text[0]); + } + } + break; + + case IDC_CALLS: + if (HIWORD(wParam) == LBN_SELCHANGE) { + HWND list = GetDlgItem(hwnd, IDC_CALLS); + + int pos = SendMessage(list, LB_GETCURSEL, 0, 0); + if (pos == LB_ERR) + break; + + POINT p; + GetCursorPos(&p); + ScreenToClient(list, &p); + + int ret = SendMessage(list, LB_ITEMFROMPOINT, 0, MAKELONG(p.x, p.y)); + if (HIWORD(ret)) + break; + if (pos != LOWORD(ret)) + break; + + SendMessage(list, LB_GETITEMRECT, pos, (LPARAM)&rc); + int x = rc.right - p.x; + + int action; + if (x >= H_SPACE && x <= ICON_SIZE + H_SPACE) + action = 2; + else if (x >= ICON_SIZE + 2 * H_SPACE && x <= 2 * (ICON_SIZE + H_SPACE)) + action = 1; + else + break; + + VoiceCall *call = (VoiceCall *)SendMessage(list, LB_GETITEMDATA, pos, 0); + switch (call->state) { + case VOICE_STATE_TALKING: + if (action == 1) + call->Hold(); + else + call->Drop(); + break; + + case VOICE_STATE_RINGING: + case VOICE_STATE_ON_HOLD: + if (action == 1) + Answer(call); + else + call->Drop(); + break; + + case VOICE_STATE_CALLING: + if (action == 2) + call->Drop(); + break; + } + } + } + break; + + case WM_CONTEXTMENU: + { + HWND list = GetDlgItem(hwnd, IDC_CALLS); + if ((HANDLE)wParam != list) + break; + + POINT p; + p.x = LOWORD(lParam); + p.y = HIWORD(lParam); + ScreenToClient(list, &p); + + int pos = SendMessage(list, LB_ITEMFROMPOINT, 0, MAKELONG(p.x, p.y)); + if (HIWORD(pos)) + break; + pos = LOWORD(pos); + + if (pos >= calls.getCount()) + break; + + if (IsFinalState(calls[pos].state)) + break; + + // Just to get things strait + SendMessage(list, LB_SETCURSEL, pos, 0); + + HMENU menu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_MENUS)); + HMENU submenu = GetSubMenu(menu, 0); + TranslateMenu(submenu); + + switch (calls[pos].state) { + case VOICE_STATE_CALLING: + DeleteMenu(menu, ID_FRAMEPOPUP_ANSWERCALL, MF_BYCOMMAND); + DeleteMenu(menu, ID_FRAMEPOPUP_HOLDCALL, MF_BYCOMMAND); + break; + + case VOICE_STATE_TALKING: + DeleteMenu(menu, ID_FRAMEPOPUP_ANSWERCALL, MF_BYCOMMAND); + if (!calls[pos].module->CanHold()) + DeleteMenu(menu, ID_FRAMEPOPUP_HOLDCALL, MF_BYCOMMAND); + break; + } + + p.x = LOWORD(lParam); + p.y = HIWORD(lParam); + int ret = TrackPopupMenu(submenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL); + DestroyMenu(menu); + + switch (ret) { + case ID_FRAMEPOPUP_DROPCALL: + calls[pos].Drop(); + break; + + case ID_FRAMEPOPUP_ANSWERCALL: + Answer(&calls[pos]); + break; + + case ID_FRAMEPOPUP_HOLDCALL: + calls[pos].Hold(); + break; + } + break; + } + + case WM_MEASUREITEM: + { + LPMEASUREITEMSTRUCT mis = (LPMEASUREITEMSTRUCT)lParam; + if (mis->CtlID != IDC_CALLS) + break; + + mis->itemHeight = GetMaxLineHeight(); + } + return TRUE; + + case WM_CTLCOLORLISTBOX: + return (LRESULT)bk_brush; + + case WM_DRAWITEM: + { + DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; + if (dis->CtlID != IDC_CALLS || dis->itemID == -1) + break; + + VoiceCall *call = (VoiceCall *)dis->itemData; + if (call == NULL) + break; + + rc = dis->rcItem; + + FillRect(dis->hDC, &rc, bk_brush); + + rc.left += H_SPACE; + rc.right -= H_SPACE; + rc.bottom--; + + int old_bk_mode = SetBkMode(dis->hDC, TRANSPARENT); + + // Draw status + DrawIconLib(dis->hDC, rc, IDI_TALKING + call->state); + + if (call->secure) + DrawIconLib(dis->hDC, rc, IDI_SECURE); + + // Draw voice provider icon + rc.left += ICON_SIZE + H_SPACE; + + HICON hIcon = call->module->GetIcon(); + if (hIcon != NULL) { + DrawIconEx(dis->hDC, rc.left, (rc.top + rc.bottom - ICON_SIZE) / 2, hIcon, ICON_SIZE, ICON_SIZE, 0, NULL, DI_NORMAL); + call->module->ReleaseIcon(hIcon); + } + + // Draw contact + rc.left += ICON_SIZE + H_SPACE; + + int numIcons = 0; + switch (call->state) { + case VOICE_STATE_CALLING: + numIcons = 1; + break; + + case VOICE_STATE_TALKING: + if (call->module->CanHold()) + numIcons = 2; + else + numIcons = 1; + break; + + case VOICE_STATE_RINGING: + case VOICE_STATE_ON_HOLD: + numIcons = 2; + break; + } + + rc.right -= numIcons * (ICON_SIZE + H_SPACE); + + HFONT old_font = (HFONT)SelectObject(dis->hDC, fonts[call->state]); + COLORREF old_color = SetTextColor(dis->hDC, font_colors[call->state]); + + DrawText(dis->hDC, call->displayName, -1, &rc, DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS | DT_VCENTER); + + SelectObject(dis->hDC, old_font); + SetTextColor(dis->hDC, old_color); + + // Draw action icons + rc = dis->rcItem; + rc.right -= H_SPACE; + rc.bottom--; + + switch (call->state) { + case VOICE_STATE_CALLING: + rc.left = rc.right - ICON_SIZE; + DrawIconLib(dis->hDC, rc, IDI_ACTION_DROP); + break; + + case VOICE_STATE_TALKING: + rc.left = rc.right - ICON_SIZE; + DrawIconLib(dis->hDC, rc, IDI_ACTION_DROP); + + if (call->module->CanHold()) { + rc.right -= ICON_SIZE + H_SPACE; + rc.left = rc.right - ICON_SIZE; + DrawIconLib(dis->hDC, rc, IDI_ACTION_HOLD); + } + break; + + case VOICE_STATE_RINGING: + case VOICE_STATE_ON_HOLD: + rc.left = rc.right - ICON_SIZE; + DrawIconLib(dis->hDC, rc, IDI_ACTION_DROP); + + rc.right -= ICON_SIZE + H_SPACE; + rc.left = rc.right - ICON_SIZE; + DrawIconLib(dis->hDC, rc, IDI_ACTION_ANSWER); + break; + } + + SetBkMode(dis->hDC, old_bk_mode); + return TRUE; + } + + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} |