bool Ctrl::HotKey(dword key) { GuiLock __; LLOG("HotKey " << GetKeyDesc(key) << " at " << Name(this)); if(!IsEnabled() || !IsVisible()) return false; for(Ptr<Ctrl> ctrl = firstchild; ctrl; ctrl = ctrl->next) { LLOG("Trying HotKey " << GetKeyDesc(key) << " at " << Name(ctrl)); if(ctrl->IsOpen() && ctrl->IsVisible() && ctrl->IsEnabled() && ctrl->HotKey(key)) { if(Ini::user_log && s_hotkey) { USRLOG(" HOT-> " << UPP::Name(ctrl)); s_hotkey = false; } LLOG("ACCEPTED"); return true; } } return false; }
bool Ctrl::DoKeyFB(dword key, int cnt) { LLOG("DoKeyFB [" << GetKeyDesc(key) << "] " << key << ", " << cnt); bool b = DispatchKey(key, cnt); SyncCaret(); Ctrl *desktop = GetDesktop(); if(desktop) desktop->PostInput(); return b; }
void ToolButton::UpdateTip() { LTIMING("UpdateTip"); String s = tiptext; if(IsNull(s) && kind == NOLABEL) s = text; if(accel) { if(s.GetCount()) s << ' '; s << '(' << GetKeyDesc(accel) << ')'; } Ctrl::Tip(s); }
Size MenuItem::GetMinSize() const { Size sz1 = GetTextSize(text, font); Size sz2(0, 0); if(accel) { sz2 = GetTextSize(GetKeyDesc(accel), font); sz2.cx += Zx(12); } Size lsz = min(maxiconsize, licon.GetSize()); Size rsz = ricon.GetSize(); return AddFrameSize(Size(max(lsz.cx, leftgap) + sz1.cx + max(sz2.cx, (rsz.cx ? Zx(16) : 0)) + max(rsz.cx, Zx(16)) + textgap + Zx(10), max(max(lsz.cy, rsz.cy) + Zy(4), sz1.cy + Zy(6)))); }
void Navigator::SyncCursor() { String k = "(" + GetKeyDesc(IdeKeys::AK_GOTO().key[0]) + ") "; search.NullText("Symbol/lineno " + k); search.Tip(IsNull(search) ? String() : "Clear " + k); if(!navigating && theide->editfile.GetCount()) { navlines.KillCursor(); int q = linefo.Find(GetSourceFileIndex(theide->editfile)); if(q < 0) return; navigating = true; SortedVectorMap<int, int>& m = linefo[q]; q = m.FindUpperBound(GetCurrentLine() + 1) - 1; if(q >= 0 && q < m.GetCount()) list.SetCursor(m[q]); navigating = false; } SyncLines(); }
static void ReadMacro(CParser& p) { IdeMacro macro; if(p.IsString()) { macro.menu = p.ReadString(); if(p.Char(':')) macro.submenu = p.ReadString(); } if(!p.IsChar('{')) macro.hotkey = ParseKeyDesc(p); EscLambda& l = macro.code.CreateLambda(); const char *t = p.GetPtr(); l.filename = p.GetFileName(); l.line = p.GetLine(); if(!p.Char('{')) p.ThrowError("missing '{'"); SkipBlock(p); l.code = String(t, p.GetPtr()); Array<IdeMacro>& mlist = UscMacros(); if(macro.hotkey) { int f = FindFieldIndex(mlist, &IdeMacro::hotkey, macro.hotkey); if(f >= 0) { PutConsole(NFormat("%s(%d): duplicate macro hotkey %s\n", l.filename, l.line, GetKeyDesc(macro.hotkey))); const EscLambda& lambda = UscMacros()[f].code.GetLambda(); PutConsole(NFormat("%s(%d): previously defined here\n", lambda.filename, lambda.line)); } } if(!IsNull(macro.menu)) { for(int i = 0; i < mlist.GetCount(); i++) if(mlist[i].menu == macro.menu && mlist[i].submenu == macro.submenu) { PutConsole(NFormat("%s(%d): duplicate macro menu item (%s:%s)\n", l.filename, l.line, macro.menu, macro.submenu)); const EscLambda& lambda = UscMacros()[i].code.GetLambda(); PutConsole(NFormat("%s(%d): previously defined here\n", lambda.filename, lambda.line)); break; } } mlist.Add(macro); }
void MenuItem::Paint(Draw& w) { int q = text.Find('\t'); String txt, keydesc; if(accel) keydesc = GetKeyDesc(accel); if(q >= 0) { keydesc = text.Mid(q + 1); txt = text.Mid(0, q); } else txt = text; state = GetVisualState(); bool hl = state != NORMAL; Size sz = GetSize(); if(hl) { if(GUI_GlobalStyle() >= GUISTYLE_XP) ChPaint(w, 0, 0, sz.cx, sz.cy, style->item); else w.DrawRect(sz, SColorHighlight); } UPP::Image li = licon; if(li.IsEmpty()) { switch(type) { case CHECK0: li = CtrlImg::MenuCheck0(); break; case CHECK1: li = CtrlImg::MenuCheck1(); break; case RADIO0: li = CtrlImg::MenuRadio0(); break; case RADIO1: li = CtrlImg::MenuRadio1(); break; } } Size isz = li.GetSize(); // Size isz = min(maxiconsize, imsz); // if(isz != imsz) // li = CachedRescale(li, isz); int iy = (sz.cy - isz.cy) / 2; bool chk = false; int x = Zx(2); if(!licon.IsEmpty() && type) { chk = type == CHECK1 || type == RADIO1; if(GUI_GlobalStyle() >= GUISTYLE_XP) { if(chk && !hl) DrawXPButton(w, RectC(0, iy - Zy(2), isz.cx + Zx(4), isz.cy + Zy(4)), BUTTON_EDGE|BUTTON_CHECKED); } else { w.DrawRect(x - Zx(1), iy - Zy(1), isz.cx + Zx(2), isz.cy + Zy(2), chk ? Blend(SColorFace, SColorLight) : SColorFace); DrawBorder(w, x - Zx(2), iy - Zy(2), isz.cx + Zx(4), isz.cy + Zy(4), chk ? ThinInsetBorder : ThinOutsetBorder); } } if(isenabled) DrawHighlightImage(w, x, iy, li, hl || chk, true); else w.DrawImage(x, iy, DisabledImage(li)); x = max(isz.cx, leftgap) + textgap; isz = GetTextSize(text, StdFont()); DrawMenuText(w, x, (sz.cy - isz.cy) / 2, txt, font, isenabled, hl, style->menutext, style->itemtext); isz = ricon.GetSize(); if(isenabled) w.DrawImage(sz.cx - isz.cx, (sz.cy - isz.cy) / 2, ricon, hl ? style->itemtext : style->menutext); else w.DrawImage(sz.cx - isz.cx, (sz.cy - isz.cy) / 2, DisabledImage(ricon)); x = sz.cx - max(isz.cx, Zx(16)) - Zx(1); if(!IsEmpty(keydesc)) { isz = GetTextSize(keydesc, StdFont()); UPP::DrawMenuText(w, x - isz.cx - Zx(2), (sz.cy - isz.cy) / 2, keydesc, font, isenabled, hl, 0, SColorMenuMark(), style->itemtext, false); } }
virtual bool Key(dword key, int count) { text = GetKeyDesc(key); Refresh(); return true; }
bool Ctrl::DispatchKey(dword keycode, int count) { GuiLock __; if(GUI_AltAccessKeys()) { bool alt = GetAlt(); Ctrl *c = GetActiveCtrl(); if(c) c->RefreshAccessKeysDo(alt); } // RLOGBLOCK("Ctrl::DispatchKey"); // RLOG("DispatchKey: focusCtrl = " << FormatIntHex((int)~focusCtrl) << ", wnd = " << FormatIntHex((int)~focusCtrlWnd) << ")"); LLOG("DispatchKey " << keycode << " (0x" << Sprintf("%08x", keycode) << ", " << GetKeyDesc(keycode) << "), count:" << count << " focusCtrl:" << UPP::Name(focusCtrl) << " focusCtrlWnd:" << UPP::Name(focusCtrlWnd)); if((keycode & K_KEYUP) && ignorekeyup) { ignorekeyup = false; return true; } for(int i = 0; i < keyhook().GetCount(); i++) if((*keyhook()[i])(focusCtrl, keycode, count)) return true; dword k = keycode; word l = LOWORD(keycode); if(!(k & K_DELTA) && l >= 32 && l != 127 && GetDefaultCharset() != CHARSET_UNICODE) k = MAKELONG((word)FromUnicode(l, CHARSET_DEFAULT), HIWORD(keycode)); if(!focusCtrl) return false; Ptr<Ctrl> p = focusCtrl; if(Ini::user_log) { String kl; dword k = keycode; const char *l = ""; if(k < 65536) { kl << "CHAR \'" << ToUtf8((wchar)keycode) << "\' (" << keycode << ')'; l = " "; } else { kl << "KEY"; if(k & K_KEYUP) { kl << "UP"; k &= ~K_KEYUP; l = " "; } kl << " " << GetKeyDesc(k); } USRLOG(l << kl); } for(;;) { LLOG("Trying to DispatchKey: p = " << Desc(p)); if(p->IsEnabled() && p->Key(p->unicode ? keycode : k, count)) { LLOG("Ctrl::DispatchKey(" << FormatIntHex(keycode) << ", " << GetKeyDesc(keycode) << "): eaten in " << Desc(p)); if(Ini::user_log) USRLOG(" -> " << Desc(p)); eventCtrl = focusCtrl; return true; } s_hotkey = true; if(!p->GetParent()) { if(p->HotKey(keycode)) { eventCtrl = focusCtrl; return true; } return false; } p = p->GetParent(); } USRLOG(" key was ignored"); return false; }
bool MenuBar::Key(dword key, int count) { LLOG("KEY " << GetKeyDesc(key)); bool horz = IsChild(); if((horz ? key == K_RIGHT : key == K_DOWN)) { Ctrl *ctrl = GetFocusChildDeep(); LLOG("MenuBar::Key(" << key << ") -> IterateFocusForward for " << UPP::Name(ctrl) << ", pane " << UPP::Name(&pane)); if(HasMouseDeep()) GetMouseCtrl()->Refresh(); if(ctrl && IterateFocusForward(ctrl, &pane, false, false, true)) return true; Ctrl *f = pane.GetFirstChild(); if(!f) return true; if(f->IsEnabled()) { f->SetFocus(); return true; } if(IterateFocusForward(pane.GetFirstChild(), &pane, false, false, true)) return true; } else if((horz ? key == K_LEFT : key == K_UP)) { Ctrl *ctrl = GetFocusChildDeep(); LLOG("MenuBar::Key(" << key << ") -> IterateFocusBackward for " << UPP::Name(ctrl) << ", pane " << UPP::Name(&pane)); if(HasMouseDeep()) GetMouseCtrl()->Refresh(); if(ctrl && IterateFocusBackward(ctrl, &pane, false, true)) return true; Ctrl *f = pane.GetLastChild(); if(!f) return true; if(f->IsEnabled()) { f->SetFocus(); return true; } if(IterateFocusBackward(pane.GetLastChild(), &pane, false, true)) return true; } else if(parentmenu && !parentmenu->IsChild() && key == K_LEFT || key == K_ESCAPE) { if(HasMouseDeep()) GetMouseCtrl()->Refresh(); if(parentmenu && parentmenu->submenu) parentmenu->submenuitem->SetFocus(); else if(IsChild() && HasFocusDeep()) { if(restorefocus) restorefocus->SetFocus(); doeffect = true; return true; } if(IsPopUp()) { SubmenuClose(); return true; } doeffect = true; } if(parentmenu && parentmenu->IsChild() && parentmenu->GetActiveSubmenu() && parentmenu->pane.GetFirstChild() && parentmenu->submenuitem) { Ctrl *smi = parentmenu->submenuitem; Ctrl *q = smi; q->Refresh(); if(key == K_RIGHT) for(;;) { q = q->GetNext(); if(!q) q = parentmenu->pane.GetFirstChild(); if(q == smi) break; if(PullMenu(q)) { q->Refresh(); SyncState(); return true; } } if(key == K_LEFT) for(;;) { q = q->GetPrev(); if(!q) q = parentmenu->pane.GetLastChild(); if(q == smi) break; if(PullMenu(q)) { q->Refresh(); SyncState(); return true; } } } LLOG("MenuBar::Key -> HotKey"); return HotKey(key); }
void Ctrl::Proc() { #ifdef LOG_EVENTS String ev = "?"; Tuple2<int, const char *> *f = FindTuple(xEvent, __countof(xEvent), CurrentEvent.type); if(f) ev = f->b; LOG(rmsecs() << " PROCESS EVENT " << Upp::Name(this) << " " << ev); ProcStop tm; tm.ev = ev; #endif if(!IsOpen()) return; Ptr<Ctrl> _this = this; bool pressed = false; int kv; static int clicktime = msecs() - 100000; switch(CurrentEvent.type) { case GDK_MOTION_NOTIFY: { GtkMouseEvent(MOUSEMOVE, MOUSEMOVE, 0); break; } case GDK_BUTTON_PRESS: if(!HasWndFocus() && !popup) SetWndFocus(); ClickActivateWnd(); if(ignoremouseup) { KillRepeat(); ignoreclick = false; ignoremouseup = false; } if(!ignoreclick) GtkButtonEvent(msecs(clicktime) < 250 ? DOUBLE : DOWN); clicktime = msecs(); break; /* case GDK_2BUTTON_PRESS: if(!ignoreclick) GtkButtonEvent(DOUBLE); break; */ case GDK_BUTTON_RELEASE: if(ignoreclick) EndIgnore(); else GtkButtonEvent(UP); break; case GDK_SCROLL: { GtkMouseEvent(MOUSEWHEEL, MOUSEWHEEL, CurrentEvent.value); break; } case GDK_KEY_PRESS: pressed = true; case GDK_KEY_RELEASE: kv = CurrentEvent.value; if(kv >= 0 && kv < 65536) { LLOG("keyval " << FormatIntHex(kv) << ' ' << (char)kv); if(kv >= 'a' && kv <= 'z') kv = kv - 'a' + 'A'; static Tuple2<int, int> cv[] = { { GDKEY(BackSpace), K_BACKSPACE }, { GDKEY(Tab), K_TAB }, { GDKEY(ISO_Left_Tab), K_TAB }, { GDKEY(Return), K_ENTER }, { GDKEY(Escape), K_ESCAPE }, { GDKEY(space), K_SPACE }, { GDKEY(Control_L), K_CTRL_KEY }, { GDKEY(Control_R), K_CTRL_KEY }, { GDKEY(Shift_L), K_SHIFT_KEY }, { GDKEY(Shift_R), K_SHIFT_KEY }, { GDKEY(Alt_L), K_ALT_KEY }, { GDKEY(Alt_R), K_ALT_KEY }, { GDKEY(KP_Space), K_SPACE }, { GDKEY(KP_Tab), K_TAB }, { GDKEY(KP_Enter), K_ENTER }, { GDKEY(KP_F1), K_F1 }, { GDKEY(KP_F2), K_F2 }, { GDKEY(KP_F3), K_F3 }, { GDKEY(KP_F4), K_F4 }, { GDKEY(KP_Home), K_HOME }, { GDKEY(KP_Left), K_LEFT }, { GDKEY(KP_Up), K_UP }, { GDKEY(KP_Right), K_RIGHT }, { GDKEY(KP_Down), K_DOWN }, { GDKEY(KP_Page_Up), K_PAGEUP }, { GDKEY(KP_Page_Down), K_PAGEDOWN }, { GDKEY(KP_End), K_END }, { GDKEY(KP_Begin), K_HOME }, { GDKEY(KP_Insert), K_INSERT }, { GDKEY(KP_Delete), K_DELETE }, }; Tuple2<int, int> *x = FindTuple(cv, __countof(cv), kv); if(x) kv = x->b; else kv += K_DELTA; if(GetShift() && kv != K_SHIFT_KEY) kv |= K_SHIFT; if(GetCtrl() && kv != K_CTRL_KEY) kv |= K_CTRL; if(GetAlt() && kv != K_ALT_KEY) kv |= K_ALT; LLOG(GetKeyDesc(kv) << ", pressed: " << pressed << ", count: " << CurrentEvent.count); #ifdef GDK_WINDOWING_X11 if(pressed) for(int i = 0; i < hotkey.GetCount(); i++) { if(hotkey[i] && keyhot[i] == (dword)kv) { hotkey[i](); return; } } #endif DispatchKey(!pressed * K_KEYUP + kv, CurrentEvent.count); } break; case EVENT_TEXT: { WString h = CurrentEvent.value; for(int i = 0; i < h.GetCount(); i++) // TODO: Add compression DispatchKey(h[i], 1); break; } case GDK_DELETE: { TopWindow *w = dynamic_cast<TopWindow *>(this); if(w) { if(IsEnabled()) { IgnoreMouseUp(); w->WhenClose(); } } return; } case GDK_CONFIGURE: { Rect rect = CurrentEvent.value; if(GetRect() != rect) SetWndRect(rect); } break; default: return; } if(_this) _this->PostInput(); }