6 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
7 * Copyright (C) 2012, 2013, MinGW.org Project
10 * Implementation of the layout controller for the main mingw-get
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.
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.
32 using WTK::StringResource;
33 using WTK::HorizontalSashWindowMaker;
34 using WTK::VerticalSashWindowMaker;
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.
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;
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.
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;
58 HWND AppWindowMaker::Create( const char *class_name, const char *caption )
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.
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 );
70 long AppWindowMaker::OnCreate()
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.
76 HorizontalSash = new HorizontalSashWindowMaker( ID_HORIZONTAL_SASH,
77 AppWindow, AppInstance, HSASH_MIN_POS, HSASH_INIT_POS, HSASH_MAX_POS
79 VerticalSash = new VerticalSashWindowMaker( ID_VERTICAL_SASH,
80 AppWindow, AppInstance, VSASH_MIN_POS, VSASH_INIT_POS, VSASH_MAX_POS
83 /* Assign the preferred font for use in the main window, falling
84 * back to the system default, if the choice is unavailable.
87 HFONT font = DefaultFont;
88 GetObject( font, sizeof( LOGFONT ), &font_info );
89 strcpy( (char *)(&(font_info.lfFaceName)),
90 StringResource( AppInstance, ID_FONT_PREF )
92 if( (font = CreateFontIndirect( &font_info )) != NULL )
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.
98 DeleteObject( DefaultFont );
102 /* Report that we've successfully handled the window set-up.
108 /* FIXME: this stub implementation has been superseded by an
109 * alternative implementation in pkgdata.cpp; eventually, this
110 * may itself be superseded, and may migrate elsewhere, perhaps
113 long AppWindowMaker::OnNotify( WPARAM client_id, LPARAM data )
115 /* Handler for notifications received from user controls; for now
116 * we simply quash any of these which we might receive.
122 long AppWindowMaker::OnSize( WPARAM mode, int width, int height )
124 /* Handler for WM_SIZE event, applied to main application window;
125 * we delegate to the LayoutController, to place, resize, and update
126 * the view for each child window pane, such that they fit within,
127 * and fill the main window's client area.
130 GetClientRect( AppWindow, &ClientArea );
131 EnumChildWindows( AppWindow, LayoutController, (LPARAM)(&ClientArea) );
135 int CALLBACK AppWindowMaker::LayoutController( HWND pane, LPARAM region )
137 /* The LayoutController provides a windows API callback hook, to
138 * service the WM_SIZE event; implemented as a static method...
141 if( (parent = GetParent( pane )) != NULL )
143 /* ...it must retrieve an instance pointer to the C++ class
144 * object associated with the window to be laid out, then it
145 * may delegate the actual layout duty to the (non-static)
146 * LayoutEngine method associated with this object.
149 if( (p = GetAppWindow( parent )) != NULL )
150 return p->LayoutEngine( pane, region );
155 int AppWindowMaker::LayoutEngine( HWND pane, LPARAM region )
157 /* Formal implementation for the LayoutController; this computes
158 * the positions and sizes for each of the panes and sash bars, to
159 * create a three pane layout similar to:
161 * +----------+----------------------------+
163 * | TREE | LIST VIEW PANE |
165 * | VIEW +----------------------------+
167 * | PANE | TABBED DATA-SHEET PANE |
170 * +----------+----------------------------+
174 int pane_top = ((LPRECT)(region))->top;
175 int pane_left = ((LPRECT)(region))->left;
176 int pane_height = ((LPRECT)(region))->bottom - pane_top;
177 int pane_width = ((LPRECT)(region))->right - pane_left;
179 pane_top = pane_left = 0;
180 switch( pane_id = GetWindowLong( pane, GWL_ID ) )
182 /* Each of the panes and sashes is computed individually, in the
185 case ID_PACKAGE_TREEVIEW:
186 /* Left hand pane; occupies the full height of the parent window,
187 * and shares its top-left co-ordinate position, with width set to
188 * the fraction of the parent's width specified as...
190 pane_width = HorizontalSash->Displacement( pane_width );
193 case ID_PACKAGE_LISTVIEW:
194 /* Upper right hand pane; occupies the full width of the parent
195 * window which remains to the right of the tree view, (after an
196 * allowance for a small gap to accommodate the sash bar has been
197 * deducted); its upper edge is co-incident with the top of the
198 * parent, and its height is set to the fraction of the parent's
199 * height specified as...
201 pane_height = VerticalSash->Displacement( pane_height );
202 pane_left = HorizontalSash->Displacement( pane_width ) + SASH_BAR_THICKNESS;
203 pane_width -= pane_left;
206 case ID_PACKAGE_TABPANE:
207 case ID_PACKAGE_TABCONTROL:
208 case ID_PACKAGE_DATASHEET:
209 /* Lower right hand pane; occupies the remaining area of the parent,
210 * to the right of the tree view pane, and below the list view, again
211 * with allowance for small gaps to the left and above, to accommodate
212 * the sash bars separating it from the adjacent panes.
214 pane_top = VerticalSash->Displacement( pane_height ) + SASH_BAR_THICKNESS;
215 pane_left = HorizontalSash->Displacement( pane_width ) + SASH_BAR_THICKNESS;
216 if( pane_id == ID_PACKAGE_TABCONTROL )
218 /* Shift the tab control window, and shrink it, so that it doesn't
219 * occlude the border surrounding the underlying tab pane window.
221 ++pane_left; ++pane_top; --pane_width; --pane_height;
223 else if( pane_id == ID_PACKAGE_DATASHEET )
225 /* Leave the data sheet window at the full width of the tab pane,
226 * but adjust its height and top edge position so that it appears
227 * below to tabs; (its own border will appear in place of the tab
228 * pane border, where they overlap.
231 frame.top = pane_top;
232 frame.left = pane_left;
233 frame.right = pane_left + pane_width;
234 frame.bottom = pane_top + pane_height;
235 TabCtrl_AdjustRect( PackageTabControl, FALSE, &frame );
236 pane_top = frame.top - 1;
238 /* Adjust height and width to fill the space below and to the right
239 * of the two sash bars.
241 pane_height -= pane_top; pane_width -= pane_left;
244 case ID_HORIZONTAL_SASH:
245 /* A slim window, placed to the right of the tree view pane, and
246 * occupying the full height of the parent window, representing the
247 * vertical sash bar, (which may be moved horizontally), and which
248 * separates the tree view pane from the list view and the tabbed
251 pane_left = HorizontalSash->Displacement( pane_width ) - 1;
252 pane_width = 1 + SASH_BAR_THICKNESS;
255 case ID_VERTICAL_SASH:
256 /* A slim window, placed below PANE TWO, and occupying the parent
257 * to the same width as PANE TWO and PANE THREE, representing the
258 * horizontal sash bar, (which may be moved vertically), which
259 * separates PANE TWO from PANE THREE.
261 pane_top = VerticalSash->Displacement( pane_height ) - 1;
262 pane_left = HorizontalSash->Displacement( pane_width ) + SASH_BAR_THICKNESS;
263 pane_height = 1 + SASH_BAR_THICKNESS; pane_width -= pane_left;
266 /* Having computed the size and position for the pane or sash which
267 * is the target of the current call, move it into place within the
268 * parent window, and cause it to be displayed.
270 MoveWindow( pane, pane_left, pane_top, pane_width, pane_height, TRUE );
271 ShowWindow( pane, SW_SHOW );
275 /* $RCSfile$: end of file */