Example #1
0
/*****************************************************************************
 * Function:	_DtCanvasProcessSelection()
 *
 * Purpose:	Indicate an new point for a selection.
 *
 *****************************************************************************/
void
_DtCanvasProcessSelection (
    _DtCvHandle		canvas_handle,
    _DtCvUnit		x,
    _DtCvUnit		y,
    _DtCvSelectMode	mode)
{
    int			 i;
    _DtCanvasStruct	*canvas = (_DtCanvasStruct *) canvas_handle;
    _DtCvSelectData	 temp;

    switch (mode)
	  {
	case _DtCvSELECTION_CLEAR:
		CheckAndSwitchPoints(&(canvas->select_start),
							&(canvas->select_end));

	case _DtCvSELECTION_START:
		_DtCvDrawAreaWithFlags(canvas, canvas->select_start,
				canvas->select_end,
				_DtCvSELECTED_FLAG, 0,
				_DtCvBAD_TYPE, NULL);

		canvas->select_start = defaultSelect;
		if (mode == _DtCvSELECTION_START)
		    SearchForClosestLine(canvas, x, y, &(canvas->select_start));

		canvas->select_end   = canvas->select_start;
		break;

	case _DtCvSELECTION_END:
	case _DtCvSELECTION_UPDATE:
		SearchForClosestLine(canvas, x, y, &temp);

		AdjustSelection (canvas, temp);
		if (mode == _DtCvSELECTION_END)
		    CheckAndSwitchPoints(&(canvas->select_start),
							&(canvas->select_end));
		break;
      }
}
Example #2
0
/*****************************************************************************
 * Function: AdjustSelection
 *
 *****************************************************************************/
static	void
AdjustSelection (
    _DtCanvasStruct	*canvas,
    _DtCvSelectData next)
{
    _DtCvSelectData  start = canvas->select_start;
    _DtCvSelectData  end   = canvas->select_end;

    if (!(Equal(next, end)))
      {
	if (next.line_idx != -1 && next.line_idx == canvas->select_end.line_idx
		&&
	    next.char_idx != -1 && next.char_idx == canvas->select_end.char_idx)
	    return;

	if (GreaterThan(next, end))
	  {
	    if (LessThanEq(start, end))
		_DtCvDrawAreaWithFlags (canvas, end, next,
						0, _DtCvSELECTED_FLAG,
						_DtCvBAD_TYPE, NULL);

	    else if (GreaterThanEq(start, next))
		_DtCvDrawAreaWithFlags (canvas, end, next,
						_DtCvSELECTED_FLAG, 0,
						_DtCvBAD_TYPE, NULL);

	    else /* end < start < next */
	      {
		_DtCvDrawAreaWithFlags (canvas, end  , start,
						_DtCvSELECTED_FLAG, 0,
						_DtCvBAD_TYPE, NULL);
		_DtCvDrawAreaWithFlags (canvas, start, next ,
						0, _DtCvSELECTED_FLAG,
						_DtCvBAD_TYPE, NULL);
	      }
	  }
	else /* if (next < end) */
	  {
	    if (LessThanEq(start, next))
		_DtCvDrawAreaWithFlags (canvas, next, end,
						_DtCvSELECTED_FLAG, 0,
						_DtCvBAD_TYPE, NULL);

	    else if (GreaterThanEq(start, end))
		_DtCvDrawAreaWithFlags (canvas, next, end,
						0, _DtCvSELECTED_FLAG,
						_DtCvBAD_TYPE, NULL);

	    else /* next < start < end */
	      {
		_DtCvDrawAreaWithFlags (canvas, start, end  ,
						_DtCvSELECTED_FLAG, 0,
						_DtCvBAD_TYPE, NULL);
		_DtCvDrawAreaWithFlags (canvas, next , start,
						0, _DtCvSELECTED_FLAG,
						_DtCvBAD_TYPE, NULL);
	      }
	  }
      }

    canvas->select_end = next;
}
Example #3
0
/*****************************************************************************
 * Function:	_DtCanvasActivatePts()
 *
 * Purpose:	Activate the points given.
 *
 *****************************************************************************/
_DtCvStatus
_DtCanvasActivatePts (
    _DtCvHandle		 canvas_handle,
    unsigned int	 mask,
    _DtCvPointInfo	*info,
    _DtCvUnit		*ret_y1,
    _DtCvUnit		*ret_y2)
{
    int			 markIdx;
    _DtCanvasStruct	*canvas = (_DtCanvasStruct *) canvas_handle;
    _DtCvSelectData	 startSel = defaultSelect;
    _DtCvSelectData	 endSel   = defaultSelect;
    _DtCvFlags		 flag;
    _DtCvSegmentI	*firstSeg;

#define	REQUIRE_SEGS \
		(_DtCvACTIVATE_MARK | _DtCvACTIVATE_SELECTION)
    /*
     * check to see if there is anything to do
     */
    if (0 == mask)
	return _DtCvSTATUS_NONE;

    if ((mask & _DtCvACTIVATE_MARK) && (mask & _DtCvDEACTIVATE))
	return _DtCvSTATUS_BAD;

    /*
     * Convert the segments into starting and ending positions.
     */
    if (((mask & _DtCvDEACTIVATE) && NULL == info->client_data)
		|| (mask & REQUIRE_SEGS))
      {
	if (NULL == info || NULL == info->segs ||
		_DtCvSTATUS_BAD == _DtCvCvtSegsToPts(canvas, info->segs,
						&startSel, &endSel,
						ret_y1, ret_y2, &firstSeg))
	    return _DtCvSTATUS_BAD;
      }

    /*
     * Activate as a selection
     */
    if (mask & _DtCvACTIVATE_SELECTION)
      {
	_DtCanvasProcessSelection (canvas_handle, 0, 0, _DtCvSELECTION_CLEAR);

	canvas->select_start = startSel;
	canvas->select_end   = endSel;

	_DtCvDrawAreaWithFlags (canvas, startSel, endSel,
						0, _DtCvSELECTED_FLAG,
						_DtCvBAD_TYPE, NULL);
      }

    /*
     * Activate as a mark
     */
    if (mask & _DtCvACTIVATE_MARK)
      {
	int		travIdx;
	_DtCvUnit	x;
	_DtCvUnit	y;
	_DtCvUnit	width;
	_DtCvUnit	height;

	markIdx = _DtCvAddToMarkList(canvas, info->client_data,
				_DtCvIsMarkMaskOn(mask), &startSel, &endSel);
	if (-1 == markIdx)
	    return _DtCvSTATUS_BAD;

	/*
	 * now put the mark in the traversal list and merge it into the
	 * proper place.
	 */
	travIdx = _DtCvGetNextTravEntry(canvas);
	if (-1 == travIdx
		|| 0 != _DtCvSetTravEntryInfo(canvas, travIdx,
						_DtCvTraversalMark, firstSeg,
						markIdx, _DtCvTRUE)
		|| 0 != _DtCvCalcMarkPos(canvas, markIdx,
						&x, &y, &width, &height)
		|| 0 != _DtCvSetTravEntryPos(canvas, travIdx,
						x, y, width, height))
	    return _DtCvSTATUS_BAD;

	_DtCvSortTraversalList(canvas, _DtCvTRUE);

	/*
	 * draw these segments marked.
	 */
	flag = _DtCvMARK_FLAG;
	if (_DtCvTRUE == canvas->marks[markIdx].on)
	    flag |= _DtCvMARK_ON;

	_DtCvDrawAreaWithFlags (canvas, startSel, endSel,
							0, flag,
							_DtCvBAD_TYPE, NULL);
      }

    /*
     * Clear the mark flag.
     */
    else if (mask & _DtCvDEACTIVATE)
      {
	int	travIdx;

	/*
	 * is there anything to deacivate?
	 */
	if (NULL == canvas->marks || 0 == canvas->mark_cnt)
	    return _DtCvSTATUS_BAD;

	/*
	 * was client data specified? If so, then look for it and ignore
	 * the segment data.
	 */
	markIdx = 0;
	if (NULL != info->client_data)
	  {
	    while (markIdx < canvas->mark_cnt &&
		   canvas->marks[markIdx].client_data != info->client_data)
		markIdx++;

	    /*
	     * initialize the selection points
	     */
	    if (markIdx < canvas->mark_cnt)
	      {
		startSel = canvas->marks[markIdx].beg;
		endSel   = canvas->marks[markIdx].end;
	      }
	  }
	/*
	 * look for the marked set using the segments.
	 */
	else
	  {
	    while (markIdx < canvas->mark_cnt
		   && startSel.line_idx != canvas->marks[markIdx].beg.line_idx
		   && startSel.char_idx != canvas->marks[markIdx].beg.char_idx
		   && endSel.line_idx != canvas->marks[markIdx].end.line_idx
		   && endSel.line_idx != canvas->marks[markIdx].end.char_idx)
		markIdx++;
	  }

	if (markIdx >= canvas->mark_cnt)
	    return _DtCvSTATUS_BAD;

	/*
	 * draw these segments unmarked.
	 */
	flag = _DtCvMARK_FLAG;
	if (_DtCvTRUE == canvas->marks[markIdx].on)
	    flag |= _DtCvMARK_ON;

	canvas->marks[markIdx].on = _DtCvFALSE;
	_DtCvDrawAreaWithFlags (canvas, startSel, endSel, flag, 0,
						_DtCvBAD_TYPE, NULL);

	/*
	 * remove the mark from the traversal list
	 *
	 * first find the traversal entry of the mark and adjust any
	 * traversal mark index values to reflect that the mark
	 * list is about to shrink by 1.
	 */
	for (travIdx = 0; _DtCvTraversalMark != canvas->trav_lst[travIdx].type
			|| markIdx != canvas->trav_lst[travIdx].idx; travIdx++)
	  {
	    /*
	     * is this mark after the one being removed?
	     * if so, decrease its index because it's about to move.
	     */
	    if (_DtCvTraversalMark == canvas->trav_lst[travIdx].type &&
					markIdx < canvas->trav_lst[travIdx].idx)
		canvas->trav_lst[travIdx].idx--;
	  }

	/*
	 * move the list of traversal entries to eliminate the mark entry.
	 */
	while (travIdx + 1 < canvas->trav_cnt)
	  {
	    canvas->trav_lst[travIdx] = canvas->trav_lst[travIdx + 1];

	    /*
	     * is this a mark after the one being removed?
	     * if so, decrease it's index because it's about to move.
	     */
	    if (_DtCvTraversalMark == canvas->trav_lst[travIdx].type &&
					markIdx < canvas->trav_lst[travIdx].idx)
		canvas->trav_lst[travIdx].idx--;

	    travIdx++;
	  }

	/*
	 * update the traversal count and back up to the previous traversal
	 * if the mark was at the end of the traversal list.
	 */
	canvas->trav_cnt--;
	if (canvas->cur_trav >= canvas->trav_cnt)
	    canvas->cur_trav--;

	/*
	 * move the list of marks up
	 */
	while (markIdx + 1 < canvas->mark_cnt)
	  {
	    canvas->marks[markIdx] = canvas->marks[markIdx + 1];
	    markIdx++;
	  }

	canvas->mark_cnt--;
      }
    else if ((_DtCvACTIVATE_MARK_ON | _DtCvACTIVATE_MARK_OFF) & mask)
      {
	markIdx = 0;
	if (NULL != info && NULL != info->client_data)
	  {
	    while (markIdx < canvas->mark_cnt &&
		   canvas->marks[markIdx].client_data != info->client_data)
		markIdx++;

	    /*
	     * was a mark with this client data found?
	     */
	    if (markIdx >= canvas->mark_cnt)
	        return _DtCvSTATUS_BAD;
	  }
	else
	  {
	    /*
	     * are there any traversals? Is the current one sitting on a mark?
	     */
	    if (0 == canvas->trav_cnt || -1 == canvas->cur_trav ||
		_DtCvTraversalMark != canvas->trav_lst[canvas->cur_trav].type)
	        return _DtCvSTATUS_BAD;

	    /*
	     * get the mark index
	     */
	    markIdx = canvas->trav_lst[canvas->cur_trav].idx;
	  }

	/*
	 * is this different than what it is set at now? If not, do nothing.
	 */
	if (_DtCvIsMarkMaskOn(mask) == canvas->marks[markIdx].on)
	    return _DtCvSTATUS_NONE;

	/*
	 * set to mask value.
	 */
	canvas->marks[markIdx].on = _DtCvIsMarkMaskOn(mask);

	/*
	 * set the flags correctly.
	 */
	flag = _DtCvMARK_FLAG;
	if (_DtCvTRUE == canvas->marks[markIdx].on)
	    flag |= _DtCvMARK_ON;
	if (_DtCvTRUE == canvas->trav_on &&
			markIdx == canvas->trav_lst[canvas->cur_trav].idx)
	    flag |= _DtCvTRAVERSAL_FLAG;

	/*
	 * draw the mark opposite what it was
	 */
	_DtCvDrawAreaWithFlags (canvas, canvas->marks[markIdx].beg,
				canvas->marks[markIdx].end,
				(flag ^ _DtCvMARK_ON), flag,
				_DtCvBAD_TYPE, NULL);
      }

    return _DtCvSTATUS_OK;
}