view syl_window.cpp @ 189:d0e3a13c1bd9 default tip

Remove old calculator example
author Mike Pavone <pavone@retrodev.com>
date Fri, 07 Oct 2011 00:24:04 -0700
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;
}*/