34 #include "config_auto.h" 40 #pragma warning(disable : 4786) // Don't give irrelevant warnings for stl 41 #pragma warning(disable : 4018) // signed/unsigned warnings 42 #pragma warning(disable : 4530) // exception warnings 51 #include "allheaders.h" 60 static std::map<int, ScrollView*> svmap;
63 static std::map<std::pair<ScrollView*, SVEventType>,
64 std::pair<SVSemaphore*, SVEvent*> > waiting_for_events;
65 static SVMutex* waiting_for_events_mu;
71 any->
parameter =
new char[strlen(parameter) + 1];
82 #ifndef GRAPHICS_DISABLED 83 void* ScrollView::MessageReceiver(
void* a) {
88 int counter_event_id = 0;
92 message = ScrollView::GetStream()->
Receive();
93 }
while (message == NULL);
108 sscanf(message,
"%d,%d,%d,%d,%d,%d,%d,%n", &window_id, &ev_type, &cur->
x,
110 char* p = (message + n);
113 cur->
window = svmap[window_id];
115 if (cur->
window != NULL) {
116 cur->
parameter =
new char[strlen(p) + 1];
132 if (cur->
window->y_axis_is_reversed_)
134 cur->
counter = counter_event_id;
138 counter_event_id += 2;
144 cur->
window->SetEvent(cur);
147 std::pair<ScrollView*, SVEventType> awaiting_list(cur->
window,
149 std::pair<ScrollView*, SVEventType> awaiting_list_any(cur->
window,
151 std::pair<ScrollView*, SVEventType> awaiting_list_any_window((
ScrollView*)0,
153 waiting_for_events_mu->
Lock();
154 if (waiting_for_events.count(awaiting_list) > 0) {
155 waiting_for_events[awaiting_list].second = cur;
156 waiting_for_events[awaiting_list].first->Signal();
157 }
else if (waiting_for_events.count(awaiting_list_any) > 0) {
158 waiting_for_events[awaiting_list_any].second = cur;
159 waiting_for_events[awaiting_list_any].first->Signal();
160 }
else if (waiting_for_events.count(awaiting_list_any_window) > 0) {
161 waiting_for_events[awaiting_list_any_window].second = cur;
162 waiting_for_events[awaiting_list_any_window].first->Signal();
167 waiting_for_events_mu->
Unlock();
181 message = ScrollView::GetStream()->
Receive();
182 }
while (message == NULL);
191 {255, 255, 255, 255},
200 {128, 128, 255, 255},
204 {192, 192, 255, 255},
207 {255, 128, 128, 255},
211 {192, 192, 128, 255},
216 {192, 255, 192, 255},
218 {192, 192, 192, 255},
221 {128, 128, 128, 255},
226 {255, 192, 192, 255},
231 {255, 192, 128, 255},
246 int ScrollView::nr_created_windows_ = 0;
247 int ScrollView::image_index_ = 0;
251 int y_size,
int x_canvas_size,
int y_canvas_size,
252 bool y_axis_reversed,
const char* server_name) {
253 Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,
254 y_axis_reversed, server_name);}
258 int y_size,
int x_canvas_size,
int y_canvas_size,
259 bool y_axis_reversed) {
260 Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,
261 y_axis_reversed,
"localhost");
266 int y_size,
int x_canvas_size,
int y_canvas_size) {
267 Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,
272 void ScrollView::Initialize(
const char* name,
int x_pos,
int y_pos,
int x_size,
273 int y_size,
int x_canvas_size,
int y_canvas_size,
274 bool y_axis_reversed,
const char* server_name) {
277 if (stream_ == NULL) {
278 nr_created_windows_ = 0;
280 waiting_for_events_mu =
new SVMutex();
283 "svmain = luajava.bindClass('com.google.scrollview.ScrollView')\n");
288 nr_created_windows_++;
289 event_handler_ = NULL;
290 event_handler_ended_ =
false;
291 y_axis_is_reversed_ = y_axis_reversed;
292 y_size_ = y_canvas_size;
294 window_id_ = nr_created_windows_;
297 points_->
empty =
true;
300 svmap[window_id_] =
this;
304 event_table_[i] = NULL;
312 snprintf(message,
sizeof(message),
313 "w%u = luajava.newInstance('com.google.scrollview.ui" 314 ".SVWindow','%s',%u,%u,%u,%u,%u,%u,%u)\n",
315 window_id_, window_name_, window_id_,
316 x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size);
317 SendRawMessage(message);
323 void* ScrollView::StartEventHandler(
void* a) {
329 sv->semaphore_->
Wait();
337 if (sv->event_table_[i] != NULL &&
338 (serial < 0 || sv->event_table_[i]->counter < serial)) {
339 new_event = sv->event_table_[i];
340 serial = sv->event_table_[i]->
counter;
345 if (new_event != NULL) {
346 sv->event_table_[k] = NULL;
348 if (sv->event_handler_ != NULL) { sv->event_handler_->
Notify(new_event); }
351 sv->event_handler_ended_ =
true;
355 }
else { sv->mutex_->
Unlock(); }
357 }
while (sv != NULL);
360 #endif // GRAPHICS_DISABLED 363 #ifndef GRAPHICS_DISABLED 365 if (svmap[window_id_] != NULL) {
368 SendMsg(
"destroy()");
373 svmap[window_id_] = NULL;
378 while (!event_handler_ended_)
387 delete event_table_[i];
389 #endif // GRAPHICS_DISABLED 392 #ifndef GRAPHICS_DISABLED 400 va_start(args, format);
405 snprintf(form,
kMaxMsgSize,
"w%u:%s\n", window_id_, message);
418 event_handler_ = listener;
421 void ScrollView::Signal() {
422 semaphore_->Signal();
425 void ScrollView::SetEvent(
SVEvent* svevent) {
434 if (event_table_[specific->
type] != NULL) {
435 delete event_table_[specific->
type]; }
436 if (event_table_[
SVET_ANY] != NULL) {
439 event_table_[specific->
type] = specific;
451 std::pair<ScrollView*, SVEventType> ea(
this, type);
452 waiting_for_events_mu->
Lock();
453 waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, (
SVEvent*)0);
454 waiting_for_events_mu->
Unlock();
459 waiting_for_events_mu->
Lock();
460 SVEvent* ret = waiting_for_events[ea].second;
461 waiting_for_events.erase(ea);
463 waiting_for_events_mu->
Unlock();
473 waiting_for_events_mu->
Lock();
474 waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, (
SVEvent*)0);
475 waiting_for_events_mu->
Unlock();
480 waiting_for_events_mu->
Lock();
481 SVEvent* ret = waiting_for_events[ea].second;
482 waiting_for_events.erase(ea);
483 waiting_for_events_mu->
Unlock();
488 void ScrollView::SendPolygon() {
489 if (!points_->empty) {
490 points_->empty =
true;
491 int length = points_->xcoords.size();
496 SendMsg(
"drawLine(%d,%d,%d,%d)",
497 points_->xcoords[0], points_->ycoords[0],
498 points_->xcoords[1], points_->ycoords[1]);
499 }
else if (length > 2) {
501 SendMsg(
"createPolyline(%d)", length);
503 std::string decimal_coords;
504 for (
int i = 0; i < length; ++i) {
506 points_->xcoords[i], points_->ycoords[i]);
507 decimal_coords += coordpair;
509 decimal_coords +=
'\n';
510 SendRawMessage(decimal_coords.c_str());
511 SendMsg(
"drawPolyline()");
513 points_->xcoords.clear();
514 points_->ycoords.clear();
531 points_->xcoords.push_back(x);
532 points_->ycoords.push_back(TranslateYCoordinate(y));
533 points_->empty =
false;
538 if (!points_->xcoords.empty() && x1 == points_->xcoords.back() &&
539 TranslateYCoordinate(y1) == points_->ycoords.back()) {
542 }
else if (!points_->xcoords.empty() && x2 == points_->xcoords.back() &&
543 TranslateYCoordinate(y2) == points_->ycoords.back()) {
555 if (visible) { SendMsg(
"setVisible(true)");
556 }
else { SendMsg(
"setVisible(false)"); }
561 if (b) { SendMsg(
"setAlwaysOnTop(true)");
562 }
else { SendMsg(
"setAlwaysOnTop(false)"); }
571 va_start(args, format);
575 snprintf(form,
kMaxMsgSize,
"w%u:%s", window_id_, message);
577 char* esc = AddEscapeChars(form);
578 SendMsg(
"addMessage(\"%s\")", esc);
584 SendMsg(
"addMessageBox()");
589 SendRawMessage(
"svmain:exit()");
600 SendMsg(
"setStrokeWidth(%f)", width);
606 if (x1 == x2 && y1 == y2)
608 SendMsg(
"drawRectangle(%d,%d,%d,%d)",
609 x1, TranslateYCoordinate(y1), x2, TranslateYCoordinate(y2));
615 SendMsg(
"drawEllipse(%d,%d,%u,%u)",
616 x1, TranslateYCoordinate(y1), width, height);
621 SendMsg(
"pen(%d,%d,%d)", red, green, blue);
626 SendMsg(
"pen(%d,%d,%d,%d)", red, green, blue, alpha);
631 SendMsg(
"brush(%d,%d,%d)", red, green, blue);
636 SendMsg(
"brush(%d,%d,%d,%d)", red, green, blue, alpha);
641 bool bold,
bool italic,
bool underlined) {
646 if (bold) { b =
"true";
647 }
else { b =
"false"; }
648 if (italic) { i =
"true";
649 }
else { i =
"false"; }
650 if (underlined) { u =
"true";
651 }
else { u =
"false"; }
652 SendMsg(
"textAttributes('%s',%u,%s,%s,%s)", font, pixel_size,
658 SendMsg(
"drawText(%d,%d,'%s')", x, TranslateYCoordinate(y), mystring);
663 SendMsg(
"openImage('%s')", image);
664 SendMsg(
"drawImage('%s',%d,%d)",
665 image, x_pos, TranslateYCoordinate(y_pos));
670 int cmdEvent,
bool flag) {
671 if (parent == NULL) { parent =
""; }
672 if (flag) { SendMsg(
"addMenuBarItem('%s','%s',%d,true)",
673 parent, name, cmdEvent);
674 }
else { SendMsg(
"addMenuBarItem('%s','%s',%d,false)",
675 parent, name, cmdEvent); }
680 if (parent == NULL) { parent =
""; }
681 SendMsg(
"addMenuBarItem('%s','%s',%d)", parent, name, cmdEvent);
686 if (parent == NULL) { parent =
""; }
687 SendMsg(
"addMenuBarItem('%s','%s')", parent, name);
692 if (parent == NULL) { parent =
""; }
693 SendMsg(
"addPopupMenuItem('%s','%s')", parent, name);
698 int cmdEvent,
const char* value,
const char* desc) {
699 if (parent == NULL) { parent =
""; }
700 char* esc = AddEscapeChars(value);
701 char* esc2 = AddEscapeChars(desc);
702 SendMsg(
"addPopupMenuItem('%s','%s',%d,'%s','%s')", parent, name,
703 cmdEvent, esc, esc2);
716 for (std::map<int, ScrollView*>::iterator iter = svmap.begin();
717 iter != svmap.end(); ++iter) {
718 if (iter->second != NULL)
719 iter->second->UpdateWindow();
740 SendMsg(
"showInputDialog(\"%s\")", msg);
744 char* p =
new char[strlen(ev->
parameter) + 1];
752 SendMsg(
"showYesNoDialog(\"%s\")", msg);
764 y1 = TranslateYCoordinate(y1);
765 y2 = TranslateYCoordinate(y2);
766 SendMsg(
"zoomRectangle(%d,%d,%d,%d)",
774 pixWriteMem(&data, &size, image, IFF_PNG);
775 int base64_len = (size + 2) / 3 * 4;
776 y_pos = TranslateYCoordinate(y_pos);
777 SendMsg(
"readImage(%d,%d,%d)", x_pos, y_pos, base64_len);
779 const char kBase64Table[64] = {
780 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
781 'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
782 'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
783 'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
784 'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
785 'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
786 'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
787 '4',
'5',
'6',
'7',
'8',
'9',
'+',
'/',
789 char* base64 =
new char[base64_len + 1];
790 memset(base64,
'=', base64_len);
791 base64[base64_len] =
'\0';
795 for (
size_t i = 0; i < size; ++i) {
796 int code = (data[i] >> (bits_left + 2)) | remainder;
797 base64[code_len++] = kBase64Table[code & 63];
799 remainder = data[i] << (6 - bits_left);
800 if (bits_left == 6) {
801 base64[code_len++] = kBase64Table[remainder & 63];
807 base64[code_len++] = kBase64Table[remainder & 63];
808 SendRawMessage(base64);
815 char* ScrollView::AddEscapeChars(
const char* input) {
816 const char* nextptr = strchr(input,
'\'');
817 const char* lastptr = input;
820 while (nextptr != NULL) {
821 strncpy(message+pos, lastptr, nextptr-lastptr);
822 pos += nextptr - lastptr;
826 nextptr = strchr(nextptr+1,
'\'');
828 strcpy(message+pos, lastptr);
834 if (!y_axis_is_reversed_) {
return y;
835 }
else {
return y_size_ - y; }
838 #endif // GRAPHICS_DISABLED void SetVisible(bool visible)
char * ShowInputDialog(const char *msg)
void Ellipse(int x, int y, int width, int height)
void ZoomToRectangle(int x1, int y1, int x2, int y2)
SVEvent * AwaitEventAnyWindow()
std::vector< int > xcoords
void DrawTo(int x, int y)
void Image(struct Pix *image, int x_pos, int y_pos)
void PopupItem(const char *parent, const char *name)
int table_colors[ScrollView::GREEN_YELLOW+1][4]
static void StartThread(void *(*func)(void *), void *arg)
Create new thread.
ScrollView(const char *name, int x_pos, int y_pos, int x_size, int y_size, int x_canvas_size, int y_canvas_size)
Calls Initialize with default argument for server_name_ & y_axis_reversed.
void Wait()
Wait on a semaphore.
void TextAttributes(const char *font, int pixel_size, bool bold, bool italic, bool underlined)
int TranslateYCoordinate(int y)
virtual void Notify(const SVEvent *sve)
const int kMaxIntPairSize
void Text(int x, int y, const char *mystring)
std::vector< int > ycoords
void Lock()
Locks on a mutex.
void SetCursor(int x, int y)
void AddEventHandler(SVEventHandler *listener)
Add an Event Listener to this ScrollView Window.
void SendMsg(const char *msg,...)
Send a message to the server, attaching the window id.
int ShowYesNoDialog(const char *msg)
void Rectangle(int x1, int y1, int x2, int y2)
void Unlock()
Unlocks on a mutex.
SVEvent * AwaitEvent(SVEventType type)
static void SendRawMessage(const char *msg)
void AddMessage(const char *format,...)
void Line(int x1, int y1, int x2, int y2)
void MenuItem(const char *parent, const char *name)