No HMG4 Font object

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

User avatar
l3whmg
Posts: 694
Joined: Mon Feb 23, 2009 8:46 pm
Location: Italy
Contact:

Re: No HMG4 Font object

Post by l3whmg »

Hi friends,
I'm sorry if I use this post, but subject corresponding to my problem.
I've download today last HMG4 and then I compile "samples\label\demo_4.prg" and doesn't work. The poblem comes from AUTOSIZE, but I think it's more complex.
In Autosize function we have this

Code: Select all

            oFont   := QFont()
            oFont:SetFamily( Self:FontName )
            oFont:SetPointSize( Self:FontSize )
            oFont:SetBold( Self:FontBold )
            oFont:SetItalic( Self:FontItalic )
First: QFont() create an object font, but it's not inherit from parent (this is a common problem).
Second: oFont:SetFamily( Self:FontName) can not work because the ::cFontName var is not valued - or might not be valued - and the same can happen to other variables. For this reason I get a crash.
I think we must:
  • - insert "::Font( ::oParent:oQtObject:Font() )" at the beginning of every control in this way we inherit Font object from window and setup a default font object for this object (more or less the same can be for form
  • - change Font method in control.prg

Code: Select all

         ELSEIF Valtype( xValue ) == "O"
            ::oFont := xValue
      ::oQTObject:SetFont( ::oFont )
      ::cFontName := ::oFont:family()
      ::nFontSize := IF( ::oFont:pointSize()==-1, ::oFont:pixelSize(), ::oFont:pointSize() )
      ::lFontBold := ::oFont:bold()
      ::lFontItalic := ::oFont:italic()
      ::lFontUnderLine := ::oFont:strikeOut()
      ::lFontStrikeOut := ::oFont:underline()
Luigi from Italy
www.L3W.it
User avatar
concentra
Posts: 256
Joined: Fri Nov 26, 2010 11:31 am
Location: Piracicaba - Brasil

Re: No HMG4 Font object

Post by concentra »

Hi.
In my opinion, the problem is that NEW() does not instantiate the object, the parent window ACTIVATE() does.
If NEW() instantiates the object, it can automatically inherit the parent font, and, the AUTOSIZE() method could be:

Code: Select all

METHOD AutoSize( lValue ) CLASS LABEL
   LOCAL oFM

   IF Pcount() == 0
      RETURN ::lAutoSize
   ELSEIF Pcount() == 1
      IF lValue
         oFM        := QFontMetrics( ::oFont )
         Self:Width := oFM:width( ::cValue )
      ENDIF
      ::lAutoSize := lValue
   ENDIF

   RETURN NIL
The NEW() method for control classes could be something like this:

Code: Select all

METHOD NEW() CLASS LABEL

   // Get the parent object from the WITH OBJECT stack
   ::oParent   := HB_QWith(1)

   // Instantiate the object
   ::oQTObject := QLabel( ::oParent:oQTObject )
   
   .
   .
   .
   .

   RETURN Self

But this implies a big change...
And what you suggested must work, this is only my opinion !
[[]] Mauricio Ventura Faria
User avatar
l3whmg
Posts: 694
Joined: Mon Feb 23, 2009 8:46 pm
Location: Italy
Contact:

Re: No HMG4 Font object

Post by l3whmg »

Hi Mauricio,
I'm in agreement with you and for this reason I write my HMG experiment to do test; I create Qt object in NEW() method and seem to work fine, but I write little HMG: I don't know if there are other problem.

For this and other reason I write: we must think about source code written so far :mrgreen:

This code not work in HMG4: it is my experiment.

Code: Select all

/*---------------------------------------------------------------
 New
 ---------------------------------------------------------------*/
METHOD HMGLABLE:New( oParent )

// set-up a default name
   ::cName          := '_HMG_OBJECT_' + hb_ntos( ::nObjectCounter++ )
// set-up parent in this order: parameter, current or default (last one is Qt QApplication():DeskTop()
   ::oParent := IF( hb_IsObject( oParent ), oParent, IF( hb_IsObject( ::oCurrentParent ), ::oCurrentParent, ::oDefaultParent ) )
// add this HMG object to its parent
   ::oParent:AddChild( Self )
// create QT object with its parent
   ::oQtObject := QLabel( ::oParent:Qtobject() )
// inherit properties
   ::Font( ::oParent:QtObject:Font() )

   ::oQtObject:setAutoFillBackground( ::lAutoFillBackground )

RETURN Self

Code: Select all

/*---------------------------------------------------------------
 AutoSize
 ATTENTION: if you want different Font properties you MUST change font properties BEFORE and then use it else doesn't work
 ---------------------------------------------------------------*/
METHOD HMGLABLE:AutoSize( lArg1 )

   LOCAL oFontMetrics, nWidth

   IF PCOUNT() == 0
      RETURN ::lAutoSize
   ELSEIF VALTYPE( lArg1 ) == "L"
      ::lAutoSize := lArg1
      oFontMetrics := QFontMetrics( ::oFont )
      nWidth   := oFontMetrics:width( ::cCaption )
      ::Width( nWidth )
   ENDIF

RETURN NIL

Cheers
Luigi from Italy
www.L3W.it
User avatar
l3whmg
Posts: 694
Joined: Mon Feb 23, 2009 8:46 pm
Location: Italy
Contact:

Re: No HMG4 Font object

Post by l3whmg »

Hi Mauricio,
about HB_QWith(1) I can't figure out how to use, I'm sorry. I try to explain my problem.

Every form can have its parent. MainWindow parent is Application():Desktop()
Then I can have a simpleform and its parent it's MainWindow.
But I can have a subform and its parent it's simpleform and its parent is MainWindow.

When I define a form (with HMG3) normally I use this syntax:

Code: Select all

DEFINE WINDOW name1
...
END WINDOW

DEFINE WINDOW name2
...
END WINDOW
Attention: when I use "DEFINE..." I create an object and ::oDefaultParent it's SELF. But when I use "END WINDOW" I do: End Object and EndWindow (::oDefaultParent := NIL).

In this situation, name2 can't has name1 as its parent in other words how can I use Hb_Qwith( n )? I don't know n level.

Can you help me to understand please?

Regards
Luigi from Italy
www.L3W.it
User avatar
concentra
Posts: 256
Joined: Fri Nov 26, 2010 11:31 am
Location: Piracicaba - Brasil

Re: No HMG4 Font object

Post by concentra »

Hi Luigi and everyone !
I will suggest a half-way solution to the NEW() / CREATE() dilemma.
I found a QT method that sets the parent of an object ==> SetParent().
So we can instantiate an independent object and, later, set the parent in the window ACTIVATE() method, without loosing the current CREATE() approach already implemented.
In this way, it is possible to change the control classes one by one until all of them are changed and then the window methods itself ( or not... ).

In window.prg we need to change one line:

Code: Select all

METHOD CreatePendingChildControls() CLASS Window
   LOCAL i

   // Create Child Controls
   FOR i := 1 TO Len( ::aControls )
      IF !::aControls[i]:lCreated
         ::aControls[i]:Create( ::oQTObject )  // The change...
      ENDIF
   NEXT i

   RETURN NIL
And I took buttom.prg as an example, changing the CREATE() method and adding NEW():

Code: Select all

#include "hbclass.ch"
#include "common.ch"

/*----------------------------------------------------------------------*/

CLASS BUTTON FROM CONTROL

   // Internal Data
   DATA nPictAlignment                            INIT   0
   DATA lDefault                                  INIT   .F.
   DATA lAutoDefault                              INIT   .F.

   // Properties
   METHOD PictAlignment                           SETGET
   METHOD Default                                 SETGET
   METHOD AutoDefault                             SETGET

   // Methods
   METHOD NEW()
   METHOD Create( oParentQtObject )

ENDCLASS

/*----------------------------------------------------------------------*/

METHOD PictAlignment( nValue ) CLASS BUTTON

   IF Pcount() == 0
      RETURN ::nPictAlignment
   ELSEIF Pcount() == 1
      IF   nValue == 0 // Top
      ELSEIF   nValue == 1 // Bottom
      ELSEIF   nValue == 2 // Left
         ::oQTObject:SetLayoutDirection( 0 )
      ELSEIF   nValue == 3 // Right
         ::oQTObject:SetLayoutDirection( 1 )
      ENDIF
      ::nPictAlignment := nValue
   ENDIF

   RETURN NIL

/*----------------------------------------------------------------------*/

METHOD Default( lValue ) CLASS BUTTON

   IF Pcount() == 0
      RETURN ::lDefault
   ELSEIF Pcount() == 1 .AND. VALTYPE( lValue ) == "L"
      ::oQTObject:setDefault( lValue )
   ENDIF

   RETURN NIL

/*----------------------------------------------------------------------*/

METHOD AutoDefault( lValue ) CLASS BUTTON

   IF Pcount() == 0
      RETURN ::lAutoDefault
   ELSEIF Pcount() == 1 .AND. VALTYPE( lValue ) == "L"
      ::oQTObject:setAutoDefault( lValue )
   ENDIF

   RETURN NIL

/*----------------------------------------------------------------------*/

METHOD Create( oParentQtObject ) CLASS BUTTON

   IF valtype( ::oContainer ) == 'U'
      // The object is already instantiated !
      ::oQTObject:SetParent(oParentQtObject)
   ELSE
      ::oQTObject := QPushButton( ::oContainer:oQTObject )
   ENDIF

   ::oParent:AddData( ::cName , Self )

   ::lCreated := .T.

   IF ValType( ::lFlat )              != 'U'; Self:Flat              := ::lFlat              ; ENDIF
   IF ValType( ::nPictAlignment )     != 'U'; Self:PictAlignment     := ::nPictAlignment     ; ENDIF
   IF ValType( ::nRow )               != 'U'; Self:Row               := ::nRow               ; ENDIF
   IF ValType( ::nCol )               != 'U'; Self:Col               := ::nCol               ; ENDIF
   IF ValType( ::nWidth )             != 'U'; Self:Width             := ::nWidth             ; ENDIF
   IF ValType( ::nHeight )            != 'U'; Self:Height            := ::nHeight            ; ENDIF
   IF ValType( ::cCaption )           != 'U'; Self:Caption           := ::cCaption           ; ENDIF
   IF ValType( ::cPicture )           != 'U'; Self:Picture           := ::cPicture           ; ENDIF
   IF ValType( ::cFontName )          != 'U'; Self:FontName          := ::cFontName          ; ENDIF
   IF ValType( ::nFontSize )          != 'U'; Self:FontSize          := ::nFontSize          ; ENDIF
   IF ValType( ::lBold )              != 'U'; Self:FontBold          := ::lBold              ; ENDIF
   IF ValType( ::lItalic )            != 'U'; Self:FontItalic        := ::lItalic            ; ENDIF
   IF ValType( ::lUnderline )         != 'U'; Self:FontUnderline     := ::lUnderline         ; ENDIF
   IF ValType( ::lStrikeout )         != 'U'; Self:FontStrikeOut     := ::lStrikeout         ; ENDIF
   IF ValType( ::cToolTip )           != 'U'; Self:ToolTip           := ::cToolTip           ; ENDIF
   IF ValType( ::lTabStop )           != 'U'; Self:TabStop           := ::lTabStop           ; ENDIF
   IF ValType( ::lDefault )           != 'U'; Self:Default           := ::lDefault           ; ENDIF
   IF ValType( ::lAutoDefault )       != 'U'; Self:AutoDefault       := ::lAutoDefault       ; ENDIF
   IF ValType( ::bOnGotFocus )        != 'U'; Self:OnGotFocus        := ::bOnGotFocus        ; ENDIF
   IF ValType( ::bOnLostFocus )       != 'U'; Self:OnLostFocus       := ::bOnLostFocus       ; ENDIF
   IF ValType( ::aBackColor )         != 'U'; Self:backColor         := ::aBackColor         ; ENDIF
   IF ValType( ::aFontColor )         != 'U'; Self:FontColor         := ::aFontColor         ; ENDIF
   IF ValType( ::aDisabledFontColor ) != 'U'; Self:DisabledFontColor := ::aDisabledFontColor ; ENDIF
   IF ValType( ::aDisabledBackColor ) != 'U'; Self:DisabledbackColor := ::aDisabledBackColor ; ENDIF
   IF ValType( ::bOnClick )           != 'U'; Self:OnClick           := ::bOnClick           ; ENDIF
   IF ValType( ::lVisible )           != 'U'; Self:Visible           := ::lVisible           ; ELSE   ; ::oQTObject:show()   ; ENDIF

   RETURN Self

/*----------------------------------------------------------------------*/

METHOD New() CLASS BUTTON

   super:new()

   ::oQTObject := QPushButton()
   ::oFont     := QFont()
   ::Height    := 24               // Must set a default value...

   RETURN Self

/*----------------------------------------------------------------------*/
Note that since the object is always "created", all IF ! lCreated stuff is unnecessary.
The new button class needs a default value in the HEIGHT property, and possible another defaults will be needed here and in other classes.
Last edited by concentra on Mon Mar 21, 2011 7:35 pm, edited 4 times in total.
[[]] Mauricio Ventura Faria
User avatar
concentra
Posts: 256
Joined: Fri Nov 26, 2010 11:31 am
Location: Piracicaba - Brasil

Re: No HMG4 Font object

Post by concentra »

Hi Luigi.
l3whmg wrote: about HB_QWith(1) I can't figure out how to use.
When in HMG3 we use DEFINEs to define the objects this is translated by the preprocessor in a WITH OBJECT / END nested structure.
For example a window with a button that contains an image:

Code: Select all

DEFINE WINDOW name1
   ...
   DEFINE BUTTON oBtn
      ...
      DEFINE IMAGE oImg
         ...
      END
      ...
   END 
   ...
END WINDOW
Is translated to

Code: Select all

WITH OBJECT name1 := WINDOW:NEW()
   ...
   WITH OBJECT oBtn := BUTTON:NEW()
      HB_QWith(1)   ==> Points to the previous object in this structure ( name1 )
      // The button NEW() method can invite HB_QWith(1) in order to know the parent, name1,
      // without knowing its name ( name1 ).
      // And we can instantiate the object referencing its parent in the NEW() method,
      // before the window is activated, without breaking HMG3 compatibility.
      ...
      WITH OBJECT oImg := IMAGE:NEW()
         HB_QWith(1)   ==> Points to the previous object in this structure ( oBtn )
      END WITH
      ...
   END WITH
   ...
END WITH
[[]] Mauricio Ventura Faria
User avatar
l3whmg
Posts: 694
Joined: Mon Feb 23, 2009 8:46 pm
Location: Italy
Contact:

Re: No HMG4 Font object

Post by l3whmg »

Hi Mauricio,
I'm in agreement with you when you write about control! But I have write about forms.

Anyway, I study your idea and do some tests, many thanks.

Cheers
Luigi from Italy
www.L3W.it
User avatar
l3whmg
Posts: 694
Joined: Mon Feb 23, 2009 8:46 pm
Location: Italy
Contact:

Re: No HMG4 Font object

Post by l3whmg »

Hello Mauricio,
I don't want to be boring, maybe I do not understand.
Seems to me that you've mixed HMG object and QT object. The relationship we have at HMG object-level and then at QT object-level.
From HMG4 pseudo-code:
form case
::oDefaultParent := HMG-form and not ::oDefaultParent := QT-form
button case
::oParent := ::oDefaultParent
::oParent := HMG-formParent not ::oParent := QT-formParent
ie for button I can use
::oQtObject:setParent( ::oParent:oQtObject )
And for this

Code: Select all

METHOD Default( lValue ) CLASS BUTTON

   IF Pcount() == 0
      RETURN ::lDefault
   ELSEIF Pcount() == 1 .AND. VALTYPE( lValue ) == "L"
      ::oQTObject:setDefault( lValue )
   ENDIF

   RETURN NIL
I think it's no good, because HMG loose ::lDefault value
This is good

Code: Select all

METHOD Default( lValue ) CLASS BUTTON

   IF Pcount() == 0
      RETURN ::lDefault
   ELSEIF Pcount() == 1 .AND. VALTYPE( lValue ) == "L"
      ::lDefault := lValue
      ::oQTObject:setDefault( lValue )
   ENDIF

   RETURN NIL
Obviously, everything is different if the class BUTTON is equivalent to QPushButton

I am writing this in great friendship. I repeat: maybe I did not understand.

Best regards
Luigi from Italy
www.L3W.it
User avatar
concentra
Posts: 256
Joined: Fri Nov 26, 2010 11:31 am
Location: Piracicaba - Brasil

Re: No HMG4 Font object

Post by concentra »

Hi Luigi.
I read your post talking about forms superficially and I think you asked something and I answered another ! :mrgreen:
And please remember that I am new to HMG and never used HMG3.
Everything I wrote was about controls, nothing about forms at all...
Sorry !

And backing to the beginning of my thoughts about controls, many issues could be avoided if the controls NEW() method instantiates the correspondent QT object.
Today, the correspondent QT object is instantiated when the ACTIVATE() method of the form that contains the control is called.
Seems this is by design, probably because of HMG3 compatibility.
What I suggested was a simple way to instantiate a QT control in the NEW() method without big changes in the code and preserving the compatibility.

In a post here you noted about a problem in AUTOSIZE method of label control, and I pointed that in my opinion the problem was related to the fact that label NEW() method doesn´t instantiate a QT object.

But to instantiate a QT control object, we need to know its QT parent and the way HMG4 is coded this could not possible without a big change in the window (forms) classes and all controls, what I want to avoid.

Please, forget HB_QWith(1) this was a nonsense, my mistake in interpreting some code in my mind. And thank you, because trying to understand what you didn´t, I understood that I wasn´t understanding... :mrgreen:

Finally I presented a suggestion to instantiate controls changing 1 line in window.prg and a few in button.prg. I used the button class button.prg only to present an example and see if others agree with it or not.
First: QFont() create an object font, but it's not inherit from parent (this is a common problem).
In the suggestion I presented this will probably still occur.
Seems to me that you've mixed HMG object and QT object.
A little. But they are very related.
form case
::oDefaultParent := HMG-form and not ::oDefaultParent := QT-form
Please forget about forms... I wasn´t talking about forms.
button case
::oParent := ::oDefaultParent
::oParent := HMG-formParent not ::oParent := QT-formParent
Ok, I understood that ::oParent is an HMG object, but the time control´s NEW() method is called, ::oParent don´t have a QT object associated and it´s not possible to instantiate a control´s QT object referencing the associated parent QT object.
In the suggestion I presented, the control class instantiates the QT object earlier, in the NEW() method, without associating it with the corresponding QT object.
The association will be made later, in the window class´s ACTIVATE() method, replacing the actual mode of instantiating controls and preserving compatibility with the actual code.
ie for button I can use
::oQtObject:setParent( ::oParent:oQtObject )
I suppose that this can be used to all controls ( don´t know about windows/forms... ).

And the button class Default() method was already wrong, I just cut and pasted. I will fix.
[[]] Mauricio Ventura Faria
User avatar
concentra
Posts: 256
Joined: Fri Nov 26, 2010 11:31 am
Location: Piracicaba - Brasil

Re: No HMG4 Font object

Post by concentra »

Hi Luigi.
And the button class Default() method was already wrong
Seems that this happens all the time in the control classes, not only in button.
[[]] Mauricio Ventura Faria
Post Reply