/** @file
This contains the high-level commands for transitioning between the different annotation tool states. They are: REST, DRAW, SELECTED, QUERY.
*/
// Handles all of the user's actions and delegates tasks to other classes.
// Also keeps track of global information.
var REST_CANVAS = 1;
var DRAW_CANVAS = 2;
var SELECTED_CANVAS = 3;
var QUERY_CANVAS = 4;
// Global variable indicating which canvas is active:
var active_canvas = REST_CANVAS;
function handler() {
// *******************************************
// Public methods:
// *******************************************
// Handles when the user presses the delete button in response to
// the "What is this object?" popup bubble.
this.WhatIsThisObjectDeleteButton = function () {
submission_edited = 0;
this.QueryToRest();
};
// Submits the object label in response to the edit/delete popup bubble.
this.SubmitEditLabel = function () {
submission_edited = 1;
var anno = select_anno;
// object name
old_name = LMgetObjectField(LM_xml,anno.anno_id,'name');
if(document.getElementById('objEnter')) new_name = RemoveSpecialChars(document.getElementById('objEnter').value);
else new_name = RemoveSpecialChars(adjust_objEnter);
var re = /[a-zA-Z0-9]/;
if(!re.test(new_name)) {
alert('Please enter an object name');
return;
}
if (use_attributes) {
// occlusion field
if (document.getElementById('occluded')) new_occluded = RemoveSpecialChars(document.getElementById('occluded').value);
else new_occluded = RemoveSpecialChars(adjust_occluded);
// attributes field
if(document.getElementById('attributes')) new_attributes = RemoveSpecialChars(document.getElementById('attributes').value);
else new_attributes = RemoveSpecialChars(adjust_attributes);
}
StopEditEvent();
// Insert data to write to logfile:
if(editedControlPoints) InsertServerLogData('cpts_modified');
else InsertServerLogData('cpts_not_modified');
// Object index:
var obj_ndx = anno.anno_id;
// Pointer to object:
var curr_obj = $(LM_xml).children("annotation").children("object").eq(obj_ndx);
// Set fields:
curr_obj.children("name").text(new_name);
if(curr_obj.children("automatic").length > 0) curr_obj.children("automatic").text("0");
// Insert attributes (and create field if it is not there):
if(curr_obj.children("attributes").length>0) curr_obj.children("attributes").text(new_attributes);
else curr_obj.append("<attributes>" + new_attributes + "</attributes>");
if(curr_obj.children("occluded").length>0) curr_obj.children("occluded").text(new_occluded);
else curr_obj.append("<occluded>" + new_occluded + "</occluded>");
if(editedControlPoints) {
for(var jj=0; jj < AllAnnotations[obj_ndx].GetPtsX().length; jj++) {
curr_obj.children("polygon").children("pt").eq(jj).children("x").text(AllAnnotations[obj_ndx].GetPtsX()[jj]);
curr_obj.children("polygon").children("pt").eq(jj).children("y").text(AllAnnotations[obj_ndx].GetPtsY()[jj]);
}
}
// Write XML to server:
WriteXML(SubmitXmlUrl,LM_xml,function(){return;});
// Refresh object list:
if(view_ObjList) {
RenderObjectList();
ChangeLinkColorFG(anno.GetAnnoID());
}
};
// Handles when the user presses the delete button in response to
// the edit popup bubble.
this.EditBubbleDeleteButton = function () {
var idx = select_anno.GetAnnoID();
if((IsUserAnonymous() || (!IsCreator(select_anno.GetUsername()))) && (!IsUserAdmin()) && (idx<num_orig_anno) && !action_DeleteExistingObjects) {
alert('You do not have permission to delete this polygon');
return;
}
if(idx>=num_orig_anno) {
global_count--;
}
submission_edited = 0;
// Insert data for server logfile:
old_name = LMgetObjectField(LM_xml,select_anno.anno_id,'name');
new_name = old_name;
WriteLogMsg('*Deleting_object');
InsertServerLogData('cpts_not_modified');
// Set <deleted> in LM_xml:
$(LM_xml).children("annotation").children("object").eq(idx).children("deleted").text('1');
// Remove all the part dependencies for the deleted object
removeAllParts(idx);
// Write XML to server:
WriteXML(SubmitXmlUrl,LM_xml,function(){return;});
// Refresh object list:
if(view_ObjList) RenderObjectList();
unselectObjects(); // Perhaps this should go elsewhere...
StopEditEvent();
};
// Handles when the user clicks on the link for an annotation.
this.AnnotationLinkClick = function (idx) {
if(active_canvas==REST_CANVAS) StartEditEvent(idx,null);
else if(active_canvas==SELECTED_CANVAS) {
var anno_id = select_anno.GetAnnoID();
if(edit_popup_open && (idx==anno_id)) StopEditEvent();
}
};
// Handles when the user moves the mouse over an annotation link.
this.AnnotationLinkMouseOver = function (a) {
if(active_canvas!=SELECTED_CANVAS) selectObject(a);
};
// Handles when the user moves the mouse away from an annotation link.
this.AnnotationLinkMouseOut = function () {
if(active_canvas!=SELECTED_CANVAS) unselectObjects();
};
// Handles when the user moves the mouse over a polygon on the drawing
// canvas.
this.CanvasMouseMove = function (event,pp) {
var x = GetEventPosX(event);
var y = GetEventPosY(event);
if(IsNearPolygon(x,y,pp)) selectObject(pp);
else unselectObjects();
};
// Submits the object label in response to the "What is this object?"
// popup bubble. THIS FUNCTION IS A MESS!!!!
this.SubmitQuery = function () {
var nn;
var anno;
// If the attributes are active, read the fields.
if (use_attributes) {
// get attributes (is the field exists)
if(document.getElementById('attributes')) new_attributes = RemoveSpecialChars(document.getElementById('attributes').value);
else new_attributes = "";
// get occlusion field (is the field exists)
if (document.getElementById('occluded')) new_occluded = RemoveSpecialChars(document.getElementById('occluded').value);
else new_occluded = "";
}
if((object_choices!='...') && (object_choices.length==1)) {
nn = RemoveSpecialChars(object_choices[0]);
active_canvas = REST_CANVAS;
// Move draw canvas to the back:
document.getElementById('draw_canvas').style.zIndex = -2;
document.getElementById('draw_canvas_div').style.zIndex = -2;
// Remove polygon from the draw canvas:
var anno = null;
if(draw_anno) {
draw_anno.DeletePolygon();
anno = draw_anno;
draw_anno = null;
}
}
else {
nn = RemoveSpecialChars(document.getElementById('objEnter').value);
anno = this.QueryToRest();
}
var re = /[a-zA-Z0-9]/;
if(!re.test(nn)) {
alert('Please enter an object name');
return;
}
// Update old and new object names for logfile:
new_name = nn;
old_name = nn;
submission_edited = 0;
global_count++;
// Insert data for server logfile:
InsertServerLogData('cpts_not_modified');
// Insert data into XML:
var html_str = '<object>';
html_str += '<name>' + new_name + '</name>';
html_str += '<deleted>0</deleted>';
html_str += '<verified>0</verified>';
if(use_attributes) {
html_str += '<occluded>' + new_occluded + '</occluded>';
html_str += '<attributes>' + new_attributes + '</attributes>';
}
html_str += '<parts><hasparts></hasparts><ispartof></ispartof></parts>';
var ts = GetTimeStamp();
if(ts.length==20) html_str += '<date>' + ts + '</date>';
html_str += '<id>' + anno.anno_id + '</id>';
if(anno.GetType() == 1) {
/*************************************************************/
/*************************************************************/
// Scribble: Add annotation to LM_xml:
html_str += '<segm>';
html_str += '<username>' + username + '</username>';
html_str += '<box>';
html_str += '<xmin>' + anno.GetPtsX()[0] + '</xmin>';
html_str += '<ymin>' + anno.GetPtsY()[0] + '</ymin>';
html_str += '<xmax>' + anno.GetPtsX()[1] + '</xmax>';
html_str += '<ymax>' + anno.GetPtsY()[2] + '</ymax>';
html_str += '</box>';
html_str += '<mask>'+ anno.GetImName()+'</mask>';
html_str += '<scribbles>';
html_str += '<xmin>' + anno.GetCornerLX() + '</xmin>';
html_str += '<ymin>' + anno.GetCornerLY() + '</ymin>';
html_str += '<xmax>' + anno.GetCornerRX() + '</xmax>';
html_str += '<ymax>' + anno.GetCornerRY() + '</ymax>';
html_str += '<scribble_name>'+ anno.GetScribbleName()+'</scribble_name>';
html_str += '</scribbles>';
html_str += '</segm>';
html_str += '</object>';
$(LM_xml).children("annotation").append($(html_str));
/*************************************************************/
/*************************************************************/
}
else {
html_str += '<polygon>';
html_str += '<username>' + username + '</username>';
for(var jj=0; jj < anno.GetPtsX().length; jj++) {
html_str += '<pt>';
html_str += '<x>' + anno.GetPtsX()[jj] + '</x>';
html_str += '<y>' + anno.GetPtsY()[jj] + '</y>';
html_str += '</pt>';
}
html_str += '</polygon>';
html_str += '</object>';
$(LM_xml).children("annotation").append($(html_str));
}
AllAnnotations.push(anno);
if(!anno.GetDeleted()||view_Deleted) {
main_canvas.AttachAnnotation(anno);
anno.RenderAnnotation('rest');
}
/*************************************************************/
/*************************************************************/
// Scribble: Clean scribbles.
if(anno.GetType() == 1) {
scribble_canvas.cleanscribbles();
scribble_canvas.scribble_image = "";
scribble_canvas.colorseg = Math.floor(Math.random()*14);
}
/*************************************************************/
/*************************************************************/
// Write XML to server:
WriteXML(SubmitXmlUrl,LM_xml,function(){return;});
if(view_ObjList) RenderObjectList();
var m = main_media.GetFileInfo().GetMode();
if(m=='mt') {
document.getElementById('object_name').value=new_name;
document.getElementById('number_objects').value=global_count;
document.getElementById('LMurl').value = LMbaseurl + '?collection=LabelMe&mode=i&folder=' + main_media.GetFileInfo().GetDirName() + '&image=' + main_media.GetFileInfo().GetImName();
if(global_count >= mt_N) document.getElementById('mt_submit').disabled=false;
}
};
// Handles when we wish to change from "query" to "rest".
this.QueryToRest = function () {
active_canvas = REST_CANVAS;
// Move query canvas to the back:
document.getElementById('query_canvas').style.zIndex = -2;
document.getElementById('query_canvas_div').style.zIndex = -2;
// Remove polygon from the query canvas:
if(query_anno) query_anno.DeletePolygon();
var anno = query_anno;
query_anno = null;
CloseQueryPopup();
main_media.ScrollbarsOn();
return anno;
};
// Handles when the user presses a key while interacting with the tool.
this.KeyPress = function (event) {
// Delete event: 46 - delete key; 8 - backspace key
if(((event.keyCode==46) || (event.keyCode==8)) && !wait_for_input && !edit_popup_open && !username_flag) {
// Determine whether we are deleting a complete or partially
// complete polygon.
if(!main_handler.EraseSegment()) DeleteSelectedPolygon();
}
// 27 - Esc key
// Close edit popup if it is open.
if(event.keyCode==27 && edit_popup_open) StopEditEvent();
};
// Handles when the user erases a segment.
this.EraseSegment = function () {
if(draw_anno && !draw_anno.DeleteLastControlPoint()) {
submission_edited = 0;
StopDrawEvent();
}
return draw_anno;
};
// *******************************************
// Private methods:
// *******************************************
}