Added fixes for layouts+ComboBoxevents

This commit is contained in:
Peter Schojer
2008-05-27 12:58:28 +00:00
parent 0362659ac9
commit e07a2126e9
22 changed files with 258 additions and 27 deletions

View File

@@ -42,10 +42,15 @@
#include "Poco/WebWidgets/ExtJS/ExtJS.h"
#include "Poco/WebWidgets/Renderer.h"
#include "Poco/Net/HTTPServerResponse.h"
namespace Poco {
namespace WebWidgets {
class ComboBoxCell;
class ComboBox;
namespace ExtJS {
@@ -53,6 +58,8 @@ class ExtJS_API ComboBoxCellRenderer: public Poco::WebWidgets::Renderer
/// ComboBoxCellRenderer renders a ComboBox
{
public:
static const std::string EV_SELECTED;
ComboBoxCellRenderer();
/// Creates the ComboBoxCellRenderer.
@@ -64,6 +71,15 @@ public:
void renderBody(const Renderable* pRenderable, const RenderContext& context, std::ostream& ostr);
/// Emits code for the page body to the given output stream.
static void addSelectedServerCallback(ComboBox* pCombo, const std::string& onSuccess, const std::string& onFailure);
/// Adds a server callback for the selected event. The method signature for select is
/// select : ( Ext.form.ComboBox combo, Ext.data.Record record, Number index )
private:
static void onLoad(void* pSender, Poco::Net::HTTPServerResponse* &pResponse);
static void serialize(const ComboBoxCell* pCell, std::ostream& out);
};

View File

@@ -68,7 +68,7 @@ public:
void renderBody(const Renderable* pRenderable, const RenderContext& context, std::ostream& ostr);
/// Emits code for the page body to the given output stream.
static void writeCellProperties(const TextFieldCell* pCell, std::ostream& ostr, bool writeValue=true);
static void writeCellProperties(const TextFieldCell* pCell, std::ostream& ostr, bool writeValue=true, bool writeListeners = true);
/// Writes cell properties
};

View File

@@ -85,7 +85,21 @@ void ButtonCellRenderer::renderProperties(const ButtonCell* pButtonCell, const s
//ostr << "handler: function(){Ext.getCmp('" << pForm->id() << "').getForm().submit({url:'" << pForm->getURI().toString() << "',waitMsg:'Loading'});},";
ostr << "handler: function(){Ext.getCmp('" << pForm->id() << "').getForm().submit();},";
}
Utility::writeCellProperties(pButtonCell, ostr, writeId);
if (writeId)
Utility::writeRenderableProperties(pButtonCell, ostr);
if (!pButtonCell->isEnabled())
ostr << ",disabled:true";
View* pOwner = pButtonCell->getOwner();
if (pOwner)
{
if (!pOwner->getName().empty())
ostr << ",name:'" << pOwner->getName() << "'";
if (pOwner->getWidth() != 0)
ostr << ",minWidth:" << pOwner->getWidth();
if (!pOwner->isVisible())
ostr << ",hidden:true";
}
std::string toolTip(pButtonCell->getToolTip());
if (!toolTip.empty())
ostr << ",tooltip:'" << Utility::safe(toolTip) << "'";

View File

@@ -39,6 +39,12 @@
#include "Poco/WebWidgets/ExtJS/FormRenderer.h"
#include "Poco/WebWidgets/ExtJS/Utility.h"
#include "Poco/WebWidgets/ComboBoxCell.h"
#include "Poco/WebWidgets/ComboBox.h"
#include "Poco/WebWidgets/WebApplication.h"
#include "Poco/WebWidgets/RequestHandler.h"
#include "Poco/NumberFormatter.h"
#include "Poco/Delegate.h"
#include <map>
namespace Poco {
@@ -46,6 +52,9 @@ namespace WebWidgets {
namespace ExtJS {
const std::string ComboBoxCellRenderer::EV_SELECTED("select");
ComboBoxCellRenderer::ComboBoxCellRenderer()
{
}
@@ -56,20 +65,80 @@ ComboBoxCellRenderer::~ComboBoxCellRenderer()
}
void ComboBoxCellRenderer::addSelectedServerCallback(ComboBox* pCombo, const std::string& onSuccess, const std::string& onFailure)
{
//select : ( Ext.form.ComboBox combo, Ext.data.Record record, Number index )
static const std::string signature("function(combo,rec, idx)");
std::map<std::string, std::string> addParams;
addParams.insert(std::make_pair(ComboBoxCell::FIELD_VAL, "+rec.get('d')"));
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, ComboBoxCell::EV_SELECTED));
Utility::addServerCallback(pCombo->selected, signature, addParams, pCombo->id(), onSuccess, onFailure);
}
void ComboBoxCellRenderer::renderHead(const Renderable* pRenderable, const RenderContext& context, std::ostream& ostr)
{
poco_assert_dbg (pRenderable != 0);
poco_assert_dbg (pRenderable->type() == typeid(Poco::WebWidgets::ComboBoxCell));
const ComboBoxCell* pCell = static_cast<const Poco::WebWidgets::ComboBoxCell*>(pRenderable);
ComboBoxCell* pCell = const_cast<ComboBoxCell*>(static_cast<const Poco::WebWidgets::ComboBoxCell*>(pRenderable));
ComboBox* pOwner = dynamic_cast<ComboBox*>(pCell->getOwner());
poco_check_ptr (pOwner);
ostr << "new Ext.form.ComboBox({";
TextFieldCellRenderer::writeCellProperties(pCell, ostr);
ostr << ", store: new Ext.data.SimpleStore({fields:['d'], data:[";
TextFieldCellRenderer::writeCellProperties(pCell, ostr, true, false);
ostr << ",store:new Ext.data.SimpleStore({autoLoad:true,fields:['d'],";
ostr << "proxy:new Ext.data.HttpProxy({url:";
std::map<std::string, std::string> addParams;
addParams.insert(std::make_pair(RequestHandler::KEY_EVID,ComboBoxCell::EV_LOAD));
std::string url(Utility::createURI(addParams, pOwner->id()));
ostr << url << "}),";
ostr << "reader:new Ext.data.ArrayReader()})";
ostr << ",displayField:'d',typeAhead:true,triggerAction:'all'";
std::string tooltip (pCell->getToolTip());
if (!pOwner->selected.jsDelegates().empty())
{
ostr << ",listeners:{";
Utility::writeJSEvent(ostr, EV_SELECTED, pOwner->selected.jsDelegates());
if (!tooltip.empty())
ostr << ",render:function(c){Ext.QuickTips.register({target:c.getEl(),text:'" << Utility::safe(tooltip) << "'});}";
ostr << "}";
}
else if (!tooltip.empty())
{
ostr << ",listeners:{";
ostr << "render:function(c){Ext.QuickTips.register({target:c.getEl(),text:'" << Utility::safe(tooltip) << "'});}}";
}
ostr << "})";
pCell->beforeLoad += Poco::delegate(&ComboBoxCellRenderer::onLoad);
WebApplication::instance().registerAjaxProcessor(Poco::NumberFormatter::format(pOwner->id()), pCell);
}
void ComboBoxCellRenderer::onLoad(void* pSender, Poco::Net::HTTPServerResponse* &pResponse)
{
poco_check_ptr (pSender);
poco_check_ptr (pResponse);
ComboBoxCell* pCell = reinterpret_cast<ComboBoxCell*>(pSender);
poco_check_ptr (pCell);
pResponse->setChunkedTransferEncoding(true);
pResponse->setContentType("text/javascript");
std::ostream& out = pResponse->send();
serialize (pCell, out);
}
void ComboBoxCellRenderer::serialize(const ComboBoxCell* pCell, std::ostream& ostr)
{
//now serialize data
std::vector<Any>::const_iterator it = pCell->begin();
std::vector<Any>::const_iterator itEnd = pCell->end();
Formatter::Ptr ptrFormatter = pCell->getFormatter();
ostr << "[";
for (; it != itEnd; ++it)
{
if (it != pCell->begin())
@@ -79,9 +148,7 @@ void ComboBoxCellRenderer::renderHead(const Renderable* pRenderable, const Rende
else
ostr << "['" << RefAnyCast<std::string>(*it) << "']";
}
ostr << "]})";
ostr << ",displayField:'d',typeAhead:true,mode:'local',triggerAction:'all'";
ostr << "})";
ostr << "]";
}

View File

@@ -62,7 +62,8 @@ void HorizontalLayoutRenderer::renderHead(const Renderable* pRenderable, const R
const HorizontalLayout* pLayout = static_cast<const Poco::WebWidgets::HorizontalLayout*>(pRenderable);
std::ostringstream layoutConfig;
layoutConfig << "{columns:" << pLayout->size() << "}";
std::string layout("column");
static std::string layout("column");
LayoutRenderer::renderLayoutHead(pLayout, context, ostr, layout, layoutConfig.str());
}

View File

@@ -61,7 +61,11 @@ void LabelRenderer::renderHead(const Renderable* pRenderable, const RenderContex
poco_assert_dbg (pRenderable->type() == typeid(Poco::WebWidgets::Label));
const Label* pLabel = static_cast<const Poco::WebWidgets::Label*>(pRenderable);
ostr << "{xtype:'label', text:'" << Utility::safe(pLabel->getText()) << "'}";
//ostr << "{xtype:'label', text:'" << Utility::safe(pLabel->getText()) << "'}";
ostr << "new Ext.form.Label({text:'" << Utility::safe(pLabel->getText()) << "',cls:'lbl'";
if (pLabel->getWidth() > 0)
ostr << ",width:" << pLabel->getWidth();
ostr << "})";
}

View File

@@ -119,7 +119,12 @@ void LayoutRenderer::visitChildren(const Layout* pLayout, const RenderContext& c
if (it != pLayout->begin())
ostr << ",";
if (*it)
{
//horizontallayout works only when children are panels
ostr << "{xtype:'panel',items:";
(*it)->renderHead(context, ostr);
ostr << "}";
}
else
ostr << "{}";

View File

@@ -59,7 +59,11 @@ PageRenderer::~PageRenderer()
void PageRenderer::renderHead(const Renderable* pRenderable, const RenderContext& context, std::ostream& ostr)
{
static const std::string STRO_HTML("<html>");
static const std::string STRO_HTML("<html>");
static const std::string STRO_HEAD ("<head>");
static const std::string STRO_TITLE ("<title>");
static const std::string STRC_HEAD ("</head>");
static const std::string STRC_TITLE ("</title>");
poco_assert_dbg (pRenderable != 0);
poco_assert_dbg (pRenderable->type() == typeid(Poco::WebWidgets::Page));
const Page* pPage = static_cast<const Poco::WebWidgets::Page*>(pRenderable);
@@ -70,11 +74,13 @@ void PageRenderer::renderHead(const Renderable* pRenderable, const RenderContext
ostr << pPage->getName();
ostr << STRC_TITLE;
//include javascript files: TODO: use ResourceManager
ostr << STRO_HTML << STRO_HEAD << STRO_TITLE;
ostr << "<script type=\"text/javascript\" src=\"ext-base.js\"></script>";
ostr << "<script type=\"text/javascript\" src=\"ext-all.js\"></script>";
ostr << "<script type=\"text/javascript\" src=\"DDView.js\"></script>";
ostr << "<script type=\"text/javascript\" src=\"MultiSelect.js\"></script>";
ostr << "<link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/ext-all.css\">";
ostr << "<link rel=\"stylesheet\" type=\"text/css\" href=\"MultiSelect.css\">";
ostr << "<style type=\"text/css\">.lbl {font:normal 12px tahoma, verdana, helvetica}</style>";
if (!pPage->empty())
{
//start inline javascript block

View File

@@ -244,13 +244,13 @@ void TableRenderer::renderStore(const Table* pTable, std::ostream& ostr)
}
ostr << ",{name:'" << i << "'}";
ostr << "],"; // close fields
ostr << "proxy: new Ext.data.HttpProxy({url:";
ostr << "proxy:new Ext.data.HttpProxy({url:";
std::map<std::string, std::string> addParams;
addParams.insert(std::make_pair(RequestHandler::KEY_EVID,Table::EV_LOADDATA));
std::string url(Utility::createURI(addParams, pTable->id()));
ostr << url << "}),";
ostr << "reader: new Ext.data.ArrayReader()";
ostr << "reader:new Ext.data.ArrayReader()";
//Write data
/*ostr << "data:";
renderDataModel(pTable, ostr);*/

View File

@@ -79,7 +79,7 @@ void TextFieldCellRenderer::renderBody(const Renderable* pRenderable, const Rend
}
void TextFieldCellRenderer::writeCellProperties(const TextFieldCell* pCell, std::ostream& ostr, bool writeValue)
void TextFieldCellRenderer::writeCellProperties(const TextFieldCell* pCell, std::ostream& ostr, bool writeValue, bool writeListeners)
{
Utility::writeCellProperties(pCell, ostr);
@@ -97,10 +97,13 @@ void TextFieldCellRenderer::writeCellProperties(const TextFieldCell* pCell, std:
if (pCell->getMaxLength() > 0)
ostr << ",maxLength:" << pCell->getMaxLength();
//tooltip is not supported by textField, add listeners
std::string tooltip (pCell->getToolTip());
if (!tooltip.empty())
ostr << ",listeners:{render:function(c){Ext.QuickTips.register({target:c.getEl(),text:'" << Utility::safe(tooltip) << "'});}}";
if (writeListeners)
{
//tooltip is not supported by textField, add listeners
std::string tooltip (pCell->getToolTip());
if (!tooltip.empty())
ostr << ",listeners:{render:function(c){Ext.QuickTips.register({target:c.getEl(),text:'" << Utility::safe(tooltip) << "'});}}";
}
}

View File

@@ -66,6 +66,7 @@ void ToggleButtonCellRenderer::renderProperties(const ToggleButtonCell* pToggleB
if (!pToggleButtonCell->getLabel().empty())
ostr << "boxLabel:'" << Utility::safe(pToggleButtonCell->getLabel()) << "',";
ostr << "checked:" << (pToggleButtonCell->isChecked()?"true":"false") << ",";
Utility::writeCellProperties(pToggleButtonCell, ostr);
//tooltip is not supported by togglebutton
std::string tooltip (pToggleButtonCell->getToolTip());

View File

@@ -142,6 +142,7 @@ const std::string& Utility::getTmpID()
void Utility::writeRenderableProperties(const Renderable* pRend, std::ostream& ostr)
{
poco_assert_dbg (pRend != 0);
ostr << "id:'" << pRend->id() << "'";
}
@@ -156,11 +157,12 @@ void Utility::writeRenderableProperties(const std::string& id, std::ostream& ost
void Utility::writeCellProperties(const Cell* pCell, std::ostream& ostr, bool writeId)
{
if (writeId)
writeRenderableProperties(pCell, ostr);
writeRenderableProperties(pCell->getOwner(), ostr);
//don't support label for cell, keep this separate
ostr << ",hideLabel:true";
if (!pCell->isEnabled())
ostr << ",disabled:true";
ostr << ",disabled:true";
View* pOwner = pCell->getOwner();
if (pOwner)
{
@@ -170,6 +172,8 @@ void Utility::writeCellProperties(const Cell* pCell, std::ostream& ostr, bool wr
ostr << ",width:" << pOwner->getWidth();
if (pOwner->getHeight() != 0)
ostr << ",height:" << pOwner->getHeight();
if (!pOwner->isVisible())
ostr << ",hidden:true";
}
}

View File

@@ -40,7 +40,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\include;..\..\..\Foundation\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\WebWidgets\include"
AdditionalIncludeDirectories="..\include;..\..\..\Foundation\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\WebWidgets\include;..\..\..\Net\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -129,7 +129,7 @@
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="..\include;..\..\..\Foundation\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\WebWidgets\include"
AdditionalIncludeDirectories="..\include;..\..\..\Foundation\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\WebWidgets\include;..\..\..\Net\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
StringPooling="true"
RuntimeLibrary="2"

View File

@@ -42,6 +42,8 @@
#include "Poco/WebWidgets/TextField.h"
#include "Poco/WebWidgets/ComboBoxCell.h"
#include "Poco/WebWidgets/Event.h"
#include "Poco/WebWidgets/JavaScriptEvent.h"
#include <vector>
@@ -58,6 +60,10 @@ class WebWidgets_API ComboBox: public TextField
public:
typedef Poco::AutoPtr<ComboBox> Ptr;
typedef Event<ComboBox> ComboBoxEvent;
JavaScriptEvent<ComboBoxEvent> selected; /// thrown whenever a new element is selected
ComboBox();
/// Creates the ComboBox.
@@ -79,6 +85,17 @@ public:
void setElements(const std::vector<Any>& elems);
/// Initializes the combo box with the provided elements
template <typename T>
void setElements(const std::vector<T>& elems)
/// Initializes the combo box with the provided elements
{
std::vector<Any> result;
typename std::vector<T>::const_iterator it = elems.begin();
for (; it != elems.end(); ++it)
result.push_back(*it);
setElements(result);
}
const std::vector<Any>& getElements() const;
/// Returns all elements
@@ -106,6 +123,9 @@ protected:
~ComboBox();
/// Destroys the ComboBox.
void fireSelected(void* pSender);
/// Fires the selected event.
};

View File

@@ -41,6 +41,9 @@
#include "Poco/WebWidgets/TextFieldCell.h"
#include "Poco/WebWidgets/Delegate.h"
#include "Poco/FIFOEvent.h"
#include "Poco/Net/HTTPServerResponse.h"
#include <vector>
@@ -54,6 +57,13 @@ class WebWidgets_API ComboBoxCell: public TextFieldCell
public:
typedef Poco::AutoPtr<ComboBoxCell> Ptr;
static const std::string EV_SELECTED;
static const std::string EV_LOAD;
static const std::string FIELD_VAL;
Delegate selected;
FIFOEvent<Poco::Net::HTTPServerResponse*> beforeLoad; /// thrown whenever a load is requested
ComboBoxCell(View* pOwner);
/// Creates the ComboBoxCell.
@@ -90,12 +100,22 @@ public:
const Any& getSelected() const;
/// Returns the selected element, excpetion if none was selected
void handleForm(const std::string& field, const std::string& value);
void handleRequest(const Poco::Net::HTTPServerRequest& request);
/// Handles a complete HTTP request submitted by the client.
void handleRequestAndResponse(const Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
/// Handles a complete HTTP request submitted by the client. Also takes care of handling the response,
/// e.g. if one wants to send back data.
protected:
~ComboBoxCell();
/// Destroys the ComboBoxCell.
private:
std::vector<Any> _elements;
std::string _ev;
};
@@ -152,6 +172,7 @@ inline void ComboBoxCell::setSelected(const Any& elem)
/// Selects the element.
{
setValue(elem);
selected(this);
}

View File

@@ -125,7 +125,7 @@ public:
/// Handles a complete HTTP request submitted by the client.
void handleRequestAndResponse(const Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
/// Handles a complete HTTP request submitted by the client. Also takes care of handing the response,
/// Handles a complete HTTP request submitted by the client. Also takes care of handling the response,
/// e.g. if one wants to send back data.
private:

View File

@@ -58,6 +58,9 @@ public:
Poco::BasicEvent<TextFieldEvent> textChanged;
TextField(const std::string& name, const std::string& text);
/// Creates a TextField with the given name and content.
TextField(const std::string& name);
/// Creates a TextField with the given name.

View File

@@ -115,7 +115,7 @@ void Button::init()
void Button::fireButtonClicked(void* pSender)
{
ButtonEvent clickedEvent(Button::Ptr(this, true));
ButtonEvent clickedEvent(this);
buttonClicked(this, clickedEvent);
}

View File

@@ -42,28 +42,35 @@ namespace Poco {
namespace WebWidgets {
ComboBox::ComboBox(const std::string& name, const std::type_info& type):
TextField(name, type, new ComboBoxCell(this))
{
ComboBoxCell::Ptr pCell = cell<ComboBoxCell>();
pCell->selected = delegate(*this, &ComboBox::fireSelected);
}
ComboBox::ComboBox(const std::type_info& type):
TextField(type, new ComboBoxCell(this))
{
ComboBoxCell::Ptr pCell = cell<ComboBoxCell>();
pCell->selected = delegate(*this, &ComboBox::fireSelected);
}
ComboBox::ComboBox(const std::string& name):
TextField(name, typeid(ComboBox), new ComboBoxCell(this))
{
ComboBoxCell::Ptr pCell = cell<ComboBoxCell>();
pCell->selected = delegate(*this, &ComboBox::fireSelected);
}
ComboBox::ComboBox():
TextField(typeid(ComboBox), new ComboBoxCell(this))
{
ComboBoxCell::Ptr pCell = cell<ComboBoxCell>();
pCell->selected = delegate(*this, &ComboBox::fireSelected);
}
@@ -72,4 +79,11 @@ ComboBox::~ComboBox()
}
void ComboBox::fireSelected(void* pSender)
{
ComboBoxEvent sel(this);
selected(this, sel);
}
} } // namespace Poco::WebWidgets

View File

@@ -35,12 +35,18 @@
#include "Poco/WebWidgets/ComboBoxCell.h"
#include "Poco/WebWidgets/RequestHandler.h"
namespace Poco {
namespace WebWidgets {
const std::string ComboBoxCell::FIELD_VAL("val");
const std::string ComboBoxCell::EV_LOAD("load");
const std::string ComboBoxCell::EV_SELECTED("sel");
ComboBoxCell::ComboBoxCell(View* pOwner):
TextFieldCell(pOwner, typeid(ComboBoxCell))
{
@@ -69,4 +75,42 @@ void ComboBoxCell::erase(const Any& elem)
}
void ComboBoxCell::handleForm(const std::string& field, const std::string& value)
{
if (field == FIELD_VAL)
{
Formatter::Ptr pForm(getFormatter());
if (pForm)
{
setSelected(pForm->parse(value));
}
}
else if (field == RequestHandler::KEY_EVID)
_ev = value;
}
void ComboBoxCell::handleRequest(const Poco::Net::HTTPServerRequest& request)
{
//ev selected already handled in handleForm
}
void ComboBoxCell::handleRequestAndResponse(const Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)
{
// RequestHandler has already called all the handeForm stuff
if (_ev == EV_LOAD)
{
Poco::Net::HTTPServerResponse* pResponse = &response;
beforeLoad.notify(this, pResponse);
}
else
{
handleRequest(request);
response.send();
}
}
} } // namespace Poco::WebWidgets

View File

@@ -190,7 +190,6 @@ void Table::handleRequestAndResponse(const Poco::Net::HTTPServerRequest& request
}
void Table::handleValueChanged()
{
if (_col < 0 || _row < 0 || _col >= getColumnCount())

View File

@@ -70,6 +70,15 @@ TextField::TextField(const std::type_info& type):
}
TextField::TextField(const std::string& name, const std::string& txt):
Control(name, typeid(TextField))
{
init();
setString(txt);
}
TextField::TextField(const std::string& name):
Control(name, typeid(TextField))
{