OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
bardescr.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1998 by Yura Bidus, All Rights Reserved
4//
5/// \file
6/// Implementation of class TBarDescr
7//----------------------------------------------------------------------------
8
9#include <owl/pch.h>
10
11#include <owl/resource.h>
12#include <owl/celarray.h>
13#include <owl/gadget.h>
14#include <owl/buttonga.h>
15#include <owl/gadgetwi.h>
16#include <owl/functor.h>
17#include <owl/bardescr.h>
18#include <owl/template.h>
19#include <owl/functor.h>
20#include <owl/glyphbtn.h>
21
22namespace owl {
23
25/// \cond
26struct __TBarDescrGdNode {
27 __TBarDescrGdNode(TGadget* gd, bool ug): Gadget(gd),UseGlyph(ug){}
29 TGadget* Gadget;
30 bool UseGlyph;
31};
32//
33__TBarDescrGdNode::~__TBarDescrGdNode()
34{
35 delete Gadget;
36}
37//
38class TBarDescrGdArray: public TIPtrArray<__TBarDescrGdNode*>{ // internal usage
39 public:
40 TBarDescrGdArray(int count):TIPtrArray<__TBarDescrGdNode*>(count){}
41};
42/// \endcond
43
44//
45//
46//
47static TGadget* CreateGadget(int index, int id, bool& usecell)
48{
49 usecell = false;
50 if(id == 0)
51 return new TSeparatorGadget;
52 usecell = true;
53 return new TButtonGadget(index,
54 id,
56 false,
58}
59
60// -----------------------------------------------------------------------------
61////////////////////////////////////////////////////////////////////////////////
62// class TBarDescr
63// ~~~~~ ~~~~~~~~~
64
65/// \class TBarDescr
66/// TBarDescr describes your control bar and its functional groups. TBarDescr
67/// provides an easy way for you to group gadgets on your control bar and to add new
68/// groups to an existing control bar. It uses a resource ID to identify the bar
69/// resource and an array of count values to indicate the number of gadgets in each
70/// group on the control bar.
71///
72/// The TGroup enum enumerates the six basic functional groups on a control bar:
73/// File, Edit, Container, Object, Window, and Help. TBarDescr's constructors simply
74/// initialize the members based on the arguments passed.
75///
76/// TFrameWindow::MergeBar actually performs the real work of merging the gadgets
77/// groups.
78///
79/// For a single document application (SDI), the gadgets are merged as soon as you
80/// load the application. See the sample program, bardescm, for an example of MDI
81/// control bar merging, and bardescr, for an example of SDI control bar merging.
82///
83/// One technique you can use to create a control bar involves invoking the
84/// TBarDescr constructor and passing the number of group counts for each gadgets
85/// selection.
86///
87/// For example, if your original gadgets groups included these items:
88/// \image html bm78.BMP
89/// you might use the following group counts:
90/// <TABLE>
91/// <TR><TD>Group</TD> <TD>Count</TD> <TD>Menu</TD></TR>
92/// <TR><TD>FileGroup</TD> <TD>1</TD> <TD>File</TD></TR>
93/// <TR><TD>EditGroup</TD> <TD>2</TD> <TD>Edit Search</TD></TR>
94/// <TR><TD>ContainerGroup</TD> <TD>1</TD> <TD>View</TD></TR>
95/// <TR><TD>ObjectGroup</TD> <TD>3</TD> <TD>Page Paragraph Word</TD></TR>
96/// <TR><TD>WindowGroup</TD> <TD>1</TD> <TD>Window</TD></TR>
97/// <TR><TD>HelpGroup</TD> <TD>1</TD> <TD>Help</TD></TR>
98/// </TABLE>
99/// You would then invoke the constructor this way:
100/// \code
101/// TBarDescr(IDM_MYMENU, 1, 2, 1, 3, 1, 1)
102/// \endcode
103/// You can build the previous control bar by merging two control bars. When a zero
104/// is passed in the TBarDescr's constructor, the group indicated by the zero is
105/// filled in by the child control bar's group, if an item is specified, when the
106/// bar merging occurs. Set your application's parent frame control bar by
107/// specifying these gadget groups:
108/// \image html bm79.BMP
109/// and passing these group counts in the constructor:
110/// \code
111/// TBarDescr(IDM_FRAME, 1, 0, 1, 0, 1, 1)
112/// \endcode
113/// Set the word-processor child control bar this way:
114/// \image html bm80.BMP
115/// and pass these values in the constructor:
116/// \code
117/// TBarDescr(IDM_WPROC, 0, 2, 0, 3, 0, 1)
118/// \endcode
119/// If no child is active, only the frame menu will be active. When the word
120/// processor's child window becomes active, the child control bar is merged with
121/// the frame bar. Every group that is 0 in the child control bar leaves the
122/// parent's group intact. The previous example interleaves every group except for
123/// the last group, the Help group, in which the child replaces the frame bar.
124///
125/// By convention, the even groups (File, Container, Window) usually belong to the
126/// outside frame or container, and the odd groups (Edit, Object, Help) belong to
127/// the child or contained group.
128///
129/// If a -1 is used in a group count, the merger eliminates the parent's group
130/// without replacing it. For example, another child control bar, such as a
131/// calculator, could be added to your application in this way:
132/// \image html bm81.BMP
133/// \code
134/// TBarDescr(IDM_WCALC, 0, 1, -1, 1, 0, 1)
135/// \endcode
136/// In this example, the child's control group contributes nothing from the
137/// container group, and the parent's container group is removed. This produces a
138/// merged bar (with the View control bar selection eliminated as a result of the
139/// -1) that looks like this:
140/// \image html bm82.BMP
141///
142/// If you want to merge the following parent gadget groups
143/// \image html bm79.BMP
144/// with these paint window gadget groups,
145/// \image html bm83.BMP
146/// pass the following group counts in the constructor:
147/// \code
148/// TBarDescr(IDM_WPAINT, 0, 1, 0, 2, 0, 1)
149/// \endcode
150/// This produces the following merged control bar:
151/// \image html bm84.BMP
152///
153/// The simplest way to add groups to a control bar involves defining the control
154/// groups and adding separators in a resource file. Insert the term BUTTON -1
155/// between each gadgets group and an additional separator if one of the gadgets
156/// groups is not present. For example, the resource file for Step 13 of the
157/// ObjectWindows tutorial defines the following gadgets groups and separators:
158/// \code
159/// IDB_DVMDI TOOLBAR 20, 20
160/// {
161/// BUTTON CM_FILENEW
162/// BUTTON CM_FILEOPEN
163/// BUTTON CM_FILESAVE
164/// BUTTON CM_FILESAVEAS
165/// SEPARATOR
166/// BUTTON -1
167/// BUTTON -1
168/// BUTTON CM_ABOUT
169/// BUTTON -1
170/// }
171/// IDB_DVMDI BITMAP "dvmain.bmp"
172/// \endcode
173/// You can see the separators by loading Step13.rc into Resource Workshop.
174///
175/// Step13.cpp uses these commands from the resource file to set the main window and
176/// its menu, passing IDM_MDICMNDS as the parameter to SetMenuDescr function, as
177/// follows:
178/// \code
179/// frame->SetBarDescr(new TBarDescr(IDB_DVMDI));
180/// \endcode
181/// It produces the following menu groups:
182/// \image html bm85.BMP
183///
184/// TBarDescr's functions let you perform control bar merging similar to menu
185/// merging. That is, you can merge control bars from a MDI frame window, with
186/// those of an the MDI child window. When child is selected, the control bars of
187/// the child window merges with that of the frame window.
188
189
190
191
192
193/// Default constructor for a TBarDescr object. No menu resources or groups are
194/// specified. Constructs an empty control bar. For internal use only.
196:
197 BarRes(0),
198 CelArray(0),
199 Id(0),
200 Module(0)
201{
202 GadgetFunctor = new TGadgetFunctor;
203 SetBuilder(TGadget_FUNCTOR(CreateGadget));
204 Gadgets = new TBarDescrGdArray(5);
205 for (int i = 0; i < NumGroups; i++)
206 GroupCount[i] = 0;
207
208}
209// -----------------------------------------------------------------------------
210/// Not implemented. Forbidden and protected contructor.
212:
213 Id(bar.Id),
215{
216 GadgetFunctor = new TGadgetFunctor;
217 SetBuilder(TGadget_FUNCTOR(CreateGadget));
218
219 Gadgets = new TBarDescrGdArray(5);
220 BarRes = new TToolbarRes(*bar.BarRes);
221
222 CHECK(BarRes->IsOK());
223 { // map colors
224 TBtnBitmap bitmap(BarRes->GetBitmap(),
227 }
228 CelArray = new TCelArray(&BarRes->GetBitmap(),
229 BarRes->GetCount(),
230 TSize(BarRes->GetWidth(), BarRes->GetHeight()),
231 TPoint(0, 0), // offset
232 BarRes->GetBitmap().Height()/BarRes->GetHeight());
234}
235// -----------------------------------------------------------------------------
236/// Creates a control bar descriptor from the controlbar resource specified in the
237/// id parameter. Calls the function ExtractGroups to extract the group counts based
238/// on the separator items in the control bar.
240:
241 Id(barResId),
242 Module(module),
243 BarRes(0),
244 CelArray(0)
245{
246 GadgetFunctor = new TGadgetFunctor;
247 SetBuilder(TGadget_FUNCTOR(CreateGadget));
248
249 Gadgets = new TBarDescrGdArray(5);
250
251 SetBitmap(barResId, module);
252
254}
255// -----------------------------------------------------------------------------
256/// Constructs a control bar descriptor from the resource indicated by id. Places
257/// the gadgets in groups according the values of the fg, eg, cg, of, wg, and hg
258/// parameters. The fg, eg, cg, of, wg, and hg parameters represent the functional
259/// groups identified by the TGroup enum. Calls the function ExtractGroups to
260/// extract the group counts based on the separator items in the menu bar.
261TBarDescr::TBarDescr(TResId id, int fg, int eg, int cg, int og, int wg,
262 int hg, TModule* module)
263:
264 Id(id),
265 Module(module),
266 BarRes(0),
267 CelArray(0)
268{
269 GadgetFunctor = new TGadgetFunctor;
270 SetBuilder(TGadget_FUNCTOR(CreateGadget));
271
272 Gadgets = new TBarDescrGdArray(5);
273
274 SetBitmap(id, module);
275
276 if (!ExtractGroups()) {
277 GroupCount[FileGroup] = fg;
278 GroupCount[EditGroup] = eg;
279 GroupCount[ContainerGroup] = cg;
280 GroupCount[ObjectGroup] = og;
281 GroupCount[WindowGroup] = wg;
282 GroupCount[HelpGroup] = hg;
283 }
284}
285// -----------------------------------------------------------------------------
286/// Destroys the TBarDescr object.
288{
289 delete Gadgets;
290 delete BarRes;
291 delete CelArray;
292 delete GadgetFunctor;
293}
294//
296{
297 *GadgetFunctor = functor;
298}
299// -----------------------------------------------------------------------------
300/// Set new bitmap for use in gadgets.
301bool
303{
304 delete BarRes;
305 BarRes = 0;
306 Module = module;
307
308 // Load toolbar resource
309 // NOTE: Don't let TToolbarRes own bitmap, we'll give it to TCelArray
310 // instead.
311 BarRes = new TToolbarRes(module ? module->GetHandle() : 0,
312 newResId,
314
315 if (BarRes->IsOK()){
316 delete CelArray;
317 CelArray = 0;
318 { // map colors
319 TBtnBitmap bitmap(BarRes->GetBitmap(),
322 }
323 CelArray = new TCelArray(&BarRes->GetBitmap(), BarRes->GetCount(),
324 TSize(BarRes->GetWidth(), BarRes->GetHeight()),
325 TPoint(0, 0), // offset
326 BarRes->GetBitmap().Height()/BarRes->GetHeight());
327 return true;
328 }
329 return false;
330}
331//
332static void CreateGadgets(TBarDescrGdArray* array, const TGadgetFunctor& builder,
334{
335 for (int i=0,j=0; i < barRes->GetCount(); i++) {
336 if(barRes->GetIds()[i] == uint16(-1))
337 continue;
338
339 bool usecell;
340 TGadget* gd = (builder)(j, barRes->GetIds()[i], usecell);
341 array->Add(new __TBarDescrGdNode(gd,usecell));
342
343 if(usecell)
344 j++;
345 }
346}
347// -----------------------------------------------------------------------------
348/// Inserts into destWindow's gadgets.
349bool
351{
352 // Build toolbar from resource and from descriptor string
353 if (BarRes && BarRes->IsOK()) {
354 if(!Gadgets->Size())
355 CreateGadgets(Gadgets, *GetBuilder(), BarRes);
356
357 int numRows = BarRes->GetBitmap().Height()/BarRes->GetHeight();
358 TCelArray* cellArray = new TCelArray(TSize(BarRes->GetWidth(), BarRes->GetHeight()),
359 0, BarRes->GetCount(), 5, numRows);
360 cellArray->RemoveAll();
361 destWindow.SetCelArray(cellArray);
362 for (int i=0,j=0; i < (int)Gadgets->Size(); i++){
363 destWindow.Insert(*(*Gadgets)[i]->Gadget);
364 if((*Gadgets)[i]->UseGlyph)
365 cellArray->Add(*CelArray, j++);
366 }
367 return true;
368 }
369 return false;
370}
371// -----------------------------------------------------------------------------
372/// Merges this gadgets and sourceBarDescr gadgets and inserts them into
373/// destWindow's gadgets.
374bool
376{
377 if (BarRes && BarRes->IsOK()){
378
380
381 if(!srcBarDescr.Gadgets->Size())
382 CreateGadgets(srcBarDescr.Gadgets, *((TBarDescr&)srcBarDescr).GetBuilder(),
383 srcBarDescr.BarRes);
384
385 TCelArray& cellArray = destWindow.GetCelArray();
386
387 cellArray.RemoveAll();
388
389 int gdIndex1 = 0;
390 int gdIndex2 = 0;
391 int cellIndex = 0;
392 int cellIndex1 = 0;
393 int cellIndex2 = 0;
394
395 for (int g = 0; g < NumGroups; g++){
396 if (srcBarDescr.GroupCount[g] > 0){
397 for (int i=0; i < srcBarDescr.GroupCount[g]; i++){
399 destWindow.Insert(*node->Gadget);
400 if(node->UseGlyph){
401 cellArray.Add(*srcBarDescr.CelArray, cellIndex1);
403 if(bg)
404 bg->SetGlyphIndex(cellIndex);
405 cellIndex++;
406 cellIndex1++;
407 }
408 gdIndex1++;
409 }
410 }
411 else if (srcBarDescr.GroupCount[g] == 0 && GroupCount[g] > 0) {
412 for (int i=0; i < GroupCount[g]; i++){
413 __TBarDescrGdNode* node = (*Gadgets)[gdIndex2];
414 destWindow.Insert(*node->Gadget);
415 if(node->UseGlyph){
416 cellArray.Add(*CelArray, cellIndex2);
418 if(bg)
419 bg->SetGlyphIndex(cellIndex);
420 cellIndex++;
421 cellIndex2++;
422 }
423 gdIndex2++;
424 }
425 }
426 }
427 destWindow.Invalidate();
428 destWindow.LayoutSession();
429 destWindow.UpdateWindow();
430 return true;
431 }
432 return false;
433}
434// -----------------------------------------------------------------------------
435/// Removes the gadgets in destWindow and then inserts these gadgets.
436bool
438{
439 if (BarRes && BarRes->IsOK()){
440
442
443 TCelArray& cellArray = destWindow.GetCelArray();
444 cellArray.RemoveAll();
445
446 int gdIndex = 0;
447 int cellIndex = 0;
448 for (int g=0; g < NumGroups; g++){
449 if(GroupCount[g]!= 0){
450 for (int i=0; i < GroupCount[g]; i++){
451 __TBarDescrGdNode* node = (*Gadgets)[gdIndex];
452 destWindow.Insert(*node->Gadget);
453 if(node->UseGlyph){
454 cellArray.Add(*CelArray, cellIndex);
456 if(bg)
457 bg->SetGlyphIndex(cellIndex);
458 cellIndex++;
459 }
460 gdIndex++;
461 }
462 }
463 }
464 destWindow.Invalidate();
465 destWindow.LayoutSession();
466 destWindow.UpdateWindow();
467 return true;
468 }
469 return false;
470}
471// -----------------------------------------------------------------------------
472/// Removes all gadgets from destWindow.
473bool
475{
476 TGadget* gadget = destWindow.FirstGadget();
477 if(gadget && gadget->GetId() == IDG_FLATHANDLE)
478 gadget = gadget->NextGadget();
479 while (gadget) {
480 TGadget* tmp = gadget;
481 gadget = gadget->NextGadget();
482 destWindow.Remove(*tmp);
483 }
484 return true;
485}
486//
487/// Scan bar looking for separators that signify group divisions
488/// return whether we found any at all
489//
490/// Extracts the group counts from the loaded menu bar by counting the number of
491/// menus between separator items. After the group counts are extracted, the
492/// separators are removed. Returns true if separators (groups) were found; false
493/// otherwise.
494bool
496{
497 if (!BarRes)
498 return false; // no bar to extract from...
499
500 // walk BarRes & remove separators, setting up count as we go.
501 //
502 int itemCount = BarRes->GetCount();
503 int g = 0;
504 int count = 0;
505 for (int i = 0; i < itemCount;i++) {
506 if (BarRes->GetIds()[i] == uint16(-1)){
507 if (g < NumGroups)
508 GroupCount[g++] = count;
509 count = 0;
510 }
511 else
512 count++;
513 }
514 // Leave if no separators were found
515 //
516 bool retval = true;
517 if (!g)
518 retval = false;
519
520 // Get trailing group
521 //
522 if (g < NumGroups)
523 GroupCount[g++] = count;
524
525 // Finish zeroing groups
526 //
527 for (; g < NumGroups; g++)
528 GroupCount[g] = 0;
529 return retval;
530}
531
532//
533//
534//
535#if OWL_PERSISTENT_STREAMS
536//
537/// Extract the menu descriptor from the persistent stream.
538//
541{
542 is >> b.Id;
543 is >> b.Module;
544 b.BarRes = new TToolbarRes((b.Module ? b.Module->GetHandle() : 0), b.Id, NoAutoDelete);
545 { // map colors
546 TBtnBitmap bitmap(b.BarRes->GetBitmap(), TColor::LtGray, NoAutoDelete);
547 }
548 int numRows = b.BarRes->GetBitmap().Height()/b.BarRes->GetHeight();
549 b.CelArray = new TCelArray(&b.BarRes->GetBitmap(),b.BarRes->GetCount(),
550 TSize(b.BarRes->GetWidth(), b.BarRes->GetHeight()),
551 TPoint(0, 0), // offset
552 numRows);
553
554 for (int i = 0; i < TBarDescr::NumGroups; i++)
555 is >> b.GroupCount[i];
556
557 return is;
558}
559
560//
561/// Insert the menu descriptor into the persistent stream.
562//
563_OWLCFUNC(opstream&)
564operator <<(opstream& os, const TBarDescr& b)
565{
566 os << b.Id;
567 os << b.Module;
568 for (int i = 0; i < TBarDescr::NumGroups; i++)
569 os << b.GroupCount[i];
570 return os;
571}
572
573#endif
574
575} // OWL namespace
576
577/* ========================================================================== */
Class definition for TBarDescr.
#define TGadget_FUNCTOR(func)
Definition bardescr.h:31
Definition of class TButtonGadget.
Definition of a bitmap Cel array class.
#define CHECK(condition)
Definition checks.h:239
Descriptor of Bar Implementation.
Definition bardescr.h:71
void SetBuilder(const TGadgetFunctor &functor)
Definition bardescr.cpp:295
bool ExtractGroups()
Scan bar looking for separators that signify group divisions return whether we found any at all.
Definition bardescr.cpp:495
virtual bool Restore(TGadgetWindow &destWindow)
Removes the gadgets in destWindow and then inserts these gadgets.
Definition bardescr.cpp:437
TGadgetFunctor * GetBuilder()
Definition bardescr.h:151
@ FileGroup
Index of the File gadget group count.
Definition bardescr.h:78
@ EditGroup
Index of the Edit gadget group count.
Definition bardescr.h:79
@ HelpGroup
Index of the Help gadget group count.
Definition bardescr.h:83
@ NumGroups
Total number of groups.
Definition bardescr.h:84
@ WindowGroup
Index of the Window gadget group count.
Definition bardescr.h:82
@ ObjectGroup
Index of the Object gadget group count.
Definition bardescr.h:81
@ ContainerGroup
Index of the Container gadget group count.
Definition bardescr.h:80
virtual bool Merge(const TBarDescr &sourceBarDescr, TGadgetWindow &destWindow)
Merges this gadgets and sourceBarDescr gadgets and inserts them into destWindow's gadgets.
Definition bardescr.cpp:375
virtual ~TBarDescr()
Destroys the TBarDescr object.
Definition bardescr.cpp:287
TBarDescr()
Default constructor for a TBarDescr object.
Definition bardescr.cpp:195
bool RemoveGadgets(TGadgetWindow &destWindow)
Removes all gadgets from destWindow.
Definition bardescr.cpp:474
virtual bool Create(TGadgetWindow &destWindow)
Inserts into destWindow's gadgets.
Definition bardescr.cpp:350
bool SetBitmap(TResId newResId, TModule *module)
Set new bitmap for use in gadgets.
Definition bardescr.cpp:302
int Height() const
Returns the height of this bitmap using GDI's GetObject.
Definition bitmap.cpp:289
TBtnBitmap is an enhanced version of TBitmap with the ability to update the face color of a bitmap to...
Definition glyphbtn.h:49
Derived from TGadget, TButtonGadget represent buttons that you can click on or off.
Definition buttonga.h:65
@ Up
Current state of this button.
Definition buttonga.h:81
@ Command
Basic type of this button.
Definition buttonga.h:70
TCelArray is a horizontal array of cels (a unit of animation) created by slicing a portion of or an e...
Definition celarray.h:35
static const TColor LtGray
Static TColor object with fixed Value set by RGB(192, 192, 192).
Definition color.h:306
Functor with 3 parameters, return R.
Definition functor.h:589
TGadget is the base class for the following derived gadget classes:
Definition gadget.h:120
Derived from TWindow, TGadgetWindow maintains a list of tiled gadgets for a window and lets you dynam...
Definition gadgetwi.h:122
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Definition module.h:75
TPoint is a support class, derived from tagPOINT.
Definition geometry.h:87
bool IsOK() const
Confirms whether resource was found.
Definition wsyscls.h:676
The tagSIZE struct is defined as.
Definition geometry.h:234
ushort * GetIds() const
Definition resource.cpp:226
TBitmap & GetBitmap()
Definition resource.cpp:207
int GetCount() const
Definition resource.cpp:217
int GetWidth() const
Definition resource.cpp:235
int GetHeight() const
Definition resource.cpp:244
ipstream, a specialized input stream derivative of pstream, is the base class for reading (extracting...
Definition objstrm.h:391
C++ Functor template implementation.
Base class TGadget and simple derived TSeparatorGadget.
#define IDG_FLATHANDLE
The ID for a flat bar handle.
Definition gadget.h:37
Definition of TGadgetList, TGadgetWindow & TGadgetWindowFont A list holding gadgets,...
Definition of class TGlyphButton.
@ NoAutoDelete
Definition gdibase.h:70
THandle GetHandle() const
Return the instance handle of the library module represented by the TModule obect.
Definition module.h:1233
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
owl::opstream & operator<<(owl::opstream &os, const TColor &c)
Insert the color value into a persistent output stream.
Definition color.h:498
TModule * Module
Definition global.cpp:34
OWL_DIAGINFO
Definition animctrl.cpp:14
TFunctor3< TGadget *, int, int, bool & > TGadgetFunctor
Definition bardescr.h:29
unsigned short uint16
Definition number.h:33
owl::ipstream & operator>>(owl::ipstream &is, TColor &c)
Extract the color value from a persistent input stream.
Definition color.h:489
#define _OWLCFUNC(p)
Definition defs.h:342
#define TYPESAFE_DOWNCAST(object, toClass)
Definition defs.h:269
Defines classes handling Windows resources.
Definition of container classes used and made available by OWL.