/* * Copyright 2009 Mark Benjamin * * This file is part of NetSurf, http://www.netsurf-browser.org/ * * NetSurf 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; version 2 of the License. * * NetSurf 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 . */ #include #include #define _WIN32_IE (0x0501) #include #include "desktop/browser.h" #include "desktop/history_core.h" #include "desktop/plotters.h" #include "utils/utils.h" #include "utils/log.h" #include "utils/messages.h" #include "windows/localhistory.h" #include "windows/gui.h" #include "windows/plot.h" #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif struct nsws_localhistory { HWND hwnd; /**< the window handle */ int width; /**< the width of the memory history */ int height; /**< the height of the memory history */ int guiwidth; /**< the width of the history window */ int guiheight; /**< the height of the history window */ int vscroll; /**< the vertical scroll location */ int hscroll; /**< the horizontal scroll location */ }; static struct nsws_localhistory localhistory; LRESULT CALLBACK nsws_localhistory_event_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); static void nsws_localhistory_scroll_check(struct gui_window *w); static void nsws_localhistory_clear(struct gui_window *w); void nsws_localhistory_init(struct gui_window *w) { LOG(("gui window %p", w)); static const char localhistorywindowclassname[] = "nsws_localhistory_window"; WNDCLASSEX we; HWND mainhwnd = gui_window_main_window(w); INITCOMMONCONTROLSEX icc; HICON hIcon = nsws_window_get_ico(true); HICON hIconS = nsws_window_get_ico(false); struct browser_window *bw = gui_window_browser_window(w); int margin = 50; RECT r; localhistory.width = 0; localhistory.height = 0; current_gui = NULL; current_hwnd = NULL; doublebuffering = false; if ((bw != NULL) && (bw->history != NULL)) history_size(bw->history, &(localhistory.width), &(localhistory.height)); GetWindowRect(mainhwnd, &r); SetWindowPos(mainhwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); localhistory.guiwidth = MIN(r.right - r.left - margin, localhistory.width + margin); localhistory.guiheight = MIN(r.bottom - r.top - margin, localhistory.height + margin); icc.dwSize = sizeof(icc); icc.dwICC = ICC_BAR_CLASSES | ICC_WIN95_CLASSES; #if WINVER > 0x0501 icc.dwICC |= ICC_STANDARD_CLASSES; #endif InitCommonControlsEx(&icc); we.cbSize = sizeof(WNDCLASSEX); we.style = 0; we.lpfnWndProc = nsws_localhistory_event_callback; we.cbClsExtra = 0; we.cbWndExtra = 0; we.hInstance = hinstance; we.hIcon = (hIcon == NULL) ? LoadIcon(NULL, IDI_APPLICATION) : hIcon; we.hCursor = LoadCursor(NULL, IDC_ARROW); we.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); we.lpszMenuName = NULL; we.lpszClassName = localhistorywindowclassname; we.hIconSm = (hIconS == NULL) ? LoadIcon(NULL, IDI_APPLICATION) : hIconS; RegisterClassEx(&we); LOG(("creating local history window for hInstance %p", hinstance)); localhistory.hwnd = CreateWindow(localhistorywindowclassname, "NetSurf History",WS_THICKFRAME | WS_HSCROLL | WS_VSCROLL | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CS_DBLCLKS, r.left + margin/2, r.top + margin/2, localhistory.guiwidth, localhistory.guiheight, NULL, NULL, hinstance, NULL); LOG(("gui_window %p width %d height %d hwnd %p", w, localhistory.guiwidth, localhistory.guiheight, localhistory.hwnd)); current_hwnd = localhistory.hwnd; ShowWindow(localhistory.hwnd, SW_SHOWNORMAL); UpdateWindow(localhistory.hwnd); gui_window_set_localhistory(w, &localhistory); nsws_localhistory_up(w); } LRESULT CALLBACK nsws_localhistory_event_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { bool match = false; struct gui_window *w = window_list; struct browser_window *bw = NULL; struct nsws_localhistory *local; while (w != NULL) { local = gui_window_localhistory(w); if ((local != NULL) && (local->hwnd == hwnd)) { match = true; break; } w = gui_window_iterate(w); } if (match) bw = gui_window_browser_window(w); switch(msg) { case WM_CREATE: nsws_localhistory_scroll_check(w); break; case WM_SIZE: localhistory.guiheight = HIWORD(lparam); localhistory.guiwidth = LOWORD(lparam); nsws_localhistory_scroll_check(w); current_gui = NULL; current_hwnd = hwnd; plot.rectangle(0, 0, localhistory.guiwidth, localhistory.guiheight, plot_style_fill_white); break; case WM_MOVE: { RECT r, rmain; if (w != NULL) { current_gui = w; current_hwnd = gui_window_main_window(w); GetWindowRect(hwnd, &r); GetWindowRect(current_hwnd, &rmain); gui_window_redraw(w, MIN(r.top - rmain.top , 0), MIN(r.left - rmain.left, 0), gui_window_height(w) - MIN(rmain.bottom - r.bottom, 0), gui_window_width(w) - MIN(rmain.right - r.right, 0)); current_gui = NULL; current_hwnd = hwnd; return DefWindowProc(hwnd, msg, wparam, lparam); } } case WM_LBUTTONUP: { int x,y; x = GET_X_LPARAM(lparam); y = GET_Y_LPARAM(lparam); if (bw == NULL) break; current_hwnd = gui_window_main_window(w); current_gui = w; if ((bw != NULL) && (history_click(bw, bw->history, x, y, false))) DestroyWindow(hwnd); else { current_hwnd = hwnd; current_gui = NULL; } } case WM_MOUSEMOVE: { int x,y; x = GET_X_LPARAM(lparam); y = GET_Y_LPARAM(lparam); /* if (bw != NULL) history_hover(bw->history, x, y, (void *)hwnd);*/ return DefWindowProc(hwnd, msg, wparam, lparam); break; } case WM_VSCROLL: { if ((w == NULL) || (bw == NULL)) break; SCROLLINFO si; int mem; si.cbSize = sizeof(si); si.fMask = SIF_ALL; GetScrollInfo(hwnd, SB_VERT, &si); mem = si.nPos; switch (LOWORD(wparam)) { case SB_TOP: si.nPos = si.nMin; break; case SB_BOTTOM: si.nPos = si.nMax; break; case SB_LINEUP: si.nPos -= 30; break; case SB_LINEDOWN: si.nPos += 30; break; case SB_PAGEUP: si.nPos -= localhistory.guiheight; break; case SB_PAGEDOWN: si.nPos += localhistory.guiheight; break; case SB_THUMBTRACK: si.nPos = si.nTrackPos; break; default: break; } si.nPos = MIN(si.nPos, localhistory.width); si.nPos = MAX(si.nPos, 0); si.fMask = SIF_POS; SetScrollInfo(hwnd, SB_VERT, &si, TRUE); GetScrollInfo(hwnd, SB_VERT, &si); if (si.nPos != mem) { current_gui = NULL; current_hwnd = hwnd; localhistory.vscroll += si.nPos - mem; plot.rectangle(0, 0, localhistory.guiwidth, localhistory.guiheight, plot_style_fill_white); history_redraw_rectangle(bw->history, localhistory.hscroll, localhistory.vscroll, localhistory.guiwidth + localhistory.hscroll, localhistory.guiheight + localhistory.vscroll, 0, 0); } break; } case WM_HSCROLL: { if ((w == NULL) || (bw == NULL)) break; SCROLLINFO si; int mem; si.cbSize = sizeof(si); si.fMask = SIF_ALL; GetScrollInfo(hwnd, SB_HORZ, &si); mem = si.nPos; switch (LOWORD(wparam)) { case SB_LINELEFT: si.nPos -= 30; break; case SB_LINERIGHT: si.nPos += 30; break; case SB_PAGELEFT: si.nPos -= localhistory.guiwidth; break; case SB_PAGERIGHT: si.nPos += localhistory.guiwidth; break; case SB_THUMBTRACK: si.nPos = si.nTrackPos; break; default: break; } si.nPos = MIN(si.nPos, localhistory.height); si.nPos = MAX(si.nPos, 0); si.fMask = SIF_POS; SetScrollInfo(hwnd, SB_HORZ, &si, TRUE); GetScrollInfo(hwnd, SB_HORZ, &si); if (si.nPos != mem) { current_gui = NULL; current_hwnd = hwnd; localhistory.hscroll += si.nPos - mem; if (bw == NULL) break; plot.rectangle(0, 0, localhistory.guiwidth, localhistory.guiheight, plot_style_fill_white); history_redraw_rectangle(bw->history, localhistory.hscroll, localhistory.vscroll, localhistory.guiwidth + localhistory.hscroll, localhistory.guiheight + localhistory.vscroll, 0, 0); } break; } case WM_PAINT: { current_gui = NULL; current_hwnd = hwnd; PAINTSTRUCT ps; BeginPaint(hwnd, &ps); if (bw != NULL) history_redraw_rectangle(bw->history, localhistory.hscroll, localhistory.vscroll, localhistory.hscroll + localhistory.guiwidth, localhistory.vscroll + localhistory.guiheight, 0, 0); EndPaint(hwnd, &ps); return DefWindowProc(hwnd, msg, wparam, lparam); break; } case WM_CLOSE: nsws_localhistory_clear(w); DestroyWindow(hwnd); break; case WM_DESTROY: nsws_localhistory_clear(w); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wparam, lparam); } return 0; } void nsws_localhistory_up(struct gui_window *w) { LOG(("gui window %p", w)); HDC hdc = GetDC(NULL); struct browser_window *bw = gui_window_browser_window(w); localhistory.vscroll = 0; localhistory.hscroll = 0; if (bw != NULL) history_redraw(bw->history); nsws_localhistory_scroll_check(w); ReleaseDC(localhistory.hwnd, hdc); } void nsws_localhistory_scroll_check(struct gui_window *w) { if (w == NULL) return; struct browser_window *bw = gui_window_browser_window(w); if ((bw == NULL) || (localhistory.hwnd == NULL)) return; history_size(bw->history, &(localhistory.width), &(localhistory.height)); SCROLLINFO si; si.cbSize = sizeof(si); si.fMask = SIF_ALL; si.nMin = 0; si.nMax = localhistory.height; si.nPage = localhistory.guiheight; si.nPos = 0; SetScrollInfo(localhistory.hwnd, SB_VERT, &si, TRUE); si.nMax = localhistory.width; si.nPage = localhistory.guiwidth; SetScrollInfo(localhistory.hwnd, SB_HORZ, &si, TRUE); if (localhistory.guiheight >= localhistory.height) localhistory.vscroll = 0; if (localhistory.guiwidth >= localhistory.width) localhistory.hscroll = 0; SendMessage(localhistory.hwnd, WM_PAINT, 0, 0); } /* void history_gui_set_pointer(gui_pointer_shape shape, void *p) { struct nsws_pointers *pointers = nsws_get_pointers(); if (pointers == NULL) return; switch(shape) { case GUI_POINTER_POINT: SetCursor(pointers->hand); break; default: SetCursor(pointers->arrow); break; } } */ void nsws_localhistory_close(struct gui_window *w) { struct nsws_localhistory *l = gui_window_localhistory(w); if (l != NULL) DestroyWindow(l->hwnd); } void nsws_localhistory_clear(struct gui_window *w) { if (w != NULL) gui_window_set_localhistory(w, NULL); }