When I use comboboxtext with a lot of options, I can see that there is no scroll. I can go up and down with the mouse, moving it or with the central button, but the typical scroll widget to move faster up and down does not appear anywhere.
How can I make the scroll widget appear in the options of the comboboxtext?
require 'gtk3'
Material2 = Gtk::ComboBoxText.new()
for i in (0..100)
string = "material " + i.to_s
Material2.append_text(string)
end
$MenuPrincipal = Gtk::Table.new(60, 60, true)
$MenuPrincipal.attach(Material2, 0, 60, 0, 10, $options, $options, 0, 0)
$window = Gtk::Window.new
$options = Gtk::AttachOptions::EXPAND | Gtk::AttachOptions::SHRINK
$window.add($MenuPrincipal)
$window.show_all
Gtk.main
Thanks in advance
You need to change (or add) line in the css style:
* {
-GtkComboBox-appears-as-list: 1;
}
If you don't have control over user's style see my answer about modifying labels' style from code (example is in python).
I have not found how to achieve it without modifying style but maybe there is some hidden gem in ruby bindings.
Related
I need to make tooltip a little bit right and lower to mouse cursor, but i can't do it in any way, tried different coordintaes but nothing seems to work. Where is the problem? Thank you.
// Add the new tooltip (if available)
if (m_LastToolTipRow!=-1 && m_LastToolTipRow!=-1)
{
// Not using CToolTipCtrl::AddTool() because it redirects the messages to CListCtrl parent
TOOLINFO ti = {0};
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_IDISHWND | TTF_TRANSPARENT; // Indicate that uId is handle to a control
ti.uId = (UINT_PTR)m_hWnd; // Handle to the control
ti.hwnd = m_hWnd; // Handle to window to receive the tooltip-messages
ti.hinst = AfxGetInstanceHandle();
ti.lpszText = LPSTR_TEXTCALLBACK;
m_OwnToolTipCtrl.SendMessage(TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
m_OwnToolTipCtrl.SendMessage(TTM_TRACKPOSITION, 0, (LPARAM)MAKELPARAM(pt.x + 100, pt.y + 100));
m_OwnToolTipCtrl.SendMessage(TTM_TRACKACTIVATE, true, (LPARAM)&ti);
m_OwnToolTipCtrl.Activate(TRUE);
//Multiline
m_OwnToolTipCtrl.SetMaxTipWidth(256);
//m_OwnToolTipCtrl.SetMaxTipWidth(SHRT_MAX);
}
TTF_IDISHWND
Indicates that the uId member is the window handle to the tool. If this flag is not set, uId is the tool's identifier.
According to this, the window with m_hWnd handle is the one that shows the tooltip and you can position the window itself. If you meant a tooltip separate to that window than there is a principal problem there.
I'm using the CMFCPopupMenu to create a right click popup menu. The problem is that the first time the menu is shown only the menu frame with shades is shown but the contents is white. The second time the menu is shown there are no problems. The code looks like this:
CPoint point;
::GetCursorPos (&point);
CMFCPopupMenu* pop = new CMFCPopupMenu();
pop->InsertItem(CMFCToolBarMenuButton(ID_COMMAND_1,NULL,-1,_T("Command 1")));
pop->InsertItem(CMFCToolBarMenuButton(ID_COMMAND_2,NULL,-1,_T("Command 2")));
pop->InsertItem(CMFCToolBarMenuButton(ID_COMMAND_3,NULL,-1,_T("Command 3")));
pop->InsertItem(CMFCToolBarMenuButton(ID_COMMAND_4,NULL,-1,_T("Command 4")));
pop->Create(this,point.x,point.y,NULL,0,true);
The parent class is based on CDialogEx.
Thanks.
I don't understand why my approach doesn't work but I found a way around it by defining the menu in the ressource and do like this:
CMenu menu;
menu.LoadMenu(IDR_SESSION_MENU);
HMENU hMenu = menu.GetSubMenu (0)->Detach ();
CMFCPopupMenu* pMenu = theApp.GetContextMenuManager()->ShowPopupMenu(hMenu, point.x, point.y, this, TRUE);
That Works and the only problem is that it's a bit more complicated to have a menu with dynamic entries depending on state and selection.
CMFCPopupMenu* pPopupMenu = new CMFCPopupMenu;
if (pPopupMenu->Create(pWndOwner, point.x, point.y, NULL, FALSE, TRUE))
{
pPopupMenu->InsertItem(CMFCToolBarMenuButton(57645, NULL, -1, _T("Command 1")), -1);
pPopupMenu->InsertItem(CMFCToolBarMenuButton(57646, NULL, -1, _T("Command 2")), -1);
pPopupMenu->RecalcLayout();
}
Need call RecalcLayout() after insert
I have an EDIT control created like this:
hwndEDIT_5 = CreateWindowEx (
0, "EDIT", NULL,
WS_VSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_READONLY,
135, 450, 555, 200,
h2, ( HMENU ) ID_EDIT_CONSOLE,
h1, NULL
);
As you can see it is a read-only EDIT area where multi lines text can be displayed. It is supposed to be a console where I can display some information for users when they use the program. I would like the text area to automatically scroll to the bottom-most entry (the newest one) whenever a new line (or message for an user) is added. I've implemented this:
SetDlgItemText ( h2, ID_EDIT_CONSOLE, ch_s );
SCROLLINFO scr;
SCROLLINFO * scr_p = &scr;
scr.cbSize = sizeof ( SCROLLINFO );
scr.fMask = SIF_RANGE;
GetScrollInfo ( GetDlgItem ( h2, ID_EDIT_CONSOLE), SB_VERT, scr_p );
int mmax = scr.nMax;
scr.fMask = SIF_POS;
scr.nPos = mmax;
SetScrollInfo ( GetDlgItem ( h2, ID_EDIT_CONSOLE), SB_VERT, scr_p, TRUE );
That code is scrolling vertical scrollbar to the end of an EDIT control after adding new msg and it works great, the scrollbar gets scrolled but the text still remains visible from the beginning - it rewinds to the beginning after addition while scrollbar rewinds to the bottom. How to make it properly?
Last but not least - this is might be important - in order to display a message firstly I capture the text that is already displayed by using:
GetDlgItemText ( h2, ID_EDIT_CONSOLE, buf, len + 1 );
then I convert buf into string and add to that string a new message that I want to display. Then I convert it back to char array and set it up with SetDlgItemText. I seperate lines by using \r\n. I've coded it that way because I didn't know how to add a line to an EDIT control in different way than using SetDlgItemText. And it adds only one entry AFAIK - if used twice I will not come up with two entries added to an EDIT control, but the first one will get replaced by second function call.
Don't use SetScrollInfo. Use SendMessage() with the EM_LINESCROLL message, sending the message to the edit control's window handle.
SendMessage(MemoHwnd, EM_LINESCROLL, 0, NumLinesToScroll);
The documentation says:
The control does not scroll vertically past the last line of text in the edit control. If the current line plus the number of lines specified by the lParam parameter exceeds the total number of lines in the edit control, the value is adjusted so that the last line of the edit control is scrolled to the top of the edit-control window.
I had the same problem and solved it with Jerry Coffin's answer and some research.
This is the way I use now:
string text = "Append this text";
SendMessageA(hEdit, EM_SETSEL, 0, -1); //Select all
SendMessageA(hEdit, EM_SETSEL, -1, -1);//Unselect and stay at the end pos
SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)(text.c_str())); //append text to current pos and scroll down
If needed: To scroll at the end of Edit Control without appending text:
SendMessageA(hEdit, EM_SETSEL, 0, -1); //Select all.
SendMessageA(hEdit, EM_SETSEL, -1, -1);//Unselect and stay at the end pos
SendMessageA(hEdit, EM_SCROLLCARET, 0, 0); //Set scrollcaret to the current Pos
You can add text by setting the beginning and end of the selection to the end of the text in the control (EM_SETSEL), then replacing the (empty) selection with your new text (EM_REPLACESEL).
Scrolling to the bottom can be done with EM_SCROLLCARET after the caret (the selection) is at the end of the text. There are other ways, but if you're doing it immediately after adding text, this is probably the easiest.
in my case I had a multi line string and Ken White's idea worked very well:
HWND hEdit = this->GetDlgItem(IDC_EDIT_LOG)->m_hWnd;
if (hEdit)
{
int lineCount = m_strClientLog.Replace(_T("\n"), _T("\n"));
::SendMessage(hEdit, EM_LINESCROLL, 0, lineCount);
}
for MFC projects you can use:
mLoggingTextCtl.SendMessage(EM_SETSEL, 0, -1); //Select all.
mLoggingTextCtl.SendMessage(EM_SETSEL, -1, -1);//Unselect and stay at the end pos
mLoggingTextCtl.SendMessage(EM_SCROLLCARET, 0, 0); //Set scrollcaret to the current Pos
I'm coding on Tk 8.5.9 from ActiveTcl on Ruby 1.8.7 on a Mac OS X 10.6.
To meet my application requirements I need to make the button widgets as small as the gif image but I am not able to. I have been hours searching and experimenting with negative results.
Greatly thankful in advance for any clues.
Following is the code i am trying to get small buttons from.
require 'tk'
require 'tkextlib/tile'
$up_img = TkPhotoImage.new("file"=>"arrowup-n.gif")
$down_img = TkPhotoImage.new("file"=>"arrowdown-n.gif")
root = TkRoot.new {title "Ek Composer"}
content = Tk::Tile::Frame.new(root).pack
Tk::Tile::Button.new(content) {width 1;image $up_img; command {move_up} }.pack
Tk::Tile::Button.new(content) {width 1;image $down_img;command {move_down}}.pack
def move_up
p "move up"
end
def move_down
p "move down"
end
Tk.mainloop
But the buttons remain too big :(.
It's awkward. The OSX theme really wants to add extra space at either end of the button.
You can try switching to the classic button (in tk itself) but that puts more space vertically and looks a bit less native. Or you can put the image in a label (which you can shrink exactly) and add bindings to it to make it respond to mouse clicks.
I added binding to label. Works fine. Thanks. Follows a code snippet of label with binding as button.
require 'tk'
$resultsVar = TkVariable.new
root = TkRoot.new
root.title = "Window"
$up_img = TkPhotoImage.new("file"=>"arrowup-n.gif")
$down_img = TkPhotoImage.new("file"=>"arrowdown-n.gif")
Lbl = TkLabel.new(root) do
image $up_img
borderwidth 0
font TkFont.new('times 20 bold')
foreground "red"
relief "groove"
pack("side" => "right", "padx"=> "50", "pady"=> "50")
end
Lbl.bind("ButtonPress-1") {
Lbl.configure("image"=>$down_img)
}
Lbl.bind("ButtonRelease-1") {
Lbl.configure("image"=>$up_img)
}
Lbl['textvariable'] = $resultsVar
$resultsVar.value = 'New value to display'
Tk.mainloop
I'm using Unity 3 to build my game. I have a basic GUI button that when clicked, I would like the user to be taken to a random level. There are 10 levels in my game. Below is a copy of the code I'm trying to implement.
function OnGUI()
{
// Make a background box
GUI.Box(Rect(10, 10, 100, 90), "Oracle");
if (GUI.Button(Rect(20, 40, 80, 20), 9)) ;
{
Application.LoadLevel(Random.Range(0, 9));
}
}
It's not happening. I've also tried:
function OnGUI()
{
// Make a background box
GUI.Box(Rect(10, 10, 100, 90), "Oracle");
if (GUI.Button(Rect(20, 40, 80, 20))) ;
{
Application.LoadLevel(Random.Range(0, Application.levelCount 9));
}
}
I've never used the Random.Range function before and somewhat confused at the proper format.
Also I have EZ GUI available and was wondering if I could enter the correct Random Range script into the 'script' dropdown or 'script with method' drop down work it, as I'd rather use a custom button. Any assistance would be greatly appreciated.
Here is the code that worked. I will be rebuilding and adding a few more levels I will try the straight from the Unity docs and see if the random scene loads from just the number of scenes in the build. Thanks DigitalD
static var levelCount : int;
function OnGUI () {
// Make a background box
GUI.Box (Rect (10,10,100,90), "ORACLE");
if (GUI.Button (Rect (20,40,80,20), "Genie")) {
Application.LoadLevel (Random.Range(0, Application.levelCount-5));
}
}
The example code from the Unity docs should work fine. "Application.LoadLevel(Random.Range(0, Application.levelCount))" will load a random scene. The level numbers are based on the order in your build settings. Is is possible you forgot to include them in the build? Just having 10 scenes isn't enough, they'll be stripped out if they're not included in the build.