<commit_before>/*  $Id$

    Part of XPCE
    Designed and implemented by <NAME> and <NAME>
    E-mail: <EMAIL>

    Copyright (C) 1992 University of Amsterdam. All rights reserved.
*/

#include <h/kernel.h>
#include <h/graphics.h>
#include <h/layout.h>

NewClass(resize_table_slice_gesture)
  ABSTRACT_GESTURE
  Name	mode;				/* column,row */
  Int	row;				/* Number of the row */
  Int	column;				/* Number of the column */
End;


status
initialiseResizeTableSliceGesture(ResizeTableSliceGesture g, Name mode,
				  Name button, Modifier modifier)
{ initialiseGesture((Gesture) g, button, modifier);

  assign(g, mode, mode);

  succeed;
}


		/********************************
		*       GESTURE BEHAVIOUR	*
		********************************/

static Table
getTableFromEvent(EventObj ev)
{ Device dev = (Device)ev->receiver;
  Table tab;

  if ( !instanceOfObject(dev, ClassDevice) ||
       !instanceOfObject((tab=(Table)dev->layout_manager), ClassTable) )
    fail;

  return tab;       
}


static status
verifyResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ int frac = valInt(getClassVariableValueObject(g, NAME_marginFraction));
  int mx   = valInt(getClassVariableValueObject(g, NAME_marginWidth));
  Int X, Y;
  int ex, ey;
  int x, y, w, h;
  Table tab;
  Any down;
  int cn, rn;
  TableRow row;
  TableColumn col;

  if ( !(tab = getTableFromEvent(ev)) ||
       !(down = getCellFromPositionTable(tab, ev)) )
    fail;

  if ( instanceOfObject(down, ClassTableCell) )
  { TableCell cell = down;

    if ( isNil(cell->column) || isNil(cell->row) )
      fail;

    cn = valInt(cell->column);
    rn = valInt(cell->row);
  } else
  { Point pt = down;

    cn = valInt(pt->x);
    rn = valInt(pt->y);
  }

  row = getRowTable(tab,    toInt(rn), ON); /* play safe */
  col = getColumnTable(tab, toInt(cn), ON); /* play safe */

  get_xy_event(ev, ev->receiver, ON, &X, &Y);
  ex = valInt(X), ey = valInt(Y);
  x = valInt(col->position);
  y = valInt(row->position);
  w = valInt(col->width);
  h = valInt(row->width);

  assign(g, row, NIL);			/* play safe */
  assign(g, column, NIL);

  if ( g->mode == NAME_column )
  { if ( ex < x+w/frac && ex < x+mx )	/* determine horizontal-mode */
      assign(g, column, toInt(cn-1));
    else if ( ex > x+((frac-1) * w)/frac && ex > x + w - mx )
      assign(g, column, toInt(cn));
    else
      fail;
  } else /* if ( g->mode == NAME_row ) */
  { if ( ey < y+h/frac && ey < y+mx )	/* determine vertical-mode */
      assign(g, row, toInt(rn-1));
    else if ( ey > y+((frac-1) * h)/frac && ey > y + h - mx )
      assign(g, row, toInt(rn));
    else
      fail;
  }

  succeed;
}

		/********************************
		*           INITIATE		*
		********************************/

static status
setCursorResizeTableSliceGesture(ResizeTableSliceGesture g, PceWindow sw)
{ Any av[1];

  if ( g->mode == NAME_column )
    av[0] = NAME_sbHDoubleArrow;
  else
    av[0] = NAME_sbVDoubleArrow;

  return sendv(sw, NAME_focusCursor, 1, av);
}


static status
setPointerResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ Table tab;

  if ( (tab=getTableFromEvent(ev)) )
  { Int cx, cy;
    Int px = ZERO, py = ZERO;	/* keep compiler happy */
    Point pos;
  
    get_xy_event(ev, ev->receiver, ON, &cx, &cy);

    if ( g->mode == NAME_column )
    { TableColumn col = getColumnTable(tab, g->column, ON);
      
      px = add(col->position, col->width);
      py = cy;
    } else
    { TableRow row = getRowTable(tab, g->row, ON);

      py = add(row->position, row->width);
      px = cx;
    }
    
    pos = tempObject(ClassPoint, px, py, 0);
    pointerGraphical(ev->receiver, pos);
    considerPreserveObject(pos);

    succeed;
  }

  fail;
}


static status
initiateResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ setCursorResizeTableSliceGesture(g, ev->window);
  setPointerResizeTableSliceGesture(g, ev);

  succeed;
}


static status
dragResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ Table tab;

  if ( (tab = getTableFromEvent(ev)) )
  { Int cx, cy;

    get_xy_event(ev, ev->receiver, ON, &cx, &cy);
    
    if ( g->mode == NAME_column )
    { TableColumn col = getColumnTable(tab, g->column, ON);
      int nw = valInt(cx) - valInt(col->position);

      nw = max(0, nw);
      send(col, NAME_width, toInt(nw), 0);
    } else
    { TableRow row = getRowTable(tab, g->row, ON);
      int nh = valInt(cy) - valInt(row->position);

      nh = max(0, nh);
      send(row, NAME_height, toInt(nh), 0);
    }

    succeed;
  }

  fail;
}


static status
terminateResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ return dragResizeTableSliceGesture(g, ev);
}


		 /*******************************
		 *	 CLASS DECLARATION	*
		 *******************************/

/* Type declarations */

static char *T_initialise[] =
	{ "mode=[{row,column}]",
	  "button=[button_name]",
	  "modifier=[modifier]"
	};
<commit_msg>* Check for first/last column<commit_after>/*  $Id$

    Part of XPCE
    Designed and implemented by <NAME> and <NAME>
    E-mail: <EMAIL>

    Copyright (C) 1992 University of Amsterdam. All rights reserved.
*/

#include <h/kernel.h>
#include <h/graphics.h>
#include <h/layout.h>

NewClass(resize_table_slice_gesture)
  ABSTRACT_GESTURE
  Name	mode;				/* column,row */
  Int	row;				/* Number of the row */
  Int	column;				/* Number of the column */
End;


status
initialiseResizeTableSliceGesture(ResizeTableSliceGesture g, Name mode,
				  Name button, Modifier modifier)
{ initialiseGesture((Gesture) g, button, modifier);

  assign(g, mode, mode);

  succeed;
}


		/********************************
		*       GESTURE BEHAVIOUR	*
		********************************/

static Table
getTableFromEvent(EventObj ev)
{ Device dev = (Device)ev->receiver;
  Table tab;

  if ( !instanceOfObject(dev, ClassDevice) ||
       !instanceOfObject((tab=(Table)dev->layout_manager), ClassTable) )
    fail;

  return tab;       
}


static status
verifyResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ int frac = valInt(getClassVariableValueObject(g, NAME_marginFraction));
  int mx   = valInt(getClassVariableValueObject(g, NAME_marginWidth));
  Int X, Y;
  int ex, ey;
  int x, y, w, h;
  Table tab;
  Any down;
  int cn, rn;
  TableRow row;
  TableColumn col;

  if ( !(tab = getTableFromEvent(ev)) ||
       !(down = getCellFromPositionTable(tab, ev)) )
    fail;

  if ( instanceOfObject(down, ClassTableCell) )
  { TableCell cell = down;

    if ( isNil(cell->column) || isNil(cell->row) )
      fail;

    cn = valInt(cell->column);
    rn = valInt(cell->row);
  } else
  { Point pt = down;

    cn = valInt(pt->x);
    rn = valInt(pt->y);
  }

  row = getRowTable(tab,    toInt(rn), ON); /* play safe */
  col = getColumnTable(tab, toInt(cn), ON); /* play safe */

  get_xy_event(ev, ev->receiver, ON, &X, &Y);
  ex = valInt(X), ey = valInt(Y);
  x = valInt(col->position);
  y = valInt(row->position);
  w = valInt(col->width);
  h = valInt(row->width);

  assign(g, row, NIL);			/* play safe */
  assign(g, column, NIL);

  if ( g->mode == NAME_column )
  { if ( ex < x+w/frac && ex < x+mx )	/* determine horizontal-mode */
    { int cmin, cmax;

      table_column_range(tab, &cmin, &cmax);
      if ( cn <= cmin )
	fail;
      assign(g, column, toInt(cn-1));
    } else if ( ex > x+((frac-1) * w)/frac && ex > x + w - mx )
    { assign(g, column, toInt(cn));
    } else
      fail;
  } else /* if ( g->mode == NAME_row ) */
  { if ( ey < y+h/frac && ey < y+mx )	/* determine vertical-mode */
    { int rmin, rmax;

      table_row_range(tab, &rmin, &rmax);
      if ( rn <= rmin )
	fail;
      assign(g, row, toInt(rn-1));
    } else if ( ey > y+((frac-1) * h)/frac && ey > y + h - mx )
    { assign(g, row, toInt(rn));
    } else
      fail;
  }

  succeed;
}

		/********************************
		*           INITIATE		*
		********************************/

static status
setCursorResizeTableSliceGesture(ResizeTableSliceGesture g, PceWindow sw)
{ Any av[1];

  if ( g->mode == NAME_column )
    av[0] = NAME_sbHDoubleArrow;
  else
    av[0] = NAME_sbVDoubleArrow;

  return sendv(sw, NAME_focusCursor, 1, av);
}


static status
setPointerResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ Table tab;

  if ( (tab=getTableFromEvent(ev)) )
  { Int cx, cy;
    Int px = ZERO, py = ZERO;	/* keep compiler happy */
    Point pos;
  
    get_xy_event(ev, ev->receiver, ON, &cx, &cy);

    if ( g->mode == NAME_column )
    { TableColumn col = getColumnTable(tab, g->column, ON);
      
      px = add(col->position, col->width);
      py = cy;
    } else
    { TableRow row = getRowTable(tab, g->row, ON);

      py = add(row->position, row->width);
      px = cx;
    }
    
    pos = tempObject(ClassPoint, px, py, 0);
    pointerGraphical(ev->receiver, pos);
    considerPreserveObject(pos);

    succeed;
  }

  fail;
}


static status
initiateResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ setCursorResizeTableSliceGesture(g, ev->window);
  setPointerResizeTableSliceGesture(g, ev);

  succeed;
}


static status
dragResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ Table tab;

  if ( (tab = getTableFromEvent(ev)) )
  { Int cx, cy;

    get_xy_event(ev, ev->receiver, ON, &cx, &cy);
    
    if ( g->mode == NAME_column )
    { TableColumn col = getColumnTable(tab, g->column, ON);
      int nw = valInt(cx) - valInt(col->position);

      nw = max(0, nw);
      send(tab, NAME_userResizeSlice, col, toInt(nw), 0);
    } else
    { TableRow row = getRowTable(tab, g->row, ON);
      int nh = valInt(cy) - valInt(row->position);

      nh = max(0, nh);
      send(tab, NAME_userResizeSlice, row, toInt(nh), 0);
    }

    succeed;
  }

  fail;
}


static status
terminateResizeTableSliceGesture(ResizeTableSliceGesture g, EventObj ev)
{ return dragResizeTableSliceGesture(g, ev);
}


		 /*******************************
		 *	 CLASS DECLARATION	*
		 *******************************/

/* Type declarations */

static char *T_initialise[] =
	{ "mode=[{row,column}]",
	  "button=[button_name]",
	  "modifier=[modifier]"
	};

{'fraction_non_alphanumeric': 0.17964898442121868, 'fraction_numerical': 0.0033523959771248274, 'mean_word_length': 3.160377358490566, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2350636', 'n_tokens_mistral': 3813, 'n_tokens_neox': 3630, 'n_words': 850}