NewStartCenterBehavior/es

EN PROGRESO

All the changes added to the original OpenOffice.org source code provided in this page, are :


 * '''Under LGPL License V3, ( and you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation)
 * Copyright Eric Bachard 20 December 2010

OOo4Kids 1.1 o versiones previas
Until the 1.1 version, the startcenter had the following feature (see image below) :




 * when the mouse cursor rolls over the icons, a bubble appears and describes the role of the concerned application.


 * one message by icon. For the english version it gives :
 * Create a Text with Writer
 * Draw something
 * Create a presentation with Impress
 * Create a Calc sheet
 * Open a document...


 * some time after the mouse cursor goes out of the icon area, the bubble disappears

The problème was, that the help bubble could appear anywhere, including over the icon, sometimes hidding it, what was basicaly bad on the user experience side.

Versión futura 1.2
The proposed enhancement allows now to display :


 * the same string as the one in the bubble ;
 * '''always at a given location, whatever the icon under the mouse cursor (but the appearing text will match with the icon).
 * no need to add new localized strings : we'll simply reuse the existing one

The features works already, and some screenshots describing the existing cases are proposed below.

Possible improvement :


 * no longer display "Create a new document" (probably useless and overloading the visual);
 * modify the current Design (move the frame containing the icons higher, say better centered;
 * (thanks to add your proposal on the list).

Capturas (solo frances, se mejorará pronto)
New StartCenter behavior, when the mouse cursor rolls over the applications icons

Introducción
Below, you'll find a technical description of the New StartCenter behavior feature. It is question of OpenOffice.org source code (mainly C++), e.g. the internal source code organisation in OpenOffice.org framework. Thus, we suppose the reader has the mandatory basics to understand the content of what is proposed.

The pre-requisites to read this article still have to be defined, but if the reader is not used with some notions, we invite him to have a look at the OpenOffice.org wiki to complete his knowledge, and read this article in the best conditions.

At the beginning, I had no precise idea where to start. So I imagined a solution, but it was not correct. I must say a big thank you to Philipp Lohmann, who - one more time - kindly explained me what I had to do (  see this mail). To share what I learned, I added as much of information I could, as described below.

Any constructive remark, helping to improve this documentation is welcome.

Especificaciones

 * Make the Help bubbles shut up
 * Start an Events Listener, of VclWindowEvent type
 * Terminate this Events listeners (in the BackingWindow object desctructor, when the window is closing)
 * Initialize the strings to be displayed, in particular initialize the fonts the right way
 * Implement a callback, triggered by the right event (VclWindowEvent)
 * Propose an algorithm allowing to display the right string, for all possibles cases
 * Make it work
 * Remove obsolete code
 * Validate

Modulos marcados
Only one module is concerned in that feature. It's framework, and the modified code stands in framework/source/services:


 * framework/source/services/backingwindow.hxx // interface
 * framework/source/services/backingwindow-OOo4Kids.hxx // OOo4Kids implementation only
 * framework/source/services/backingwindow-OOoLight.cxx // OOoLight implementation only

Hacer que la burbuja de ayuda se cierre
As Philipp Lohmann explained in his initial mail, to prevent the toolbox from still popping up its quick help window, it's sufficient to derive from the toolbox (since it's a DecoToolbox in backingwindow.cxx) and to implement the same -doing nothing- method.

In the code, this is summarized by :

Index: framework/source/services/backingwindow.hxx

=
====================================================== --- framework/source/services/backingwindow.hxx	(revision 1034) +++ framework/source/services/backingwindow.hxx	(working copy) @@ -78,6 +78,9 @@                DecoToolBox( Window* pParent, const ResId& rResId ); void   DataChanged( const DataChangedEvent& rDCEvt ); + +       // The goal is to overload the Toolbox method, thus make the QuickHelp shut up +        void    RequestHelp( const HelpEvent& rHEvt );

Implementation (in framework/source/services/backingwindow-OOo4Kids.cxx for example) :

Add the method doing nothing : +       void DecotoolBox::RequestHelp( const HelpEvent& rHEvt ) + { +    (void)rHEvt; // makes the compiler happy + };

Works out of the box :-)

Agrega nuevo eventlistener
The BackingWindow::initControls method is called once only (following "singleton" Design Pattern), and it looks ok, to implement the events listened there @@ -383,15 +413,7 @@        }     }			 (removed code) +   maToolbox.AddEventListener( LINK( this, BackingWindow, DecoToolboxHdl ) ); maToolbox.SetSelectHdl( LINK( this, BackingWindow, ToolboxHdl ) ); maToolbox.Show;

The call is done as a Callback, with the purpose to execute an action when an event of the right type will be detected.

Agrega nuevos callbacks
Le callback does catch events of VclWindowEvent* type (pointers on VclWindowEvent type), in particular, these two event, who appear in the code below:


 * VCLEVENT_TOOLBOX_HIGHLIGHT : Triggers the highlight. Sent when the mouse cursor rolls over one of the startcenter icons
 * VCLEVENT_TOOLBOX_HIGHLIGHTOFF : end of highlight. Sent when the mouse cursor goes out of any application icon area.

The (trivial) algorithm is : If event is of VclWindowEvent type and if this event is one VCLEVENT_TOOLBOX_HIGHLIGHT event

Choose the icon in the following cases :

Case Calc application identified : display Calc message End

Case Draw application identified : display Draw message End

Case Impress application identified : display Impress message End

Case Open a document identified : display Open a document message End

Case Writer application identified : display Writer message End

Case whatever else: End

Else if event is of VclWindowEvent type and if this event is one VCLEVENT_TOOLBOX_HIGHLIGHTOFF event Hide all messages End if

Inicialización de cadenas
The initialization counts 3 steps :

Paso 1 declaración en la interfaz.
For that, we'll use objects of type :


 * Control: FixedText
 * 2D containers : Size (width, heigth)
 * Fonts
 * String (constants) of String types (already defined, simply reused)

Paso 2: Inicialización de fuentes por cada cadena que muestre
Concerned : Backingwindow::initControls

maTextFont : already intialized, and obtained the following way : maTextFont = GetSettings.GetStyleSettings.GetLabelFont;

We'll have to initialize:


 * the font for every string,
 * the caracters size (including kerning value - we don't care here -)
 * style attribute (WEIGHT_NORMAL for us)

As example, how is set the message who will appear when the mouse cursor will roll over Calc icon:

+   // Set the messages to be displayed +   maTextFont.SetSize( Size( 0, 13 ) ); +   maTextFont.SetWeight( WEIGHT_NORMAL ); +   maCalcMessageText.SetText( maCalcString ); +   maCalcMessageText.SetFont( maTextFont ); +   maCalcMessageText.SetControlFont( maTextFont ); +   maCalcMessageSize = Size( maCalcMessageText.GetTextWidth( maCalcString ), maCalcMessageText.GetTextHeight * 1.18 );

No need to re-initialize the size (SetSize method) for the next strings, because nothing is modified :

+ +   maDrawMessageText.SetText( maDrawString ); +   maDrawMessageText.SetFont( maTextFont ); +   maDrawMessageText.SetControlFont( maTextFont ); +   maDrawMessageSize = Size( maDrawMessageText.GetTextWidth( maDrawString ), maDrawMessageText.GetTextHeight * 1.18 ); +

-> please read the code for the next/other strings

Paso 3 : cadenas posicionadas en la Ventana
This happens in the BackingWindow::Resize method, called every time something changes in the window

@@ -501,8 +519,70 @@    maCreateText.SetPosSizePixel( Point( (aWindowSize.Width - maCreateSize.Width + STRING_OFFSET_X) / 2, nYPos ),                                   Size( maControlRect.GetWidth, maCreateSize.Height ) ); + +   // defines the location of the Create text +   nYPos += 170;// FIXME: better method ... + +   maCalcMessageText.SetPosSizePixel( Point( (aWindowSize.Width - maCalcMessageSize.Width + STRING_OFFSET_X) / 2, nYPos ), +                                  Size( maControlRect.GetWidth, maCalcMessageSize.Height ) );

It is important to notice the calculation mode for the positioning (the previous one was wrong). Remain anyway a problem, because we need the second displaying of the Backingwindow, to see a correct calculation. [FIXME]

Same thing for the other controls below :

+ +   maDrawMessageText.SetPosSizePixel( Point( (aWindowSize.Width - maDrawMessageSize.Width + STRING_OFFSET_X) / 2, nYPos ), +                                  Size( maControlRect.GetWidth, maDrawMessageSize.Height ) ); + +   maImpressMessageText.SetPosSizePixel( Point( (aWindowSize.Width - maImpressMessageSize.Width + STRING_OFFSET_X) / 2, nYPos ), +                                  Size( maControlRect.GetWidth, maImpressMessageSize.Height ) ); + +   maOpenMessageText.SetPosSizePixel( Point( (aWindowSize.Width - maOpenMessageSize.Width + STRING_OFFSET_X) / 2, nYPos ), +                                  Size( maControlRect.GetWidth, maOpenMessageSize.Height ) ); + +   maWriterMessageText.SetPosSizePixel( Point( (aWindowSize.Width - maWriterMessageSize.Width + STRING_OFFSET_X) / 2, nYPos ), +                                  Size( maControlRect.GetWidth, maWriterMessageSize.Height ) ); }

==== Implementación del Callback

+IMPL_LINK( BackingWindow, DecoToolboxHdl, VclWindowEvent*, pEvent ) + { +   if( pEvent && pEvent->GetId == VCLEVENT_TOOLBOX_HIGHLIGHT ) +   { +#ifdef DEBUG +       fprintf(stderr, "Toolbox nItemId = %d \n", maToolbox.GetHighlightItemId ); +#endif +       switch ( maToolbox.GetHighlightItemId ) +       { +            case nItemId_Calc: +           { +                maMessageText.SetText( maCalcString ); +               maMessageSize = Size( maMessageText.GetTextWidth( maCalcString ), +                                       maMessageText.GetTextHeight * DEFAULT_ZOOM_FACTOR ); +           } +                break; +           case nItemId_Draw: +           { +                maMessageText.SetText( maDrawString ); +               maMessageSize = Size( maMessageText.GetTextWidth( maDrawString ), +                                      maMessageText.GetTextHeight * DEFAULT_ZOOM_FACTOR ); +           } +                break; +           case nItemId_Impress: +           { +                maMessageText.SetText( maImpressString ); +               maMessageSize = Size( maMessageText.GetTextWidth( maImpressString ), +                                      maMessageText.GetTextHeight * DEFAULT_ZOOM_FACTOR ); +           } +                break; +           case nItemId_Info: +           { +                maMessageText.SetText( maOpenString ); +               maMessageSize = Size( maMessageText.GetTextWidth( maOpenString ), +                                      maMessageText.GetTextHeight * DEFAULT_ZOOM_FACTOR ); +           } +                break; +           case nItemId_Writer: +           { +                maMessageText.SetText( maWriterString ); +               maMessageSize = Size( maMessageText.GetTextWidth( maWriterString ), +                                      maMessageText.GetTextHeight * DEFAULT_ZOOM_FACTOR ); +           } +                break; +           case nItemId_Extensions: +           case nItemId_Reg: +           case nItemId_TplRep: +           default: +               break; +       } +	 setMessageTextSize; +       maMessageText.Show; +   } +    else if( pEvent && pEvent->GetId == VCLEVENT_TOOLBOX_HIGHLIGHTOFF ) +       maMessageText.Hide; +   return 0; +}

Resumen : que fue importante, y que fue... aburrido

 * Time necessary for the implementation : between 20h and 24h of work(full time) (includes debugging)
 * Retrieve the right id : use maToolbox.GetHighlightItemId instead of maToolbox.GetCurItemId who will always give "0") .. can save a precious time.
 * Callback choice : linked to what is a Decotoolbox to the BackingWindow (the effort is mandatory)
 * Correct fonts initialization : use SetControl saves ... (I lost a lot of time because of that :/ )
 * Knowledge of the possible / accessible methods : opengrok helps a lot (what a nice tool !)