OSDN Git Service

Implement GUI list view compiler for XML catalogue.
[mingw/mingw-get.git] / src / pkgview.cpp
1 /*
2  * pkgview.cpp
3  *
4  * $Id$
5  *
6  * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
7  * Copyright (C) 2012, MinGW.org Project
8  *
9  *
10  * Implementation of the layout controller for the main mingw-get
11  * application window.
12  *
13  *
14  * This is free software.  Permission is granted to copy, modify and
15  * redistribute this software, under the provisions of the GNU General
16  * Public License, Version 3, (or, at your option, any later version),
17  * as published by the Free Software Foundation; see the file COPYING
18  * for licensing details.
19  *
20  * Note, in particular, that this software is provided "as is", in the
21  * hope that it may prove useful, but WITHOUT WARRANTY OF ANY KIND; not
22  * even an implied WARRANTY OF MERCHANTABILITY, nor of FITNESS FOR ANY
23  * PARTICULAR PURPOSE.  Under no circumstances will the author, or the
24  * MinGW Project, accept liability for any damages, however caused,
25  * arising from the use of this software.
26  *
27  */
28 #include "guimain.h"
29 #include "dmh.h"
30
31 using WTK::GenericDialogue;
32 using WTK::HorizontalSashWindowMaker;
33 using WTK::VerticalSashWindowMaker;
34 using WTK::StringResource;
35
36 /* The main application window is divided into two
37  * horizontally adjustable sash panes; the following
38  * three constants specify the starting position for
39  * the sash bar, and the range over which it may be
40  * moved, as fractions of the width of the window,
41  * measured from its left hand side.
42  */
43 static const double HSASH_MIN_POS = 0.10;
44 static const double HSASH_INIT_POS = 0.20;
45 static const double HSASH_MAX_POS = 0.40;
46
47 /* The rightmost of these sash panes is further
48  * subdivided into two vertically adjustable panes;
49  * the following three constants similarly specify the
50  * initial position for the sash bar, and its range of
51  * adjustment, as fractions of the main window height,
52  * measured from its top edge.
53  */
54 static const double VSASH_MIN_POS = 0.25;
55 static const double VSASH_INIT_POS = 0.30;
56 static const double VSASH_MAX_POS = 0.60;
57
58 HWND AppWindowMaker::Create( const char *class_name, const char *caption )
59 {
60   /* A thin wrapper around the generic main window Create() function;
61    * it initialises the diagnostic message handler, and registers the
62    * requisite window class, before delegating creation of the main
63    * application window to the generic function.
64    */
65   dmh_init( DMH_SUBSYSTEM_GUI, class_name );
66   WTK::WindowClassMaker( AppInstance, ID_MAIN_WINDOW ).Register( class_name );
67   return WTK::MainWindowMaker::Create( class_name, caption );
68 }
69
70 long AppWindowMaker::OnCreate()
71 {
72   /* Handler for creation of the top-level application window;
73    * begin by initialising the sash window controls to support the
74    * desired three-pane sash window layout.
75    */
76   HorizontalSash = new HorizontalSashWindowMaker( ID_HORIZONTAL_SASH,
77       AppWindow, AppInstance, HSASH_MIN_POS, HSASH_INIT_POS, HSASH_MAX_POS
78     );
79   VerticalSash = new VerticalSashWindowMaker( ID_VERTICAL_SASH,
80       AppWindow, AppInstance, VSASH_MIN_POS, VSASH_INIT_POS, VSASH_MAX_POS
81     );
82
83   /* Assign the preferred font for use in the main window, falling
84    * back to the system default, if the choice is unavailable.
85    */
86   LOGFONT font_info;
87   HFONT font = DefaultFont;
88   GetObject( font, sizeof( LOGFONT ), &font_info );
89   strcpy( (char *)(&(font_info.lfFaceName)),
90       StringResource( AppInstance, ID_FONT_PREF )
91     );
92   if( (font = CreateFontIndirect( &font_info )) != NULL )
93   {
94     /* The preferred font choice is available; we may delete the
95      * object reference for the system default, then assign our
96      * preference in its place.
97      */
98     DeleteObject( DefaultFont );
99     DefaultFont = font;
100   }
101
102   /* Report that we've successfully handled the window set-up.
103    */
104   return EXIT_SUCCESS;
105 }
106
107 long AppWindowMaker::OnCommand( WPARAM cmd )
108 {
109   /* Handler for WM_COMMAND messages which are directed to the
110    * top level application window.
111    */
112   switch( cmd )
113   {
114     case IDM_HELP_ABOUT:
115       /*
116        * This request is initiated by selecting "About mingw-get"
117        * from the "Help" menu; we respond by displaying the "about"
118        * dialogue box.
119        */
120       GenericDialogue( AppInstance, AppWindow, IDD_HELP_ABOUT );
121       break;
122
123     case IDM_REPO_QUIT:
124       /*
125        * This request is initiated by selecting the "Quit" option
126        * from the "Repository" menu; we respond by sending a WM_QUIT
127        * message, to terminate the current application instance.
128        */
129       SendMessage( AppWindow, WM_CLOSE, 0, 0L );
130       break;
131   }
132   return EXIT_SUCCESS;
133 }
134
135 long AppWindowMaker::OnNotify( WPARAM client_id, LPARAM data )
136 {
137   /* Handler for notifications received from user controls; for now
138    * we simply quash any of these which we might receive.
139    */
140   return EXIT_SUCCESS;
141 }
142
143 long AppWindowMaker::OnSize( WPARAM mode, int width, int height )
144 {
145   /* Handler for WM_SIZE event, applied to main application window;
146    * we delegate to the LayoutController, to place, resize, and update
147    * the view for each child window pane, such that they fit within,
148    * and fill the main window's client area.
149    */
150   RECT ClientArea;
151   GetClientRect( AppWindow, &ClientArea );
152   EnumChildWindows( AppWindow, LayoutController, (LPARAM)(&ClientArea) );
153   return EXIT_SUCCESS;
154 }
155
156 int CALLBACK AppWindowMaker::LayoutController( HWND pane, LPARAM region )
157 {
158   /* The LayoutController provides a windows API callback hook, to
159    * service the WM_SIZE event; implemented as a static method...
160    */
161   HWND parent;
162   if( (parent = GetParent( pane )) != NULL )
163   {
164     /* ...it must retrieve an instance pointer to the C++ class
165      * object associated with the window to be laid out, then it
166      * may delegate the actual layout duty to the (non-static)
167      * LayoutEngine method associated with this object.
168      */
169     AppWindowMaker *p;
170     if( (p = GetAppWindow( parent )) != NULL )
171       return p->LayoutEngine( pane, region );
172   }
173   return TRUE;
174 }
175
176 int AppWindowMaker::LayoutEngine( HWND pane, LPARAM region )
177 {
178   /* Formal implementation for the LayoutController; this computes
179    * the positions and sizes for each of the panes and sash bars, to
180    * create a three pane layout similar to:
181    *
182    *         +----------+----------------------------+
183    *         |          |                            |
184    *         |   TREE   |       LIST VIEW PANE       |
185    *         |          |                            |
186    *         |   VIEW   +----------------------------+
187    *         |          |                            |
188    *         |   PANE   |   TABBED DATA-SHEET PANE   |
189    *         |          |                            |
190    *         |          |                            |
191    *         +----------+----------------------------+
192    */
193   long pane_id;
194
195   int pane_top = ((LPRECT)(region))->top;
196   int pane_left = ((LPRECT)(region))->left;
197   int pane_height = ((LPRECT)(region))->bottom - pane_top;
198   int pane_width = ((LPRECT)(region))->right - pane_left;
199
200   pane_top = pane_left = 0;
201   switch( pane_id = GetWindowLong( pane, GWL_ID ) )
202   {
203     /* Each of the panes and sashes is computed individually, in the
204      * following order:
205      */
206     case ID_PACKAGE_LISTVIEW:
207       /* Upper right hand pane; occupies the full width of the parent
208        * window which remains to the right of the tree view, (after an
209        * allowance for a small gap to accommodate the sash bar has been
210        * deducted); its upper edge is co-incident with the top of the
211        * parent, and its height is set to the fraction of the parent's
212        * height specified as...
213        */
214       pane_height = VerticalSash->Displacement( pane_height );
215       pane_left = HorizontalSash->Displacement( pane_width ) + SASH_BAR_THICKNESS;
216       pane_width -= pane_left;
217       break;
218
219     case ID_HORIZONTAL_SASH:
220       /* A slim window, placed to the right of the tree view pane, and
221        * occupying the full height of the parent window, representing the
222        * vertical sash bar, (which may be moved horizontally), and which
223        * separates the tree view pane from the list view and the tabbed
224        * data sheet panes.
225        */
226       pane_left = HorizontalSash->Displacement( pane_width ) - 1;
227       pane_width = 1 + SASH_BAR_THICKNESS;
228       break;
229
230     case ID_VERTICAL_SASH:
231       /* A slim window, placed below PANE TWO, and occupying the parent
232        * to the same width as PANE TWO and PANE THREE, representing the
233        * horizontal sash bar, (which may be moved vertically), which
234        * separates PANE TWO from PANE THREE.
235        */
236       pane_top = VerticalSash->Displacement( pane_height ) - 1;
237       pane_left = HorizontalSash->Displacement( pane_width ) + SASH_BAR_THICKNESS;
238       pane_height = 1 + SASH_BAR_THICKNESS; pane_width -= pane_left;
239       break;
240   }
241   /* Having computed the size and position for the pane or sash which
242    * is the target of the current call, move it into place within the
243    * parent window, and cause it to be displayed.
244    */
245   MoveWindow( pane, pane_left, pane_top, pane_width, pane_height, TRUE );
246   ShowWindow( pane, SW_SHOW );
247   return TRUE;
248 }
249
250 /* $RCSfile$: end of file */