How to have a single tool tip display for multiple controls - tooltip

I have a number of different controls that I want to display the same tool tip. The issue is that the 'for' property appears to be single value. Is there a way to have a single tool tip respond to the mouse over on multiple controls.

You can set a single tool tip for all controls using the following steps
Create a div element
Set style.display = 'none' for the div
Append it to the body of the document
In mouseover event , get the mouse co-ordinates using evt.clientX and evt.clientY and then set
style.display = 'block'
style.position = 'absolute'
style.top = evt.clientY +'px'
style.left = evt.clientX + 'px' for the div

Related

VoiceOver accessibility focus on a series of elements

Say I have a dialog box like this:
and I want to focus on title, then body and then each button one after another. I am able to focus on body using
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, dialog.bodyLabel);
but is there any way to define a set of elements we want to focus instead of a single one?
EDIT:
I have also tried to make a list of elements I want to focus on using this syntax:
dialog.accessibilityElements = #[dialog.titleLable, dialog.bodyLable, etc];
but it just reads the first element (in this case dialog.titleLable) and doesn't move to the next one. Any thoughts?
The default value is set to NO for all the elements.
set the isAccessibleElement to YES for the all individual elements in the dialog
and then you can do
dialog.accessibilityElements = #[dialog.titleLable, dialog.bodyLable];
so that voice over reads title label first and body label next.

Scroll bar in LibreOffice dialog

I am trying to make an image picker component in LibreOffice.
I have a dialog that is dynamically filled with images. When the user clicks on one images, it should be selected and the dialog should be closed.
The problem is that the number of images is variable. So I need to enable scrolling in the dialog (so that the user can navigate through all images).
There seems to be some properties on the dialog object (Scrollbars, Scroll width, Scroll height, etc)
However, I cannot find a way to use them anywhere.
Any ideas?
The scrollbar is one of the Controls available through the dialog box editor. That is the easier way to put a ScrollBar on a dialog box. Just insert it like any other control. There is a harder way via DialogModel.addControl but that seems non-essential to answering this question.
If you add a scrollbar to the dialog box and run the dialog box, you will find it does nothing by default. The functionality (apparently) must be written into a macro. The appropriate triggering event is the While Adjusting event on the ScrollBar object, although it does not trigger the macro simply with the "Test Mode" function in the dialog editor. Running the dialog box through a macro triggers the While Adjusting event when the scroll arrows are triggered, when the slider area is clicked to move the slider, and when the slider itself is dragged. The Object variable returned by the scrollbar event contains a property .Value which is an absolute value between 0 and the EventObject.Model.ScrollValueMax, which allows you to manipulate the other objects on the page manually based on the position of the slider.
Yes, that's right, manipulate objects manually. The sole example I found, from the LibreOffice 4.5 SDK, does precisely this. Of course, it is not as bad as it sounds, because one can iterate through all of the objects on the page by reading the array Dialog.getControls(). In any event, the secret sauce of the example provided in the SDK is to define Static variables to save the initial positions of all of the objects you manipulate with the scrollbar and then simply index those initial positions based on a ratio derived from the scrollbar Value divided by the ScrollValueMax.
Here is a very simple working example of how to scroll. This requires a saved Dialog1 in the Standard library of your document, which contains an object ScrollBar1 (a vertical scrollbar) and Label1 anywhere in the dialog. The ScrollBar1 must be configured to execute the macro ScrBar subroutine (below) on the While Adjusting event. Open the dialog by executing the OpenDialog macro and the scrollbar will move the Label1 control up and down in proportion to the page.
Sub OpenDialog
DialogLibraries.LoadLibrary("Standard")
oVariable = DialogLibraries.Standard.Dialog1
oDialog1 = CreateUnoDialog( oVariable )
oDialog1.Execute()
End Sub
Sub ScrBar (oEventObj As Object)
Static bInit As Boolean
Static PositionLbl1Y0 As Long
oSrc = oEventObj.Source
oSrcModel = oSrc.Model
scrollRatio = oEventObj.Value / oSrcModel.ScrollValueMax
oContx = oSrc.Context
oContxModl = oContx.Model
oLbl1 = oContx.getControl("Label1")
oLbl1Model = oLbl1.Model
REM on initialization remember the position of the label
If bInit = False Then
bInit = True
PositionLbl1Y0 = oLbl1Model.PositionY
End If
oLbl1Model.PositionY = PositionLbl1Y0 - (scrollRatio * oContx.Size.Height)
End Sub
The example provided by the SDK does not run on my setup, but the principles are sound.
There appears to be a second improvised method closer to the functionality one might expect. This method uses the DialogModel.scrollTop property. The property appears to iterate the entire box up or down as a scroll based on the user input. There are two problems using this methodology, however. First, unless you put the scrollbar somewhere else, the scroll bar will scroll away along with the rest of the page. You will need to adjust the location of the scrollbar precisely to compensate for/negate the scrolling of the entire page. In the example below I tried but did not perfect this. Second, the property seems to miss inputs with frequency and easily goes out of alignment/ enters a maladjusted state. Perhaps you can overcome these limitations. Here is the example, relying on the same setup described above.
Sub ScrBar (oEventObj As Object)
Static scrollPos
oSrc = oEventObj.Source
oSrcModel = oSrc.Model
scrollRatio = oEventObj.Value / oSrcModel.ScrollValueMax
If IsEmpty(scrollPos) = False Then
scrollDiff = oEventObj.Value - scrollPos
Else
scrollDiff = oEventObj.Value
End If
scrollPos = oEventObj.Value
oContx = oSrc.Context
oContxModl = oContx.Model
oContxModl.scrollTop = scrollDiff * -1
oSrcModel.PositionY=(scrollRatio * oContx.Size.Height/5) * -1
End Sub
This (sort of) will scroll the contents of the entire dialog box, within limits and with the caveats noted above.

Select2 change container position

How can I adjust the position of Select2 container so that the search box is position right over the original select element like in this website
http://www.jobnisit.com/en
It look cleaner in terms of UI in my opinion.
Ps. sorry, I can't post the image now.
There is 2 ways to do this.
1) With css:
.select2-dropdown--below {
top: -2.8rem; /*your input height*/
}
This will not affect a container (.select2-container), but will move dropdown and search field, so you will have a desired effect.
2) With js:
$('select').select2().on('select2:open', function() {
var container = .$('.select2-container').last();
/*Add some css-class to container or reposition it*/
});
This code attaches a handler to 'select2:open' event, which will be fired every time when user opens a dropdown. This method is better if you have more than one select on page.
Tested with select2 4.0.0
The proper way of positioning the dropdown is using the core feature provided by select2 plugin.
It provides us with 'dropdownParent' property to place to dropdown inside the particular element
select field: #edit-field-job-skillsets-tid
parent item: div.form-item-field-job-skillsets-tid
jQuery("#edit-field-job-skillsets-tid").select2(
{dropdownParent: jQuery('div.form-item-field-job-skillsets-tid')}
);

slide up remaining items

I am working on a tool based on jQuery UI draggable functionality.
I have a number of boxes in the left column of the table. When they are dragged in yellow area, I would expect the remaining divs to move upwards to fill the space left by the box that was moved.
But it's not happening. Why?
It is pretty difficult to test but from my knowledge on the question here is a possible cause/solution to this.
The droppable plugin does not remove the dragged element from its original markup position, it is visually moved to the droppable element (with some option allowing to accept to drop certain elements or not, events, etc).
The elements have a position: relative css rule, which represents the "normal flow" for elements (in the order they appear in the markup). So even if the element is visually placed elsewhere on the page with css, its place in the markup is still the same and it is still taking the space it normally should.
This fiddle illustrate what i'm trying to explain :-)
By looking at the source code form the "working website", they actually remove the dragged element from the original draggable list and re-create it in the droppable list !
When they define the .droppable() they do this:
h.droppable({
tolerance: "intersect",
accept: ".card",
greedy: true,
drop: function (a, b) {
card = b.draggable;
putCardIntoStack(card, c)
}
});
On the drop event, they call putCardIntoStack(card, c) passing the currently dragged element as the card parameter. Within this method, they remove the original "card" (a.remove()) and re-create it in the dropzone (newcard = createCard();):
function putCardIntoStack(a, b) {
progressVal = $('#progBarRd').width();
card_idDOM = a.attr('id');
card_idDB = card_idDOM.substr(IDPREFIX_CARD.length, card_idDOM.length - IDPREFIX_CARD.length);
stack_idDB = b.substr(IDPREFIX_STACK.length, b.length - IDPREFIX_STACK.length);
$.ajax({
url: URL_DRAGDROPAJAX,
type: 'POST',
data: 'action=movecard&cardid=' + card_idDB + '&tostack=' + stack_idDB + '&prog=' + progressVal
});
// 'a' is the card
// they extract the id/content from the dragged card
cardId = a.attr('id');
cardLabel = a.text();
// they remove the card from the DOM
a.remove();
// they create a new card with the extracted info
newcard = createCard(cardId, cardLabel);
newcard.addClass('stackcard');
// and append it to the dropzone
$('#' + b).removeClass("empty").find('.stackDrop').append(newcard);
globalcheck()
}
jQuery UI does a similar thing on the droppable demo page. On the drop event, they call a function deleteImage() which removes the dragged image from the original markup and appends it to the drop zone.
I hope I'm clear enough :-)
I also hope I'm right, it is pretty difficult to test quickly but it makes sense :-)

Creating a ComboBox with one or more separator items?

I'm using Delphi7 and I'd like to have a ComboBox with separator items (Just like in popup menus).
I've seen this beautifully implemented in Mozilla Sunbird (I know, it's not Delphi...) the following way:
The separator item is a simple gray line
drawn in the center of the item
If you hover over the separator with
the mouse, the selection doesn't
appear
If the user clicks the separator,
it's not selected either AND the
combobox doesn't closeup.
No. 1 could be implemented using DrawItem. I could live without No. 2 because I have no idea about that.
For No. 3 I'm asking for your help. I've figured out that straight after closing up a CBN_CLOSEUP message is sent to the combobox.
I thought about hooking the window proc and if CBN_CLOSEUP is sent to a certain combobox then countering it. But I'm unsure if this is the best solution, or maybe there are other, more elegant ways?
Whatever the solution is, I'd like to have a standard ComboBox which supports WinXP/Vista/7 theming properly.
Thanks!
Edit: For a working component please see this thread:
Can you help translating this very small C++ component to Delphi?
I played around with making unclickable separator items (as described in this answer) and ran into several UI glitches. The problem is that combo boxes have several aspects to their behavior that can be hard to get exactly right:
Pressing the up and down arrow keys navigates the list while the list is dropped down.
Pressing Enter closes the dropped down list, selecting the current item.
Pressing Escape closes the dropped down list, selecting the current item (if the current item was chosen with the up and down arrow keys) or the last selected item.
If the combo box has the focus, then pressing the up and down arrow keys to changes the current selection without displaying the list.
If the combo box has the focus, then typing anything selects the combo box item matching whatever is typing.
If the combo box has the focus, then pressing F4 drops down the combo box list, which can then be controlled by keyboard or mouse.
Ensuring that disabled separator items don't respond to any of these events (plus any other events which I may be missing, e.g., screen readers?) seems fraught with error.
Instead, the approach I'm using is to draw the separator as part of the item:
Use a variable height owner draw combo box.
Add 3 pixels to the height for any items that need separators.
Draw a horizontal line at the top of each item needing a separator.
Here's some C++Builder code to accomplish this; translating it to Delphi should be easy enough.
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control,
int Index, TRect &Rect, TOwnerDrawState State)
{
bool draw_separator = NeedsSeparator(Index) &&
!State.Contains(odComboBoxEdit);
TCanvas *canvas = dynamic_cast<TCustomCombo*>(Control)->Canvas;
canvas->FillRect(Rect);
TRect text_rect = Rect;
// Add space for separator if needed.
if (draw_separator) {
text_rect.Top += 3;
}
canvas->TextOut(text_rect.Left + 3,
(text_rect.Top + text_rect.Bottom) / 2 -
canvas->TextHeight(ComboBox1->Items->Strings[Index]) / 2),
ComboBox1->Items->Strings[Index]);
// Draw a separator line above the item if needed.
if (draw_separator) {
canvas->Pen->Color = canvas->Font->Color;
canvas->MoveTo(Rect.Left, Rect.Top + 1);
canvas->LineTo(Rect.Right, Rect.Top + 1);
}
}
void __fastcall TForm1::ComboBox1MeasureItem(
TWinControl * /* Control */, int Index, int &Height)
{
Height = ComboBox1->ItemHeight;
// Add space for the separator if needed.
if (Index != -1 && NeedsSeparator(Index)) {
Height += 3;
}
}
What you want is an owner-drawn combobox. See this: http://delphi.about.com/od/vclusing/a/drawincombobox.htm
Also, this seems to solve making the item unclicable:
http://borland.newsgroups.archived.at/public.delphi.vcl.components.using.win32/200708/0708225320.html
As far as I know there is no VCL way of doing that, so you'll have to subclass the combobox. It would be nice to create component encapsulating those functionalities so you can reuse them easily.
God bless
If you want your controls to look good use the free SpTBXLib. It supports combo style components which popup a popup menu with lines.

Resources