oleview: Mimick native treeview display of enumerations.
[wine] / programs / oleview / pane.c
1 /*
2  * OleView (pane.c)
3  *
4  * Copyright 2006 Piotr Caban
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 
19  */
20
21 #include "main.h"
22
23 int GetSplitPos(HWND hWnd)
24 {
25     PANE *pane = (PANE *)GetMenu(hWnd);
26
27     if(pane->pos < pane->size/2+1) pane->pos = pane->size/2+1;
28
29     return (pane->width>pane->pos+pane->size/2+1 ?
30             pane->pos : pane->width-pane->size/2-1);
31 }
32
33 void DrawSplitMoving(HWND hWnd, int x)
34 {
35     RECT rt;
36     HDC hdc = GetDC(hWnd);
37     PANE *pane = (PANE *)GetMenu(hWnd);
38
39     GetClientRect(hWnd, &rt);
40
41     if(pane->last!=-1)
42     {
43         rt.left = pane->last-pane->size/2;
44         rt.right = pane->last+pane->size/2;
45         InvertRect(hdc, &rt);
46     }
47
48     pane->pos = x>MAX_WINDOW_WIDTH ? -1 : x;
49     x = GetSplitPos(hWnd);
50
51     pane->pos = x;
52     rt.left = x-pane->size/2;
53     rt.right = x+pane->size/2;
54     pane->last = x;
55     InvertRect(hdc, &rt);
56
57     ReleaseDC(hWnd, hdc);
58 }
59
60 LRESULT CALLBACK PaneProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
61 {
62     POINT pt;
63     PANE *pane = (PANE*)GetMenu(hWnd);
64
65     switch(uMsg)
66     {
67         case WM_SETCURSOR:
68             GetCursorPos(&pt);
69             ScreenToClient(hWnd, &pt);
70
71             if(pt.x >= GetSplitPos(hWnd)-pane->size/2 &&
72                     pt.x <= GetSplitPos(hWnd)+pane->size/2)
73                 SetCursor(LoadCursor(0, IDC_SIZEWE));
74             break;
75         case WM_LBUTTONDOWN:
76             if((short)LOWORD(lParam) >= GetSplitPos(hWnd)-pane->size/2 &&
77                (short)LOWORD(lParam) <= GetSplitPos(hWnd)+pane->size/2)
78             {
79                 pane->last = -1;
80                 DrawSplitMoving(hWnd, (short)LOWORD(lParam));
81                 SetCapture(hWnd);
82             }
83             break;
84         case WM_LBUTTONUP:
85             if(GetCapture() == hWnd)
86             {
87                 pane->last = -1;
88                 DrawSplitMoving(hWnd, (short)LOWORD(lParam));
89
90                 MoveWindow(pane->left, 0, 0,
91                         GetSplitPos(hWnd)-pane->size/2, pane->height, TRUE);
92                 MoveWindow(pane->right, GetSplitPos(hWnd)+pane->size/2, 0,
93                         pane->width-GetSplitPos(hWnd)-pane->size/2, pane->height, TRUE);
94
95                 ReleaseCapture();
96             }
97             break;
98         case WM_MOUSEMOVE:
99             if(GetCapture() == hWnd)
100                 DrawSplitMoving(hWnd, (short)LOWORD(lParam));
101             break;
102         case WM_NOTIFY:
103             if((int)wParam != TYPELIB_TREE) break;
104             switch(((LPNMHDR)lParam)->code)
105             {
106                 case TVN_SELCHANGED:
107                     UpdateData(((NMTREEVIEW *)lParam)->itemNew.hItem);
108                     break;
109             }
110             break;
111         case WM_SIZE:
112             if(wParam == SIZE_MINIMIZED) break;
113             pane->width = LOWORD(lParam);
114             pane->height = HIWORD(lParam);
115
116             MoveWindow(pane->left, 0, 0,
117                     GetSplitPos(hWnd)-pane->size/2, HIWORD(lParam), TRUE);
118             MoveWindow(pane->right, GetSplitPos(hWnd)+pane->size/2, 0,
119                     LOWORD(lParam)-GetSplitPos(hWnd)-pane->size/2,
120                     HIWORD(lParam), TRUE);
121             break;
122         case WM_DESTROY:
123             HeapFree(GetProcessHeap(), 0, pane);
124             break;
125         default:
126             return DefWindowProc(hWnd, uMsg, wParam, lParam);
127     }
128     return 0;
129 }
130
131 BOOL PaneRegisterClass(void)
132 {
133     WNDCLASS wcc;
134     const WCHAR wszPaneClass[] = { 'P','A','N','E','\0' };
135
136     memset(&wcc, 0, sizeof(WNDCLASS));
137     wcc.lpfnWndProc = PaneProc;
138     wcc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
139     wcc.lpszClassName = wszPaneClass;
140
141     if(!RegisterClass(&wcc))
142         return FALSE;
143     return TRUE;
144 }
145
146 BOOL CreatePanedWindow(HWND hWnd, HWND *hWndCreated, HINSTANCE hInst)
147 {
148     const WCHAR wszPaneClass[] = { 'P','A','N','E','\0' };
149     PANE *pane;
150
151     pane = HeapAlloc(GetProcessHeap(), 0, sizeof(PANE));
152     *hWndCreated = CreateWindow(wszPaneClass, NULL, WS_CHILD|WS_VISIBLE,
153             CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,    hWnd, (HMENU)pane, hInst, NULL);
154     if(!hWndCreated) return FALSE;
155
156     pane->left = NULL;
157     pane->right = NULL;
158     pane->pos = 300;
159     pane->size = 5;
160     
161     return TRUE;
162 }
163
164 void SetLeft(HWND hParent, HWND hWnd)
165 {
166     PANE *pane = (PANE *)GetMenu(hParent);
167     pane->left = hWnd;
168 }
169
170 void SetRight(HWND hParent, HWND hWnd)
171 {
172     PANE *pane = (PANE *)GetMenu(hParent);
173     pane->right = hWnd;
174 }