libyui-mga  1.0.7
YMGAAboutDialog.cc
1 /*
2  Copyright 2014-2016 by Matteo Pasotti
3  2016 Angelo Naselli
4 
5  This library is free software; you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as
7  published by the Free Software Foundation; either version 2.1 of the
8  License, or (at your option) version 3.0 of the License. This library
9  is distributed in the hope that it will be useful, but WITHOUT ANY
10  WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12  License for more details. You should have received a copy of the GNU
13  Lesser General Public License along with this library; if not, write
14  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
15  Floor, Boston, MA 02110-1301 USA
16 */
17 
18 /*-/
19 
20  File: YMGAAboutDialog.cc
21 
22  Author: Matteo Pasotti <matteo.pasotti@gmail.com>
23 
24 /-*/
25 
26 #define YUILogComponent "mga-ui"
27 #include "YUILog.h"
28 
29 #include <yui/YUI.h>
30 #include <yui/YOptionalWidgetFactory.h>
31 #include <yui/YApplication.h>
32 #include <yui/YWidgetFactory.h>
33 #include <yui/YDialog.h>
34 #include <yui/YLayoutBox.h>
35 #include <yui/YLabel.h>
36 #include <yui/YPushButton.h>
37 #include <yui/YEvent.h>
38 #include <yui/YImage.h>
39 #include <yui/YRichText.h>
40 #include <yui/YDumbTab.h>
41 #include <yui/YReplacePoint.h>
42 #include <yui/YAlignment.h>
43 
44 #include <boost/algorithm/string/trim.hpp>
45 
46 #include "YMGAAboutDialog.h"
47 
48 using std::endl;
49 
51 public:
53  virtual ~YMGAAboutDialogPrivate(){}
54 
55  std::string appName;
56  std::string appVersion;
57  std::string appLicense;
58  std::string appAuthors;
59  std::string appDescription;
60  std::string appLogo;
61  std::string appIcon;
62  std::string appCredits;
63  std::string appInformation;
64  YLayoutSize_t columns;
65  YLayoutSize_t lines;
66 
67  YDialog* mainDialog;
68 };
69 
70 /**
71  * The constructor. Note that this object is not a widget, so you must deleted it, if allocated on the heap.
72  * @param name the application name
73  * @param version the application version
74  * @param license the application license, the short length one (e.g. GPLv2, GPLv3, LGPLv2+, etc)
75  * @param authors the string providing the list of authors; it could be html-formatted
76  * @param description the string providing a brief description of the application
77  * @param logo the string providing the file path for the application logo (high-res image)
78  * @param icon the string providing the file path for the application icon (low-res image)
79  * @param credits optional, the application credits, they can be html-formatted
80  * @param information optional, other extra informations, they can be html-formatted
81  */
82 YMGAAboutDialog::YMGAAboutDialog(const std::string& name,
83  const std::string& version,
84  const std::string& license,
85  const std::string& authors,
86  const std::string& description,
87  const std::string& logo,
88  const std::string& icon,
89  const std::string& credits,
90  const std::string& information
91  ) :
92  priv ( new YMGAAboutDialogPrivate())
93 {
94  YUI_CHECK_NEW ( priv );
95 
96  priv->appName = name;
97  priv->appVersion = version;
98  priv->appLicense = license;
99  priv->appAuthors = authors;
100  priv->appDescription = description;
101  priv->appLogo = logo;
102  priv->appIcon = icon;
103  priv->appCredits = credits;
104  priv->appInformation = information;
105  priv->columns = 50;
106  priv->lines = 6;
107  boost::algorithm::trim(priv->appIcon);
108 }
109 
110 YMGAAboutDialog::~YMGAAboutDialog()
111 {
112  delete priv;
113 }
114 
115 /**
116  * invoked by pressing the information button inside the Classic dialog, it shows a popup dialog providing the information passed to the constructor
117  * @see YMGAAboutDialog()
118  * @see Classic()
119  */
120 void YMGAAboutDialog::showInformation()
121 {
122  auto infoDialog = YUI::widgetFactory()->createPopupDialog();
123  auto minsize = YUI::widgetFactory()->createMinSize(infoDialog, priv->columns, priv->lines);
124  auto vbox = YUI::widgetFactory()->createVBox(minsize);
125  auto tophbox = YUI::widgetFactory()->createHBox(vbox);
126  YUI::widgetFactory()->createSpacing(tophbox,YD_HORIZ,false,10.0);
127  YUI::widgetFactory()->createLabel(tophbox,"Information");
128  YUI::widgetFactory()->createSpacing(tophbox,YD_HORIZ,false,10.0);
129  auto bottomhbox = YUI::widgetFactory()->createHBox(vbox);
130  YUI::widgetFactory()->createSpacing(bottomhbox,YD_HORIZ,false,1.0);
131  auto rtcontent = YUI::widgetFactory()->createRichText(bottomhbox);
132  YUI::widgetFactory()->createSpacing(bottomhbox,YD_HORIZ,false,1.0);
133  rtcontent->setText(priv->appInformation);
134  auto closeButton = YUI::widgetFactory()->createPushButton(vbox,"Close");
135  while(true)
136  {
137  YEvent* event = infoDialog->waitForEvent();
138  if(event)
139  {
140  // window manager "close window" button
141  if ( event->eventType() == YEvent::CancelEvent
142  || event->widget() == closeButton )
143  break; // leave event loop
144  }
145  }
146  infoDialog->destroy();
147 }
148 
149 /**
150  * invoked by pressing the credits button inside the Classic dialog, it shows a popup dialog providing the credit list passed to the constructor
151  * @see YMGAAboutDialog()
152  * @see Classic()
153  */
154 void YMGAAboutDialog::showCredits()
155 {
156  auto creditDialog = YUI::widgetFactory()->createPopupDialog();
157  auto vbox = YUI::widgetFactory()->createVBox(creditDialog);
158  auto tophbox = YUI::widgetFactory()->createHBox(vbox);
159  YUI::widgetFactory()->createSpacing(tophbox,YD_HORIZ,false,16.0);
160  YUI::widgetFactory()->createLabel(tophbox,"Credits");
161  YUI::widgetFactory()->createSpacing(tophbox,YD_HORIZ,false,16.0);
162  auto rtcontent = YUI::widgetFactory()->createLabel(vbox,"");
163  rtcontent->setText(priv->appCredits);
164  auto closeButton = YUI::widgetFactory()->createPushButton(vbox,"Close");
165  while(true)
166  {
167  YEvent* event = creditDialog->waitForEvent();
168  if(event)
169  {
170  // window manager "close window" button
171  if ( event->eventType() == YEvent::CancelEvent
172  || event->widget() == closeButton )
173  break; // leave event loop
174  }
175  }
176  creditDialog->destroy();
177 }
178 
179 /**
180  * it generates the layout and the widgets providing the authors info
181  * @param rpoint the replace point inside the Tabbed dialog
182  * @see YMGAAboutDialog()
183  * @see Tabbed()
184  */
185 
186 void YMGAAboutDialog::genAuthorsTab(YReplacePoint* rpoint)
187 {
188  rpoint->deleteChildren();
189  auto hbox = YUI::widgetFactory()->createHBox(rpoint);
190  auto minsize = YUI::widgetFactory()->createMinSize(hbox, priv->columns, priv->lines);
191 
192  YUI::widgetFactory()->createRichText(minsize,priv->appAuthors);
193  rpoint->showChild();
194  priv->mainDialog->recalcLayout();
195 }
196 
197 /**
198  * it generates the layout and the widgets providing the contributors info
199  * @param rpoint the replace point inside the Tabbed dialog
200  * @see YMGAAboutDialog()
201  * @see Tabbed()
202  */
203 void YMGAAboutDialog::genContributorsTab(YReplacePoint* rpoint)
204 {
205  rpoint->deleteChildren();
206  auto hbox = YUI::widgetFactory()->createHBox(rpoint);
207  auto minsize = YUI::widgetFactory()->createMinSize(hbox, priv->columns, priv->lines);
208  YUI::widgetFactory()->createRichText(minsize,priv->appDescription);
209  rpoint->showChild();
210  priv->mainDialog->recalcLayout();
211 }
212 
213 /**
214  * it generates the layout and the widgets providing extra information
215  * @param rpoint the replace point inside the Tabbed dialog
216  * @see YMGAAboutDialog()
217  * @see Tabbed()
218  */
219 void YMGAAboutDialog::genInformationTab(YReplacePoint* rpoint)
220 {
221  rpoint->deleteChildren();
222  auto hbox = YUI::widgetFactory()->createHBox(rpoint);
223  auto minsize = YUI::widgetFactory()->createMinSize(hbox, priv->columns, priv->lines);
224  YUI::widgetFactory()->createRichText(minsize,priv->appInformation);
225  rpoint->showChild();
226  priv->mainDialog->recalcLayout();
227 }
228 
229 /**
230  * Set the dialog mimimum size if Classic dialog is shown, minimum text size otherwise.
231  * @param columns Columns for dialog minimum size
232  * @param lines Lines for dialog minimum size
233  */
234 void YMGAAboutDialog::setMinSize ( YLayoutSize_t columns, YLayoutSize_t lines )
235 {
236  priv->columns = columns;
237  priv->lines = lines;
238 }
239 
240 /**
241  * it builds the tabbed version for the about dialog box.
242  * @see YMGAAboutDialog()
243  * @see Classic()
244  */
245 void YMGAAboutDialog::Tabbed()
246 {
247  std::string oldTitle = YUI::app()->applicationTitle();
248  YUI::app()->setApplicationTitle("About " + priv->appName);
249  if(priv->appIcon.length())
250  YUI::app()->setApplicationIcon(priv->appIcon);
251  priv->mainDialog = YUI::widgetFactory()->createPopupDialog();
252  auto vbox = YUI::widgetFactory()->createVBox(priv->mainDialog);
253 
254  /*
255  * Layout
256  * ______________________
257  * | ICON APPNAME VER |
258  * |___CREDITS__________|
259  * |_a_|_b_|_c__________|
260  * | |
261  * | |
262  * |____________________|
263  */
264 
265  YUI::widgetFactory()->createSpacing(vbox,YD_VERT,false,1.0);
266  auto upperhbox = YUI::widgetFactory()->createHBox(vbox);
267 
268  // the logo, if defined, if available
269  if(priv->appLogo.length())
270  {
271  YUI::widgetFactory()->createSpacing(upperhbox,YD_HORIZ,false,3.0);
272  YUI::widgetFactory()->createImage(upperhbox,priv->appLogo);
273  YUI::widgetFactory()->createSpacing(upperhbox,YD_HORIZ,false,3.0);
274  }
275 
276  // app name and version
277  YUI::widgetFactory()->createSpacing(upperhbox,YD_HORIZ,false,3.0);
278  YUI::widgetFactory()->createLabel(upperhbox,priv->appName + " " + priv->appVersion);
279  YUI::widgetFactory()->createSpacing(upperhbox,YD_HORIZ,false,5.0);
280  YUI::widgetFactory()->createSpacing(vbox,YD_VERT,false,1.0);
281 
282  // credits
283  auto tophbox = YUI::widgetFactory()->createHBox(vbox);
284  YUI::widgetFactory()->createSpacing(tophbox,YD_HORIZ,false,3.0);
285  YUI::widgetFactory()->createLabel(tophbox,priv->appCredits);
286  YUI::widgetFactory()->createSpacing(tophbox,YD_HORIZ,false,3.0);
287  YUI::widgetFactory()->createSpacing(vbox,YD_VERT,false,0.5);
288 
289  // license
290  auto licensehbox = YUI::widgetFactory()->createHBox(vbox);
291  YUI::widgetFactory()->createSpacing(licensehbox,YD_HORIZ,false,3.0);
292  YUI::widgetFactory()->createLabel(licensehbox,priv->appLicense);
293  YUI::widgetFactory()->createSpacing(licensehbox,YD_HORIZ,false,3.0);
294  YUI::widgetFactory()->createSpacing(vbox,YD_VERT,false,0.5);
295 
296  if(YUI::optionalWidgetFactory()->hasDumbTab())
297  {
298  auto dumbTab = YUI::optionalWidgetFactory()->createDumbTab(vbox);
299 
300  if(priv->appAuthors.length())
301  {
302  dumbTab->addItem(new YItem("Authors"));
303  }
304  if(priv->appDescription.length())
305  {
306  dumbTab->addItem(new YItem("Description"));
307  }
308  if(priv->appInformation.length())
309  {
310  dumbTab->addItem(new YItem("Information"));
311  }
312 
313  auto bottomvbox = YUI::widgetFactory()->createVBox(vbox);
314  auto rpoint = YUI::widgetFactory()->createReplacePoint(bottomvbox);
315 
316  if(priv->appAuthors.length())
317  {
318  this->genAuthorsTab(rpoint);
319  }
320 
321  auto cancelButton = YUI::widgetFactory()->createPushButton(vbox,"Close");
322  cancelButton->setDefaultButton();
323 
324  while(true)
325  {
326  YEvent* event = priv->mainDialog->waitForEvent();
327  if(event)
328  {
329  // window manager "close window" button
330  if ( event->eventType() == YEvent::CancelEvent
331  || event->widget() == cancelButton )
332  break; // leave event loop
333  if ( event->eventType() == YEvent::MenuEvent )
334  {
335  if( event->item()->label().replace(event->item()->label().find("&"),1,"").compare("Authors")==0 )
336  {
337  this->genAuthorsTab(rpoint);
338  }
339  else if( event->item()->label().replace(event->item()->label().find("&"),1,"").compare("Description")==0 )
340  {
341  this->genContributorsTab(rpoint);
342  }
343  else if( event->item()->label().replace(event->item()->label().find("&"),1,"").compare("Information")==0 )
344  {
345  this->genInformationTab(rpoint);
346  }
347  }
348  }
349  }
350  priv->mainDialog->destroy();
351  }
352  else
353  {
354  // handle it
355  }
356  YUI::app()->setApplicationTitle(oldTitle);
357 }
358 
359 /**
360  * it builds the classic version for the about dialog box.
361  * @see YMGAAboutDialog()
362  * @see Tabbed()
363  */
364 void YMGAAboutDialog::Classic()
365 {
366  YPushButton* creditsButton = nullptr;
367  YPushButton* infoButton = nullptr;
368  std::string oldTitle = YUI::app()->applicationTitle();
369  YUI::app()->setApplicationTitle("About " + priv->appName);
370  if(priv->appIcon.length())
371  YUI::app()->setApplicationIcon(priv->appIcon);
372  priv->mainDialog = YUI::widgetFactory()->createPopupDialog();
373  auto minsize = YUI::widgetFactory()->createMinSize(priv->mainDialog, priv->columns, priv->lines);
374  auto vbox = YUI::widgetFactory()->createVBox(minsize);
375  auto tophbox = YUI::widgetFactory()->createHBox(vbox);
376 
377  // logo, if defined, if available
378  if(priv->appLogo.length())
379  {
380  YUI::widgetFactory()->createSpacing(tophbox,YD_HORIZ,false,2.0);
381  YUI::widgetFactory()->createImage(tophbox,priv->appLogo);
382  }
383 
384  YUI::widgetFactory()->createSpacing(tophbox,YD_HORIZ,false,8.0);
385  auto headvbox = YUI::widgetFactory()->createVBox(tophbox);
386  YUI::widgetFactory()->createSpacing(tophbox,YD_HORIZ,false,12.0);
387 
388  // app name and version
389  auto lblAppName = YUI::widgetFactory()->createLabel(headvbox, "");
390  lblAppName->setValue(priv->appName);
391  auto lblAppVersion = YUI::widgetFactory()->createLabel(headvbox, "");
392  lblAppVersion->setValue(priv->appVersion);
393  auto lblLicense = YUI::widgetFactory()->createLabel(headvbox, "");
394  lblLicense->setValue(priv->appLicense);
395 
396  auto midhbox = YUI::widgetFactory()->createHBox(vbox);
397  // app description
398  auto toprightvbox = YUI::widgetFactory()->createVBox(midhbox);
399  toprightvbox->setWeight(YD_HORIZ, 5);
400  YUI::widgetFactory()->createSpacing(toprightvbox,YD_HORIZ,false,5.0);
401  auto rt = YUI::widgetFactory()->createRichText(toprightvbox,"");
402  YUI::widgetFactory()->createSpacing(toprightvbox,YD_HORIZ,false,5.0);
403  rt->setValue(priv->appDescription);
404 
405  // info button, if information are defined
406  auto bottomhbox = YUI::widgetFactory()->createHBox(vbox);
407  if(priv->appInformation.length())
408  {
409  infoButton = YUI::widgetFactory()->createPushButton(bottomhbox, "Info");
410  }
411 
412  // credits button, if credits are defined
413  if(!priv->appCredits.empty())
414  {
415  creditsButton = YUI::widgetFactory()->createPushButton(bottomhbox, "Credits");
416  }
417 
418  auto cancelButton = YUI::widgetFactory()->createPushButton(bottomhbox, "Close");
419  cancelButton->setDefaultButton();
420 
421  while(true)
422  {
423  YEvent* event = priv->mainDialog->waitForEvent();
424  if(event)
425  {
426  // window manager "close window" button
427  if ( event->eventType() == YEvent::CancelEvent
428  || event->widget() == cancelButton )
429  break; // leave event loop
430  else if( ( infoButton != nullptr ) && event->widget() == infoButton )
431  {
432  this->showInformation();
433  }
434  else if( ( creditsButton != nullptr ) && event->widget() == creditsButton )
435  {
436  this->showCredits();
437  }
438  }
439  }
440  priv->mainDialog->destroy();
441  YUI::app()->setApplicationTitle(oldTitle);
442 }
443 
444 /**
445  * it actually shows the about dialog
446  * @param type optional, DLG_MODE: defaulting to CLASSIC if not defined
447  * @see Classic()
448  * @see Tabbed()
449  * @see YMGAAboutDialog::DLG_MODE
450  */
451 void YMGAAboutDialog::show(YMGAAboutDialog::DLG_MODE type)
452 {
453  if(type == TABBED)
454  {
455  this->Tabbed();
456  }
457  else
458  {
459  this->Classic();
460  }
461 }
void setMinSize(YLayoutSize_t columns, YLayoutSize_t lines)
Set the dialog mimimum size if Classic dialog is shown, minimum text size otherwise.
YMGAAboutDialog(const std::string &name, const std::string &version, const std::string &license, const std::string &authors, const std::string &description, const std::string &logo, const std::string &icon=std::string(), const std::string &credits=std::string(), const std::string &information=std::string())
The constructor.
void show(DLG_MODE type=TABBED)
it actually shows the about dialog