• R/O
  • HTTP
  • SSH
  • HTTPS

Molby: コミット

Molecular Modeling Software


コミットメタ情報

リビジョン07b7aec16f7dcc452d77ed3df18064332054cbfb (tree)
日時2014-09-21 22:51:49
作者toshinagata1964 <toshinagata1964@a2be...>
コミッターtoshinagata1964

ログメッセージ

Keyboard focus issues in Ruby dialog is (hopefully) improved.

git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@572 a2be9bc6-48de-4e38-9406-05402d4bc13c

変更サマリ

差分

--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@ ifeq ($(TARGET_PLATFORM),MSW)
3030 endif
3131
3232 WXLIB_LIST = core,base,gl,adv
33-OBJECTS = ConsoleFrame.o GlobalParameterFrame.o GlobalParameterFilesFrame.o MoleculeView.o MyApp.o MyCommand.o MyDocument.o MyGLCanvas.o MySlider.o MyClipboardData.o ProgressFrame.o MyListCtrl.o MyDocManager.o wxKillAddition.o RubyDialogFrame.o MyIPCSupport.o MyVersion.o MyThread.o MyProgressIndicator.o modalwindow.o
33+OBJECTS = ConsoleFrame.o GlobalParameterFrame.o GlobalParameterFilesFrame.o MoleculeView.o MyApp.o MyCommand.o MyDocument.o MyGLCanvas.o MySlider.o MyClipboardData.o ProgressFrame.o MyListCtrl.o MyDocManager.o wxKillAddition.o RubyDialogFrame.o MyIPCSupport.o MyVersion.o MyThread.o MyProgressIndicator.o modalwindow.o MyTextCtrl.o
3434 LIBS = MolLib.a Ruby_bind.a
3535 RUBY_EXTLIB = scanf.rb
3636
--- a/MolLib/Ruby_bind/ruby_dialog.c
+++ b/MolLib/Ruby_bind/ruby_dialog.c
@@ -2006,6 +2006,14 @@ s_RubyDialog_doItemAction(VALUE val)
20062006 VALUE items = rb_iv_get(self, "_items");
20072007 int nitems = RARRAY_LEN(items);
20082008 int idx = RubyDialogCallback_indexOfItem(dref, ip);
2009+ static VALUE sTextActionSym = Qfalse, sEscapeActionSym, sReturnActionSym;
2010+
2011+ if (sTextActionSym == Qfalse) {
2012+ sTextActionSym = ID2SYM(rb_intern("text_action"));
2013+ sEscapeActionSym = ID2SYM(rb_intern("escape_action"));
2014+ sReturnActionSym = ID2SYM(rb_intern("return_action"));
2015+ }
2016+
20092017 if (idx < 0)
20102018 return Qnil;
20112019 ival = INT2NUM(idx);
@@ -2048,7 +2056,14 @@ s_RubyDialog_doItemAction(VALUE val)
20482056
20492057 if (tval == sTextFieldSymbol || tval == sTextViewSymbol) {
20502058 if (options == 1)
2051- aval = ID2SYM(rb_intern("text_action")); /* Action for every text update */
2059+ aval = sTextActionSym; /* Action for every text update */
2060+ }
2061+
2062+ if (tval == sTextFieldSymbol) {
2063+ if (options == 2)
2064+ aval = sReturnActionSym;
2065+ else if (options == 4)
2066+ aval = sEscapeActionSym;
20522067 }
20532068
20542069 /* If the item has the "action" attribute, call it */
@@ -2061,6 +2076,11 @@ s_RubyDialog_doItemAction(VALUE val)
20612076 } else if (rb_respond_to(itval, SYM2ID(aval))) {
20622077 /* If "action" method is defined, then call it without arguments */
20632078 rb_funcall(itval, SYM2ID(aval), 0);
2079+ } else if (aval == sReturnActionSym || aval == sEscapeActionSym) {
2080+ /* Enter or escape is pressed on text field */
2081+ rb_ivar_set(itval, SYM2ID(sIsProcessingActionSymbol), Qfalse);
2082+ itval = s_RubyDialog_ItemAtIndex(self, (aval == sReturnActionSym ? INT2FIX(0) : INT2FIX(1)));
2083+ s_RubyDialog_EndModal(1, &itval, self);
20642084 } else {
20652085 /* Default action (only for default buttons) */
20662086 if (idx == 0 || idx == 1) {
--- /dev/null
+++ b/wxSources/MyTextCtrl.cpp
@@ -0,0 +1,84 @@
1+/*
2+ * MyTextCtrl.cpp
3+ * Molby
4+ *
5+ * Created by Toshi Nagata on 2014/09/21.
6+ * Copyright 2014 Toshi Nagata. All rights reserved.
7+ *
8+ This program is free software; you can redistribute it and/or modify
9+ it under the terms of the GNU General Public License as published by
10+ the Free Software Foundation version 2 of the License.
11+
12+ This program is distributed in the hope that it will be useful,
13+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ GNU General Public License for more details.
16+ */
17+
18+#include "MyTextCtrl.h"
19+
20+IMPLEMENT_DYNAMIC_CLASS(MyTextCtrl, wxTextCtrl)
21+
22+BEGIN_EVENT_TABLE(MyTextCtrl, wxTextCtrl)
23+EVT_KEY_UP(MyTextCtrl::OnKeyUp)
24+END_EVENT_TABLE()
25+
26+const wxEventType myTextCtrl_EVT_PROCESS_ESCAPE = wxNewEventType();
27+
28+MyTextCtrl::MyTextCtrl() : wxTextCtrl()
29+{}
30+
31+MyTextCtrl::MyTextCtrl(wxWindow *parent, wxWindowID id, const wxString &value,
32+ const wxPoint &pos, const wxSize &size,
33+ long style, const wxValidator &validator,
34+ const wxString &name)
35+ : wxTextCtrl(parent, id, value, pos, size, style & ~(MyTextCtrl_Process_Escape), validator)
36+{
37+ processEscape = (style & MyTextCtrl_Process_Escape) != 0;
38+}
39+
40+MyTextCtrl::~MyTextCtrl()
41+{}
42+
43+// Call escape key handler on _releasing_ the ESC key
44+// Note: Overriding OnChar() function does not work!
45+// (Escape key is swallowed somewhere between OnKeyDown and OnChar)
46+void
47+MyTextCtrl::OnKeyUp(wxKeyEvent &event) {
48+ if (processEscape && event.GetKeyCode() == WXK_ESCAPE) {
49+ wxCommandEvent event(myTextCtrl_EVT_PROCESS_ESCAPE, m_windowId);
50+ InitCommandEvent(event);
51+ if (HandleWindowEvent(event)) {
52+ return;
53+ }
54+ }
55+ event.Skip();
56+ return;
57+#if defined(__WXMSW__)
58+ // OnKeyDown() is private in WXMSW, so we cannot call the superclass handler.
59+ // Here we copy the code in wxTextCtrl::OnKeyDown()
60+ if ( event.GetModifiers() == wxMOD_CONTROL && IsRich() )
61+ {
62+ switch ( event.GetKeyCode() )
63+ {
64+ case 'C':
65+ Copy();
66+ return;
67+ case 'X':
68+ Cut();
69+ return;
70+ case 'V':
71+ Paste();
72+ return;
73+ default:
74+ break;
75+ }
76+ }
77+ if ( event.GetKeyCode() == WXK_ESCAPE && IsMultiLine() )
78+ return;
79+ event.Skip();
80+#else
81+ // Pass the event to the superclass handler
82+ wxTextCtrl::OnKeyDown(event);
83+#endif
84+}
--- /dev/null
+++ b/wxSources/MyTextCtrl.h
@@ -0,0 +1,44 @@
1+/*
2+ * MyTextCtrl.h
3+ *
4+ * Created by Toshi Nagata on 2014/09/21.
5+ * Copyright 2014 Toshi Nagata. All rights reserved.
6+
7+ This program is free software; you can redistribute it and/or modify
8+ it under the terms of the GNU General Public License as published by
9+ the Free Software Foundation version 2 of the License.
10+
11+ This program is distributed in the hope that it will be useful,
12+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ GNU General Public License for more details.
15+
16+ */
17+
18+#ifndef __MyTextCtrl_h__
19+#define __MyTextCtrl_h__
20+
21+#include "wx/textctrl.h"
22+
23+#define MyTextCtrl_Process_Escape 0x10000000
24+
25+extern const wxEventType myTextCtrl_EVT_PROCESS_ESCAPE;
26+
27+class MyTextCtrl: public wxTextCtrl {
28+
29+public:
30+ MyTextCtrl();
31+ MyTextCtrl(wxWindow *parent, wxWindowID id, const wxString &value=wxEmptyString,
32+ const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize,
33+ long style=0, const wxValidator &validator=wxDefaultValidator,
34+ const wxString &name=wxTextCtrlNameStr);
35+ virtual ~MyTextCtrl();
36+ bool processEscape;
37+ void OnKeyUp(wxKeyEvent& event);
38+
39+private:
40+ DECLARE_DYNAMIC_CLASS(MyTextCtrl)
41+ DECLARE_EVENT_TABLE()
42+};
43+
44+#endif /* __MyListCtrl_h__ */
--- a/wxSources/RubyDialogFrame.cpp
+++ b/wxSources/RubyDialogFrame.cpp
@@ -34,6 +34,7 @@
3434 #include "MyApp.h"
3535 #include "MyMBConv.h"
3636 #include "MyDocument.h"
37+#include "MyTextCtrl.h"
3738
3839 IMPLEMENT_DYNAMIC_CLASS(MyLayoutPanel, wxPanel)
3940
@@ -268,10 +269,17 @@ RubyDialogFrame::OnEnterProcessedOnText(wxCommandEvent &event)
268269 void
269270 RubyDialogFrame::OnKillFocusOnText(wxFocusEvent &event)
270271 {
272+ event.Skip();
271273 RubyDialog_doItemAction((RubyValue)dval, (RDItem *)(event.GetEventObject()), 3);
272274 }
273275
274276 void
277+RubyDialogFrame::OnEscapeProcessedOnText(wxCommandEvent &event)
278+{
279+ RubyDialog_doItemAction((RubyValue)dval, (RDItem *)(event.GetEventObject()), 4);
280+}
281+
282+void
275283 RubyDialogFrame::OnDefaultButtonPressed(wxCommandEvent &event)
276284 {
277285 /* Ignore the wxID_OK and wxID_CANCEL requests if the default buttons are hidden */
@@ -416,6 +424,7 @@ void
416424 RubyDialogFrame::OnActivate(wxActivateEvent &event)
417425 {
418426 wxModalWindow::OnActivate(event);
427+#if defined(__WXMAC__)
419428 if (event.GetActive()) {
420429 int i;
421430 RDItem *itemp;
@@ -431,6 +440,7 @@ RubyDialogFrame::OnActivate(wxActivateEvent &event)
431440 }
432441 }
433442 }
443+#endif
434444 }
435445
436446 /* Remember the focused window after every focus change */
@@ -440,11 +450,14 @@ RubyDialogFrame::OnChildFocus(wxChildFocusEvent &event)
440450 {
441451 wxWindow *winp = wxWindow::FindFocus();
442452 if (winp != NULL) {
453+#if defined(__WXMAC__)
443454 if (winp != lastFocusedWindow && wxDynamicCast(winp, wxTextCtrl) != NULL && ((wxTextCtrl *)winp)->IsEditable()) {
444455 ((wxTextCtrl *)winp)->SelectAll();
445456 }
457+#endif
446458 lastFocusedWindow = winp;
447459 }
460+ event.Skip();
448461 }
449462
450463 void
@@ -655,7 +668,7 @@ RubyDialog *
655668 RubyDialogCallback_new(int style)
656669 {
657670 RubyDialogFrame *dref;
658- int fstyle = wxCAPTION | wxSYSTEM_MENU;
671+ int fstyle = wxCAPTION | wxSYSTEM_MENU | wxTAB_TRAVERSAL;
659672 if (style & rd_Resizable)
660673 fstyle |= wxMAXIMIZE_BOX | wxRESIZE_BORDER;
661674 if (style & rd_HasCloseBox) {
@@ -689,10 +702,49 @@ RubyDialogCallback_setWindowTitle(RubyDialog *dref, const char *title)
689702 ((RubyDialogFrame *)dref)->SetLabel(str);
690703 }
691704
705+void
706+RubyDialogCallback_initializeBeforeShow(RubyDialog *dref, int modal)
707+{
708+ RubyDialogFrame *dframe = (RubyDialogFrame *)dref;
709+
710+ if (dframe->shouldInitializeBeforeShow) {
711+ if (modal == 0) {
712+ // Set a menu bar
713+ // The window size may change on setting the menu bar, so restore the original size
714+ // after setting the menu bar
715+ int width, height;
716+ dframe->GetClientSize(&width, &height);
717+ dframe->SetMenuBar(wxGetApp().CreateMenuBar(3, NULL, NULL));
718+ dframe->SetClientSize(width, height);
719+ }
720+ // If there is a textfield or textview control, then set focus on the first one
721+ int i;
722+ RDItem *itemp;
723+ for (i = 2; (itemp = dframe->DialogItemAtIndex(i)) != NULL; i++) {
724+ bool canAcceptFocus;
725+#if defined(__WXMAC__)
726+ canAcceptFocus = (wxDynamicCast((wxWindow *)itemp, wxTextCtrl) != NULL && ((wxTextCtrl *)itemp)->IsEditable());
727+#else
728+ canAcceptFocus = ((wxWindow *)itemp)->CanAcceptFocusFromKeyboard();
729+#endif
730+
731+ if (canAcceptFocus) {
732+ if (wxDynamicCast((wxWindow *)itemp, wxTextCtrl) != NULL && ((wxTextCtrl *)itemp)->IsEditable()) {
733+ ((wxTextCtrl *)itemp)->SelectAll();
734+ }
735+ ((wxWindow *)itemp)->SetFocus();
736+ break;
737+ }
738+ }
739+ dframe->shouldInitializeBeforeShow = false;
740+ }
741+}
742+
692743 int
693744 RubyDialogCallback_runModal(RubyDialog *dref)
694745 {
695746 int retval;
747+ RubyDialogCallback_initializeBeforeShow(dref, 1);
696748 ((RubyDialogFrame *)dref)->CenterOnScreen();
697749 retval = ((RubyDialogFrame *)dref)->ShowModal();
698750 if (retval == wxID_OK)
@@ -734,11 +786,7 @@ RubyDialogCallback_show(RubyDialog *dref)
734786 {
735787 RubyDialogFrame *dframe = (RubyDialogFrame *)dref;
736788
737- if (dframe->shouldInitializeBeforeShow) {
738- // Set a menu bar
739- dframe->SetMenuBar(wxGetApp().CreateMenuBar(3, NULL, NULL));
740- dframe->shouldInitializeBeforeShow = false;
741- }
789+ RubyDialogCallback_initializeBeforeShow(dref, 0);
742790
743791 if (dframe->myTimer != NULL)
744792 dframe->StartIntervalTimer(-1);
@@ -921,10 +969,11 @@ RubyDialogCallback_createItem(RubyDialog *dref, const char *type, const char *ti
921969 no_action = true;
922970 } else if (strcmp(type, "textfield") == 0) {
923971 /* Editable text */
924- wxTextCtrl *tc = new wxTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize(), wxTE_PROCESS_ENTER);
972+ MyTextCtrl *tc = new MyTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize(), wxTE_PROCESS_ENTER | MyTextCtrl_Process_Escape);
925973 control = tc;
926974 tc->Connect(-1, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(RubyDialogFrame::OnTextUpdated), NULL, parent);
927975 tc->Connect(-1, wxEVT_TEXT_ENTER, wxCommandEventHandler(RubyDialogFrame::OnEnterProcessedOnText), NULL, parent);
976+ tc->Connect(-1, myTextCtrl_EVT_PROCESS_ESCAPE, wxCommandEventHandler(RubyDialogFrame::OnEscapeProcessedOnText), NULL, parent);
928977 tc->Connect(-1, wxEVT_KILL_FOCUS, wxFocusEventHandler(RubyDialogFrame::OnKillFocusOnText), NULL, parent);
929978 } else if (strcmp(type, "textview") == 0) {
930979 /* Text view */
--- a/wxSources/RubyDialogFrame.h
+++ b/wxSources/RubyDialogFrame.h
@@ -105,6 +105,7 @@ public:
105105 void OnDialogItemAction(wxCommandEvent &event);
106106 void OnTextUpdated(wxCommandEvent &event);
107107 void OnEnterProcessedOnText(wxCommandEvent &event);
108+ void OnEscapeProcessedOnText(wxCommandEvent &event);
108109 void OnKillFocusOnText(wxFocusEvent &event);
109110
110111 void OnTimerEvent(wxTimerEvent &event);
--- a/xcode-build/Molby.xcodeproj/project.pbxproj
+++ b/xcode-build/Molby.xcodeproj/project.pbxproj
@@ -56,6 +56,7 @@
5656 E4ACACE718C6D32300F08B67 /* ortep3 in Resources */ = {isa = PBXBuildFile; fileRef = E4ACACE418C6D32300F08B67 /* ortep3 */; };
5757 E4D379A219C87C2200636D28 /* modalwindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D379A119C87C2200636D28 /* modalwindow.cpp */; };
5858 E4D37E0E19CC831500636D28 /* modalwindow_osx.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4D37E0D19CC831500636D28 /* modalwindow_osx.mm */; };
59+ E4D3806619CEC7B600636D28 /* MyTextCtrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D3806419CEC7B600636D28 /* MyTextCtrl.cpp */; };
5960 E4FC77A9183E4F3F0064FB2E /* Dcd.c in Sources */ = {isa = PBXBuildFile; fileRef = E4FC777B183E4F3F0064FB2E /* Dcd.c */; };
6061 E4FC77AA183E4F3F0064FB2E /* IntGroup.c in Sources */ = {isa = PBXBuildFile; fileRef = E4FC777D183E4F3F0064FB2E /* IntGroup.c */; };
6162 E4FC77AB183E4F3F0064FB2E /* MainView.c in Sources */ = {isa = PBXBuildFile; fileRef = E4FC777F183E4F3F0064FB2E /* MainView.c */; };
@@ -145,6 +146,8 @@
145146 E4D379A019C87C1200636D28 /* modalwindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = modalwindow.h; sourceTree = "<group>"; };
146147 E4D379A119C87C2200636D28 /* modalwindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = modalwindow.cpp; sourceTree = "<group>"; };
147148 E4D37E0D19CC831500636D28 /* modalwindow_osx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = modalwindow_osx.mm; sourceTree = "<group>"; };
149+ E4D3806419CEC7B600636D28 /* MyTextCtrl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MyTextCtrl.cpp; sourceTree = "<group>"; };
150+ E4D3806519CEC7B600636D28 /* MyTextCtrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyTextCtrl.h; sourceTree = "<group>"; };
148151 E4FC777A183E4F3F0064FB2E /* cmdtool_stubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmdtool_stubs.c; path = ../MolLib/cmdtool_stubs.c; sourceTree = SOURCE_ROOT; };
149152 E4FC777B183E4F3F0064FB2E /* Dcd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Dcd.c; path = ../MolLib/Dcd.c; sourceTree = SOURCE_ROOT; };
150153 E4FC777C183E4F3F0064FB2E /* Dcd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Dcd.h; path = ../MolLib/Dcd.h; sourceTree = SOURCE_ROOT; };
@@ -431,6 +434,8 @@
431434 E420BE09188574AD00A2B983 /* MyIPCSupport.h */,
432435 E420BE0A188574AD00A2B983 /* MyListCtrl.cpp */,
433436 E420BE0B188574AD00A2B983 /* MyListCtrl.h */,
437+ E4D3806419CEC7B600636D28 /* MyTextCtrl.cpp */,
438+ E4D3806519CEC7B600636D28 /* MyTextCtrl.h */,
434439 E420BE11188574D700A2B983 /* MyMBConv.h */,
435440 E420BE12188574D700A2B983 /* MyProgressIndicator.cpp */,
436441 E420BE13188574D700A2B983 /* MyProgressIndicator.h */,
@@ -625,6 +630,7 @@
625630 E4196C66190B2FA500183E62 /* menu.mm in Sources */,
626631 E4D379A219C87C2200636D28 /* modalwindow.cpp in Sources */,
627632 E4D37E0E19CC831500636D28 /* modalwindow_osx.mm in Sources */,
633+ E4D3806619CEC7B600636D28 /* MyTextCtrl.cpp in Sources */,
628634 );
629635 runOnlyForDeploymentPostprocessing = 0;
630636 };
旧リポジトリブラウザで表示