00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "SeaBee/SubGUI.H"
00039 #include "Component/ModelOptionDef.H"
00040 #include "Component/ModelParam.H"
00041 #include "Image/CutPaste.H"
00042 #include "GUI/DebugWin.H"
00043 #include "Media/FrameSeries.H"
00044 #include "Transport/FrameInfo.H"
00045
00046 #include "Util/JobWithSemaphore.H"
00047 #include "Util/StringUtil.H"
00048 #include "Util/WorkThreadServer.H"
00049 #include "Util/sformat.H"
00050 #include "rutz/compat_snprintf.h"
00051
00052 #include <ctype.h>
00053 #include <deque>
00054 #include <iterator>
00055 #include <stdlib.h>
00056 #include <string.h>
00057 #include <sys/resource.h>
00058 #include <time.h>
00059 #include <vector>
00060
00061
00062 namespace
00063 {
00064 class SubGUILoop : public JobWithSemaphore
00065 {
00066 public:
00067 SubGUILoop(SubGUI* subGUI)
00068 :
00069 itsSubGUI(subGUI),
00070 itsPriority(1),
00071 itsJobType("controllerLoop")
00072 {}
00073
00074 virtual ~SubGUILoop() {}
00075
00076 virtual void run()
00077 {
00078 ASSERT(itsSubGUI);
00079 while(1)
00080 {
00081 itsSubGUI->update();
00082 usleep(10000);
00083 }
00084 }
00085
00086 virtual const char* jobType() const
00087 { return itsJobType.c_str(); }
00088
00089 virtual int priority() const
00090 { return itsPriority; }
00091
00092 private:
00093 SubGUI* itsSubGUI;
00094 const int itsPriority;
00095 const std::string itsJobType;
00096 };
00097 }
00098
00099
00100
00101
00102
00103
00104 SubGUI::SubGUI(OptionManager& mgr,
00105 const std::string& descrName,
00106 const std::string& tagName):
00107 ModelComponent(mgr, descrName, tagName),
00108 itsPWins(0),
00109 itsWinDims(512,512),
00110 itsModelComponent(NULL),
00111 itsMeters(0)
00112
00113 {
00114
00115 }
00116
00117
00118 SubGUI::~SubGUI()
00119 {
00120 for(unsigned int i=0; i<itsPWins.size(); i++)
00121 if (itsPWins[i] != NULL)
00122 delete itsPWins[i];
00123 }
00124
00125 void SubGUI::start2()
00126 {
00127 }
00128
00129 void SubGUI::startThread(nub::soft_ref<OutputFrameSeries> &ofs)
00130 {
00131 LINFO("Starting Gui thread");
00132 itsOfs = ofs;
00133
00134
00135 itsThreadServer.reset(new WorkThreadServer("SubController",1));
00136 itsThreadServer->setFlushBeforeStopping(false);
00137 rutz::shared_ptr<SubGUILoop> j(new SubGUILoop(this));
00138 itsThreadServer->enqueueJob(j);
00139
00140 }
00141
00142 void SubGUI::stopThread()
00143 {
00144 for(unsigned int i=0; i<itsPWins.size(); i++)
00145 if (itsPWins[i] != NULL)
00146 delete itsPWins[i];
00147
00148
00149 }
00150
00151
00152
00153
00154 void SubGUI::setupGUI(ModelComponent* comp, bool recurse)
00155 {
00156 PrefsWindow* pWin = new PrefsWindow("Control", SimpleFont::FIXED(8));
00157 ASSERT(pWin);
00158 pWin->setValueNumChars(16);
00159 pWin->addPrefsForComponent(comp, false);
00160
00161 itsPWins.push_back(pWin);
00162
00163 }
00164
00165 void SubGUI::update()
00166 {
00167 for (unsigned int i=0; i<itsPWins.size(); i++)
00168 if (itsPWins[i] != NULL)
00169 itsPWins[i]->update();
00170
00171 Image<PixRGB<byte> > disp(itsWinDims, ZEROS);
00172 Image<PixRGB<byte> > meters =
00173 makeMeters(2, Dims(disp.getDims().w() / 2, 13));
00174 inplacePaste(disp, meters, Point2D<int>(0,0));
00175
00176 for(unsigned int i=0; i<itsImages.size(); i++) {
00177 const size_t ax = i % 2;
00178 const size_t ay = i / 2;
00179 Point2D<int> pasteLoc(Point2D<int>(256*ax,
00180 meters.getHeight()+ (ay * itsImages[i]->getHeight())));
00181
00182 inplacePaste(disp, *itsImages[i], pasteLoc);
00183 }
00184
00185 itsOfs->writeRGB(disp, "GUIDisplay",
00186 FrameInfo("SubGui Display", SRC_POS));
00187
00188
00189 }
00190
00191 void SubGUI::addMeter(const int* valPtr, const std::string label,
00192 const int valMax, const PixRGB<byte> color)
00193 {
00194
00195 if (valPtr != NULL)
00196 {
00197 const MeterInfo minfo = {valPtr, label, valMax, color};
00198 itsMeters.push_back(minfo);
00199 }
00200 }
00201
00202 void SubGUI::addImage(const Image<PixRGB<byte> > *imgPtr)
00203 {
00204 if (imgPtr != NULL)
00205 itsImages.push_back(imgPtr);
00206 }
00207
00208
00209
00210 Image<PixRGB<byte> > SubGUI::makeMeters(const size_t nx,
00211 const Dims& meterdims)
00212 {
00213 if (itsMeters.size() == 0)
00214 return Image<PixRGB<byte> >();
00215
00216 ASSERT(meterdims.w() > 0);
00217 ASSERT(meterdims.h() > 0);
00218
00219 size_t maxlabelsize = itsMeters[0].label.size();
00220 for(unsigned int i=0; i<itsMeters.size(); i++)
00221 if (itsMeters[i].label.size() > maxlabelsize)
00222 maxlabelsize = itsMeters[i].label.size();
00223
00224 const SimpleFont f = SimpleFont::fixedMaxHeight(meterdims.h());
00225
00226 const int meterx = f.w() * (maxlabelsize + 7);
00227 const int maxmeterlen = meterdims.w() - meterx;
00228
00229 const size_t ny = (itsMeters.size() + nx-1) / nx;
00230
00231 Image<PixRGB<byte> > result(meterdims.w() * nx, meterdims.h() * ny, ZEROS);
00232
00233 for (unsigned int i = 0; i < itsMeters.size(); ++i)
00234 {
00235 const size_t ay = i % ny;
00236 const size_t ax = i / ny;
00237
00238 const std::string txt =
00239 sformat("%*s %i",
00240 int(maxlabelsize),
00241 itsMeters[i].label.c_str(),
00242 *itsMeters[i].valPtr);
00243
00244 writeText(result, Point2D<int>(meterdims.w() * ax, meterdims.h() * ay),
00245 txt.c_str(),
00246 PixRGB<byte>(255), PixRGB<byte>(0), f);
00247
00248 int meterlen =
00249 clampValue(int(maxmeterlen * abs(*itsMeters[i].valPtr) / abs(itsMeters[i].valmax)),
00250 1, maxmeterlen);
00251
00252
00253 Image<PixRGB<byte> >::iterator itr =
00254 result.beginw()
00255 + meterdims.w()*ax + meterx + ay*meterdims.h()*result.getWidth();
00256
00257 const int rowskip = result.getWidth() - maxmeterlen;
00258
00259 const PixRGB<byte> c1(itsMeters[i].color);
00260 const PixRGB<byte> c2(c1/2);
00261 const PixRGB<byte> c3(c2/3);
00262 const PixRGB<byte> c4(c3/2);
00263
00264 for (int y = 0; y < meterdims.h()-1; ++y)
00265 {
00266 for (int x = 0; x < meterlen; ++x)
00267 *itr++ = (x & 1) ? c2 : c1;
00268 for (int x = meterlen; x < maxmeterlen; ++x)
00269 *itr++ = (x & 1) ? c4 : c3;
00270 itr += rowskip;
00271 }
00272 }
00273
00274 return result;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283