diff options
author | George Hazan <ghazan@miranda.im> | 2021-05-29 21:56:06 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2021-05-29 21:56:06 +0300 |
commit | 80042a770a94fbb2dc56d81fd889a6d8b22a5ff1 (patch) | |
tree | 6d8c476090ccf4bd742687796400695e2aeed6f3 /protocols/Weather/src | |
parent | a2692125ca412d116857438d44306ce91e3f3dce (diff) |
fixes #2886 (Weather: display weather as extra-icon instead of status)
Diffstat (limited to 'protocols/Weather/src')
-rw-r--r-- | protocols/Weather/src/stdafx.h | 61 | ||||
-rw-r--r-- | protocols/Weather/src/weather.cpp | 6 | ||||
-rw-r--r-- | protocols/Weather/src/weather_contacts.cpp | 2 | ||||
-rw-r--r-- | protocols/Weather/src/weather_data.cpp | 4 | ||||
-rw-r--r-- | protocols/Weather/src/weather_opt.cpp | 2 | ||||
-rw-r--r-- | protocols/Weather/src/weather_popup.cpp | 4 | ||||
-rw-r--r-- | protocols/Weather/src/weather_svcs.cpp | 97 | ||||
-rw-r--r-- | protocols/Weather/src/weather_update.cpp | 7 | ||||
-rw-r--r-- | protocols/Weather/src/weather_userinfo.cpp | 4 |
9 files changed, 133 insertions, 54 deletions
diff --git a/protocols/Weather/src/stdafx.h b/protocols/Weather/src/stdafx.h index 5b105d19ca..a734e91a14 100644 --- a/protocols/Weather/src/stdafx.h +++ b/protocols/Weather/src/stdafx.h @@ -34,26 +34,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <malloc.h> #include <newpluginapi.h> +#include <m_acc.h> +#include <m_avatars.h> +#include <m_button.h> +#include <m_clc.h> +#include <m_cluiframes.h> #include <m_contacts.h> -#include <m_icolib.h> -#include <m_options.h> -#include <m_langpack.h> -#include <m_skin.h> #include <m_database.h> -#include <m_history.h> -#include <m_protosvc.h> -#include <m_userinfo.h> -#include <m_netlib.h> -#include <m_ignore.h> #include <m_findadd.h> -#include <m_button.h> -#include <m_avatars.h> -#include <m_clc.h> #include <m_fontservice.h> -#include <m_skin_eng.h> -#include <m_cluiframes.h> +#include <m_history.h> +#include <m_icolib.h> +#include <m_ignore.h> +#include <m_langpack.h> +#include <m_netlib.h> +#include <m_options.h> #include <m_popup.h> -#include <m_acc.h> +#include <m_protosvc.h> +#include <m_skin.h> +#include <m_skin_eng.h> +#include <m_userinfo.h> +#include <m_xstatus.h> #include <m_tipper.h> #include <m_weather.h> @@ -71,16 +72,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define WEATHERCONDITION "Current" // weather conditions -#define SUNNY ID_STATUS_ONLINE -#define NA ID_STATUS_OFFLINE -#define PCLOUDY ID_STATUS_AWAY -#define CLOUDY ID_STATUS_NA -#define RAIN ID_STATUS_OCCUPIED -#define FOG ID_STATUS_DND -#define SNOW ID_STATUS_FREECHAT -#define LIGHT ID_STATUS_INVISIBLE -#define THUNDER ID_STATUS_INVISIBLE -#define UNAVAIL 40081 +enum EWeatherCondition +{ + SUNNY, + NA, + PCLOUDY, + CLOUDY, + RAIN, + RSHOWER, + FOG, + SNOW, + SSHOWER, + LIGHT, + MAX_COND +}; // status #define NOSTATUSDATA 1 @@ -386,6 +391,10 @@ void GetPressure(wchar_t *tempchar, wchar_t *unit, wchar_t *str); void GetDist(wchar_t *tempchar, wchar_t *unit, wchar_t *str); void GetElev(wchar_t *tempchar, wchar_t *unit, wchar_t *str); +void ClearStatusIcons(); +int MapCondToStatus(MCONTACT hContact); +HICON GetStatusIcon(MCONTACT hContact); + WORD GetIcon(const wchar_t* cond, WIDATA *Data); void CaseConv(wchar_t *str); void TrimString(char *str); @@ -505,6 +514,8 @@ struct CMPlugin : public PLUGIN<CMPlugin> { CMPlugin(); + HINSTANCE hIconsDll; + int Load() override; int Unload() override; }; diff --git a/protocols/Weather/src/weather.cpp b/protocols/Weather/src/weather.cpp index 8d1f3e6a1e..bb2a7cbbd0 100644 --- a/protocols/Weather/src/weather.cpp +++ b/protocols/Weather/src/weather.cpp @@ -158,6 +158,9 @@ int CMPlugin::Load() { g_plugin.registerIcon(MODULENAME, iconList, MODULENAME); + // load dll with icons + hIconsDll = LoadLibraryW(VARSW(L"%miranda_path%\\Icons\\proto_Weather.dll")); + // load options and set defaults LoadOptions(); @@ -210,6 +213,9 @@ int CMPlugin::Load() int CMPlugin::Unload() { + if (hIconsDll) + FreeModule(hIconsDll); + DestroyMwin(); DestroyWindow(hPopupWindow); diff --git a/protocols/Weather/src/weather_contacts.cpp b/protocols/Weather/src/weather_contacts.cpp index 19f1b03d80..559238410b 100644 --- a/protocols/Weather/src/weather_contacts.cpp +++ b/protocols/Weather/src/weather_contacts.cpp @@ -353,7 +353,7 @@ static INT_PTR CALLBACK DlgProcChange(HWND hwndDlg, UINT msg, WPARAM wParam, LPA GetDlgItemText(hwndDlg, IDC_MURL, str, _countof(str)); g_plugin.setWString(hContact, "MapURL", str); g_plugin.setWord(hContact, "Status", ID_STATUS_OFFLINE); - g_plugin.setWord(hContact, "StatusIcon", ID_STATUS_OFFLINE); + g_plugin.setWord(hContact, "StatusIcon", -1); AvatarDownloaded(hContact); g_plugin.setWString(hContact, "About", str2); g_plugin.setByte(hContact, "History", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_Internal)); diff --git a/protocols/Weather/src/weather_data.cpp b/protocols/Weather/src/weather_data.cpp index 57bc17830e..bb34a3112a 100644 --- a/protocols/Weather/src/weather_data.cpp +++ b/protocols/Weather/src/weather_data.cpp @@ -79,8 +79,6 @@ WEATHERINFO LoadWeatherInfo(MCONTACT hContact) wcsncpy(winfo.humid, NODATA, _countof(winfo.humid) - 1); if (db_get_wstatic(hContact, WEATHERCONDITION, "Feel", winfo.feel, _countof(winfo.feel))) wcsncpy(winfo.feel, NODATA, _countof(winfo.feel) - 1); - - winfo.status = g_plugin.getWord(hContact, "StatusIcon", ID_STATUS_OFFLINE); return winfo; } @@ -114,7 +112,7 @@ void EraseAllInfo() // loop through all contacts for (auto &hContact : Contacts(MODULENAME)) { g_plugin.setWord(hContact, "Status", ID_STATUS_OFFLINE); - g_plugin.setWord(hContact, "StatusIcon", ID_STATUS_OFFLINE); + g_plugin.setWord(hContact, "StatusIcon", -1); db_unset(hContact, "CList", "MyHandle"); // clear all data if (g_plugin.getWString(hContact, "Nick", &dbv)) { diff --git a/protocols/Weather/src/weather_opt.cpp b/protocols/Weather/src/weather_opt.cpp index f560ae3e49..19173b430b 100644 --- a/protocols/Weather/src/weather_opt.cpp +++ b/protocols/Weather/src/weather_opt.cpp @@ -262,7 +262,7 @@ static INT_PTR CALLBACK OptionsProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM l // change the status for weather protocol if (IsDlgButtonChecked(hdlg, IDC_PROTOCOND) && opt.DefStn != NULL) { old_status = status; - status = g_plugin.getWord(opt.DefStn, "StatusIcon", NOSTATUSDATA); + status = MapCondToStatus(opt.DefStn); ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status); } diff --git a/protocols/Weather/src/weather_popup.cpp b/protocols/Weather/src/weather_popup.cpp index aca5559e6b..1ad47de9fd 100644 --- a/protocols/Weather/src/weather_popup.cpp +++ b/protocols/Weather/src/weather_popup.cpp @@ -112,7 +112,7 @@ static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPA return TRUE; case UM_FREEPLUGINDATA: - IcoLib_ReleaseIcon((HICON)PUGetPluginData(hWnd)); + DestroyIcon((HICON)PUGetPluginData(hWnd)); return FALSE; } @@ -131,7 +131,7 @@ int WeatherPopup(WPARAM hContact, LPARAM lParam) // setup the popup POPUPDATAW ppd; ppd.lchContact = hContact; - ppd.PluginData = ppd.lchIcon = Skin_LoadProtoIcon(MODULENAME, winfo.status); + ppd.PluginData = ppd.lchIcon = GetStatusIcon(winfo.hContact); GetDisplay(&winfo, GetTextValue('P'), ppd.lpwzContactName); GetDisplay(&winfo, GetTextValue('p'), ppd.lpwzText); ppd.PluginWindowProc = PopupDlgProc; diff --git a/protocols/Weather/src/weather_svcs.cpp b/protocols/Weather/src/weather_svcs.cpp index e6987a40c7..7fa2b40000 100644 --- a/protocols/Weather/src/weather_svcs.cpp +++ b/protocols/Weather/src/weather_svcs.cpp @@ -115,37 +115,52 @@ INT_PTR WeatherGetInfo(WPARAM, LPARAM lParam) return 0; } +///////////////////////////////////////////////////////////////////////////////////////// // avatars -static const wchar_t *statusStr[] = { L"Light", L"Fog", L"Snow", L"Rain", L"PCloudy", L"Cloudy", L"Sunny", L"NA" }; -static const WORD statusValue[] = { LIGHT, FOG, SNOW, RAIN, PCLOUDY, CLOUDY, SUNNY, NA }; -INT_PTR WeatherGetAvatarInfo(WPARAM, LPARAM lParam) +// these data shall go in the same order as EWeatherCondition members +struct { - wchar_t szSearchPath[MAX_PATH], *chop; - unsigned i; - PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam; + const wchar_t *pwszName; + int iconIdx, status, clistIconId; +} +static statusIcons[MAX_COND] = +{ + { L"Sunny", 104, ID_STATUS_ONLINE }, + { L"NA", 105, ID_STATUS_OFFLINE }, + { L"PCloudy", 128, ID_STATUS_AWAY }, + { L"Cloudy", 131, ID_STATUS_NA }, + { L"Rain", 159, ID_STATUS_OCCUPIED }, + { L"RShower", 129, ID_STATUS_OCCUPIED }, + { L"Fog", 1003, ID_STATUS_DND }, + { L"Snow", 158, ID_STATUS_FREECHAT }, + { L"SShower", 1002, ID_STATUS_FREECHAT }, + { L"Light", 130, ID_STATUS_INVISIBLE }, +}; +INT_PTR WeatherGetAvatarInfo(WPARAM, LPARAM lParam) +{ + wchar_t szSearchPath[MAX_PATH]; GetModuleFileName(GetModuleHandle(nullptr), szSearchPath, _countof(szSearchPath)); - chop = wcsrchr(szSearchPath, '\\'); - - if (chop) *chop = '\0'; - else szSearchPath[0] = 0; - int iStatus = g_plugin.getWord(pai->hContact, "StatusIcon"); - for (i = 0; i < _countof(statusValue); i++) - if (statusValue[i] == iStatus) - break; + wchar_t *chop = wcsrchr(szSearchPath, '\\'); + if (chop) + *chop = '\0'; + else + szSearchPath[0] = 0; - if (i >= _countof(statusValue)) + PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam; + int iCond = g_plugin.getWord(pai->hContact, "StatusIcon", -1); + if (iCond < 0 || iCond >= MAX_COND) return GAIR_NOAVATAR; pai->format = PA_FORMAT_PNG; - mir_snwprintf(pai->filename, L"%s\\Plugins\\Weather\\%s.png", szSearchPath, statusStr[i]); + mir_snwprintf(pai->filename, L"%s\\Plugins\\Weather\\%s.png", szSearchPath, statusIcons[iCond].pwszName); if (_waccess(pai->filename, 4) == 0) return GAIR_SUCCESS; pai->format = PA_FORMAT_GIF; - mir_snwprintf(pai->filename, L"%s\\Plugins\\Weather\\%s.gif", szSearchPath, statusStr[i]); + mir_snwprintf(pai->filename, L"%s\\Plugins\\Weather\\%s.gif", szSearchPath, statusIcons[iCond].pwszName); if (_waccess(pai->filename, 4) == 0) return GAIR_SUCCESS; @@ -184,6 +199,53 @@ static INT_PTR WeatherGetAwayMsg(WPARAM, LPARAM lParam) return 1; } +///////////////////////////////////////////////////////////////////////////////////////// +// advanced status icons + +void ClearStatusIcons() +{ + for (auto &it : statusIcons) + it.clistIconId = 0; +} + +int MapCondToStatus(MCONTACT hContact) +{ + int iCond = g_plugin.getWord(hContact, "StatusIcon", -1); + if (iCond < 0 || iCond >= MAX_COND) + return ID_STATUS_OFFLINE; + + return statusIcons[iCond].status; +} + +HICON GetStatusIcon(MCONTACT hContact) +{ + int iCond = g_plugin.getWord(hContact, "StatusIcon", -1); + if (iCond < 0 || iCond >= MAX_COND) + return nullptr; + + auto &pIcon = statusIcons[iCond]; + if (pIcon.clistIconId == 0) + pIcon.clistIconId = ImageList_AddIcon(Clist_GetImageList(), LoadIconA(g_plugin.hIconsDll, MAKEINTRESOURCEA(pIcon.iconIdx))); + + return ImageList_GetIcon(Clist_GetImageList(), pIcon.clistIconId, ILD_NORMAL); +} + +static INT_PTR WeatherAdvancedStatusIcon(WPARAM hContact, LPARAM) +{ + if (!hContact || !g_plugin.hIconsDll) + return -1; + + int iCond = g_plugin.getWord(hContact, "StatusIcon", -1); + if (iCond < 0 || iCond >= MAX_COND) + return -1; + + auto &pIcon = statusIcons[iCond]; + if (pIcon.clistIconId == 0) + pIcon.clistIconId = ImageList_AddIcon(Clist_GetImageList(), LoadIconA(g_plugin.hIconsDll, MAKEINTRESOURCEA(pIcon.iconIdx))); + + return MAKELONG(0, pIcon.clistIconId); +} + //============ PROTOCOL INITIALIZATION ============ // protocol services void InitServices(void) @@ -201,6 +263,7 @@ void InitServices(void) CreateProtoServiceFunction(MODULENAME, PSS_GETAWAYMSG, WeatherGetAwayMsg); CreateProtoServiceFunction(MODULENAME, PS_CREATEADVSEARCHUI, WeatherCreateAdvancedSearchUI); CreateProtoServiceFunction(MODULENAME, PS_SEARCHBYADVANCED, WeatherAdvancedSearch); + CreateProtoServiceFunction(MODULENAME, PS_GETADVANCEDSTATUSICON, WeatherAdvancedStatusIcon); CreateProtoServiceFunction(MODULENAME, MS_WEATHER_GETDISPLAY, GetDisplaySvcFunc); } diff --git a/protocols/Weather/src/weather_update.cpp b/protocols/Weather/src/weather_update.cpp index 54fe72a5cb..652ac3239a 100644 --- a/protocols/Weather/src/weather_update.cpp +++ b/protocols/Weather/src/weather_update.cpp @@ -120,10 +120,11 @@ int UpdateWeather(MCONTACT hContact) g_plugin.setWString(hContact, "LastUpdate", winfo.update); // display condition on contact list - if (opt.DisCondIcon && winfo.status != ID_STATUS_OFFLINE) + int iStatus = MapCondToStatus(winfo.hContact); + if (opt.DisCondIcon && iStatus != ID_STATUS_OFFLINE) g_plugin.setWord(hContact, "Status", ID_STATUS_ONLINE); else - g_plugin.setWord(hContact, "Status", winfo.status); + g_plugin.setWord(hContact, "Status", iStatus); AvatarDownloaded(hContact); GetDisplay(&winfo, GetTextValue('C'), str2); @@ -150,7 +151,7 @@ int UpdateWeather(MCONTACT hContact) if (!mir_wstrcmp(winfo.id, opt.Default) && !opt.NoProtoCondition) { // save current condition for default station to be displayed after the update old_status = status; - status = winfo.status; + status = iStatus; // a workaround for a default station that currently have an n/a icon assigned if (status == ID_STATUS_OFFLINE) status = NOSTATUSDATA; ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status); diff --git a/protocols/Weather/src/weather_userinfo.cpp b/protocols/Weather/src/weather_userinfo.cpp index 2e8edd67c0..0f69dfa42c 100644 --- a/protocols/Weather/src/weather_userinfo.cpp +++ b/protocols/Weather/src/weather_userinfo.cpp @@ -131,7 +131,7 @@ static INT_PTR CALLBACK DlgProcMoreData(HWND hwndDlg, UINT msg, WPARAM wParam, L // set icons Window_FreeIcon_IcoLib(hwndDlg); - Window_SetProtoIcon_IcoLib(hwndDlg, MODULENAME, g_plugin.getWord(hContact, "StatusIcon", 0)); + Window_SetProtoIcon_IcoLib(hwndDlg, MODULENAME, MapCondToStatus(hContact)); RedrawWindow(GetDlgItem(hwndDlg, IDC_HEADERBAR), nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); break; @@ -253,7 +253,7 @@ static INT_PTR CALLBACK DlgProcUIPage(HWND hwndDlg, UINT msg, WPARAM wParam, LPA w = LoadWeatherInfo(lParam); SetDlgItemText(hwndDlg, IDC_INFO1, GetDisplay(&w, TranslateT("Current condition for %n"), str)); - SendDlgItemMessage(hwndDlg, IDC_INFOICON, STM_SETICON, (WPARAM)Skin_LoadProtoIcon(MODULENAME, g_plugin.getWord(hContact, "StatusIcon")), 0); + SendDlgItemMessage(hwndDlg, IDC_INFOICON, STM_SETICON, (WPARAM)Skin_LoadProtoIcon(MODULENAME, MapCondToStatus(hContact)), 0); { // bold and enlarge the current condition LOGFONT lf; |