/************************************************************************
MeOS - Orienteering Software
Copyright (C) 2009-2020 Melin Software HB
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 3 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, see .
Melin Software HB - software@melin.nu - www.melin.nu
Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
************************************************************************/
#include "stdafx.h"
#include "resource.h"
#include
#include "oEvent.h"
#include "xmlparser.h"
#include "gdioutput.h"
#include "commctrl.h"
#include "SportIdent.h"
#include "TabBase.h"
#include "TabCompetition.h"
#include "TabAuto.h"
#include "TabClass.h"
#include "TabCourse.h"
#include "TabControl.h"
#include "TabSI.h"
#include "TabList.h"
#include "TabTeam.h"
#include "TabSpeaker.h"
#include "TabMulti.h"
#include "TabRunner.h"
#include "TabClub.h"
#include "progress.h"
#include "inthashmap.h"
#include
#include "localizer.h"
#include "intkeymap.hpp"
#include "intkeymapimpl.hpp"
#include "download.h"
#include "meos_util.h"
#include "toolbar.h"
const wchar_t *szToolClass = L"MeOSToolClass";
LRESULT CALLBACK ToolProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
#define BASE_ID 1013
const DWORD buttonStyles = BTNS_AUTOSIZE;
const int bitmapSize = 24;
Toolbar::Toolbar(gdioutput &gdi_par) : gdi(gdi_par)
{
hwndFloater = 0;
hwndToolbar = 0;
isactivating = false;
// Create the imagelist.
hImageListDef = ImageList_Create(bitmapSize, bitmapSize, ILC_COLOR24 | ILC_MASK, 1, 15);
//hImageListMeOS = ImageList_Create(bitmapSize, bitmapSize, ILC_COLOR16 | ILC_MASK, 1, 10);
hImageListMeOS = ImageList_LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(BMP_TEST),
bitmapSize, 17, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION);
}
Toolbar::~Toolbar()
{
ImageList_Destroy(hImageListDef);
ImageList_Destroy(hImageListMeOS);
}
void Toolbar::reset()
{
btn.clear();
tooltips.clear();
btn_id.clear();
toolbar_id.clear();
DestroyWindow(hwndToolbar);
hwndToolbar = 0;
}
void Toolbar::show() {
if (hwndFloater)
ShowWindow(hwndFloater, SW_NORMAL);
}
void Toolbar::hide() {
if (hwndFloater)
ShowWindow(hwndFloater, SW_HIDE);
}
void Toolbar::activate(bool active) {
if (!isactivating && isVisible()) {
isactivating = true;
//SendMessage(hwndFloater, WM_NCACTIVATE, active ? 1:0, 0);
DefWindowProc(hwndFloater, WM_NCACTIVATE, active ? 1:0, 0);
isactivating = false;
}
}
void Toolbar::addButton(const string &id, int imgList, int icon, const string &tooltip)
{
tooltips.push_back(lang.tl(tooltip));
TBBUTTON tbButton = { MAKELONG(icon, imgList), int(btn_id.size()) + BASE_ID, TBSTATE_ENABLED,
buttonStyles, {0}, 0, (INT_PTR)tooltips.back().c_str() };
btn.push_back(tbButton);
btn_id.push_back(id);
}
void Toolbar::processCommand(int id, int code)
{
size_t ix = id - BASE_ID;
if (ix < btn_id.size()) {
gdi.processToolbarMessage(btn_id[ix], table.get());
}
}
void registerToolbar(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)ToolProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = 0;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = szToolClass;
wcex.hIconSm = 0;
RegisterClassEx(&wcex);
}
void Toolbar::createToolbar(const string &id, const wstring &title)
{
if (id == toolbar_id) {
show();
return;
}
wstring t = lang.tl(title);
HWND hParent = gdi.getHWNDTarget();
RECT rc;
GetWindowRect(hParent, &rc);
if (hwndFloater == 0) {
hwndFloater = CreateWindowEx(WS_EX_TOOLWINDOW, szToolClass, t.c_str(),
WS_POPUP | WS_THICKFRAME | WS_CAPTION,
rc.right-300, rc.top+10, 600, 64, hParent, NULL, GetModuleHandle(0), NULL);
SetWindowLongPtr(hwndFloater, GWLP_USERDATA, LONG_PTR(this));
}
else {
SetWindowText(hwndFloater, t.c_str());
}
if (hwndToolbar != 0)
DestroyWindow(hwndToolbar);
// Create the toolbar.
hwndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
WS_CHILD | TBSTYLE_TOOLTIPS,
0, 0, 0, 0, hwndFloater, NULL, GetModuleHandle(0), NULL);
if (hwndToolbar == NULL)
return;
toolbar_id = id;
int ImageListID = 0;
SendMessage(hwndToolbar, CCM_SETVERSION, 5, 0);
// Set the image list.
SendMessage(hwndToolbar, TB_SETIMAGELIST, (WPARAM)ImageListID,
(LPARAM)hImageListDef);
// Load the button images.
SendMessage(hwndToolbar, TB_LOADIMAGES, (WPARAM)IDB_STD_LARGE_COLOR,
(LPARAM)HINST_COMMCTRL);
ImageListID = 1;
// Set the image list.
SendMessage(hwndToolbar, TB_SETIMAGELIST, (WPARAM)ImageListID,
(LPARAM)hImageListMeOS);
// Add buttons.
SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE,
(WPARAM)sizeof(TBBUTTON), 0);
TBBUTTON *bt_ptr = &btn.at(0);
SendMessage(hwndToolbar, TB_ADDBUTTONS, (WPARAM)btn.size(),
(LPARAM)bt_ptr);
SendMessage(hwndToolbar, TB_SETMAXTEXTROWS, 0, 0);
// Tell the toolbar to resize itself, and show it.
SendMessage(hwndToolbar, TB_AUTOSIZE, 0, 0);
DWORD bsize = SendMessage(hwndToolbar, TB_GETBUTTONSIZE, 0,0);
int bw = LOWORD(bsize);
int bh = HIWORD(bsize);
int tw = bw * btn.size();
// Resize floater
GetClientRect(hwndFloater, &rc);
int dx = rc.right - rc.left - tw;
int dy = rc.bottom - rc.top - bh - 5;
WINDOWPLACEMENT wpl;
wpl.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hwndFloater, &wpl);
wpl.rcNormalPosition.right -= dx;
wpl.rcNormalPosition.bottom -= dy;
HWND desktop = GetDesktopWindow();
GetClientRect(desktop, &rc);
dx = 0;
dy = 0;
if (wpl.rcNormalPosition.right > rc.right)
dx = wpl.rcNormalPosition.right - rc.right + 10;
else if (wpl.rcNormalPosition.left < 0)
dx = wpl.rcNormalPosition.left - 10;
if (wpl.rcNormalPosition.bottom > rc.bottom)
dy = wpl.rcNormalPosition.bottom - rc.bottom + 10;
else if (wpl.rcNormalPosition.top < 0)
dy = wpl.rcNormalPosition.top - 30;
if (dx != 0 || dy != 0) {
OffsetRect(&wpl.rcNormalPosition, -dx, -dy);
}
SetWindowPlacement(hwndFloater, &wpl);
SendMessage(hwndToolbar, TB_AUTOSIZE, 0, 0);
ShowWindow(hwndFloater, SW_SHOW);
ShowWindow(hwndToolbar, TRUE);
}
LRESULT CALLBACK ToolProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE:
break;
case WM_SIZE:
break;
case WM_WINDOWPOSCHANGED:
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_ACTIVATE:
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_NCACTIVATE: {
Toolbar *tb = (Toolbar *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (tb) {
//DefWindowProc(tb->gdi.getHWND(), message, wParam, lParam);
SendMessage(tb->gdi.getHWNDMain(), message, wParam, lParam);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
break;
case WM_COMMAND: {
Toolbar *tb = (Toolbar *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
int id = LOWORD(wParam);
int code = HIWORD(wParam);
if (tb) {
tb->processCommand(id, code);
}
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
HWND Toolbar::getFloater() const {
return hwndFloater;
}
bool Toolbar::isVisible() const {
if (!hwndFloater)
return false;
return IsWindowVisible(hwndFloater) != 0;
}