view syl_window.cpp @ 75:0083b2f7b3c7

Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author Mike Pavone <pavone@retrodev.com>
date Tue, 06 Jul 2010 07:52:59 -0400
parents 76568becd6d6
children
line wrap: on
line source

#include <util/application.h>
#include <util/message.h>
#include <gui/button.h>
#include <gui/textview.h>
#include <gui/control.h>
#include <gui/checkbox.h>
#include <gui/dropdownmenu.h>
#include <atheos/threads.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "syl_window.h"
#include "structs.h"
#include "debugmacros.h"
#include "syl_generic.h"

os::Application *app;

extern "C" {


void app_thread(void * param)
{
	DEBUGPUTS("Before app->Run()\n");
	app->Run();
	DEBUGPUTS("After app->Run()\n");
}

//VIS_CRITICAL_SECTION_EXTERN(app_lock)
extern short app_lock;

void check_create_app()
{
	VIS_EnterCriticalSection(app_lock);
		if(!app)
		{
			
			app = new os::Application("mime type goes here");
			resume_thread(spawn_thread("vis_app", (void *)app_thread, 1, 0, NULL));
			DEBUGPUTS("Created application object\n");
		}
	VIS_LeaveCriticalSection(app_lock);
}

int vis_window_get_value(datum ** inputlist, queue_entry * worker_entry)
{
	datum * output = NULL, *name;
	os::String val;
	os::Control * control = NULL;
	os::DropdownMenu * drop;
	vis_window_shown * window = (vis_window_shown *)(inputlist[0]->c.generic.data);
	name = add_ref(inputlist[1]);
	inputlist[2] = inputlist[1];
	
	DEBUGPUTS("Entering window lock\n");
	VIS_EnterCriticalSection(window->lock);
		inputlist[1] = add_ref(window->widget_types);
		vis_dict_index(inputlist+1, worker_entry);
		if(inputlist[1])
		{
			switch(inputlist[1]->c.integers.num_a)
			{
			case BUILTIN_TYPE_INPUTBOX:
				control = (os::Control *)(window->wind->FindView((char *)(name->c.generic.data)));
				if(control)
				{
					DEBUGPUTS("Before GetValue\n");
					val = control->GetValue().AsString();
					output = make_string(val.c_str(), val.CountChars(), worker_entry->instance->def->prog);
				}
				break;
			case BUILTIN_TYPE_CHECKBOX:
				control = (os::Control *)(window->wind->FindView((char *)(name->c.generic.data)));
				if(control)
				{
					output = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->prog);
					output->c.integers.num_a = control->GetValue().AsBool();
				}
				break;
			case BUILTIN_TYPE_DROPDOWN:
				drop = (os::DropdownMenu *)(window->wind->FindView((char *)(name->c.generic.data)));
				if(drop)
				{
					val = drop->GetCurrentString();
					output = make_string(val.c_str(), val.CountChars(), worker_entry->instance->def->prog);
				}
				break;
			default:
				printf("Unsupported widget type %d for Get Value\n", inputlist[1]->c.integers.num_a);
				break;
			}
		}
				
	VIS_LeaveCriticalSection(window->lock);
	DEBUGPUTS("Leaving window lock\n");
	DEBUGPRINTF("window->wind: %X\n", window->wind);
	DEBUGPRINTF("window->title: %X\n", window->title);
	release_ref(inputlist[0]);
	release_ref(inputlist[1]);
	release_ref(name);
	inputlist[0] = output;
	return 0;
}

int vis_window_set_value(datum ** inputlist, queue_entry * worker_entry)
{
	datum *name, *value;
	worker_def * converter;
	os::String val;
	os::Control * control = NULL;
	os::DropdownMenu * drop;
	vis_window_shown * window = (vis_window_shown *)(inputlist[0]->c.generic.data);
	name = add_ref(inputlist[1]);
	value = inputlist[2];
	inputlist[2] = inputlist[1];
	
	DEBUGPUTS("Entering window lock\n");
	VIS_EnterCriticalSection(window->lock);
		inputlist[1] = add_ref(window->widget_types);
		vis_dict_index(inputlist+1, worker_entry);
		if(inputlist[1])
		{
			switch(inputlist[1]->c.integers.num_a)
			{
			case BUILTIN_TYPE_INPUTBOX:
				control = (os::Control *)(window->wind->FindView((char *)(name->c.generic.data)));
				if(control)
				{
					if(value->company->type_id != BUILTIN_TYPE_STRING)
					{
						converter = find_converter_method(BUILTIN_TYPE_STRING, value->company->type_id, worker_entry->instance->def->prog);
						if(!converter)
						{
							if(worker_entry->instance) {
								ERRORPRINTF("Error: Needed conversion from %s to %s for input %d of %s in worker %s\n", value->company->name, worker_entry->instance->def->prog->companylist[BUILTIN_TYPE_STRING].name, 2, "Set Value@Screen Window", worker_entry->instance->def->name);
							} else {
								ERRORPRINTF("Error: Needed conversion from %s to %s for input %d of %s\n", value->company->name, worker_entry->instance->def->prog->companylist[BUILTIN_TYPE_STRING].name, 2, "Set Value@Screen Window");
							}
							execute_active = FALSE;
							VIS_PROFILE_END(PROF_PROCESS_WORKER);
							return -3;
						}
						((worker_impl)(converter->implement_func))(&value, worker_entry);
					}
					control->SetValue(os::String((char *)(value->c.generic.data)), false);
				}
				break;
			case BUILTIN_TYPE_CHECKBOX:
				control = (os::Control *)(window->wind->FindView((char *)(name->c.generic.data)));
				if(control)
				{
					if(value->company->type_id != BUILTIN_TYPE_YESNO)
					{
						converter = find_converter_method(BUILTIN_TYPE_YESNO, value->company->type_id, worker_entry->instance->def->prog);
						if(!converter)
						{
							if(worker_entry->instance) {
								ERRORPRINTF("Error: Needed conversion from %s to %s for input %d of %s in worker %s\n", value->company->name, worker_entry->instance->def->prog->companylist[BUILTIN_TYPE_YESNO].name, 2, "Set Value@Screen Window", worker_entry->instance->def->name);
							} else {
								ERRORPRINTF("Error: Needed conversion from %s to %s for input %d of %s\n", value->company->name, worker_entry->instance->def->prog->companylist[BUILTIN_TYPE_YESNO].name, 2, "Set Value@Screen Window");
							}
							execute_active = FALSE;
							VIS_PROFILE_END(PROF_PROCESS_WORKER);
							return -3;
						}
						((worker_impl)(converter->implement_func))(&value, worker_entry);
					}
					control->SetValue((bool)(value->c.integers.num_a), false);
				}
				break;
			case BUILTIN_TYPE_DROPDOWN:
				drop = (os::DropdownMenu *)(window->wind->FindView((char *)(name->c.generic.data)));
				if(drop)
				{
					if(value->company->type_id != BUILTIN_TYPE_STRING)
					{
						converter = find_converter_method(BUILTIN_TYPE_STRING, value->company->type_id, worker_entry->instance->def->prog);
						if(!converter)
						{
							if(worker_entry->instance) {
								ERRORPRINTF("Error: Needed conversion from %s to %s for input %d of %s in worker %s\n", value->company->name, worker_entry->instance->def->prog->companylist[BUILTIN_TYPE_STRING].name, 2, "Set Value@Screen Window", worker_entry->instance->def->name);
							} else {
								ERRORPRINTF("Error: Needed conversion from %s to %s for input %d of %s\n", value->company->name, worker_entry->instance->def->prog->companylist[BUILTIN_TYPE_STRING].name, 2, "Set Value@Screen Window");
							}
							execute_active = FALSE;
							VIS_PROFILE_END(PROF_PROCESS_WORKER);
							return -3;
						}
						((worker_impl)(converter->implement_func))(&value, worker_entry);
					}
					drop->SetCurrentString(os::String((char *)(value->c.generic.data)));
				}
				break;
			default:
				printf("Unsupported widget type %d for Get Value\n", inputlist[1]->c.integers.num_a);
				break;
			}
		}
				
	VIS_LeaveCriticalSection(window->lock);

	release_ref(inputlist[1]);
	release_ref(value);
	return 0;
}

os::Message * handler_widget_to_window(vis_widget * widget, vis_window_shown * window_show, char * handler_name, queue_entry * entry, bool make_message)
{
	datum * params[3];
	params[0] = add_ref(widget->handler_dict);
	params[1] = make_string(handler_name, -1, entry->instance->def->prog);
	DEBUGPUTS("Looking up click handler\n");
	vis_dict_index(params, entry);
	//if no handler is found, make sure to release output 2
	if(params[1])
		release_ref(params[1]);
	if(params[0] || !make_message)
	{
		DEBUGPRINTF("Appending %X to handler list\n", params[0]);
		params[1] = params[0];
		params[0] = window_show->handler_list;
		vis_list_append(params, NULL);
		window_show->handler_list = params[0];
		if(make_message)
			return new os::Message(window_show->next_msg_code++);
	}
	return NULL;
}

void add_widget_shared(vis_window_shown * window_show, datum * widget_datum, char * name, double xpos, double ypos, queue_entry * worker_entry, os::View * parent_view = NULL)
{
	datum * index;
	os::View * widget_view;
	os::TextView * text_view;
	os::DropdownMenu * drop_view;
	os::Message * msg;
	vis_widget * widget;
	datum * params[3];
	params[0] = window_show->widget_types;
	params[1] = make_string(name, -1, worker_entry->instance->def->prog);
	params[2] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->prog);
	params[2]->c.integers.num_a = widget_datum->company->type_id;
	vis_dict_set(params, worker_entry);
	window_show->widget_types = params[0];
	widget = (vis_widget *)(widget_datum->c.generic.data);
		DEBUGPUTS("Instantiating OS native widget object\n");
		switch(widget_datum->company->type_id)
		{
			case BUILTIN_TYPE_BUTTON:
				DEBUGPUTS("new os::Button()\n");
				widget_view = new os::Button(
					os::Rect(
						xpos, ypos, 
						xpos+widget->width, ypos+widget->height
					), 
					name, 
					(char *)(widget->label->c.generic.data), 
					new os::Message(window_show->next_msg_code++)
				);
				/*params[0] = add_ref(widget->handler_dict);
				params[1] = new_datum(BUILTIN_TYPE_STRING, 1, 6, worker_entry->instance->def->prog);//click
				strcpy((char *)(params[1]->c.generic.data), "click");
				DEBUGPUTS("Looking up click handler\n");
				vis_dict_index(params, worker_entry);
				if(params[1])
					release_ref(params[1]);
				DEBUGPRINTF("Appending %X to handler list\n", params[0]);
				params[1] = params[0];
				params[0] = window_show->handler_list;
				vis_list_append(params, worker_entry);
				window_show->handler_list = params[0];*/
				handler_widget_to_window(widget, window_show, "click", worker_entry, false);
				break;
			case BUILTIN_TYPE_INPUTBOX:
				text_view = new os::TextView(
					os::Rect(
						xpos, ypos, 
						xpos+widget->width, ypos+widget->height
					),
					name, 
					(char *)(widget->value->c.generic.data)
				);
				switch(widget->flags)
				{
				case 1:
					text_view->SetMultiLine();
					break;
				case 2:
					text_view->SetNumeric(true);
					break;
				case 3:
					text_view->SetPasswordMode();
					break;
				case 4:
					text_view->SetReadOnly();
					break;
				default:
					break;
				}
				widget_view = text_view;
				break;
			case BUILTIN_TYPE_CUSTOM_WIDGET:
				DEBUGPUTS("Creating custom widget\n");
				widget_view = new GenericView(
					os::Rect(
						xpos, ypos, 
						xpos+widget->width, ypos+widget->height
					),
					name,
					add_ref(widget_datum),
					&(window_show->instance));
				DEBUGPRINTF("Widget view: %X\n", widget_view);
				break;
			case BUILTIN_TYPE_CHECKBOX:
				widget_view = new os::CheckBox(
					os::Rect(
						xpos, ypos,
						xpos+widget->width, ypos+widget->height
					),
					name,
					(char *)(widget->label->c.generic.data),
					new os::Message(window_show->next_msg_code++)
				);
				handler_widget_to_window(widget, window_show, "click", worker_entry, false);
				break;
			case BUILTIN_TYPE_DROPDOWN:
				drop_view = new os::DropdownMenu(
					os::Rect(
						xpos, ypos,
						xpos+widget->width, ypos+widget->height
					),
					name
				);
				params[0] = add_ref(widget->label);
				vis_list_first(params, worker_entry);
				index = params[0];
				while(index)
				{
					params[1] = add_ref(index);
					params[0] = add_ref(widget->label);
					vis_list_index(params, worker_entry);
					if(params[0] && params[0]->company->type_id == BUILTIN_TYPE_STRING)
						drop_view->AppendItem((char *)(params[0]->c.generic.data));
					params[1] = index;
					params[0] = add_ref(widget->label);
					vis_list_next(params, worker_entry);
					index = params[0];
				}
				release_ref(params[1]);
				if(widget->selected_index >= 0)
					drop_view->SetSelection(widget->selected_index, false);
				else if(widget->value && widget->value->company->type_id == BUILTIN_TYPE_STRING)
					drop_view->SetCurrentString((char *)(widget->value->c.generic.data));
				drop_view->SetSendIntermediateMsg(true);
				msg = handler_widget_to_window(widget, window_show, "change", worker_entry, true);
				if(msg)
					drop_view->SetEditMessage(msg);
				msg = handler_widget_to_window(widget, window_show, "select", worker_entry, true);
				if(msg)
					drop_view->SetSelectionMessage(msg);
				drop_view->SetTarget(window_show->wind);
				widget_view = drop_view;
				break;
			default:
				//Do error crap here
				break;
		}
		if(parent_view) {
			//widget_view->SetFlags(widget_view->GetFlags() | os::WID_TRANSPARENT);
			parent_view->AddChild(widget_view);
		} else {
			DEBUGPUTS("Adding OS native object to window\n");
			window_show->wind->AddChild(widget_view);
		}
	
}

int vis_window_shown_addwidget(datum ** inputlist, queue_entry * worker_entry)
{
	vis_window_shown * window = (vis_window_shown *)(inputlist[0]->c.generic.data);
	window->wind->Lock();
	add_widget_shared(window, inputlist[2], (char *)(inputlist[1]->c.generic.data), inputlist[3]->c.real, inputlist[4]->c.real, worker_entry, NULL);
	window->wind->Unlock();
	release_ref(inputlist[1]);
	release_ref(inputlist[2]);
	release_ref(inputlist[3]);
	release_ref(inputlist[4]);
	return 0;
}

int vis_window_show(datum ** inputlist, queue_entry * worker_entry)
{
	vis_window * window = (vis_window *)(inputlist[0]->c.generic.data);
	vis_window_shown * window_show;
	list_data * list;
	int i;
	datum * params[2];
	double xpos, ypos;
	datum * widget_datum;
	vis_widget * widget;
	datum * show_datum = new_datum(BUILTIN_TYPE_WINDOW_SHOWN, 1, sizeof(vis_window_shown), worker_entry->instance->def->prog);
	window_show = (vis_window_shown *)(show_datum->c.generic.data);
	window_show->title = add_ref(window->title);
	window_show->width = window->width;
	window_show->height = window->height;
	window_show->xpos = inputlist[1]->c.real;
	release_ref(inputlist[1]);
	window_show->ypos = inputlist[2]->c.real;
	release_ref(inputlist[2]);
	window_show->is_open = TRUE;
	window_show->wait_entry = NULL;
	window_show->next_msg_code = 0;
	window_show->instance.def = worker_entry->instance->def;
	window_show->widget_types = create_dict(worker_entry->instance->def->prog);
	
	check_create_app();
	VIS_InitializeCriticalSection(window_show->lock);
	window_show->wind = new os_window(add_ref(show_datum));
	
	window_show->handler_list = create_list(worker_entry->instance->def->prog);
	list = (list_data *)(window->id_list->c.generic.data);
	for(i = 0; i < list->num_entries; ++i)
	{
		DEBUGPRINTF("Retrieving widget %d\n", i);
		params[0] = add_ref(window->widget_dict);
		params[1] = add_ref(list->entries[i]);
		vis_dict_index(params, NULL);
		widget_datum = params[0];
		DEBUGPRINTF("Retrieving xpos for widget: %d\n", i);
		params[0] = add_ref(window->widget_xpos);
		params[1] = add_ref(list->entries[i]);
		DEBUGPUTS("Calling vis_dict_index(params, NULL) for xpos\n");
		vis_dict_index(params, NULL);
		DEBUGPUTS("After vis_dict_index\n");
		xpos = params[0]->c.real;
		DEBUGPUTS("Releasing xpos datum\n");
		release_ref(params[0]);
		DEBUGPRINTF("Retrieving ypos for widget: %d\n", i);
		params[0] = add_ref(window->widget_ypos);
		params[1] = add_ref(list->entries[i]);
		DEBUGPUTS("Calling vis_dict_index(params, NULL) for ypos\n");
		vis_dict_index(params, NULL);
		DEBUGPUTS("After vis_dict_index\n");
		ypos = params[0]->c.real;
		DEBUGPUTS("Releasing ypos datum\n");
		release_ref(params[0]);
		add_widget_shared(window_show, widget_datum, (char *)(list->entries[i]->c.generic.data), xpos, ypos, worker_entry, NULL);
	}

	DEBUGPUTS("Showing window\n");
	window_show->wind->MakeFocus();
	window_show->wind->Show();
	//resume_thread(spawn_thread("vis_mem_check", (void *)vis_mem_check, 1, 0, (void *)window_show));
	//sleep(5);
	release_ref(inputlist[0]);
	inputlist[0] = show_datum;
	return 0;
}


}

os_window::os_window(datum * vis_wind) : os::Window(
											os::Rect(
												((vis_window_shown *)(vis_wind->c.generic.data))->xpos, 
												((vis_window_shown *)(vis_wind->c.generic.data))->ypos, 
												((vis_window_shown *)(vis_wind->c.generic.data))->xpos+((vis_window_shown *)(vis_wind->c.generic.data))->width,
												((vis_window_shown *)(vis_wind->c.generic.data))->ypos+((vis_window_shown *)(vis_wind->c.generic.data))->height), 
											"vis_wnd", 
											(char *)(((vis_window_shown *)(vis_wind->c.generic.data))->title->c.generic.data))
{
	//DEBUGPRINTF("vis_wind lock: %d\n", ((vis_window_shown *)(vis_wind->c.generic.data))->lock);
	this->vis_wind = vis_wind;
//	this->current_focus = NULL;
}
os_window::~os_window()
{
	vis_window_closed(this->vis_wind);
}

void empty_callback(worker_instance * caller_instance, int caller_workernum, worker_instance * done_instance, void * data)
{
}

void os_window::HandleMessage(os::Message * msg)
{
	int returnval;
	queue_entry entry;
	datum * params[32];
	datum * io_list;
	datum * worker;
	worker_datum * work;
	int code = msg->GetCode();
	DEBUGPRINTF("Message Code: %d\n", code);
	DEBUGPRINTF("window->wind: %X\n", ((vis_window_shown *)(this->vis_wind->c.generic.data))->wind);
	DEBUGPRINTF("vis_wind->ref_count: %X\n", this->vis_wind->ref_count);
	params[0] = add_ref(((vis_window_shown *)(this->vis_wind->c.generic.data))->handler_list);
	params[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, ((vis_window_shown *)(this->vis_wind->c.generic.data))->instance.def->prog);
	params[1]->c.integers.num_a = code;
	entry.worker_num = 0;
		entry.instance = &(((vis_window_shown *)(this->vis_wind->c.generic.data))->instance);
	vis_list_index(params, &entry);
	if(params[0] && params[0]->company->type_id == BUILTIN_TYPE_WORKER)
	{
		worker = params[0];
		work = (worker_datum *)(worker->c.generic.data);
		params[0] = create_list(entry.instance->def->prog);
		params[1] = add_ref(this->vis_wind);
		vis_list_append(params, &entry);
		io_list = params[0];
		returnval = worker_populate_inputs(worker, io_list, params);
		if(!returnval)
			execute_def(work->def, entry, params, empty_callback);
	}
	DEBUGPRINTF("window->wind: %X\n", ((vis_window_shown *)(this->vis_wind->c.generic.data))->wind);
	DEBUGPUTS("End: HandleMessage\n");
}
/*
void os_window::DispatchMessage(os::Message * pcMsg, os::Handler * pcHandler)
{
	os::View * view;
	os::View * handler_view;
	//int code = pcMsg->GetCode();
	pcMsg->FindPointer("_widget", (void **)&view);
	if(view) {
		handler_view = _FindHandler(view->m_nToken);
		if(handler_view != view)
			printf("DispatchMessage, message view: %X, handler view: %X\n", view, handler_view);
		
	}
	os::Window::DispatchMessage(pcMsg, pcHandler);
}

os::View *os_window::SetFocusNoHandler(os::View * new_focus )
{
	ifthis->current_focus)
		this->current_focus->Activated(false);
	if(new_focus)
		new_focus->Activated(true);
	this->current_focus = new_focus;
	return new_focus;
}*/