[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [5230] Prepare to embed InputSequenceEntry in wxDVC (VS)
From: |
Greg Chicares |
Subject: |
[lmi-commits] [5230] Prepare to embed InputSequenceEntry in wxDVC (VS) |
Date: |
Sun, 07 Aug 2011 12:02:42 +0000 |
Revision: 5230
http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=5230
Author: chicares
Date: 2011-08-07 12:02:42 +0000 (Sun, 07 Aug 2011)
Log Message:
-----------
Prepare to embed InputSequenceEntry in wxDVC (VS)
Modified Paths:
--------------
lmi/trunk/input_sequence_entry.cpp
lmi/trunk/input_sequence_entry.hpp
Modified: lmi/trunk/input_sequence_entry.cpp
===================================================================
--- lmi/trunk/input_sequence_entry.cpp 2011-08-05 00:28:32 UTC (rev 5229)
+++ lmi/trunk/input_sequence_entry.cpp 2011-08-07 12:02:42 UTC (rev 5230)
@@ -48,7 +48,7 @@
#include <wx/textctrl.h>
#include <wx/valtext.h>
-#include <algorithm> // std::copy(), std::find()
+#include <algorithm> // std::copy()
#include <iterator> // std::back_inserter
#include <map>
#include <vector>
@@ -191,9 +191,16 @@
default_keyword_ = default_keyword;
}
+ void associate_text_ctrl(wxTextCtrl* t)
+ {
+ associated_text_ctrl_ = t;
+ }
+
void sequence(InputSequence const& s);
std::string sequence_string();
+ virtual void EndModal(int retCode);
+
private:
void add_row();
void insert_row(int row);
@@ -289,6 +296,8 @@
// scalar absolute values for end durations; this is used to recompute
// duration number for certain duration modes
std::vector<int> duration_scalars_;
+
+ wxTextCtrl* associated_text_ctrl_;
};
InputSequenceEditor::InputSequenceEditor(wxWindow* parent, wxString const&
title, Input const& input)
@@ -1129,9 +1138,95 @@
update_diagnostics();
}
+
+void InputSequenceEditor::EndModal(int retCode)
+{
+ // We need to set the value as soon as possible -- when used in
wxDataViewCtrl, the value
+ // is read from editor control as soon as focus changes, which is before
ShowModal() returns.
+ if(associated_text_ctrl_ && retCode == wxID_OK)
+ associated_text_ctrl_->SetValue(sequence_string());
+
+ wxDialog::EndModal(retCode);
+}
+
+class InputSequenceTextCtrl
+ :public wxTextCtrl
+{
+ public:
+ InputSequenceTextCtrl(wxWindow* parent, wxWindowID id);
+
+ private:
+ void UponKillFocus(wxFocusEvent& event);
+ void UponChar(wxKeyEvent& event);
+};
+
+InputSequenceTextCtrl::InputSequenceTextCtrl(wxWindow* parent, wxWindowID id)
+ :wxTextCtrl(parent, id)
+{
+ ::Connect
+ (this
+ ,wxEVT_KILL_FOCUS
+ ,&InputSequenceTextCtrl::UponKillFocus
+ );
+ ::Connect
+ (this
+ ,wxEVT_CHAR
+ ,&InputSequenceTextCtrl::UponChar
+ );
+}
+
+void InputSequenceTextCtrl::UponKillFocus(wxFocusEvent& event)
+{
+ if(0 == event.GetWindow() || event.GetWindow()->GetParent() != GetParent())
+ GetParent()->ProcessWindowEvent(event);
+ event.Skip();
+}
+
+void InputSequenceTextCtrl::UponChar(wxKeyEvent& event)
+{
+ if(!GetParent()->ProcessWindowEvent(event))
+ event.Skip();
+}
+
+class InputSequenceButton
+ :public wxButton
+{
+ public:
+ InputSequenceButton(wxWindow* parent, wxWindowID id);
+
+ private:
+ void UponKillFocus(wxFocusEvent& event);
+};
+
+InputSequenceButton::InputSequenceButton(wxWindow* parent, wxWindowID id)
+ :wxButton(parent, id, "...", wxDefaultPosition, wxDefaultSize,
wxBU_EXACTFIT)
+{
+ ::Connect
+ (this
+ ,wxEVT_KILL_FOCUS
+ ,&InputSequenceButton::UponKillFocus
+ );
+
+ SetToolTip("Open sequence editor");
+}
+
+void InputSequenceButton::UponKillFocus(wxFocusEvent& event)
+{
+ // Don't notify the parent (and thus wxDataViewCtrl) of focus change if
its within this
+ // InputSequenceEntry composite control or a InputSequenceEditor window
opened from it.
+ if(0 == event.GetWindow() ||
+ (event.GetWindow()->GetParent() != GetParent() &&
+ wxGetTopLevelParent(event.GetWindow())->GetParent() != this))
+ {
+ GetParent()->ProcessWindowEvent(event);
+ }
+ event.Skip();
+}
+
} // Unnamed namespace.
InputSequenceEntry::InputSequenceEntry()
+ :input_(0)
{
}
@@ -1140,6 +1235,7 @@
,wxWindowID id
,wxString const& name
)
+ :input_(0)
{
Create(parent, id, name);
}
@@ -1161,16 +1257,8 @@
wxSizer* sizer = new(wx) wxBoxSizer(wxHORIZONTAL);
- text_ = new(wx) wxTextCtrl(this, wxID_ANY);
- button_ = new(wx) wxButton
- (this
- ,wxID_ANY
- ,"..."
- ,wxDefaultPosition
- ,wxDefaultSize
- ,wxBU_EXACTFIT
- );
- button_->SetToolTip("Open sequence editor");
+ text_ = new(wx) InputSequenceTextCtrl(this, wxID_ANY);
+ button_ = new(wx) InputSequenceButton(this, wxID_ANY);
sizer->Add(text_, wxSizerFlags(1).Expand());
sizer->Add(button_, wxSizerFlags().Expand().Border(wxLEFT, 1));
@@ -1187,21 +1275,64 @@
return true;
}
+void InputSequenceEntry::input(Input const& input)
+{
+ input_ = &input;
+}
+
+Input const& InputSequenceEntry::input() const
+{
+ if(input_)
+ {
+ return *input_;
+ }
+ else
+ {
+ // MvcController's design uses editor controls that only have local
+ // knowledge of the value they directly edit. This isn't an
+ // unreasonable assumption and e.g. wxDataViewCtrl does the same.
+ // Unfortunately, it doesn't fit InputSequenceEditor, which needs
+ // additional information about the Input instance the sequence is used
+ // in. Hence this hack -- it gets the Input from the parent
+ // MvcController if used inside one.
+ MvcController const* tlw = dynamic_cast<MvcController
const*>(wxGetTopLevelParent(const_cast<InputSequenceEntry*>(this)));
+ LMI_ASSERT(tlw);
+ Input const* input = dynamic_cast<Input const*>(&tlw->Model());
+ LMI_ASSERT(input);
+
+ return *input;
+ }
+}
+
+void InputSequenceEntry::field_name(std::string const& name)
+{
+ field_name_ = name;
+}
+
+std::string InputSequenceEntry::field_name() const
+{
+ if(!field_name_.empty())
+ {
+ return field_name_;
+ }
+ else
+ {
+ // see the explanation in input()
+ return std::string(GetName().c_str());
+ }
+}
+
void InputSequenceEntry::UponOpenEditor(wxCommandEvent&)
{
- MvcController const* tlw = dynamic_cast<MvcController
const*>(wxGetTopLevelParent(this));
- LMI_ASSERT(tlw);
- Input const* input = dynamic_cast<Input const*>(&tlw->Model());
- LMI_ASSERT(input);
+ Input const& in = input();
// Center the window on the [...] button for best locality -- it will be
// close to user's point of attention and the mouse cursor.
- InputSequenceEditor editor(button_, title_, *input);
+ InputSequenceEditor editor(button_, title_, in);
editor.CentreOnParent();
std::string sequence_string = std::string(text_->GetValue());
- std::string const name(GetName().c_str());
- datum_sequence const& ds =
*member_cast<datum_sequence>(input->operator[](name));
+ datum_sequence const& ds = *member_cast<datum_sequence>(in[field_name()]);
std::map<std::string,std::string> const kwmap = ds.allowed_keywords();
std::vector<std::string> const keywords =
@@ -1216,11 +1347,11 @@
InputSequence sequence
(sequence_string
- ,input->years_to_maturity()
- ,input->issue_age ()
- ,input->retirement_age ()
- ,input->inforce_year ()
- ,input->effective_year ()
+ ,in.years_to_maturity()
+ ,in.issue_age ()
+ ,in.retirement_age ()
+ ,in.inforce_year ()
+ ,in.effective_year ()
,0
,keywords
);
@@ -1238,10 +1369,8 @@
editor.sequence(sequence);
- if(wxID_OK == editor.ShowModal())
- {
- text_->SetValue(editor.sequence_string());
- }
+ editor.associate_text_ctrl(text_);
+ editor.ShowModal();
}
IMPLEMENT_DYNAMIC_CLASS(InputSequenceEntryXmlHandler, wxXmlResourceHandler)
Modified: lmi/trunk/input_sequence_entry.hpp
===================================================================
--- lmi/trunk/input_sequence_entry.hpp 2011-08-05 00:28:32 UTC (rev 5229)
+++ lmi/trunk/input_sequence_entry.hpp 2011-08-07 12:02:42 UTC (rev 5230)
@@ -31,6 +31,9 @@
#include <wx/panel.h>
#include <wx/xrc/xmlres.h>
+#include <string>
+
+class Input;
class WXDLLIMPEXP_FWD_CORE wxButton;
class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
@@ -42,6 +45,12 @@
InputSequenceEntry(wxWindow* parent, wxWindowID id, wxString const& name);
bool Create(wxWindow* parent, wxWindowID id, wxString const& name);
+ void input(Input const& input);
+ Input const& input() const;
+
+ void field_name(std::string const& name);
+ std::string field_name() const;
+
wxTextCtrl& text_ctrl() {return *text_;}
void set_popup_title(wxString const& title) {title_ = title;}
@@ -49,6 +58,9 @@
private:
void UponOpenEditor(wxCommandEvent&);
+ Input const* input_;
+ std::string field_name_;
+
wxTextCtrl* text_;
wxButton* button_;
wxString title_;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi-commits] [5230] Prepare to embed InputSequenceEntry in wxDVC (VS),
Greg Chicares <=