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 "GUI/GeneralGUI.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 GeneralGUILoop : public JobWithSemaphore
00065 {
00066 public:
00067 GeneralGUILoop(GeneralGUI* genGUI)
00068 :
00069 itsGeneralGUI(genGUI),
00070 itsPriority(1),
00071 itsJobType("GUI Loop")
00072 {}
00073
00074 virtual ~GeneralGUILoop() {}
00075
00076 virtual void run()
00077 {
00078 ASSERT(itsGeneralGUI);
00079 while(1)
00080 {
00081 itsGeneralGUI->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 GeneralGUI* itsGeneralGUI;
00094 const int itsPriority;
00095 const std::string itsJobType;
00096 };
00097 }
00098
00099
00100
00101
00102
00103
00104 GeneralGUI::GeneralGUI(OptionManager& mgr,
00105 const std::string& descrName,
00106 const std::string& tagName,
00107 Dims d):
00108 ModelComponent(mgr, descrName, tagName),
00109 itsPWins(0),
00110 itsWinDims(d),
00111 itsModelComponent(NULL),
00112 itsMeters(0)
00113
00114 {
00115
00116 }
00117
00118
00119 GeneralGUI::~GeneralGUI()
00120 {
00121 for(unsigned int i=0; i<itsPWins.size(); i++)
00122 if (itsPWins[i] != NULL)
00123 delete itsPWins[i];
00124 }
00125
00126 void GeneralGUI::start2()
00127 {
00128 }
00129
00130 void GeneralGUI::startThread(nub::soft_ref<OutputFrameSeries> &ofs)
00131 {
00132 LINFO("Starting Gui thread");
00133
00134 itsThreadServer.reset(new WorkThreadServer("GuiThread",1));
00135 itsThreadServer->setFlushBeforeStopping(false);
00136 rutz::shared_ptr<GeneralGUILoop> j(new GeneralGUILoop(this));
00137 itsThreadServer->enqueueJob(j);
00138
00139 itsOfs = ofs;
00140 }
00141
00142 void GeneralGUI::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 GeneralGUI::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 GeneralGUI::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("GeneralGUI Display", SRC_POS));
00187
00188
00189 }
00190
00191 void GeneralGUI::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 GeneralGUI::addImage(const Image<PixRGB<byte> > *imgPtr)
00203 {
00204 if (imgPtr != NULL)
00205 itsImages.push_back(imgPtr);
00206 }
00207
00208
00209
00210 Image<PixRGB<byte> > GeneralGUI::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