summaryrefslogtreecommitdiff
path: root/protocols/Weather/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2021-05-29 21:56:06 +0300
committerGeorge Hazan <ghazan@miranda.im>2021-05-29 21:56:06 +0300
commit80042a770a94fbb2dc56d81fd889a6d8b22a5ff1 (patch)
tree6d8c476090ccf4bd742687796400695e2aeed6f3 /protocols/Weather/src
parenta2692125ca412d116857438d44306ce91e3f3dce (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.h61
-rw-r--r--protocols/Weather/src/weather.cpp6
-rw-r--r--protocols/Weather/src/weather_contacts.cpp2
-rw-r--r--protocols/Weather/src/weather_data.cpp4
-rw-r--r--protocols/Weather/src/weather_opt.cpp2
-rw-r--r--protocols/Weather/src/weather_popup.cpp4
-rw-r--r--protocols/Weather/src/weather_svcs.cpp97
-rw-r--r--protocols/Weather/src/weather_update.cpp7
-rw-r--r--protocols/Weather/src/weather_userinfo.cpp4
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;