Giter Site home page Giter Site logo

ribbon's People

Contributors

doughennig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ribbon's Issues

Trying to put this in _SCREEN

πŸ“ Provide detailed reproduction steps (if any)

  1. …I created a sample menu ... but rather than in a form ... I added it to _SCREEN
  2. …When the menu opens it looks good (not much there, just starting to play)
  3. …When I click on a button which bars under it. The bars appear and then disappear. If you watch very closely you can see them appear. So I know it is working...they just are not staying visible.
  4. ...I have attached a very simplistic example which shows the issue and then have attached a video trying to show what I am talking about. If you slow down the video ... you will indeed see the bars flash and disappear.

βœ”οΈ Expected result

I expect on clicking on button and the sub-menu (bars) appear below it. I then can click on one of these bars.

❌ Actual result

The bars and disappear almost immediately. You have to watch very closely to see them flash.

πŸ“· Screenshots

Are there any useful screenshots? WinKey+Shift+S and then just paste them directly into the form

ShowItOff.mp4

test.prg.txt

Some items bleed from one tab to another when ribbon is in _SCREEN

πŸ“ Provide detailed reproduction steps (if any)

  1. Run RibbonInScreen.prg in the Sample folder.
  2. Click the Send/Receive tab.

βœ”οΈ Expected result

Only items for the Send/Receive tab appear.

❌ Actual result

Some items from the Home tab appear:

image

Clicking in the ribbon makes them disappear.

Error when trying to run sample,scx

I tried to run the sample.scx form with this command:

DO FORM "k:\_tools\_programming\ribbon-master\sample\sample.scx"

When I run it, it shows me the following message:

image

It occurs when executing this line of code in the "AddControl()" method of the "oRibbon" object.:

This.NewObject(tcName, tcClass, tcLibrary)

The values of the tcName, tcClass,and tcLibrary variables are "Home", "SFRibbonTab", and "SFRibbon.vcx", respectively.

What can I do in order to run the form correctly?

Nice solution to get rid of the Menu timer

πŸ“ The menu timer is conflicting with some other complex windows events from some complicated forms.


Here are some few modifications that will make us completely leave the Menu Timer, and avoid some errors previously documented:
The trick is in having a wider border, by changing the "Padding" value to 5. This way, when the mouse reaches this border, the menu will be hidden. The MenuForm "Deactivate()" method should do some extra caring as well. Very simple changes, with IMHO, a nice result.

1 - Set the property in SfRibbonMenu.Padding = 5 && Was 2, we need a wider "border" to detect the mouse

2 - In SfRibbonMenuForm.ShpBorder.MouseEnter() add the following code:
Thisform.Hide()
3 - In SfRibbonMenuForm.Deactivate() add the following code:
Thisform.Hide()
4 - In SfRibbonMenuForm.tmrClick.Timer() , clean the code for testing

If you'd like to see this feature implemented, add a πŸ‘ reaction to this post.

button menu

Doug,
had an issue with button menus appearing in the wrong place (even the wrong monitor) depending upon a form's .showwindow setting.

So i re-worked (in my copy) sfribbonmenuform by setting
.desktop = .f.
.showwindow = 1 (in top-level form... more later)

then by adding an invisible button (1x1) and having .show() setfocus to it... i was able to add
this.hide()
to the form's .lostfocus() event and get rid of the timer.

the biggest problem was that if the ribbon is being created in a form's .init() then the 'top-level form' this menu appeared in is not the yet-to-exist-form it is supposed to be on. So.... i had to change sfribbonmenu.addbar() to store the parameters in an array and not create the sfribbonmenuform till the first call on .showmenu(). That means .addbar() doesn't return an object so i don't have submenus as yet. i'm not using submenus so haven't looked into this. Could probably add a dummy (not container) object to the array and return that.. then use that object's properties to create the submenu when it instantiates the form.

Now the menu is IN the top level it is straightforward to calculate its position; that said objtoclient() wasn't always working for me so i currently loop through parent containers summing .left and .top as i go.

it's now working for me regardless of being in _screen, top level or whatever.

Nigel

Menu for AllowShowTabsOnly

πŸ“ What's going on?

If clicked on the RibbonDisplayButton, nothing seems to happen. "Nothing" means: not even the expected menus shows up.

This Bug happens on a ribbon-usage on _SCREEN. This might be happening due to this special usage, but as the menu-use on the sfRibbonToolbarButton is working just fine, there must be more to it.

βœ”οΈ Expected result

The intended menu should show up and be selectable to the user.

❌ Actual result

If the menu-form-shows-in-taskbar-bug is not yet fixed, one can see that the menu shows up (in the taskbar) for a few milliseconds before dissapearing again.

There seems to be something going on that lets the menu dissapear right after ShowMenu()

Test
If i disable the Menu-Timer for good, the menu stays on and does not dissapear.

image

Of course a disabled timer is not a solution as it is responsible for the check-for-outofForm-Clicks. But the menu itself shows up and is workable just fine.

image

Yepp... the position is screwed up, but that is another problem i will put in another report as it might be easier to work on the individual tasks... Report for the wrong position is: #19 (comment)

So the test with deactivated menuform-timer proofs that the thing itself is working, but the menu to get to the point is simply dissapearing due to timer-action.

I have not (yet) find a solution to that and if this behavior is special to the oRibbon-on-_SCREEN-usage, but something lets the timer immediately "detect" an out-of-form-mouseclick. ...which then shuts down the menu-form right away.

I will edit/add further infos on this if i will find anything new, but until now... used on _SCREEN, this won't work.

monitor scaling causes oGDI.MeasureString() to return incorrect value

i suspect it's the hard coding of cnFACTOR ?

for now i have replaced the call on .measurestring() and subsequent use of .nwidth in my copy with variations on
TXTWIDTH(THIS.CAPTION,THIS.lblbutton.FONTNAME,THIS.lblbutton.FONTSIZE) * FONTMETRIC(6,THIS.lblbutton.FONTNAME,THIS.lblbutton.FONTSIZE)
and that seems to be working in testing so far.

I can post my new versions of .calculatewidth() for sfribbontoolbarbutton, sfribbontoolbarbuttonhorizontal and sfribbontab but suspect you'd prefer a gdi solution?

n

Suggestion: New Property for "SfRibbonToolbarButton" - "ClickEvent"

πŸ“ Use event binding to associate a form method to each button click event

Instead of using sometimes dangerous Execscript, I would add a new property to the Toolbar buttons - something like "ClickEvent". This would store the Current form related Method that would be fired when the button was clicked.
Internally, something similar to below would happen, at the button initialization:

IF NOT EMPTY(This.ClickEvent) and PEMSTATUS(Thisform, This.ClickEvent, 5) && We have the method in the form
   BINDEVENT(This, "Click", Thisform, This.ClickEvent)
ENDIF

This would provide another safe way for us to put whatever code we like.
In my case, the Ribbon was not being released because the object "loThisform" was still active. This used to happen when an external object was calling the Form.Release().

If you agree to that, the current Click event should not show the "Not Implemented" Messagebox when empty

On my side, I am currently using the way below using BINDEVENTS directly with nice results:

m.loButton = .AddButton()
WITH m.loButton
	* .IMAGE   = m.lcImagePath + "Exit.png"
	.CAPTION = "Close"
	.COMMAND = "SET REPORTBEHAVIOR 90" && Dummy command to avoid the "Not implemented" msg
ENDWITH
BINDEVENT(loButton, "Click", Thisform, "ActionClose")

Make Method sfRibbonBase.GetThemeColor Public (not protected)

πŸ“ It would be interesting to let the method "GetThemeColor" public,to allow an easier access to the themes used. For instance, to make other objects outside the Ribbon to use some of the Themed colors.

lnHighlightedColor = Thisform.oRibbon.GetThemeColor('buttonhighlightcolor')

Doug, This is an amazing work!
Loving to play with it, thanks for sharing!

Add button to hide/show the ribbon like the one on Windows Explorer

I'd like you to add a small button so that when clicked it hides the ribbon, except the main options, and when clicked again, the ribbon shows.

This would be useful when there are forms that have much information to be shown, this button would allow to leave more space for those forms (when the ribbon is hidden).

Add a Container or Shape in the Menu form to mimic MouseLeave to release it

Hi Doug,
I just played a little on this idea, and got it working. Hopefully you'd find it useful - When you find some time, you can try the following:

1 - In the menu Form, add a transparent container or a Shape control that should resize with the form every time a button is added
2 - The menu items don't need to be inside the container. Just make sure the container or shape is slightly bigger than the menu items, and Behind the menu items
3 - In the Container's 'MouseLeave()' event, add some code similar to the below

LPARAMETERS nButton, nShift, nXCoord, nYCoord
IF nXCoord <= This.Left OR nXCoord >= (This.Left + This.Width) OR ;
	nYCoord <= This.Top OR nYCoord >= (This.Top + This.Height)
	Thisform.Release()
ENDIF 

ribbon overflow

Doug,

i've added (my copy) a simple mechanism that shows a double chevron top right if the active toolbar's controls overflow the width of the form..... click and it will shuffle the toolbar left so all the remaining buttons are visible.
See photos
over1
over2
over3

is this something you would want to include?

n

Separator Bug

When I navigate through the tabs, going from right to left, the last section separator on the right, suddenly disappears. When you click on any button or menu, the separator reappears.

The problem occurs when navigating from RIGHT TO LEFT through the tabs. Going from left to right the problem does not appear.

I would like to know if you have any update to solve this bug.

public loThisform

rather than use a public variable i have added (my copy) an .oParentform property to sfribbonbase and sfribbonmenuform , set it to 'thisform' in their .init() events and then changed sfribbontoolbarbutton.click() to
loThisform = This.oparentform

n

Control not aligned when the lower label is wider than the control

πŸ“ Provide detailed reproduction steps (if any)

In class "sfRibbonToolbarSection", method "CalculateWidth"
Added some few code to realign a unique control if the section width is bigger than the inside control width

βœ”οΈ Expected result

  • Centered controls in section

❌ Actual result

  • Uncentered control

πŸ“· Screenshots

Are there any useful screenshots? WinKey+Shift+S and then just paste them directly into the form
image

A simple fix below:

LOCAL lnWidth, ;
lcType, ;
loControl, ;
llVertical, ;
lnLeft, ;
lnCaptionWidth

LOCAL lnTop
m.lnWidth = 0

  • 2023-07-07 VfpImaging
    LOCAL lnControls, loUnique as Control
    m.lnControls = 0

for each m.loControl in This.Controls foxobject
m.lcType = iif(pemstatus(m.loControl, 'Type', 5), m.loControl.Type, '')

do case
	* Do nothing if this is the separator or section label or the control isn't
	* visible.
	case inlist(m.loControl.Name, 'linSeparator', 'lblSection') or ;
			(pemstatus(m.loControl, 'Visible', 5) and not m.loControl.Visible)
		&& do nothing

		* Horizontal button: if we already have enough buttons in this column, move to
		* the next column. Set the Left property and if this isn't the first one, set
		* the Top property. Then increment the total width value.
		LOOP
		
	case m.lcType = 'HButton'
		if m.llVertical and m.lnTop + m.loControl.Height > This.Height
			m.llVertical = .F.
		endif m.llVertical ...
		
		if m.llVertical
			m.loControl.Top  = m.lnTop
			m.loControl.Left = m.lnLeft
		ELSE
			m.loControl.Left = max(m.lnWidth, This.Padding)
			m.lnLeft         = m.loControl.Left
		endif m.llVertical
		
		m.lnWidth    = max(m.lnWidth, m.loControl.Left + m.loControl.Width)
		m.lnTop      = m.loControl.Top + m.loControl.Height
		m.llVertical = .T.
		* For all other controls, move the control to the next Left position and
		* increment the total width value.

	CASE 1 = 2

	OTHERWISE 
		m.loControl.Left = max(m.lnWidth, This.Padding)
		m.lnWidth        = max(m.lnWidth, m.loControl.Left + m.loControl.Width)
		m.llVertical     = .F.

ENDCASE 

* 2023-07-07 VfpImaging
m.lnControls = m.lnControls + 1
m.loUnique = m.loControl
*

NEXT m.loControl

m.lnCaptionWidth = This.oGDI.GetWidth(This.Caption)
This.linSeparator.Left = max(m.lnWidth, m.lnCaptionWidth) + This.Padding
store This.linSeparator.Left to This.Width, This.lblSection.Width
This.Parent.AdjustSections()

  • 2023-07-07 VfpImaging
  • Realign if we are dealing with a single control, in case the lower lable width is bigger than the control width
  • If we have just one control, center it
    IF m.lnControls = 1
    m.loUnique.Left = CEILING((This.Width - m.loUnique.Width) / 2)
    ENDIF

RibbonDisplayButton - Menu shows on wrong position

πŸ“ What's going on?

The menu activated on click to the oRibbon.RibbonDisplayButton is show on a wonky position. ...at least when the Ribbon is used in _SCREEN.

As the sfribbonmenu-form is a Top-Level-Form, the menuform.left is always absolut to windows-screen-positions not to THISFORM-relative-position.

βœ”οΈ Expected result

As with the usage of menus on sfribbonToobarButton the menu should show up right "under" the button/ribbon and not "somewhere"-else.

❌ Actual result

image

The position of the menu is dependent of windows-screensize, mainform-size and -postiion. Which should not be the case.

Digging to the code, i see a difference in calling the .ShowMenu() Function between the call used in sfRibbonToolbarButton (works good) and the call used on the RibbonDisplayButton

Solutions so far

There seems to be a double-headed but in here.

sfRibbonToobarButton has special Code in its ShowMenu - Method. The ShowMenu-Call from the RibbonDisplayButton has no special treatment for positions in it. It is simply called as-is.

If i copy the code to the RibbonDisplayButton.ShowMenu, everything works (nearly)

image

But this is counteracted by a code specially built-in for "off-form"-positions to achieve menu-positions not expand over the right border of the form.

image

As sfribbonmenuform is a top-Level-form, its .LEFT is always relative to windows-screen and not THISFORM.LEFT.

My solution works for _SCREEN & DESKTOP=.T. usage, but i have not tested sideeffects to "regular" form usage. It is possible that there needs to be a different aproach for each scenario.

Some tweaking is needed for the top-position on the Ribbon-Button.ShowMenu-Call, but that's something for another day.

listbox

if you use .addcontrol() to add a listbox it looks great and works most of the time; but every so often (one in 10?) the listbox fails to repaint itself when you switch between tabs. It's there because if i click the mouse on where it is supposed to be it will re-appear one row at a time as i move the mouse around.
I suspect this is a VFP thing rather than the ribbon class but haven't found a way round it yet; i tried putting .visible = .f., .visible = .t. in the listbox's refresh event in the hope it would re-paint itself and that helped a little. But i changed my mind about using a listbox anyway in this particular instance and haven't pursued it yet.

button tooltiptext

we can set a button's tooltiptext but it only applies to the container.
So edit the property to have an assign method and in sfribbontoolbarbutton.tooltiptext_assign
add this line at end
this.SetAll('tooltiptext',this.ToolTipText)

sfribbonmenuform should have ShowInTaskBar = .F.

What's going on?

If a menu is instantiated, the form/window of the different menu-levels show up on the windows taskbar.

βœ”οΈ Expected result / Actual Result

The windows used by the menusystem should not show up on the taskbar. The forms are only cleverly used by the menu-object-hierachy and are not "real" windows to be presented to the user on the taskbar.

...especially not because their title-caption is "sffibbonmenu" πŸ˜„

Special Hint

This bug might be only true if used in a top-level-form or the _screen itself. I have not tested to the contrary as my project resides directly IN _SCREEN which works great with just two little glitches. This being on of them.

Solution

Easy: Set sfribbonmenuform.ShowInTaskbar=.F. and everyone will be happy

πŸ“· Screenshots

image

image

Menu on sfribbonToolbarMenu has top-offset when used in _SCREEN

What's going on?

When sfRibbon is used directly on _SCREEN, a menu attached to a sfRibbonToolbarButton has an offset to its top-property which should not be there.

The code shows why this happens. πŸ˜‰

This only happens when oRibbon is attached directly to _SCREEN
...which works perfectly well.

βœ”οΈ Expected result

The menu should be "attached" to the ribbon as it is when used on a "normal" form.

Solution

The Code of sfRibbonToolbarButton.ShowMenu is correctly using a special treatment if used on a "desktop=.T."-form. But... if used in _SCREEN the following code does not break, but delivers the wrong assumption as _SCREEN.Desktop is READONLY and cannot be altered to a usable .T.

Original Code
dodefault(objtoclient(This, 1) + This.Height + Thisform.Top + ; sysmetric(9) + sysmetric(4) + ; iif(Thisform.Desktop, 0, sysmetric(9) + sysmetric(20)), ; objtoclient(This, 2) + Thisform.Left + sysmetric(3))

If added an additional OR to test for _SCREEN, everything works fine:

dodefault(objtoclient(This, 1) + This.Height + Thisform.Top + ; sysmetric(9) + sysmetric(4) + ; iif(Thisform.Desktop OR thisform.HWnd==_screen.HWnd, 0, sysmetric(9) + sysmetric(20)), ; objtoclient(This, 2) + Thisform.Left + sysmetric(3))

πŸ“· Screenshots

image

image

tabs remaining highlighted

Doug,
if you press mousedown on a tab and then move the mouse up to the window's title bar before releasing... the tab doesn't get a .mouseleave() event and remains highlighted. (i must have been doing this inadvertently every once in a while when clicking on a tab).
This is compounded by the line in .mouseenter()
This.nBackColor = This.BackColor
saving the (now) highlighted colour; themes_assign will have set .nBackColor already so i have commented this line out. Now at least next time i .mouseleave() it gets reset to the correct .backcolor.

I'm guessing the only way to prevent this happening in the first place is to put the tab's .top to 1 so it gets a chance to see .mouseleave() ?

n

Wrong control width when Button caption is empty

Buttons are getting a fixed value of 100 pixels when the button caption is empty.
Fix:

In SfRibbonToolbarButton.CalculateWidth, added code to deal with the empty Caption:

LOCAL lnWidth

DO CASE
CASE NOT EMPTY(THIS.CAPTION)
IF THIS.WORDWRAP
THIS.oGDI.SETSIZE(THIS.LBLBUTTON.WIDTH, THIS.LBLBUTTON.HEIGHT)
ENDIF THIS.WORDWRAP
THIS.oGDI.MEASURESTRING(THIS.LBLBUTTON.CAPTION)
m.lnWidth = MAX(CEILING(THIS.oGDI.nWidth) + 2 * THIS.LBLBUTTON.LEFT, ;
THIS.IMGBUTTON.WIDTH + 2 * THIS.Padding)
&& use a width of the label or the image, whichever is wider
&& This.lblButton.Width is inaccurate if the form isn't visible yet
IF THIS.WIDTH <> m.lnWidth AND NOT THIS.WORDWRAP
THIS.WIDTH = m.lnWidth
THIS.LBLBUTTON.WIDTH = THIS.WIDTH - 2 * THIS.LBLBUTTON.LEFT
ENDIF THIS.WIDTH <> m.lnWidth ...
THIS.IMGBUTTON.LEFT = INT((THIS.WIDTH - THIS.IMGBUTTON.WIDTH) / 2)
&& center the image

	* If there's one line of text, center the down button below the label.

	IF THIS.oGDI.nLines = 1
		THIS.IMGDOWN.LEFT = INT((THIS.WIDTH - THIS.IMGDOWN.WIDTH) / 2)
		THIS.IMGDOWN.TOP  = THIS.LBLBUTTON.TOP  + 24
	ELSE
		THIS.IMGDOWN.LEFT = THIS.LBLBUTTON.LEFT + THIS.LBLBUTTON.WIDTH  - 5
		THIS.IMGDOWN.TOP  = THIS.LBLBUTTON.TOP  + THIS.LBLBUTTON.HEIGHT - 10
	ENDIF THIS.oGDI.nLines = 1
	THIS.nLines = THIS.oGDI.nLines
	THIS.PARENT.CalculateWidth()
  • 2023-07-06 VfpImaging

  • Align empty captions
    OTHERWISE && Empty(This.Caption)
    m.lnWidth = THIS.IMGBUTTON.WIDTH + (2 * THIS.Padding)
    THIS.WIDTH = m.lnWidth
    THIS.LBLBUTTON.WIDTH = THIS.WIDTH - 2 * THIS.LBLBUTTON.LEFT
    THIS.IMGBUTTON.LEFT = INT((THIS.WIDTH - THIS.IMGBUTTON.WIDTH) / 2)
    && center the image

      THIS.IMGDOWN.LEFT = INT((THIS.WIDTH - THIS.IMGDOWN.WIDTH) / 2)
      THIS.IMGDOWN.TOP  = THIS.LBLBUTTON.TOP  + 24
      THIS.nLines = 1
      THIS.PARENT.CalculateWidth()
    

ENDCASE

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.