Molecular Modeling Software
リビジョン | e625c5ee1f0f7e07c0c6213ede9b44c8ea5dfb1d (tree) |
---|---|
日時 | 2022-09-11 22:33:31 |
作者 | Toshi Nagata <alchemist.2005@nift...> |
コミッター | Toshi Nagata |
Start writing new MyListCtrl
@@ -64,7 +64,7 @@ | ||
64 | 64 | E4059FC128C46A6E0052B36B /* MyDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE04188574AD00A2B983 /* MyDocument.cpp */; }; |
65 | 65 | E4059FC228C46A6E0052B36B /* MyGLCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE06188574AD00A2B983 /* MyGLCanvas.cpp */; }; |
66 | 66 | E4059FC328C46A6E0052B36B /* MyIPCSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE08188574AD00A2B983 /* MyIPCSupport.cpp */; }; |
67 | - E4059FC428C46A6E0052B36B /* MyListCtrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE0A188574AD00A2B983 /* MyListCtrl.cpp */; }; | |
67 | + E4059FC428C46A6E0052B36B /* MyListCtrl_orig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE0A188574AD00A2B983 /* MyListCtrl_orig.cpp */; }; | |
68 | 68 | E4059FC528C46A6E0052B36B /* MyProgressIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE12188574D700A2B983 /* MyProgressIndicator.cpp */; }; |
69 | 69 | E4059FC628C46A6E0052B36B /* MySlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE14188574D700A2B983 /* MySlider.cpp */; }; |
70 | 70 | E4059FC728C46A6E0052B36B /* MyThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE16188574D700A2B983 /* MyThread.cpp */; }; |
@@ -92,13 +92,13 @@ | ||
92 | 92 | E4059FDE28C46A6E0052B36B /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4FC7B58183E53710064FB2E /* WebKit.framework */; }; |
93 | 93 | E4059FDF28C46A6E0052B36B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4FC7CAC183F953E0064FB2E /* AudioToolbox.framework */; }; |
94 | 94 | E4059FE728C46B330052B36B /* Molby_MacLegacy-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E4059FE628C46B320052B36B /* Molby_MacLegacy-Info.plist */; }; |
95 | - E4196C66190B2FA500183E62 /* menu.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4196C65190B2FA500183E62 /* menu.mm */; }; | |
95 | + E41251B628C4B1AB00E12983 /* listctrl_wx32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41251B528C4B1AB00E12983 /* listctrl_wx32.cpp */; }; | |
96 | + E41251B828CD92A100E12983 /* MyListCtrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41251B728CD92A100E12983 /* MyListCtrl.cpp */; }; | |
97 | + E41251B928CD92A100E12983 /* MyListCtrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41251B728CD92A100E12983 /* MyListCtrl.cpp */; }; | |
96 | 98 | E41A7F962307D61200C65830 /* bitmaps in Resources */ = {isa = PBXBuildFile; fileRef = E41A7F952307D61200C65830 /* bitmaps */; }; |
97 | 99 | E420BDEF1885746700A2B983 /* ConsoleFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BDE81885746700A2B983 /* ConsoleFrame.cpp */; }; |
98 | - E420BDF01885746700A2B983 /* filedlg.mm in Sources */ = {isa = PBXBuildFile; fileRef = E420BDEA1885746700A2B983 /* filedlg.mm */; }; | |
99 | 100 | E420BDF11885746700A2B983 /* GlobalParameterFilesFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BDEB1885746700A2B983 /* GlobalParameterFilesFrame.cpp */; }; |
100 | 101 | E420BDF21885746700A2B983 /* GlobalParameterFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BDED1885746700A2B983 /* GlobalParameterFrame.cpp */; }; |
101 | - E420BDFD1885749000A2B983 /* listctrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BDF41885749000A2B983 /* listctrl.cpp */; }; | |
102 | 102 | E420BDFE1885749000A2B983 /* MoleculeView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BDF51885749000A2B983 /* MoleculeView.cpp */; }; |
103 | 103 | E420BDFF1885749000A2B983 /* MyApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BDF71885749000A2B983 /* MyApp.cpp */; }; |
104 | 104 | E420BE001885749000A2B983 /* MyClipboardData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BDF91885749000A2B983 /* MyClipboardData.cpp */; }; |
@@ -107,7 +107,6 @@ | ||
107 | 107 | E420BE0D188574AD00A2B983 /* MyDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE04188574AD00A2B983 /* MyDocument.cpp */; }; |
108 | 108 | E420BE0E188574AD00A2B983 /* MyGLCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE06188574AD00A2B983 /* MyGLCanvas.cpp */; }; |
109 | 109 | E420BE0F188574AD00A2B983 /* MyIPCSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE08188574AD00A2B983 /* MyIPCSupport.cpp */; }; |
110 | - E420BE10188574AD00A2B983 /* MyListCtrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE0A188574AD00A2B983 /* MyListCtrl.cpp */; }; | |
111 | 110 | E420BE19188574D700A2B983 /* MyProgressIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE12188574D700A2B983 /* MyProgressIndicator.cpp */; }; |
112 | 111 | E420BE1A188574D700A2B983 /* MySlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE14188574D700A2B983 /* MySlider.cpp */; }; |
113 | 112 | E420BE1B188574D700A2B983 /* MyThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BE16188574D700A2B983 /* MyThread.cpp */; }; |
@@ -189,6 +188,9 @@ | ||
189 | 188 | 8D1107320486CEB800E47090 /* Molby.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Molby.app; sourceTree = BUILT_PRODUCTS_DIR; }; |
190 | 189 | E4059FE428C46A6E0052B36B /* Molby_MacLegacy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Molby_MacLegacy.app; sourceTree = BUILT_PRODUCTS_DIR; }; |
191 | 190 | E4059FE628C46B320052B36B /* Molby_MacLegacy-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Molby_MacLegacy-Info.plist"; sourceTree = "<group>"; }; |
191 | + E41251B528C4B1AB00E12983 /* listctrl_wx32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = listctrl_wx32.cpp; sourceTree = "<group>"; }; | |
192 | + E41251B728CD92A100E12983 /* MyListCtrl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MyListCtrl.cpp; sourceTree = "<group>"; }; | |
193 | + E41251BA28CD92AD00E12983 /* MyListCtrl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyListCtrl.h; sourceTree = "<group>"; }; | |
192 | 194 | E4196C65190B2FA500183E62 /* menu.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = menu.mm; sourceTree = "<group>"; }; |
193 | 195 | E41A7F952307D61200C65830 /* bitmaps */ = {isa = PBXFileReference; lastKnownFileType = folder; name = bitmaps; path = ../bitmaps/bitmaps; sourceTree = "<group>"; }; |
194 | 196 | E420BDE81885746700A2B983 /* ConsoleFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsoleFrame.cpp; sourceTree = "<group>"; }; |
@@ -216,8 +218,8 @@ | ||
216 | 218 | E420BE07188574AD00A2B983 /* MyGLCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyGLCanvas.h; sourceTree = "<group>"; }; |
217 | 219 | E420BE08188574AD00A2B983 /* MyIPCSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MyIPCSupport.cpp; sourceTree = "<group>"; }; |
218 | 220 | E420BE09188574AD00A2B983 /* MyIPCSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyIPCSupport.h; sourceTree = "<group>"; }; |
219 | - E420BE0A188574AD00A2B983 /* MyListCtrl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MyListCtrl.cpp; sourceTree = "<group>"; }; | |
220 | - E420BE0B188574AD00A2B983 /* MyListCtrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyListCtrl.h; sourceTree = "<group>"; }; | |
221 | + E420BE0A188574AD00A2B983 /* MyListCtrl_orig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MyListCtrl_orig.cpp; sourceTree = "<group>"; }; | |
222 | + E420BE0B188574AD00A2B983 /* MyListCtrl_orig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyListCtrl_orig.h; sourceTree = "<group>"; }; | |
221 | 223 | E420BE11188574D700A2B983 /* MyMBConv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyMBConv.h; sourceTree = "<group>"; }; |
222 | 224 | E420BE12188574D700A2B983 /* MyProgressIndicator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MyProgressIndicator.cpp; sourceTree = "<group>"; }; |
223 | 225 | E420BE13188574D700A2B983 /* MyProgressIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyProgressIndicator.h; sourceTree = "<group>"; }; |
@@ -524,6 +526,7 @@ | ||
524 | 526 | E420BDEE1885746700A2B983 /* GlobalParameterFrame.h */, |
525 | 527 | E420BDF31885749000A2B983 /* listctrl_private.h */, |
526 | 528 | E420BDF41885749000A2B983 /* listctrl.cpp */, |
529 | + E41251B528C4B1AB00E12983 /* listctrl_wx32.cpp */, | |
527 | 530 | E4653CB018A0CC7D0022377B /* textctrl_addition.mm */, |
528 | 531 | E4196C65190B2FA500183E62 /* menu.mm */, |
529 | 532 | E420BDF51885749000A2B983 /* MoleculeView.cpp */, |
@@ -542,8 +545,10 @@ | ||
542 | 545 | E420BE07188574AD00A2B983 /* MyGLCanvas.h */, |
543 | 546 | E420BE08188574AD00A2B983 /* MyIPCSupport.cpp */, |
544 | 547 | E420BE09188574AD00A2B983 /* MyIPCSupport.h */, |
545 | - E420BE0A188574AD00A2B983 /* MyListCtrl.cpp */, | |
546 | - E420BE0B188574AD00A2B983 /* MyListCtrl.h */, | |
548 | + E420BE0A188574AD00A2B983 /* MyListCtrl_orig.cpp */, | |
549 | + E420BE0B188574AD00A2B983 /* MyListCtrl_orig.h */, | |
550 | + E41251B728CD92A100E12983 /* MyListCtrl.cpp */, | |
551 | + E41251BA28CD92AD00E12983 /* MyListCtrl.h */, | |
547 | 552 | E4D3806419CEC7B600636D28 /* MyTextCtrl.cpp */, |
548 | 553 | E4D3806519CEC7B600636D28 /* MyTextCtrl.h */, |
549 | 554 | E420BE11188574D700A2B983 /* MyMBConv.h */, |
@@ -872,6 +877,7 @@ | ||
872 | 877 | E4FC77B7183E4F3F0064FB2E /* Object.c in Sources */, |
873 | 878 | E4FC77B8183E4F3F0064FB2E /* Parameter.c in Sources */, |
874 | 879 | E4FC77BA183E4F3F0064FB2E /* ruby_bind.c in Sources */, |
880 | + E41251B628C4B1AB00E12983 /* listctrl_wx32.cpp in Sources */, | |
875 | 881 | E4FC77BB183E4F3F0064FB2E /* ruby_dialog.c in Sources */, |
876 | 882 | E4FC77BC183E4F3F0064FB2E /* ruby_md.c in Sources */, |
877 | 883 | E4FC77BD183E4F3F0064FB2E /* ruby_types.c in Sources */, |
@@ -879,10 +885,9 @@ | ||
879 | 885 | E4FC77BF183E4F3F0064FB2E /* Types.c in Sources */, |
880 | 886 | E4FC7CA6183F94D30064FB2E /* buildInfo.c in Sources */, |
881 | 887 | E420BDEF1885746700A2B983 /* ConsoleFrame.cpp in Sources */, |
882 | - E420BDF01885746700A2B983 /* filedlg.mm in Sources */, | |
883 | 888 | E420BDF11885746700A2B983 /* GlobalParameterFilesFrame.cpp in Sources */, |
889 | + E41251B828CD92A100E12983 /* MyListCtrl.cpp in Sources */, | |
884 | 890 | E420BDF21885746700A2B983 /* GlobalParameterFrame.cpp in Sources */, |
885 | - E420BDFD1885749000A2B983 /* listctrl.cpp in Sources */, | |
886 | 891 | E420BDFE1885749000A2B983 /* MoleculeView.cpp in Sources */, |
887 | 892 | E420BDFF1885749000A2B983 /* MyApp.cpp in Sources */, |
888 | 893 | E420BE001885749000A2B983 /* MyClipboardData.cpp in Sources */, |
@@ -891,7 +896,6 @@ | ||
891 | 896 | E420BE0D188574AD00A2B983 /* MyDocument.cpp in Sources */, |
892 | 897 | E420BE0E188574AD00A2B983 /* MyGLCanvas.cpp in Sources */, |
893 | 898 | E420BE0F188574AD00A2B983 /* MyIPCSupport.cpp in Sources */, |
894 | - E420BE10188574AD00A2B983 /* MyListCtrl.cpp in Sources */, | |
895 | 899 | E420BE19188574D700A2B983 /* MyProgressIndicator.cpp in Sources */, |
896 | 900 | E420BE1A188574D700A2B983 /* MySlider.cpp in Sources */, |
897 | 901 | E420BE1B188574D700A2B983 /* MyThread.cpp in Sources */, |
@@ -900,7 +904,6 @@ | ||
900 | 904 | E420BE23188574F600A2B983 /* RubyDialogFrame.cpp in Sources */, |
901 | 905 | E420BE24188574F600A2B983 /* wxKillAddition.cpp in Sources */, |
902 | 906 | E4653CB118A0CC7D0022377B /* textctrl_addition.mm in Sources */, |
903 | - E4196C66190B2FA500183E62 /* menu.mm in Sources */, | |
904 | 907 | E4D379A219C87C2200636D28 /* modalwindow.cpp in Sources */, |
905 | 908 | E4D37E0E19CC831500636D28 /* modalwindow_osx.mm in Sources */, |
906 | 909 | E4D3806619CEC7B600636D28 /* MyTextCtrl.cpp in Sources */, |
@@ -938,6 +941,7 @@ | ||
938 | 941 | E4059FB828C46A6E0052B36B /* filedlg.mm in Sources */, |
939 | 942 | E4059FB928C46A6E0052B36B /* GlobalParameterFilesFrame.cpp in Sources */, |
940 | 943 | E4059FBA28C46A6E0052B36B /* GlobalParameterFrame.cpp in Sources */, |
944 | + E41251B928CD92A100E12983 /* MyListCtrl.cpp in Sources */, | |
941 | 945 | E4059FBB28C46A6E0052B36B /* listctrl.cpp in Sources */, |
942 | 946 | E4059FBC28C46A6E0052B36B /* MoleculeView.cpp in Sources */, |
943 | 947 | E4059FBD28C46A6E0052B36B /* MyApp.cpp in Sources */, |
@@ -947,7 +951,7 @@ | ||
947 | 951 | E4059FC128C46A6E0052B36B /* MyDocument.cpp in Sources */, |
948 | 952 | E4059FC228C46A6E0052B36B /* MyGLCanvas.cpp in Sources */, |
949 | 953 | E4059FC328C46A6E0052B36B /* MyIPCSupport.cpp in Sources */, |
950 | - E4059FC428C46A6E0052B36B /* MyListCtrl.cpp in Sources */, | |
954 | + E4059FC428C46A6E0052B36B /* MyListCtrl_orig.cpp in Sources */, | |
951 | 955 | E4059FC528C46A6E0052B36B /* MyProgressIndicator.cpp in Sources */, |
952 | 956 | E4059FC628C46A6E0052B36B /* MySlider.cpp in Sources */, |
953 | 957 | E4059FC728C46A6E0052B36B /* MyThread.cpp in Sources */, |
@@ -1012,6 +1016,7 @@ | ||
1012 | 1016 | "$(PROJECT_DIR)/../../ruby-2.0.0-p353", |
1013 | 1017 | "$(PROJECT_DIR)/../../ruby-2.0.0-p353/build-osx/include/ruby-2.0.0", |
1014 | 1018 | "$(PROJECT_DIR)/../../ruby-2.0.0-p353/build-osx/include/ruby-2.0.0/x86_64-darwin18.7.0", |
1019 | + /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Accelerate.framework/Frameworks/vecLib.framework/Headers, | |
1015 | 1020 | ); |
1016 | 1021 | INFOPLIST_FILE = "Molby-Info.plist"; |
1017 | 1022 | INSTALL_PATH = "$(HOME)/Applications"; |
@@ -1071,6 +1076,7 @@ | ||
1071 | 1076 | "$(PROJECT_DIR)/../../ruby-2.0.0-p353", |
1072 | 1077 | "$(PROJECT_DIR)/../../ruby-2.0.0-p353/build-osx/include/ruby-2.0.0", |
1073 | 1078 | "$(PROJECT_DIR)/../../ruby-2.0.0-p353/build-osx/include/ruby-2.0.0/x86_64-darwin18.7.0", |
1079 | + /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Accelerate.framework/Frameworks/vecLib.framework/Headers, | |
1074 | 1080 | ); |
1075 | 1081 | INFOPLIST_FILE = "Molby-Info.plist"; |
1076 | 1082 | INSTALL_PATH = "$(HOME)/Applications"; |
@@ -0,0 +1,704 @@ | ||
1 | +/* | |
2 | + * MyListCtrl.cpp | |
3 | + * Molby | |
4 | + * | |
5 | + * Created by Toshi Nagata on 2022/09/11. | |
6 | + * Copyright 2022 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 "MyListCtrl.h" | |
19 | +#include "MyMBConv.h" | |
20 | + | |
21 | +#include "wx/dcclient.h" | |
22 | +#include "wx/scrolwin.h" | |
23 | +#include "wx/glcanvas.h" | |
24 | +#include "wx/menu.h" | |
25 | +#include "wx/sizer.h" | |
26 | + | |
27 | +const wxEventType MyListCtrlEvent = wxNewEventType(); | |
28 | + | |
29 | +IMPLEMENT_DYNAMIC_CLASS(MyListCtrl, wxWindow) | |
30 | + | |
31 | +BEGIN_EVENT_TABLE(MyListCtrl, wxWindow) | |
32 | +//EVT_COMMAND(MyListCtrlEvent_tableSelectionChanged, MyListCtrlEvent, MyListCtrl::OnTableSelectionChanged) | |
33 | +//EVT_COMMAND(MyListCtrlEvent_enableTableSelectionNotification, MyListCtrlEvent, MyListCtrl::OnEnableTableSelectionNotification) | |
34 | +END_EVENT_TABLE() | |
35 | + | |
36 | +MyListCtrl::MyListCtrl() | |
37 | +{ | |
38 | + editText = NULL; | |
39 | + dataSource = NULL; | |
40 | + header = NULL; | |
41 | + scroll = NULL; | |
42 | + ncols = nrows = 0; | |
43 | + headerHeight = rowHeight = 0; | |
44 | + pageWidth = pageHeight = 0; | |
45 | + editRow = editColumn = -1; | |
46 | + dragTargetRow = -1; | |
47 | + mouseMode = 0; | |
48 | + mouseRow = -1; | |
49 | + lastMouseRow = -1; | |
50 | + draggingRows = false; | |
51 | + selectionChangeNotificationRequired = false; | |
52 | + selectionChangeNotificationEnabled = true; | |
53 | + lastPopUpColumn = lastPopUpRow = -1; | |
54 | + | |
55 | +#if defined(__WXMAC__) | |
56 | + // On OSX, the default font seems to be 14-point, which is too big. | |
57 | +// wxFont font = this->GetFont(); | |
58 | +// font.SetPointSize(12); | |
59 | +// this->SetFont(font); | |
60 | +#endif | |
61 | +} | |
62 | + | |
63 | +MyListCtrl::~MyListCtrl() | |
64 | +{ | |
65 | + if (editText != NULL) { | |
66 | + /* editText->Destroy(); */ /* May be unnecessary */ | |
67 | + editText = NULL; | |
68 | + } | |
69 | +} | |
70 | + | |
71 | +bool | |
72 | +MyListCtrl::Create(wxWindow* parent, wxWindowID wid, const wxPoint& pos, const wxSize& size) | |
73 | +{ | |
74 | + this->wxWindow::Create(parent, wid, pos, size); | |
75 | + | |
76 | + header = new wxWindow(this, 1001, wxPoint(0, 0), wxSize(size.x, 12)); | |
77 | + scroll = new wxScrolledWindow(this, 1002, wxPoint(0, 12), wxSize(size.x, (size.y <= 12 ? 100 : size.y) - 12)); | |
78 | + | |
79 | + // Set sizer | |
80 | + wxBoxSizer *vsizer = new wxBoxSizer(wxVERTICAL); | |
81 | + vsizer->Add(header, wxSizerFlags(0).Expand().Border(wxALL, 0)); | |
82 | + vsizer->Add(scroll, wxSizerFlags(1).Expand().Border(wxALL, 0)); | |
83 | + this->SetSizer(vsizer); | |
84 | + | |
85 | + // Connect events | |
86 | + header->Bind(wxEVT_PAINT, &MyListCtrl::OnPaintHeader, this); | |
87 | + scroll->Bind(wxEVT_PAINT, &MyListCtrl::OnPaint, this); | |
88 | + scroll->Bind(wxEVT_LEFT_DOWN, &MyListCtrl::OnLeftDown, this); | |
89 | + scroll->Bind(wxEVT_LEFT_UP, &MyListCtrl::OnLeftUp, this); | |
90 | + scroll->Bind(wxEVT_LEFT_DCLICK, &MyListCtrl::OnLeftDClick, this); | |
91 | + scroll->Bind(wxEVT_SCROLLWIN_BOTTOM, &MyListCtrl::OnScrollWin, this); | |
92 | + scroll->Bind(wxEVT_SCROLLWIN_TOP, &MyListCtrl::OnScrollWin, this); | |
93 | + scroll->Bind(wxEVT_SCROLLWIN_LINEDOWN, &MyListCtrl::OnScrollWin, this); | |
94 | + scroll->Bind(wxEVT_SCROLLWIN_LINEUP, &MyListCtrl::OnScrollWin, this); | |
95 | + scroll->Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyListCtrl::OnScrollWin, this); | |
96 | + scroll->Bind(wxEVT_SCROLLWIN_PAGEUP, &MyListCtrl::OnScrollWin, this); | |
97 | + scroll->Bind(wxEVT_SCROLLWIN_THUMBRELEASE, &MyListCtrl::OnScrollWin, this); | |
98 | + scroll->Bind(wxEVT_SCROLLWIN_THUMBTRACK, &MyListCtrl::OnScrollWin, this); | |
99 | + | |
100 | + headerHeight = 12; | |
101 | + rowHeight = 12; | |
102 | + | |
103 | + selectionChangeNotificationRequired = false; | |
104 | + selectionChangeNotificationEnabled = true; | |
105 | + return true; | |
106 | +} | |
107 | + | |
108 | +void | |
109 | +MyListCtrl::SetDataSource(MyListCtrlDataSource *source) | |
110 | +{ | |
111 | + dataSource = source; | |
112 | + RefreshTable(); | |
113 | +} | |
114 | + | |
115 | +void | |
116 | +MyListCtrl::RefreshTable() | |
117 | +{ | |
118 | + if (dataSource == NULL) { | |
119 | + nrows = ncols = 0; | |
120 | + } else { | |
121 | + int i; | |
122 | + wxSize sz = header->GetSize(); | |
123 | + nrows = dataSource->GetNumberOfRows(this); | |
124 | + ncols = dataSource->GetNumberOfColumns(this); | |
125 | + colWidths.resize(ncols, 10); | |
126 | + pageWidth = 0; | |
127 | + for (i = 0; i < ncols; i++) { | |
128 | + colWidths[i] = dataSource->GetColumnWidth(this, i); | |
129 | + pageWidth += colWidths[i]; | |
130 | + } | |
131 | + rowHeight = dataSource->GetRowHeight(this); | |
132 | + headerHeight = dataSource->GetHeaderHeight(this); | |
133 | + // "+4" is for drawing marker during cell dragging | |
134 | + pageHeight = rowHeight * nrows + 4; | |
135 | + // Set the subwindow infos | |
136 | + sz.y = headerHeight; | |
137 | + header->SetMinSize(sz); | |
138 | + scroll->SetScrollbars(rowHeight, rowHeight, floor((pageWidth + rowHeight - 1) / rowHeight), nrows); | |
139 | + scroll->SetVirtualSize(pageWidth, pageHeight); | |
140 | + Fit(); | |
141 | + Layout(); | |
142 | + } | |
143 | + Refresh(); | |
144 | +} | |
145 | + | |
146 | +static wxBrush lightBlueBrush(wxColour(128, 128, 255)); | |
147 | + | |
148 | +void | |
149 | +MyListCtrl::OnPaint(wxPaintEvent &event) | |
150 | +{ | |
151 | + if (dataSource == NULL) | |
152 | + return; | |
153 | + | |
154 | + wxPaintDC dc(scroll); | |
155 | + scroll->DoPrepareDC(dc); | |
156 | + int ox, oy; | |
157 | + scroll->CalcUnscrolledPosition(0, 0, &ox, &oy); | |
158 | + int col = -1, row, basex; | |
159 | + wxSize sz = scroll->GetClientSize(); | |
160 | + bool showDragTarget = (draggingRows && (dragTargetRow != mouseRow && dragTargetRow != mouseRow)); | |
161 | + // Draw background | |
162 | + int i, j; | |
163 | + basex = 0; | |
164 | + for (i = 0; i < ncols; i++) { | |
165 | + basex += colWidths[i]; | |
166 | + if (basex > ox) { | |
167 | + col = i; | |
168 | + basex -= colWidths[i]; | |
169 | + break; | |
170 | + } | |
171 | + } | |
172 | + if (col >= 0) { | |
173 | + wxTextAttr attr; | |
174 | + wxString str; | |
175 | + int x, y; | |
176 | + x = basex; | |
177 | + row = floor(oy / rowHeight); | |
178 | + for (i = col; i < ncols; i++) { | |
179 | + for (j = row; j < nrows; j++) { | |
180 | + y = j * rowHeight; | |
181 | + if (showDragTarget && j >= dragTargetRow) { | |
182 | + y += 5; | |
183 | + } | |
184 | + if (y > sz.y + oy) | |
185 | + break; | |
186 | + str = dataSource->GetCellText(this, j, i); | |
187 | + if (dataSource->GetCellAttr(this, j, i, attr)) { | |
188 | + // TODO: attribute change | |
189 | + } | |
190 | + if (IsRowSelected(j)) { | |
191 | + if (showDragTarget) { | |
192 | + dc.SetBrush(lightBlueBrush); | |
193 | + } else { | |
194 | + dc.SetBrush(*wxBLUE_BRUSH); | |
195 | + } | |
196 | + dc.SetPen(wxNullPen); | |
197 | + dc.SetTextForeground(*wxWHITE); | |
198 | + } else { | |
199 | + dc.SetBrush(*wxWHITE_BRUSH); | |
200 | + dc.SetPen(wxNullPen); | |
201 | + dc.SetTextForeground(*wxBLACK); | |
202 | + } | |
203 | + dc.DrawRectangle(x, y, colWidths[i], rowHeight - 1); | |
204 | + dc.DrawText(str, x, y); | |
205 | + } | |
206 | + if (showDragTarget) { | |
207 | + y = dragTargetRow * rowHeight + 1; | |
208 | + dc.SetBrush(*wxRED_BRUSH); | |
209 | + dc.SetPen(wxNullPen); | |
210 | + dc.DrawRectangle(x, y, colWidths[i], 3); | |
211 | + } | |
212 | + x += colWidths[i]; | |
213 | + if (x > sz.y + ox) | |
214 | + break; | |
215 | + } | |
216 | + } | |
217 | +} | |
218 | + | |
219 | +void | |
220 | +MyListCtrl::OnPaintHeader(wxPaintEvent &event) | |
221 | +{ | |
222 | + wxPaintDC dc(header); | |
223 | + dc.SetPen(*wxGREY_PEN); | |
224 | + dc.SetBrush(*wxLIGHT_GREY_BRUSH); | |
225 | + wxSize sz = header->GetSize(); | |
226 | + dc.DrawRectangle(0, 0, sz.x, sz.y); | |
227 | + if (dataSource) { | |
228 | + int ox, oy; | |
229 | + int x, x1; | |
230 | + int i; | |
231 | + wxTextAttr attr; | |
232 | + scroll->CalcUnscrolledPosition(0, 0, &ox, &oy); | |
233 | + x = -ox; | |
234 | + for (i = 0; i < ncols; i++) { | |
235 | + x1 = x + colWidths[i]; | |
236 | + if (x1 > 0) { | |
237 | + wxString str = dataSource->GetCellText(this, -1, i); | |
238 | + if (dataSource->GetCellAttr(this, -1, i, attr)) { | |
239 | + // TODO: do attribute change | |
240 | + } | |
241 | + dc.DrawText(str, x, 0); | |
242 | + } | |
243 | + } | |
244 | + } | |
245 | +} | |
246 | + | |
247 | +void | |
248 | +MyListCtrl::PrepareSelectionChangeNotification() | |
249 | +{ | |
250 | + int i; | |
251 | + if (selectionChangeNotificationRequired || !selectionChangeNotificationEnabled) | |
252 | + return; // Do nothing | |
253 | + oldSelection.resize(selection.size()); | |
254 | + for (i = 0; i < selection.size(); i++) | |
255 | + oldSelection[i] = selection[i]; | |
256 | + selectionChangeNotificationRequired = true; | |
257 | +} | |
258 | + | |
259 | +bool | |
260 | +MyListCtrl::IsRowSelected(int row) | |
261 | +{ | |
262 | + int i; | |
263 | + for (i = 0; i < selection.size(); i++) { | |
264 | + if (selection[i] == row) | |
265 | + return true; | |
266 | + } | |
267 | + return false; | |
268 | +} | |
269 | + | |
270 | +bool | |
271 | +MyListCtrl::SelectRow(int row) | |
272 | +{ | |
273 | + int i; | |
274 | + for (i = 0; i < selection.size(); i++) { | |
275 | + if (selection[i] == row) | |
276 | + return false; | |
277 | + if (selection[i] > row) | |
278 | + break; | |
279 | + } | |
280 | + selection.insert(selection.begin() + i, row); | |
281 | + Refresh(); | |
282 | + return true; | |
283 | +} | |
284 | + | |
285 | +bool | |
286 | +MyListCtrl::UnselectRow(int row) | |
287 | +{ | |
288 | + int i; | |
289 | + for (i = 0; i < selection.size(); i++) { | |
290 | + if (selection[i] == row) { | |
291 | + selection.erase(selection.begin() + i); | |
292 | + Refresh(); | |
293 | + return true; | |
294 | + } | |
295 | + } | |
296 | + return false; | |
297 | +} | |
298 | + | |
299 | +void | |
300 | +MyListCtrl::UnselectAllRows() | |
301 | +{ | |
302 | + selection.clear(); | |
303 | + Refresh(); | |
304 | +} | |
305 | + | |
306 | +// Mouse down | |
307 | +// 1. On a selected row with no modifier | |
308 | +// If dragging starts, then start dragging the selected cells (if dragging is enabled) | |
309 | +// If mouse up on another row, then try to reorder the selected cells (if dragging is enabled) | |
310 | +// (the moved cells are left selected) | |
311 | +// If mouse up on the same row, then deselect all other rows | |
312 | +// (and leave only this row selected) | |
313 | +// 2. On a selected row with shift | |
314 | +// Same as 1, except that if mouse up on the same row then do nothing | |
315 | +// 3. On a selected row with command (Mac) or control (Win) | |
316 | +// Unselect this row, and do nothing on drag or mouse-up | |
317 | +// 4. On an unselected row with no modifier | |
318 | +// Unselect all other rows and select this row (in this handler) | |
319 | +// And do the same way as 2 | |
320 | +// 5. On an unselected row with shift | |
321 | +// Select all cells between the last-clicked row and this row (in this handler) | |
322 | +// And do the same way as 2 | |
323 | +// 6. On an unselected row with command or control key | |
324 | +// Select this row (in this handler), and do the same way as 2 | |
325 | +void | |
326 | +MyListCtrl::OnLeftDown(wxMouseEvent &event) | |
327 | +{ | |
328 | + int x, y, ux, uy, row, modifiers, i; | |
329 | + bool isRowSelected, selectionChanged = false; | |
330 | + if (editText) | |
331 | + EndEditText(); | |
332 | + x = event.GetX(); | |
333 | + y = event.GetY(); | |
334 | + scroll->CalcUnscrolledPosition(x, y, &ux, &uy); | |
335 | + row = floor(uy / rowHeight); | |
336 | + isRowSelected = IsRowSelected(row); | |
337 | + modifiers = event.GetModifiers(); | |
338 | + PrepareSelectionChangeNotification(); | |
339 | + if ((modifiers & wxMOD_SHIFT) != 0) | |
340 | + mouseMode = (isRowSelected ? 2 : 5); | |
341 | +#if defined(__WXMAC__) || defined(__WXOSX__) | |
342 | + else if ((modifiers & wxMOD_CMD) != 0) | |
343 | + mouseMode = (isRowSelected ? 3 : 6); | |
344 | +#else | |
345 | + else if ((modifiers & wxMOD_CONTROL) != 0) | |
346 | + mouseMode = (isRowSelected ? 3 : 6); | |
347 | +#endif | |
348 | + else | |
349 | + mouseMode = (isRowSelected ? 1 : 4); | |
350 | + mouseRow = row; | |
351 | + if (mouseMode == 3) { | |
352 | + UnselectRow(row); | |
353 | + selectionChanged = true; | |
354 | + } else if (mouseMode == 4) { | |
355 | + UnselectAllRows(); | |
356 | + SelectRow(row); | |
357 | + selectionChanged = true; | |
358 | + } else if (mouseMode == 5) { | |
359 | + if (lastMouseRow >= 0) { | |
360 | + int rs, re; | |
361 | + if (lastMouseRow < row) { | |
362 | + rs = lastMouseRow; | |
363 | + re = row; | |
364 | + } else { | |
365 | + rs = row; | |
366 | + re = lastMouseRow; | |
367 | + } | |
368 | + for (i = rs; i <= re; i++) { | |
369 | + SelectRow(i); | |
370 | + } | |
371 | + selectionChanged = true; | |
372 | + } | |
373 | + } else if (mouseMode == 6) { | |
374 | + SelectRow(row); | |
375 | + selectionChanged = true; | |
376 | + } | |
377 | + if (!selectionChanged) { | |
378 | + // Actually no change occurred | |
379 | + selectionChangeNotificationRequired = false; | |
380 | + } | |
381 | + Refresh(); | |
382 | +} | |
383 | + | |
384 | +void | |
385 | +MyListCtrl::DragRows(int x, int y) | |
386 | +{ | |
387 | + wxSize sz = scroll->GetClientSize(); | |
388 | + int ux, uy; | |
389 | + if (y < 0) | |
390 | + y = 0; | |
391 | + else if (y > sz.y) | |
392 | + y = sz.y; | |
393 | + scroll->CalcUnscrolledPosition(x, y, &ux, &uy); | |
394 | + dragTargetRow = floor(uy / rowHeight + 0.5); | |
395 | + if (dragTargetRow < 0) | |
396 | + dragTargetRow = 0; | |
397 | + else if (dragTargetRow > nrows) | |
398 | + dragTargetRow = nrows; | |
399 | + Refresh(); | |
400 | +} | |
401 | + | |
402 | +void | |
403 | +MyListCtrl::OnMotion(wxMouseEvent &event) | |
404 | +{ | |
405 | + if (event.LeftIsDown()) { | |
406 | + // Dragging | |
407 | + if (mouseMode > 0 && !scroll->HasCapture()) { | |
408 | + // Start dragging | |
409 | + scroll->CaptureMouse(); | |
410 | + if (mouseMode != 3 && dataSource->IsDragEnabled(this, mouseRow)) { | |
411 | + draggingRows = true; | |
412 | + } | |
413 | + } | |
414 | + if (draggingRows) { | |
415 | + wxPoint cp = scroll->ScreenToClient(wxGetMousePosition()); | |
416 | + DragRows(cp.x, cp.y); | |
417 | + } | |
418 | + } | |
419 | +} | |
420 | + | |
421 | +void | |
422 | +MyListCtrl::OnLeftDClick(wxMouseEvent &event) | |
423 | +{ | |
424 | + // Start editing this cell | |
425 | + int x, y, ux, uy, row, col, cx, i; | |
426 | + x = event.GetX(); | |
427 | + y = event.GetY(); | |
428 | + scroll->CalcUnscrolledPosition(x, y, &ux, &uy); | |
429 | + row = floor(uy / rowHeight); | |
430 | + cx = 0; | |
431 | + for (i = 0; i < ncols; i++) { | |
432 | + if ((ux >= cx && ux < cx + colWidths[i]) || i == ncols - 1) { | |
433 | + col = i; | |
434 | + break; | |
435 | + } | |
436 | + cx += colWidths[i]; | |
437 | + } | |
438 | + if (!dataSource->IsEditable(this, col, row)) | |
439 | + return; | |
440 | + StartEditText(col, row); | |
441 | +} | |
442 | + | |
443 | +void | |
444 | +MyListCtrl::OnLeftUp(wxMouseEvent &event) | |
445 | +{ | |
446 | + int x, y, ux, uy, row, i; | |
447 | + bool dragged = false; | |
448 | + bool selectionChanged = selectionChangeNotifiationRequired; | |
449 | + x = event.GetX(); | |
450 | + y = event.GetY(); | |
451 | + scroll->CalcUnscrolledPosition(x, y, &ux, &uy); | |
452 | + row = floor(uy / rowHeight); | |
453 | + PrepareSelectionChangeNotification(); | |
454 | + if (scroll->HasCapture()) { | |
455 | + scroll->ReleaseMouse(); | |
456 | + dragged = true; | |
457 | + if (row != mouseRow) { | |
458 | + if (draggingRows) { | |
459 | + // TODO: move cells | |
460 | + selectionChanged = true; | |
461 | + } | |
462 | + } | |
463 | + } | |
464 | + if (!dragged) { | |
465 | + if (mouseMode == 1 || mouseMode == 4) { | |
466 | + if (selection.size() != 1 || !IsRowSelected(mouseRow)) { | |
467 | + UnselectAllRows(); | |
468 | + SelectRow(mouseRow); | |
469 | + selectionChanged = true; | |
470 | + } | |
471 | + } | |
472 | + lastMouseRow = row; | |
473 | + } | |
474 | + if (!selectionChanged) | |
475 | + selectionChangeNotificationRequired = false; | |
476 | + mouseMode = 0; | |
477 | + mouseRow = -1; | |
478 | + draggingRows = false; | |
479 | + Refresh(); | |
480 | +} | |
481 | + | |
482 | +void | |
483 | +MyListCtrl::OnScrollWin(wxScrollWinEvent &event) | |
484 | +{ | |
485 | + wxPoint cp = scroll->ScreenToClient(wxGetMousePosition()); | |
486 | + wxSize sz = scroll->GetClientSize(); | |
487 | + wxEventType etype = event.GetEventType(); | |
488 | + wxEventType etype_org = etype; | |
489 | + int vx, vy; | |
490 | + int step = rowHeight; | |
491 | + scroll->CalcUnscrolledPosition(0, 0, &vx, &vy); | |
492 | + wxSize vs = scroll->GetVirtualSize(); | |
493 | + int orient = event.GetOrientation(); | |
494 | + | |
495 | + if (scroll->IsAutoScrolling()) { | |
496 | + // Autoscrolling | |
497 | + if (mouseMode == 3) { | |
498 | + return; // Mouse is captured by do not autoscroll | |
499 | + } | |
500 | + if (etype == wxEVT_SCROLLWIN_LINEUP || etype == wxEVT_SCROLLWIN_LINEDOWN) { | |
501 | + if (orient == wxHORIZONTAL) { | |
502 | + // Is the mouse outside the client width? | |
503 | + if (cp.x < 0) { | |
504 | + etype = wxEVT_SCROLLWIN_LINEUP; | |
505 | + if (vx < step) | |
506 | + etype = 0; | |
507 | + } else if (cp.x > sz.x) { | |
508 | + etype = wxEVT_SCROLLWIN_LINEDOWN; | |
509 | + if (vx > vs.x - sz.x) | |
510 | + etype = 0; | |
511 | + } else etype = 0; | |
512 | + } else { | |
513 | + // Is the mouse outsize the client height? | |
514 | + if (cp.y < 0) { | |
515 | + etype = wxEVT_SCROLLWIN_LINEUP; | |
516 | + if (vy < step) | |
517 | + etype = 0; | |
518 | + } else if (cp.y > sz.y) { | |
519 | + etype = wxEVT_SCROLLWIN_LINEDOWN; | |
520 | + if (vy > vs.y - sz.y) | |
521 | + etype = 0; | |
522 | + } else etype = 0; | |
523 | + } | |
524 | + } | |
525 | + if (etype == 0) | |
526 | + return; // Pause scrolling | |
527 | + event.SetEventType(etype); | |
528 | + } | |
529 | + event.Skip(); | |
530 | + if (draggingRows) { | |
531 | + // Handle dragging rows | |
532 | + DragRows(cp.x, cp.y); | |
533 | + } | |
534 | + header->Refresh(); // Adjust the header display | |
535 | +} | |
536 | + | |
537 | +void | |
538 | +MyListCtrl::PostSelectionChangeNotification() | |
539 | +{ | |
540 | + if (selectionChangeNotificationRequired && selectionChangeNotificationEnabled) { | |
541 | + wxCommandEvent myEvent(MyListCtrlEvent, MyListCtrlEvent_tableSelectionChanged); | |
542 | + wxPostEvent(this, myEvent); | |
543 | + selectionChangeNotificationRequired = false; | |
544 | + } | |
545 | +} | |
546 | + | |
547 | +// Find item on list control | |
548 | +// Pos is the client coordinate in MyListCtrl (not scroll) | |
549 | +bool | |
550 | +MyListCtrl::FindItemAtPosition(const wxPoint &pos, int *row, int *col) | |
551 | +{ | |
552 | + int r, cx, i; | |
553 | + wxPoint p = this->ClientToScreen(pos); | |
554 | + p = scroll->ScreenToClient(p); | |
555 | + p = scroll->CalcUnscrolledPosition(p); | |
556 | + r = floor(p.y / rowHeight); | |
557 | + if (r < 0 || r >= nrows) | |
558 | + r = -1; | |
559 | + cx = 0; | |
560 | + for (i = 0; i < ncols; i++) { | |
561 | + if (p.x >= cx && p.x < cx + colWidths[i]) | |
562 | + break; | |
563 | + } | |
564 | + if (i >= ncols) | |
565 | + i = -1; | |
566 | + if (row != NULL) | |
567 | + *row = r; | |
568 | + if (col != NULL) | |
569 | + *col = i; | |
570 | + return (r >= 0 && i >= 0); | |
571 | +} | |
572 | + | |
573 | +void | |
574 | +MyListCtrl::StartEditText(int row, int col) | |
575 | +{ | |
576 | + int i, tx, ty; | |
577 | + int cy = rowHeight * row; | |
578 | + int cx = 0; | |
579 | + for (i = 0; i < col; i++) { | |
580 | + cx += colWidths[i]; | |
581 | + } | |
582 | + scroll->CalcScrolledPosition(cx, cy, &tx, &ty); | |
583 | + if (editText == NULL) { | |
584 | + editText = new wxTextCtrl(scroll, -1, "", wxPoint(tx - 2, ty - 2), wxSize(colWidths[col] + 4, rowHeight + 4), wxTE_PROCESS_ENTER); | |
585 | + editText->Bind(wxEVT_CHAR, &MyListCtrl::OnCharInText, this); | |
586 | + } else { | |
587 | + FinalizeEdit(); | |
588 | + editText->SetPosition(wxPoint(tx - 2, ty - 2)); | |
589 | + editText->SetSize(wxSize(colWidths[col] + 4, rowHeight + 4)); | |
590 | + } | |
591 | + wxSize sz = scroll->GetClientSize(); | |
592 | + int scx = -1, scy = -1; | |
593 | + if (tx < 0) { | |
594 | + scx = floor(cx / rowHeight); | |
595 | + } else if (tx + colWidths[col] > sz.x) { | |
596 | + scx = ceil((colWidths[col] - sz.x) / rowHeight); | |
597 | + if (scx < 0) | |
598 | + scx = 0; | |
599 | + } | |
600 | + if (ty < 0) { | |
601 | + scy = floor(cy / rowHeight); | |
602 | + } else if (ty + rowHeight > sz.y) { | |
603 | + scy = ceil((cy + rowHeight - sz.y) / rowHeight); | |
604 | + if (scy < 0) | |
605 | + scy = 0; | |
606 | + } | |
607 | + if (scx >= 0 || scy >= 0) | |
608 | + scroll->Scroll(scx, scy); | |
609 | + editText->Show(); | |
610 | + editText->SetFocus(); | |
611 | + editText->SelectAll(); | |
612 | + editRow = row; | |
613 | + editColumn = col; | |
614 | + if (selection.size() != 1 || !IsRowSelected(row)) { | |
615 | + UnselectAllRows(); | |
616 | + SelectRow(row); | |
617 | + } | |
618 | +} | |
619 | + | |
620 | +void | |
621 | +MyListCtrl::EndEditText(bool setValueFlag) | |
622 | +{ | |
623 | + if (!editText) | |
624 | + return; | |
625 | + if (setValueFlag) | |
626 | + FinalizeEdit(); | |
627 | + editText->Hide(); | |
628 | + editText->Destroy(); | |
629 | + editText = NULL; | |
630 | +} | |
631 | +void | |
632 | +MyListCtrl::EndEditTextAndRestart(bool setValueFlag, int newRow, int newCol) | |
633 | +{ | |
634 | + EndEditText(setValueFlag); | |
635 | + StartEditText(newRow, newCol); | |
636 | +} | |
637 | + | |
638 | +void | |
639 | +MyListCtrl::OnCharInText(wxKeyEvent &event) | |
640 | +{ | |
641 | + int kc = event.GetKeyCode(); | |
642 | + bool shiftDown = event.ShiftDown(); | |
643 | + bool altDown = event.AltDown(); | |
644 | + int row = editRow; | |
645 | + int col = editColumn; | |
646 | + if (kc == WXK_RETURN) { | |
647 | + if (altDown) { | |
648 | + EndEditText(); | |
649 | + } else { | |
650 | + do { | |
651 | + if (shiftDown) { | |
652 | + if (row <= 0) | |
653 | + row = -1; | |
654 | + else | |
655 | + row--; | |
656 | + } else { | |
657 | + if (row >= nrows - 1) | |
658 | + row = -1; | |
659 | + else | |
660 | + row++; | |
661 | + } | |
662 | + } while (row >= 0 && !dataSource->IsEditable(this, row, col)); | |
663 | + if (row >= 0) { | |
664 | + StartEditText(row, col); | |
665 | + } else { | |
666 | + EndEditText(); | |
667 | + } | |
668 | + } | |
669 | + } else if (kc == WXK_NUMPAD_ENTER) { | |
670 | + EndEditText(); | |
671 | + } else if (kc == WXK_TAB) { | |
672 | + do { | |
673 | + if (shiftDown) { | |
674 | + col--; | |
675 | + if (col < 0) { | |
676 | + col = ncols - 1; | |
677 | + row--; | |
678 | + if (row < 0) | |
679 | + row = -1; | |
680 | + } | |
681 | + } else { | |
682 | + col++; | |
683 | + if (col >= ncols) { | |
684 | + col = 0; | |
685 | + row++; | |
686 | + if (row >= nrows) | |
687 | + row = -1; | |
688 | + } | |
689 | + } | |
690 | + } while (row >= 0 && !dataSource->IsEditable(this, row, col)); | |
691 | + if (row >= 0) | |
692 | + StartEditText(row, col); | |
693 | + else | |
694 | + EndEditText(); | |
695 | + } else | |
696 | + event.Skip(); | |
697 | +} | |
698 | + | |
699 | +void | |
700 | +MyListCtrl::OnPopUpMenuSelected(wxCommandEvent &event) | |
701 | +{ | |
702 | + if (dataSource != NULL) | |
703 | + dataSource->OnPopUpMenuSelected(this, lastPopUpRow, lastPopUpColumn, event.GetId() - 1); | |
704 | +} |
@@ -0,0 +1,179 @@ | ||
1 | +/* | |
2 | + * MyListCtrl.h | |
3 | + * | |
4 | + * Created by Toshi Nagata on 08/12/09. | |
5 | + * Copyright 2008-2009 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 __MyListCtrl_h__ | |
19 | +#define __MyListCtrl_h__ | |
20 | + | |
21 | +#include "wx/scrolwin.h" | |
22 | + | |
23 | +#include "wx/string.h" | |
24 | +#include "wx/textctrl.h" | |
25 | +#include "wx/dc.h" | |
26 | + | |
27 | +#include <vector> | |
28 | + | |
29 | +class MyListCtrl; | |
30 | +extern const wxEventType MyListCtrlEvent; | |
31 | +enum { | |
32 | + MyListCtrlEvent_tableSelectionChanged, | |
33 | + MyListCtrlEvent_enableTableSelectionNotification | |
34 | +}; | |
35 | + | |
36 | +enum MyListColumnFormat { | |
37 | + MyLIST_FORMAT_LEFT, | |
38 | + MyLIST_FORMAT_RIGHT, | |
39 | + MyLIST_FORMAT_CENTRE | |
40 | +}; | |
41 | + | |
42 | +/* Data source protocol */ | |
43 | +class MyListCtrlDataSource { | |
44 | +public: | |
45 | + virtual int GetNumberOfRows(MyListCtrl *ctrl) { return 0; } | |
46 | + virtual int GetNumberOfColumns(MyListCtrl *ctrl) { return 0; } | |
47 | + virtual int GetColumnWidth(MyListCtrl *ctrl, int index) { return 0; } | |
48 | + virtual int GetRowHeight(MyListCtrl *ctrl) { return 0; } | |
49 | + virtual int GetHeaderHeight(MyListCtrl *ctrl) { return 0; } | |
50 | + virtual wxString GetCellText(MyListCtrl *ctrl, int row, int col) { return _T(""); } | |
51 | + virtual bool GetCellAttr(MyListCtrl *ctrl, int row, int col, wxTextAttr &attr) { return false; } | |
52 | + virtual bool IsDragEnabled(MyListCtrl *ctrl, int row = -1) { return true; } | |
53 | + virtual bool OnSelectionChanged(MyListCtrl *ctrl, std::vector<int> &oldsel, std::vector<int> &newsel) { return true; } | |
54 | + virtual bool IsEditable(MyListCtrl *ctrl, int row = -1, int col = -1) { return true; } | |
55 | + virtual bool SetCellText(MyListCtrl *ctrl, int row, int col, const wxString &str) { return true; } | |
56 | + virtual bool DragSelectionToRow(MyListCtrl *ctrl, std::vector<int> &sel, int row) { return true; } | |
57 | + | |
58 | + // If a popup menu is attached to the cell, then returns a positive integer, and *menu_titles should | |
59 | + // contain a malloc()'ed array of char* pointers (that are also malloc()'ed or strdup()'ed) | |
60 | + virtual int HasPopUpMenu(MyListCtrl *ctrl, int row, int col, char ***menu_titles) { return 0; } | |
61 | + virtual void OnPopUpMenuSelected(MyListCtrl *ctrl, int row, int col, int selected_index) {} | |
62 | + | |
63 | + //virtual int GetItemCount(MyListCtrl *ctrl) { return 0; } | |
64 | + //virtual wxString GetItemText(MyListCtrl *ctrl, long row, long column) const { return _T(""); } | |
65 | + //virtual int SetItemText(MyListCtrl *ctrl, long row, long column, const wxString &value) { return 0; } | |
66 | + //virtual void DragSelectionToRow(MyListCtrl *ctrl, long row) {} | |
67 | + //virtual bool IsItemEditable(MyListCtrl *ctrl, long row, long column) { return false; } | |
68 | + //virtual bool IsDragAndDropEnabled(MyListCtrl *ctrl) { return false; } | |
69 | + //virtual void OnSelectionChanged(MyListCtrl *ctrl) {} | |
70 | + | |
71 | + // Return 1 if foreground color should be modified, 2 if background color should be modified, 3 if both | |
72 | + //virtual int SetItemColor(MyListCtrl *ctrl, long row, long col, float *fg, float *bg) { return 0; } | |
73 | +}; | |
74 | + | |
75 | +class MyListCtrl: public wxWindow { | |
76 | + | |
77 | +public: | |
78 | + MyListCtrlDataSource *dataSource; | |
79 | + wxTextCtrl *editText; | |
80 | + wxWindow *header; | |
81 | + wxScrolledWindow *scroll; | |
82 | + | |
83 | + int ncols, nrows; | |
84 | + std::vector<int> colWidths; | |
85 | + std::vector<int> colFormats; | |
86 | + wxArrayString colNames; | |
87 | + | |
88 | + int headerHeight; | |
89 | + int rowHeight; | |
90 | + int pageWidth, pageHeight; | |
91 | + std::vector<int> selection; | |
92 | + | |
93 | + int editRow, editColumn; | |
94 | + int dragTargetRow; | |
95 | + int mouseMode; | |
96 | + int mouseRow; | |
97 | + int lastMouseRow; | |
98 | + bool draggingRows; | |
99 | + std::vector<int> oldSelection; | |
100 | + | |
101 | + MyListCtrl(); | |
102 | + virtual ~MyListCtrl(); | |
103 | + | |
104 | + bool Create(wxWindow* parent, wxWindowID wid, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); | |
105 | + | |
106 | + void SetDataSource(MyListCtrlDataSource *source); | |
107 | + | |
108 | + void RefreshTable(); | |
109 | + | |
110 | + void PrepareSelectionChangeNotification(); | |
111 | + bool IsRowSelected(int row); | |
112 | + bool SelectRow(int row); | |
113 | + bool UnselectRow(int row); | |
114 | + void UnselectAllRows(); | |
115 | + | |
116 | + void DragRows(int x, int y); | |
117 | + | |
118 | +// virtual wxString OnGetItemText(long item, long column) const; | |
119 | + | |
120 | +// void StartEditing(long item, long column); | |
121 | +// void EndEditing(long item, long column); | |
122 | + | |
123 | +// void GetScrollPixelsPerUnit(int *xunit, int *yunit); | |
124 | +// bool GetItemRectForRowAndColumn(wxRect &rect, int row, int column); | |
125 | + bool FindItemAtPosition(const wxPoint &pos, int *col, int *row); | |
126 | + | |
127 | +// void SetItemTextForColumn(long item, long column, const wxString &text); | |
128 | + | |
129 | + void StartEditText(int col, int row); | |
130 | + void EndEditTextAndRestart(bool setValueFlag, int newCol, int newRow); | |
131 | + void EndEditText(bool setValueFlag = true); | |
132 | + void FinalizeEdit(); | |
133 | + | |
134 | +// void OnKeyDownOnEditText(wxKeyEvent &event); | |
135 | +// void OnKillFocusOnEditText(wxFocusEvent &event); | |
136 | +// void OnIdle(wxIdleEvent &event); | |
137 | + | |
138 | +// void OnPaintCallback(wxDC *dc); | |
139 | + | |
140 | +// bool DeleteColumn(int col); | |
141 | +// bool InsertColumn(int col, const wxString &heading, int width = -1, int format = MyLIST_FORMAT_LEFT); | |
142 | +// int GetNumberOfColumns(); | |
143 | + | |
144 | + void OnPaintHeader(wxPaintEvent &event); | |
145 | + void OnPaint(wxPaintEvent &event); | |
146 | + void OnLeftDown(wxMouseEvent &event); | |
147 | + void OnLeftUp(wxMouseEvent &event); | |
148 | + void OnLeftDClick(wxMouseEvent &event); | |
149 | + void OnMotion(wxMouseEvent &event); | |
150 | + void OnScrollWin(wxScrollWinEvent &event); | |
151 | + void OnCharInText(wxKeyEvent &event); | |
152 | + | |
153 | +// void OnItemSelectionChanged(wxListEvent &event); | |
154 | +// void OnTableSelectionChanged(wxCommandEvent &event); | |
155 | + void EnableSelectionChangeNotification(bool flag) { selectionChangeNotificationEnabled = flag; } | |
156 | +// void OnEnableTableSelectionNotification(wxCommandEvent &event); | |
157 | + | |
158 | +// void OnBeginLabelEdit(wxListEvent &event); | |
159 | +// void OnEndLabelEdit(wxListEvent &event); | |
160 | +// void OnItemActivated(wxListEvent &event); | |
161 | +// void OnBeginDrag(wxListEvent &event); | |
162 | + | |
163 | +// void OnChar(wxKeyEvent &event); | |
164 | +// void OnMouseDown(wxMouseEvent &event); | |
165 | + | |
166 | + void OnPopUpMenuSelected(wxCommandEvent &event); | |
167 | + | |
168 | + void PostSelectionChangeNotification(); | |
169 | + | |
170 | + bool selectionChangeNotificationRequired; | |
171 | + bool selectionChangeNotificationEnabled; | |
172 | + int lastPopUpColumn, lastPopUpRow; | |
173 | + | |
174 | +private: | |
175 | + DECLARE_DYNAMIC_CLASS(MyListCtrl) | |
176 | + DECLARE_EVENT_TABLE() | |
177 | +}; | |
178 | + | |
179 | +#endif /* __MyListCtrl_h__ */ |