bool TimeEntry::on_lose_focus ( GdkEventFocus *ev ) { std::string text(get_text().c_str()); if ( text.length() == 1 || text.length() == 3 ) { text = "0" + text; } unsigned short int n = 4 - text.length(); std::string zeros(n, '0'); text += zeros; set_text(text); std::string hrs = text.substr(0, text.length()-2); std::string mins = text.substr(text.length()-2); if (hrs < "00" || hrs > "23") { grab_focus(); return false; } if (mins < "00" || mins > "59") { grab_focus(); return false; } return true; }
GUI_status MsgScrollNewUI::scroll_movement_event(ScrollEventType event) { switch(event) { case SCROLL_UP : if(position > 0) { timer = new TimedCallback(this, NULL, 2000); position--; grab_focus(); } return GUI_YUM; case SCROLL_DOWN : timer = new TimedCallback(this, NULL, 2000); if(position < msg_buf.size()) position++; return (GUI_YUM); default : release_focus(); new TimedCallback(this, NULL, 50); break; } return GUI_PASS; }
InputDialog::InputDialog(GUI_CallBack *callback) : GUI_Dialog(Game::get_game()->get_game_x_offset() + (Game::get_game()->get_game_width() - ID_WIDTH)/2, Game::get_game()->get_game_y_offset() + (Game::get_game()->get_game_height() - ID_HEIGHT)/2, ID_WIDTH, ID_HEIGHT, 244, 216, 131, GUI_DIALOG_UNMOVABLE) { callback_object = callback; init(); grab_focus(); }
void video_container_widget::receive_notification(const notification& note) { if (note.type == notification::play && dispatch::playing()) { grab_focus(); } else if (note.type == notification::quit && _timer) { QApplication::quit(); } }
VideoDialog::VideoDialog(GUI_CallBack *callback) : GUI_Dialog(Game::get_game()->get_game_x_offset() + (Game::get_game()->get_game_width() - VD_WIDTH)/2, Game::get_game()->get_game_y_offset() + (Game::get_game()->get_game_height() - VD_HEIGHT)/2, VD_WIDTH, VD_HEIGHT, 244, 216, 131, GUI_DIALOG_UNMOVABLE) { callback_object = callback; non_square_pixels_button = NULL; init(); grab_focus(); }
GUI_status GUI_TextInput::MouseUp(int x, int y, int button) { if(button == SDL_BUTTON_WHEELUP || button == SDL_BUTTON_WHEELDOWN) return GUI_PASS; //release focus if we click outside the text box. if(focused && !HitRect(x, y)) release_focus(); else { if(!focused) { grab_focus(); SDL_EnableUNICODE(1); //turn on unicode processing. } } return(GUI_PASS); }
GUI_status GUI_ScrollBar::MouseDown(int x, int y, int button) { if(button == SDL_BUTTON_WHEELUP) { send_up_button_msg(); } else if(button == SDL_BUTTON_WHEELDOWN) { send_down_button_msg(); } else if(y >= area.y + button_height + slider_y && y <= area.y + button_height + slider_y + slider_length) { drag = true; slider_click_offset = y - area.y - button_height - slider_y; grab_focus(); } else if(y < area.y + button_height + slider_y) callback_object->callback(SCROLLBAR_CB_PAGE_UP, this, NULL); else callback_object->callback(SCROLLBAR_CB_PAGE_DOWN, this, NULL); return GUI_YUM; }
GUI_status DraggableView::MouseDown(int x, int y, int button) { if(bg_image && HitRect(x, y)) { Uint32 pixel = sdl_getpixel(bg_image, x - area.x, y - area.y); if(pixel == bg_color_key) { return GUI_PASS; } } drag = true; button_x = x; button_y = y; moveToFront(); if(Game::get_game()->is_new_style()) { Game::get_game()->get_scroll()->moveToFront(); } grab_focus(); return GUI_YUM; }
void PopupMenu::_notification(int p_what) { switch(p_what) { case NOTIFICATION_DRAW: { RID ci = get_canvas_item(); Size2 size=get_size(); Ref<StyleBox> style = get_stylebox("panel"); Ref<StyleBox> hover = get_stylebox("hover"); Ref<Font> font = get_font("font"); Ref<Texture> check = get_icon("checked"); Ref<Texture> uncheck = get_icon("unchecked"); Ref<Texture> submenu= get_icon("submenu"); Ref<StyleBox> separator = get_stylebox("separator"); style->draw( ci, Rect2( Point2(), get_size() ) ); Point2 ofs=style->get_offset(); int vseparation = get_constant("vseparation"); int hseparation = get_constant("hseparation"); Color font_color = get_color("font_color"); Color font_color_disabled = get_color("font_color_disabled"); Color font_color_accel = get_color("font_color_accel"); Color font_color_hover = get_color("font_color_hover"); float font_h=font->get_height(); for (int i=0;i<items.size();i++) { if (i>0) ofs.y+=vseparation; Point2 item_ofs=ofs; float h; Size2 icon_size; if (!items[i].icon.is_null()) { icon_size = items[i].icon->get_size(); h = MAX( icon_size.height, font_h ); } else { h=font_h; } if (i==mouse_over) { hover->draw(ci, Rect2( ofs+Point2(-hseparation,-vseparation), Size2( get_size().width - style->get_minimum_size().width + hseparation*2, h+vseparation*2 ) )); } if (items[i].separator) { int sep_h=separator->get_center_size().height+separator->get_minimum_size().height; separator->draw(ci, Rect2( ofs+Point2(0,Math::floor((h-sep_h)/2.0)), Size2( get_size().width - style->get_minimum_size().width , sep_h ) )); } if (items[i].checkable) { if (items[i].checked) check->draw(ci, item_ofs+Point2(0,Math::floor((h-check->get_height())/2.0))); else uncheck->draw(ci, item_ofs+Point2(0,Math::floor((h-check->get_height())/2.0))); item_ofs.x+=check->get_width()+hseparation; } if (!items[i].icon.is_null()) { items[i].icon->draw( ci, item_ofs+Point2(0,Math::floor((h-icon_size.height)/2.0))); item_ofs.x+=items[i].icon->get_width(); item_ofs.x+=hseparation; } if (items[i].submenu!="") { submenu->draw( ci, Point2(size.width - style->get_margin(MARGIN_RIGHT) - submenu->get_width(),item_ofs.y+Math::floor(h-submenu->get_height())/2)); } item_ofs.y+=font->get_ascent(); if (!items[i].separator) font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),items[i].text,items[i].disabled?font_color_disabled:(i==mouse_over?font_color_hover:font_color)); if (items[i].accel) { //accelerator String text = _get_accel_text(items[i].accel); item_ofs.x=size.width-style->get_margin(MARGIN_RIGHT)-font->get_string_size(text).width; font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),text,i==mouse_over?font_color_hover:font_color_accel); } items[i]._ofs_cache=ofs.y; ofs.y+=h; } } break; case NOTIFICATION_MOUSE_ENTER: { grab_focus(); } break; case NOTIFICATION_MOUSE_EXIT: { if (mouse_over>=0) { mouse_over=-1; update(); } } break; } }
void PopupMenu::_notification(int p_what) { switch (p_what) { case NOTIFICATION_TRANSLATION_CHANGED: { for (int i = 0; i < items.size(); i++) { items[i].xl_text = tr(items[i].text); } minimum_size_changed(); update(); } break; case NOTIFICATION_DRAW: { RID ci = get_canvas_item(); Size2 size = get_size(); Ref<StyleBox> style = get_stylebox("panel"); Ref<StyleBox> hover = get_stylebox("hover"); Ref<Font> font = get_font("font"); // In Item::checkable_type enum order (less the non-checkable member) Ref<Texture> check[] = { get_icon("checked"), get_icon("radio_checked") }; Ref<Texture> uncheck[] = { get_icon("unchecked"), get_icon("radio_unchecked") }; Ref<Texture> submenu = get_icon("submenu"); Ref<StyleBox> separator = get_stylebox("separator"); style->draw(ci, Rect2(Point2(), get_size())); Point2 ofs = style->get_offset(); int vseparation = get_constant("vseparation"); int hseparation = get_constant("hseparation"); Color font_color = get_color("font_color"); Color font_color_disabled = get_color("font_color_disabled"); Color font_color_accel = get_color("font_color_accel"); Color font_color_hover = get_color("font_color_hover"); float font_h = font->get_height(); for (int i = 0; i < items.size(); i++) { if (i > 0) ofs.y += vseparation; Point2 item_ofs = ofs; float h; Size2 icon_size; item_ofs.x += items[i].h_ofs; if (!items[i].icon.is_null()) { icon_size = items[i].icon->get_size(); h = MAX(icon_size.height, font_h); } else { h = font_h; } if (i == mouse_over) { hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation / 2), Size2(get_size().width - style->get_minimum_size().width + hseparation * 2, h + vseparation))); } if (items[i].separator) { int sep_h = separator->get_center_size().height + separator->get_minimum_size().height; separator->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(get_size().width - style->get_minimum_size().width, sep_h))); } if (items[i].checkable_type) { Texture *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr(); icon->draw(ci, item_ofs + Point2(0, Math::floor((h - icon->get_height()) / 2.0))); item_ofs.x += icon->get_width() + hseparation; } if (!items[i].icon.is_null()) { items[i].icon->draw(ci, item_ofs + Point2(0, Math::floor((h - icon_size.height) / 2.0))); item_ofs.x += items[i].icon->get_width(); item_ofs.x += hseparation; } if (items[i].submenu != "") { submenu->draw(ci, Point2(size.width - style->get_margin(MARGIN_RIGHT) - submenu->get_width(), item_ofs.y + Math::floor(h - submenu->get_height()) / 2)); } item_ofs.y += font->get_ascent(); String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].xl_text; if (!items[i].separator) { font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text, items[i].disabled ? font_color_disabled : (i == mouse_over ? font_color_hover : font_color)); } if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) { //accelerator String text = _get_accel_text(i); item_ofs.x = size.width - style->get_margin(MARGIN_RIGHT) - font->get_string_size(text).width; font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text, i == mouse_over ? font_color_hover : font_color_accel); } items[i]._ofs_cache = ofs.y; ofs.y += h; } } break; case NOTIFICATION_MOUSE_ENTER: { grab_focus(); } break; case NOTIFICATION_MOUSE_EXIT: { if (mouse_over >= 0 && (items[mouse_over].submenu == "" || submenu_over != -1)) { mouse_over = -1; update(); } } break; case NOTIFICATION_POST_POPUP: { initial_button_mask = Input::get_singleton()->get_mouse_button_mask(); during_grabbed_click = (bool)initial_button_mask; } break; case NOTIFICATION_POPUP_HIDE: { if (mouse_over >= 0) { mouse_over = -1; update(); } } break; } }
void LineEdit::_input_event(InputEvent p_event) { switch(p_event.type) { case InputEvent::MOUSE_BUTTON: { const InputEventMouseButton &b = p_event.mouse_button; if (b.pressed && b.button_index==BUTTON_RIGHT) { menu->set_pos(get_global_transform().xform(get_local_mouse_pos())); menu->set_size(Vector2(1,1)); menu->popup(); grab_focus(); return; } if (b.button_index!=BUTTON_LEFT) break; _reset_caret_blink_timer(); if (b.pressed) { shift_selection_check_pre(b.mod.shift); set_cursor_at_pixel_pos(b.x); if (b.mod.shift) { selection_fill_at_cursor(); selection.creating=true; } else { if (b.doubleclick) { selection.enabled=true; selection.begin=0; selection.end=text.length(); selection.doubleclick=true; } selection.drag_attempt=false; if ((cursor_pos<selection.begin) || (cursor_pos>selection.end) || !selection.enabled) { selection_clear(); selection.cursor_start=cursor_pos; selection.creating=true; } else if (selection.enabled) { selection.drag_attempt=true; } } // if (!editable) // non_editable_clicked_signal.call(); update(); } else { if ( (!selection.creating) && (!selection.doubleclick)) { selection_clear(); } selection.creating=false; selection.doubleclick=false; if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->show_virtual_keyboard(text,get_global_rect()); } update(); } break; case InputEvent::MOUSE_MOTION: { const InputEventMouseMotion& m=p_event.mouse_motion; if (m.button_mask&BUTTON_LEFT) { if (selection.creating) { set_cursor_at_pixel_pos(m.x); selection_fill_at_cursor(); } } } break; case InputEvent::KEY: { const InputEventKey &k =p_event.key; if (!k.pressed) return; unsigned int code = k.scancode; if (k.mod.command) { bool handled=true; switch (code) { case (KEY_X): { // CUT if(editable) { cut_text(); } } break; case (KEY_C): { // COPY copy_text(); } break; case (KEY_V): { // PASTE if(editable) { paste_text(); } } break; case (KEY_Z): { // Simple One level undo if(editable) { undo(); } } break; case (KEY_U): { // Delete from start to cursor if(editable) { selection_clear(); undo_text = text; text = text.substr(cursor_pos,text.length()-cursor_pos); Ref<Font> font = get_font("font"); cached_width = 0; if (font != NULL) { for (int i = 0; i < text.length(); i++) cached_width += font->get_char_size(text[i]).width; } set_cursor_pos(0); _text_changed(); } } break; case (KEY_Y): { // PASTE (Yank for unix users) if(editable) { paste_text(); } } break; case (KEY_K): { // Delete from cursor_pos to end if(editable) { selection_clear(); undo_text = text; text = text.substr(0,cursor_pos); _text_changed(); } } break; case (KEY_A): { //Select All select(); } break; default: { handled=false; } } if (handled) { accept_event(); return; } } _reset_caret_blink_timer(); if (!k.mod.meta) { bool handled=true; switch (code) { case KEY_ENTER: case KEY_RETURN: { emit_signal( "text_entered",text ); if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->hide_virtual_keyboard(); return; } break; case KEY_BACKSPACE: { if (!editable) break; if (selection.enabled) { undo_text=text; selection_delete(); break; } #ifdef APPLE_STYLE_KEYS if (k.mod.alt) { #else if (k.mod.alt) { handled=false; break; } else if (k.mod.command) { #endif int cc=cursor_pos; bool prev_char=false; while (cc>0) { bool ischar=_is_text_char(text[cc-1]); if (prev_char && !ischar) break; prev_char=ischar; cc--; } delete_text(cc, cursor_pos); set_cursor_pos(cc); } else { undo_text=text; delete_char(); } } break; case KEY_KP_4: { if (k.unicode != 0) { handled = false; break; } // numlock disabled. fallthrough to key_left } case KEY_LEFT: { #ifndef APPLE_STYLE_KEYS if (!k.mod.alt) #endif shift_selection_check_pre(k.mod.shift); #ifdef APPLE_STYLE_KEYS if (k.mod.command) { set_cursor_pos(0); } else if (k.mod.alt) { #else if (k.mod.alt) { handled=false; break; } else if (k.mod.command) { #endif bool prev_char=false; int cc=cursor_pos; while (cc>0) { bool ischar=_is_text_char(text[cc-1]); if (prev_char && !ischar) break; prev_char=ischar; cc--; } set_cursor_pos(cc); } else { set_cursor_pos(get_cursor_pos()-1); } shift_selection_check_post(k.mod.shift); } break; case KEY_KP_6: { if (k.unicode != 0) { handled = false; break; } // numlock disabled. fallthrough to key_right } case KEY_RIGHT: { shift_selection_check_pre(k.mod.shift); #ifdef APPLE_STYLE_KEYS if (k.mod.command) { set_cursor_pos(text.length()); } else if (k.mod.alt) { #else if (k.mod.alt) { handled=false; break; } else if (k.mod.command) { #endif bool prev_char=false; int cc=cursor_pos; while (cc<text.length()) { bool ischar=_is_text_char(text[cc]); if (prev_char && !ischar) break; prev_char=ischar; cc++; } set_cursor_pos(cc); } else { set_cursor_pos(get_cursor_pos()+1); } shift_selection_check_post(k.mod.shift); } break; case KEY_DELETE: { if (!editable) break; if (k.mod.shift && !k.mod.command && !k.mod.alt) { cut_text(); break; } if (selection.enabled) { undo_text=text; selection_delete(); break; } int text_len = text.length(); if (cursor_pos==text_len) break; // nothing to do #ifdef APPLE_STYLE_KEYS if (k.mod.alt) { #else if (k.mod.alt) { handled=false; break; } else if (k.mod.command) { #endif int cc=cursor_pos; bool prev_char=false; while (cc<text.length()) { bool ischar=_is_text_char(text[cc]); if (prev_char && !ischar) break; prev_char=ischar; cc++; } delete_text(cursor_pos,cc); } else { undo_text=text; set_cursor_pos(cursor_pos+1); delete_char(); } } break; case KEY_KP_7: { if (k.unicode != 0) { handled = false; break; } // numlock disabled. fallthrough to key_home } case KEY_HOME: { shift_selection_check_pre(k.mod.shift); set_cursor_pos(0); shift_selection_check_post(k.mod.shift); } break; case KEY_KP_1: { if (k.unicode != 0) { handled = false; break; } // numlock disabled. fallthrough to key_end } case KEY_END: { shift_selection_check_pre(k.mod.shift); set_cursor_pos(text.length()); shift_selection_check_post(k.mod.shift); } break; default: { handled=false; } break; } if (handled) { accept_event(); } else if (!k.mod.alt && !k.mod.command) { if (k.unicode>=32 && k.scancode!=KEY_DELETE) { if (editable) { selection_delete(); CharType ucodestr[2]= {(CharType)k.unicode,0}; append_at_cursor(ucodestr); _text_changed(); accept_event(); } } else { return; } } update(); } return; } break; } } void LineEdit::set_align(Align p_align) { ERR_FAIL_INDEX(p_align, 4); align = p_align; update(); } LineEdit::Align LineEdit::get_align() const { return align; } Variant LineEdit::get_drag_data(const Point2& p_point) { if (selection.drag_attempt && selection.enabled) { String t = text.substr(selection.begin, selection.end - selection.begin); Label *l = memnew( Label ); l->set_text(t); set_drag_preview(l); return t; } return Variant(); } bool LineEdit::can_drop_data(const Point2& p_point,const Variant& p_data) const { return p_data.get_type()==Variant::STRING; } void LineEdit::drop_data(const Point2& p_point,const Variant& p_data) { if (p_data.get_type()==Variant::STRING) { set_cursor_at_pixel_pos(p_point.x); int selected = selection.end - selection.begin; Ref<Font> font = get_font("font"); if (font != NULL) { for (int i = selection.begin; i < selection.end; i++) cached_width -= font->get_char_size(text[i]).width; } text.erase(selection.begin, selected); append_at_cursor(p_data); selection.begin = cursor_pos-selected; selection.end = cursor_pos; } } void LineEdit::_notification(int p_what) { switch(p_what) { #ifdef TOOLS_ENABLED case NOTIFICATION_ENTER_TREE: { if (get_tree()->is_editor_hint()) { cursor_set_blink_enabled(EDITOR_DEF("text_editor/caret_blink", false)); cursor_set_blink_speed(EDITOR_DEF("text_editor/caret_blink_speed", 0.65)); if (!EditorSettings::get_singleton()->is_connected("settings_changed",this,"_editor_settings_changed")) { EditorSettings::get_singleton()->connect("settings_changed",this,"_editor_settings_changed"); } } } break; #endif case NOTIFICATION_RESIZED: { set_cursor_pos( get_cursor_pos() ); } break; case MainLoop::NOTIFICATION_WM_FOCUS_IN: { window_has_focus = true; draw_caret = true; update(); } break; case MainLoop::NOTIFICATION_WM_FOCUS_OUT: { window_has_focus = false; draw_caret = false; update(); } break; case NOTIFICATION_DRAW: { if ((!has_focus() && !menu->has_focus()) || !window_has_focus) { draw_caret = false; } int width,height; Size2 size=get_size(); width=size.width; height=size.height; RID ci = get_canvas_item(); Ref<StyleBox> style = get_stylebox("normal"); if (!is_editable()) style=get_stylebox("read_only"); Ref<Font> font=get_font("font"); style->draw( ci, Rect2( Point2(), size ) ); if (has_focus()) { get_stylebox("focus")->draw( ci, Rect2( Point2(), size ) ); } int x_ofs=0; switch (align) { case ALIGN_FILL: case ALIGN_LEFT: { x_ofs=style->get_offset().x; } break; case ALIGN_CENTER: { x_ofs=int(size.width-(cached_width))/2; } break; case ALIGN_RIGHT: { x_ofs=int(size.width-style->get_offset().x-(cached_width)); } break; } int ofs_max=width-style->get_minimum_size().width; int char_ofs=window_pos; int y_area=height-style->get_minimum_size().height; int y_ofs=style->get_offset().y; int font_ascent=font->get_ascent(); Color selection_color=get_color("selection_color"); Color font_color=get_color("font_color"); Color font_color_selected=get_color("font_color_selected"); Color cursor_color=get_color("cursor_color"); const String& t = text.empty() ? placeholder : text; // draw placeholder color if(text.empty()) font_color.a *= placeholder_alpha; int caret_height = font->get_height() > y_area ? y_area : font->get_height(); while(true) { //end of string, break! if (char_ofs>=t.length()) break; CharType cchar=pass?'*':t[char_ofs]; CharType next=pass?'*':t[char_ofs+1]; int char_width=font->get_char_size( cchar,next ).width; // end of widget, break! if ((x_ofs + char_width) > ofs_max) break; bool selected=selection.enabled && char_ofs>=selection.begin && char_ofs<selection.end; if (selected) VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, caret_height)), selection_color); font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, selected ? font_color_selected : font_color); if (char_ofs==cursor_pos && draw_caret) { VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( Point2( x_ofs , y_ofs ), Size2( 1, caret_height ) ), cursor_color ); } x_ofs+=char_width; char_ofs++; } if (char_ofs==cursor_pos && draw_caret) {//may be at the end VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( Point2( x_ofs , y_ofs ), Size2( 1, caret_height ) ), cursor_color ); } } break; case NOTIFICATION_FOCUS_ENTER: { if (!caret_blink_enabled) { draw_caret = true; } if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->show_virtual_keyboard(text,get_global_rect()); } break; case NOTIFICATION_FOCUS_EXIT: { if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->hide_virtual_keyboard(); } break; } } void LineEdit::copy_text() { if(selection.enabled) { OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin)); } } void LineEdit::cut_text() { if(selection.enabled) { undo_text = text; OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin)); selection_delete(); } } void LineEdit::paste_text() { String paste_buffer = OS::get_singleton()->get_clipboard(); if(paste_buffer != "") { if(selection.enabled) selection_delete(); append_at_cursor(paste_buffer); _text_changed(); } } void LineEdit::undo() { int old_cursor_pos = cursor_pos; text = undo_text; Ref<Font> font = get_font("font"); cached_width = 0; for (int i = 0; i<text.length(); i++) cached_width += font->get_char_size(text[i]).width; if(old_cursor_pos > text.length()) { set_cursor_pos(text.length()); } else { set_cursor_pos(old_cursor_pos); } _text_changed(); }
// main input processing bool Graph_disp::input() { // state vars static std::unordered_map<sf::Keyboard::Key, bool, std::hash<int>> key_lock; static sf::Vector2i old_mouse_pos = sf::Mouse::getPosition(glWindow); static sf::Clock cursor_delay; static sf::Clock zoom_delay; // the neat thing about having this in a timeout func is that we // don't need to calculate dt for movement controls. // it is always (almost) exactly 10ms // only process when the window is active and display is focused if(dynamic_cast<Gtk::Window *>(get_toplevel())->is_active()) { sf::Vector2i new_mouse_pos = sf::Mouse::getPosition(glWindow); if(!has_focus() && new_mouse_pos.x >= 0 && new_mouse_pos.y >= 0 && new_mouse_pos.x < get_allocated_width() && new_mouse_pos.y < get_allocated_height()) { grab_focus(); } if(has_focus()) { // Camera controls float mov_scale = 0.1f; if(sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) { mov_scale *= 2.0f; } if(sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt)) { mov_scale *= 0.1f; } // orbiting rotational cam if(use_orbit_cam) { // reset if(sf::Keyboard::isKeyPressed(sf::Keyboard::R) && !key_lock[sf::Keyboard::R]) { key_lock[sf::Keyboard::R] = true; reset_cam(); } else if(!sf::Keyboard::isKeyPressed(sf::Keyboard::R)) key_lock[sf::Keyboard::R] = false; // tilt up if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { _orbit_cam.phi += (float)M_PI / 90.0f * mov_scale; invalidate(); } // tilt down if(sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { _orbit_cam.phi -= (float)M_PI / 90.0f * mov_scale; invalidate(); } // rotate clockwise if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { _orbit_cam.theta += (float)M_PI / 90.0f * mov_scale; invalidate(); } // rotate counter-clockwise if(sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { _orbit_cam.theta -= (float)M_PI / 90.0f * mov_scale; invalidate(); } // move camera in if(sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) { _orbit_cam.r -= mov_scale; invalidate(); } // move camera out if(sf::Keyboard::isKeyPressed(sf::Keyboard::E)) { _orbit_cam.r += mov_scale; invalidate(); } // rotate w/ mouse click & drag if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { int d_x = new_mouse_pos.x - old_mouse_pos.x; int d_y = new_mouse_pos.y - old_mouse_pos.y; _orbit_cam.theta -= 0.005f * d_x; _orbit_cam.phi -= 0.005f * d_y; invalidate(); } // wrap theta if(_orbit_cam.theta > (float)M_PI * 2.0f) _orbit_cam.theta -= (float)M_PI * 2.0f; if(_orbit_cam.theta < 0.0f) _orbit_cam.theta += (float)M_PI * 2.0f; // clamp phi if(_orbit_cam.phi > (float)M_PI) _orbit_cam.phi = (float)M_PI; if(_orbit_cam.phi < 0.0f) _orbit_cam.phi = 0.0f; } else // free camera { // reset if(sf::Keyboard::isKeyPressed(sf::Keyboard::R) && !key_lock[sf::Keyboard::R]) { key_lock[sf::Keyboard::R] = true; reset_cam(); } else if(!sf::Keyboard::isKeyPressed(sf::Keyboard::R)) key_lock[sf::Keyboard::R] = false; // move forward if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { _cam.translate(mov_scale * _cam.forward()); invalidate(); } // move backwards if(sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { _cam.translate(-mov_scale * _cam.forward()); invalidate(); } // move left if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { _cam.translate(-mov_scale * _cam.right()); invalidate(); } // move right if(sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { _cam.translate(mov_scale * _cam.right()); invalidate(); } // move up if(sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) { _cam.translate(mov_scale * glm::vec3(0.0f, 0.0f, 1.0f)); invalidate(); } // move down if(sf::Keyboard::isKeyPressed(sf::Keyboard::E)) { _cam.translate(-mov_scale * glm::vec3(0.0f, 0.0f, 1.0f)); invalidate(); } // rotate view with mouse click & drag if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { int d_x = new_mouse_pos.x - old_mouse_pos.x; int d_y = new_mouse_pos.y - old_mouse_pos.y; _cam.rotate(0.001f * d_y, _cam.right()); _cam.rotate(0.001f * d_x, glm::vec3(0.0f, 0.0f, 1.0f)); invalidate(); } } const int zoom_timeout = 200; // zoom in if(sf::Keyboard::isKeyPressed(sf::Keyboard::Z) && zoom_delay.getElapsedTime().asMilliseconds() >= zoom_timeout) { _scale *= 2.0f; zoom_delay.restart(); invalidate(); } // zoom out if(sf::Keyboard::isKeyPressed(sf::Keyboard::X) && zoom_delay.getElapsedTime().asMilliseconds() >= zoom_timeout) { _scale *= 0.5f; zoom_delay.restart(); invalidate(); } // move cursor with arrow keys if(draw_cursor_flag && _active_graph) { const int cursor_timeout = 200; if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && cursor_delay.getElapsedTime().asMilliseconds() >= cursor_timeout) { _active_graph->move_cursor(Graph::UP); cursor_delay.restart(); invalidate(); } if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && cursor_delay.getElapsedTime().asMilliseconds() >= cursor_timeout) { _active_graph->move_cursor(Graph::DOWN); cursor_delay.restart(); invalidate(); } if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && cursor_delay.getElapsedTime().asMilliseconds() >= cursor_timeout) { _active_graph->move_cursor(Graph::LEFT); cursor_delay.restart(); invalidate(); } if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && cursor_delay.getElapsedTime().asMilliseconds() >= cursor_timeout) { _active_graph->move_cursor(Graph::RIGHT); cursor_delay.restart(); invalidate(); } } } old_mouse_pos = new_mouse_pos; } return true; }