//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //agenttype_switchedstate_getdata //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void *agenttype_switchedstate_getdata(agent *a, int datatype) { agenttype_switchedstate_details *details = (agenttype_switchedstate_details *) a->agentdetails; bool *boolptr; switch (datatype) { case DATAFETCH_VALUE_TEXT: //Get the boolean value boolptr = (bool *) agent_getdata(details->agents[AGENTTYPE_SWITCHEDSTATE_AGENT_BOOL], DATAFETCH_VALUE_BOOL); //If the boolean value is true... if (boolptr != NULL && *boolptr == true) return agent_getdata(details->agents[AGENTTYPE_SWITCHEDSTATE_AGENT_WHENTRUE], datatype); else return agent_getdata(details->agents[AGENTTYPE_SWITCHEDSTATE_AGENT_WHENFALSE], datatype); break; case DATAFETCH_SUBAGENTS_POINTERS_ARRAY: return details->agents; case DATAFETCH_SUBAGENTS_NAMES_ARRAY: return agenttype_switchedstate_agentdescriptions; case DATAFETCH_SUBAGENTS_TYPES_ARRAY: return (void *) agenttype_switchedstate_agenttypes[details->datatype]; case DATAFETCH_SUBAGENTS_COUNT: return (void *) &agenttype_switchedstate_subagentcount; } return NULL; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //controltype_button_notify //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void controltype_button_notify(control *c, int notifytype, void *messagedata) { //Variables controltype_button_details *details; bool *newvalueptr; //Get details details = (controltype_button_details *) c->controldetails; //Find out what to do switch (notifytype) { case NOTIFY_NEEDUPDATE: //When we are told we need an update, figure out what to do //Update the caption first if (details->agents[CONTROLTYPE_BUTTON_CAPTION]) { details->caption = (char *) agent_getdata(details->agents[CONTROLTYPE_BUTTON_CAPTION], DATAFETCH_VALUE_TEXT); } else { details->caption = NULL; } //Only two state buttons need updates at this point if (details->is_twostate) { //Get the value newvalueptr = (bool *)(agent_getdata(details->agents[CONTROLTYPE_TWOSTATEBUTTON_AGENT_VALUECHANGE], DATAFETCH_VALUE_BOOL)); if (newvalueptr) { //Set the new value details->is_on = *newvalueptr; } } //Tell the button to draw itself again style_draw_invalidate(c); break; case NOTIFY_SAVE_CONTROL: //Save all local values config_write(config_get_control_setcontrolprop_c(c, "HAlign", button_haligns[details->halign])); config_write(config_get_control_setcontrolprop_c(c, "VAlign", button_valigns[details->valign])); int i; for (i = 0; i < CONTROLTYPE_BUTTON_AGENTCOUNT; i++) agent_notify(details->agents[i], NOTIFY_SAVE_AGENT, NULL); if (details->is_twostate) config_write(config_get_control_setcontrolprop_b(c, "Pressed", &details->is_on)); break; case NOTIFY_DRAGACCEPT: DragAcceptFiles(c->windowptr->hwnd, NULL != details->agents[details->is_twostate ? CONTROLTYPE_TWOSTATEBUTTON_AGENT_ONDROP : CONTROLTYPE_BUTTON_AGENT_ONDROP]); break; } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //controltype_button_getdata //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void *controltype_button_getdata(control *c, int datatype) { controltype_button_details *details = (controltype_button_details *) c->controldetails; switch (datatype) { case DATAFETCH_VALUE_BOOL: if (details->is_twostate) return &details->is_on; break; case DATAFETCH_INT_DEFAULTHEIGHT: return (void *) &controltype_button_data_defaultheight; case DATAFETCH_INT_DEFAULTWIDTH: return (void *) &controltype_button_data_defaultwidth; case DATAFETCH_INT_MIN_WIDTH: return (void *) &controltype_button_data_minimumwidth; case DATAFETCH_INT_MIN_HEIGHT: return (void *) &controltype_button_data_minimumheight; case DATAFETCH_INT_MAX_WIDTH: return (void *) &controltype_button_data_maximumwidth; case DATAFETCH_INT_MAX_HEIGHT: return (void *) &controltype_button_data_maximumheight; case DATAFETCH_CONTENTSIZES: { if (details->agents[CONTROLTYPE_BUTTON_IMAGE]) return agent_getdata(details->agents[CONTROLTYPE_BUTTON_IMAGE], datatype); break; } } return NULL; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //agenttype_switchedstate_notify //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void agenttype_switchedstate_notify(agent *a, int notifytype, void *messagedata) { //Get the agent details agenttype_switchedstate_details *details = (agenttype_switchedstate_details *) a->agentdetails; //Declare variables bool *boolptr; switch(notifytype) { case NOTIFY_DRAW: case NOTIFY_CHANGE: //Get the boolean value boolptr = (bool *) agent_getdata(details->agents[AGENTTYPE_SWITCHEDSTATE_AGENT_BOOL], DATAFETCH_VALUE_BOOL); //Do the appropriate action if (boolptr != NULL && *boolptr == true) return agent_notify(details->agents[AGENTTYPE_SWITCHEDSTATE_AGENT_WHENTRUE], notifytype, messagedata); else return agent_notify(details->agents[AGENTTYPE_SWITCHEDSTATE_AGENT_WHENFALSE], notifytype, messagedata); break; case NOTIFY_SAVE_AGENT: //Write existance config_write(config_get_control_setagent_c(a->controlptr, a->agentaction, a->agenttypeptr->agenttypename, agenttype_switchedstate_typenames[details->datatype])); //Save all child agents, if necessary for (int i = 0; i < 3; i++) agent_notify(details->agents[i], NOTIFY_SAVE_AGENT, NULL); break; } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //controltype_label_getdata //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void *controltype_label_getdata(control *c, int datatype) { switch (datatype) { case DATAFETCH_INT_DEFAULTHEIGHT: return (void *) &controltype_label_data_defaultheight; case DATAFETCH_INT_DEFAULTWIDTH: return (void *) &controltype_label_data_defaultwidth; case DATAFETCH_INT_MIN_WIDTH: return (void *) &controltype_label_data_minimumwidth; case DATAFETCH_INT_MIN_HEIGHT: return (void *) &controltype_label_data_minimumheight; case DATAFETCH_INT_MAX_WIDTH: return (void *) &controltype_label_data_maximumwidth; case DATAFETCH_INT_MAX_HEIGHT: return (void *) &controltype_label_data_maximumheight; case DATAFETCH_CONTENTSIZES: { controltype_label_details *details = (controltype_label_details *) c->controldetails; if (details->agents[CONTROLTYPE_LABEL_AGENT_IMAGE]) return agent_getdata(details->agents[CONTROLTYPE_LABEL_AGENT_IMAGE], datatype); break; } } return NULL; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //controltype_label_notify //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void controltype_label_notify(control *c, int notifytype, void *messagedata) { //Variables controltype_label_details *details; int i; //Get details details = (controltype_label_details *) c->controldetails; //Find out what to do switch (notifytype) { case NOTIFY_NEEDUPDATE: //When we are told we need an update, figure out what to do //Update the caption first if (details->agents[CONTROLTYPE_LABEL_AGENT_CAPTION]) { details->caption = (char *) agent_getdata(details->agents[CONTROLTYPE_LABEL_AGENT_CAPTION], DATAFETCH_VALUE_TEXT); } else { details->caption = NULL; } //Tell the label to draw itself again style_draw_invalidate(c); break; case NOTIFY_SAVE_CONTROL: //Save all local values config_write(config_get_control_setcontrolprop_c(c, "HAlign", label_haligns[details->halign])); config_write(config_get_control_setcontrolprop_c(c, "VAlign", label_valigns[details->valign])); if (details->is_frame) { config_write(config_get_control_setcontrolprop_b(c, "HasTitleBar", &details->has_titlebar)); config_write(config_get_control_setcontrolprop_b(c, "IsLocked", &details->is_locked)); } for (i = 0; i < CONTROLTYPE_LABEL_AGENT_COUNT; i++) agent_notify(details->agents[i], NOTIFY_SAVE_AGENT, NULL); if (details->is_frame) controltype_frame_saveplugins(c); break; case NOTIFY_DRAGACCEPT: DragAcceptFiles(c->windowptr->hwnd, NULL != details->agents[CONTROLTYPE_LABEL_AGENT_ONDROP]); break; } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //agenttype_graph_notify //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void agenttype_graph_notify(agent *a, int notifytype, void *messagedata) { //Get the agent details agenttype_graph_details *details = (agenttype_graph_details *) a->agentdetails; styledrawinfo *di; HPEN hpen; HGDIOBJ oldobj; int offset_left; int width; int offset_top; int offset_bottom; int height; int currenty; int xoffset; double *currentvalue; double finalvalue; switch (notifytype) { case NOTIFY_TIMER: //Get the current value currentvalue = (double *) agent_getdata(details->agents[AGENTTYPE_GRAPH_AGENT_VALUE], DATAFETCH_VALUE_SCALE); finalvalue = (currentvalue == NULL || *currentvalue < 0.0 || *currentvalue > 1.0 ? 0.0 : *currentvalue); //Store this value in the value history details->historyindex++; if (details->historyindex == AGENTTYPE_GRAPH_HISTORYLENGTH) details->historyindex = 0; details->valuehistory[details->historyindex] = finalvalue; //Notify the control it is time to redraw control_notify(a->controlptr, NOTIFY_NEEDUPDATE, NULL); break; case NOTIFY_DRAW: //Get set up for drawing the graph di = (styledrawinfo *) messagedata; hpen = CreatePen(PS_SOLID, 1, style_get_text_color(STYLETYPE_TOOLBAR)); oldobj = SelectObject(di->buffer, hpen); //Prepare some variables for convenience offset_left = di->rect.left + 2; width = di->rect.right - di->rect.left - 4; offset_top = di->rect.top + 2; offset_bottom = di->rect.bottom - 2; height = di->rect.bottom - di->rect.top - 4; //Make sure we have a large enough area if (width > 2 && height > 2) { //Draw the graph int currenthistoryindex = details->historyindex; if (details->charttype == AGENTTYPE_GRAPH_CHARTTYPE_FILL) { for (int currentx = width; currentx >= offset_left; currentx--) { currenty = offset_bottom - (height*details->valuehistory[currenthistoryindex]); MoveToEx(di->buffer, currentx, offset_bottom, NULL); LineTo(di->buffer, currentx, currenty); currenthistoryindex--; if (currenthistoryindex < 0) currenthistoryindex = AGENTTYPE_GRAPH_HISTORYLENGTH - 1; } } else if (details->charttype == AGENTTYPE_GRAPH_CHARTTYPE_LINE) { currenty = offset_bottom - (height*details->valuehistory[currenthistoryindex]); for (int currentx = width; currentx >= offset_left; currentx--) { MoveToEx(di->buffer, currentx, currenty, NULL); currenty = offset_bottom - (height*details->valuehistory[currenthistoryindex]); LineTo(di->buffer, currentx-1, currenty); currenthistoryindex--; if (currenthistoryindex < 0) currenthistoryindex = AGENTTYPE_GRAPH_HISTORYLENGTH - 1; } } } //Cleanup SelectObject(di->buffer, oldobj); DeleteObject(hpen); break; case NOTIFY_SAVE_AGENT: //Write existance config_write(config_get_control_setagent_c(a->controlptr, a->agentaction, a->agenttypeptr->agenttypename, agenttype_graph_charttypes[details->charttype])); //Save all child agents, if necessary for (int i = 0; i < AGENTTYPE_GRAPH_AGENTCOUNT; i++) agent_notify(details->agents[i], NOTIFY_SAVE_AGENT, NULL); break; } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //agenttype_compoundtext_getdata //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void *agenttype_compoundtext_getdata(agent *a, int datatype) { if (datatype == DATAFETCH_VALUE_TEXT) { //Get the details agenttype_compoundtext_details *details; details = (agenttype_compoundtext_details *) a->agentdetails; //Copy the characters of the text to the final output string int charindex = 0; char *currentoutput = details->finaltext; int agentindex = 0; while (details->text[charindex] != '\0') { //If we hit a $ if (details->text[charindex] == '$') { //If we have an agent if (agentindex < AGENTTYPE_COMPOUNDTEXT_MAXAGENTS && details->agents[agentindex] != NULL) { char *agenttext = (char *) agent_getdata(details->agents[agentindex], DATAFETCH_VALUE_TEXT); strcpy(currentoutput, agenttext); currentoutput += strlen(agenttext); } else { strcpy(currentoutput, "[?]"); currentoutput += 3; } agentindex++; } else { currentoutput[0] = details->text[charindex]; currentoutput += 1; } charindex++; } //End the string currentoutput[0] = '\0'; return details->finaltext; } else if (datatype == DATAFETCH_SUBAGENTS_NAMES_ARRAY) { return agenttype_compoundtext_agentdescriptions; } else if (datatype == DATAFETCH_SUBAGENTS_POINTERS_ARRAY) { agenttype_compoundtext_details *details; details = (agenttype_compoundtext_details *) a->agentdetails; return details->agents; } else if (datatype == DATAFETCH_SUBAGENTS_TYPES_ARRAY) { return (void *) agenttype_compoundtext_agenttypes; } else if (datatype == DATAFETCH_SUBAGENTS_COUNT) { return (void *) &agenttype_compoundtext_subagentcount; } return NULL; }