2017-04-25 14:41:48 +02:00
|
|
|
/* NMlabel.c -
|
|
|
|
|
*
|
|
|
|
|
* This file contains routines that handle the label portion
|
|
|
|
|
* of net-list menus. The routines do things like reading
|
|
|
|
|
* labels from the terminal, placing labels in the design,
|
|
|
|
|
* re-orienting label text, and incrementing numbers inside
|
|
|
|
|
* of labels.
|
|
|
|
|
*
|
2020-05-23 23:13:14 +02:00
|
|
|
* *********************************************************************
|
|
|
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
|
|
|
* * Permission to use, copy, modify, and distribute this *
|
|
|
|
|
* * software and its documentation for any purpose and without *
|
|
|
|
|
* * fee is hereby granted, provided that the above copyright *
|
|
|
|
|
* * notice appear in all copies. The University of California *
|
|
|
|
|
* * makes no representations about the suitability of this *
|
|
|
|
|
* * software for any purpose. It is provided "as is" without *
|
|
|
|
|
* * express or implied warranty. Export of this software outside *
|
|
|
|
|
* * of the United States of America may require an export license. *
|
2017-04-25 14:41:48 +02:00
|
|
|
* *********************************************************************
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef lint
|
|
|
|
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/netmenu/NMlabel.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
|
|
#include "utils/magic.h"
|
|
|
|
|
#include "utils/geometry.h"
|
|
|
|
|
#include "utils/utils.h"
|
|
|
|
|
#include "tiles/tile.h"
|
|
|
|
|
#include "utils/hash.h"
|
|
|
|
|
#include "database/database.h"
|
|
|
|
|
#include "windows/windows.h"
|
|
|
|
|
#include "utils/main.h"
|
|
|
|
|
#include "dbwind/dbwind.h"
|
|
|
|
|
#include "netmenu/nmInt.h"
|
|
|
|
|
#include "textio/textio.h"
|
|
|
|
|
#include "textio/txcommands.h"
|
|
|
|
|
#include "commands/commands.h"
|
|
|
|
|
#include "utils/styles.h"
|
|
|
|
|
#include "utils/malloc.h"
|
|
|
|
|
|
|
|
|
|
/* The user can enter several labels at once, so he doesn't have
|
|
|
|
|
* to keep going back and forth between the mouse and the keyboard.
|
|
|
|
|
* We store the labels in a big array. At any given time, only one
|
|
|
|
|
* of them is visible in the menu; only it can be placed in the
|
|
|
|
|
* design. There are menu buttons for going to the next or previous
|
|
|
|
|
* label.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define MAXLABELS 100
|
|
|
|
|
char * nmLabelArray[MAXLABELS]; /* Holds pointers to all labels
|
|
|
|
|
* entered together.
|
|
|
|
|
*/
|
|
|
|
|
int nmCurLabel; /* Index of current label. */
|
|
|
|
|
int nmNum1 = -1; /* First two numbers in current label. */
|
|
|
|
|
int nmNum2 = -1;
|
|
|
|
|
char nmNum1String[12]; /* String equivalents of nmNum1 and nmNum2. */
|
|
|
|
|
char nmNum2String[12];
|
|
|
|
|
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* nmGetNums --
|
|
|
|
|
*
|
|
|
|
|
* Picks one or two positive decimal numbers out of a string of text.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The string is scanned for positive decimal numbers. If any are
|
|
|
|
|
* found, the first one is put in num1 and the second one is put in
|
|
|
|
|
* num2. If there aren't two numbers, num1 and/or num2 will be
|
|
|
|
|
* set to -1. This routine ignores "-" signs, so the numbers are
|
|
|
|
|
* always positive.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nmGetNums(string, num1, num2)
|
|
|
|
|
char *string; /* String to scan. */
|
|
|
|
|
int *num1, *num2; /* Pointers to places to store numbers. */
|
|
|
|
|
{
|
|
|
|
|
char *p;
|
|
|
|
|
bool gotNum = FALSE;
|
|
|
|
|
bool gotDigit = FALSE;
|
|
|
|
|
int num = 0;
|
|
|
|
|
|
|
|
|
|
*num1 = *num2 = -1;
|
|
|
|
|
for (p = string; ; p++)
|
|
|
|
|
{
|
|
|
|
|
if (isdigit(*p))
|
|
|
|
|
{
|
|
|
|
|
num = (10*num) + *p - '0';
|
|
|
|
|
gotDigit = TRUE;
|
|
|
|
|
}
|
|
|
|
|
else if (gotDigit)
|
|
|
|
|
{
|
|
|
|
|
if (gotNum)
|
|
|
|
|
{
|
|
|
|
|
*num2 = num;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
*num1 = num;
|
|
|
|
|
gotDigit = FALSE;
|
|
|
|
|
gotNum = TRUE;
|
|
|
|
|
num = 0;
|
|
|
|
|
}
|
|
|
|
|
if (*p == 0) return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* nmPutNums --
|
|
|
|
|
*
|
|
|
|
|
* This routine generates a new string by replaces the first two
|
|
|
|
|
* numbers in an old string with new numbers.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* The return value is a pointer to a string that is identical
|
|
|
|
|
* to src, except that if there are decimal numbers in src, the
|
|
|
|
|
* first two of those are replaced with the string equivalents
|
|
|
|
|
* of num1 and num2. For example, if src is "bus[14,22]" and
|
|
|
|
|
* num1 is 3 and num2 is 177, the return value will be "bus[3,177]".
|
|
|
|
|
* Note: the result is a statically allocated string, so the
|
|
|
|
|
* caller should copy it before calling this routine again.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
nmPutNums(src, num1, num2)
|
|
|
|
|
char *src; /* String on which substitution is
|
|
|
|
|
* to be done. */
|
|
|
|
|
int num1, num2; /* Numbers to substitute. A number less
|
|
|
|
|
* than zero means keep the old value.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
static char *result = NULL;
|
|
|
|
|
static int resultLength = 0;
|
|
|
|
|
char num1String[12], num2String[12];
|
|
|
|
|
int spaceNeeded;
|
|
|
|
|
char *pSrc, *pResult;
|
|
|
|
|
|
|
|
|
|
/* First, translate the numbers into strings. Then, make sure
|
|
|
|
|
* we have enough space to store the result. Allocate a new
|
|
|
|
|
* result area if there isn't enough space. The space computation
|
|
|
|
|
* is a bit conservative, but simpler that way.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
(void) sprintf(num1String, "%d", num1);
|
|
|
|
|
(void) sprintf(num2String, "%d", num2);
|
|
|
|
|
spaceNeeded = strlen(num1String) + strlen(num2String) + strlen(src) + 1;
|
|
|
|
|
if (resultLength < spaceNeeded)
|
|
|
|
|
{
|
|
|
|
|
if (result != NULL) freeMagic(result);
|
|
|
|
|
result = mallocMagic((unsigned) spaceNeeded);
|
|
|
|
|
resultLength = spaceNeeded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now scan through the source string. Copy everything up
|
|
|
|
|
* to the first number into the result.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
pSrc = src;
|
|
|
|
|
pResult = result;
|
|
|
|
|
while (!isdigit(*pSrc))
|
|
|
|
|
if ((*pResult++ = *pSrc++) == 0) return result;
|
|
|
|
|
|
|
|
|
|
/* Now copy num1String into result and skip the number in
|
|
|
|
|
* the original string. Or, if num1 is less than zero,
|
|
|
|
|
* then just copy the number from src.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
if (num1 < 0)
|
|
|
|
|
{
|
|
|
|
|
while (isdigit(*pSrc)) *pResult++ = *pSrc++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
while (isdigit(*pSrc)) pSrc += 1;
|
|
|
|
|
(void) strcpy(pResult, num1String);
|
|
|
|
|
while (isdigit(*pResult)) pResult += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy more non-digits from source to destination. */
|
|
|
|
|
|
|
|
|
|
while (!isdigit(*pSrc))
|
|
|
|
|
if ((*pResult++ = *pSrc++) == 0) return result;
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* Copy the second number. */
|
|
|
|
|
|
|
|
|
|
if (num2 < 0)
|
|
|
|
|
{
|
|
|
|
|
while (isdigit(*pSrc)) *pResult++ = *pSrc++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
while (isdigit(*pSrc)) pSrc += 1;
|
|
|
|
|
(void) strcpy(pResult, num2String);
|
|
|
|
|
while (isdigit(*pResult)) pResult += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy the rest of the source to the destination. */
|
|
|
|
|
|
|
|
|
|
while (TRUE)
|
|
|
|
|
if ((*pResult++ = *pSrc++) == 0) return result;
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* nmSetCurrentLabel --
|
|
|
|
|
*
|
|
|
|
|
* This is a utility procedure called when the current label changes.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Number information is extracted from the label, and the menu
|
|
|
|
|
* is redisplayed.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nmSetCurrentLabel()
|
|
|
|
|
{
|
|
|
|
|
nmGetNums(nmLabelArray[nmCurLabel], &nmNum1, &nmNum2);
|
|
|
|
|
if (nmNum1 >= 0) (void) sprintf(nmNum1String, "%d", nmNum1);
|
|
|
|
|
else nmNum1String[0] = 0;
|
|
|
|
|
if (nmNum2 >= 0) (void) sprintf(nmNum2String, "%d", nmNum2);
|
|
|
|
|
else nmNum2String[0] = 0;
|
|
|
|
|
|
|
|
|
|
/* Set up the menu buttons to refer to this information, and
|
|
|
|
|
* redisplay relevant stuff.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
NMLabelButton.nmb_text = nmLabelArray[nmCurLabel];
|
|
|
|
|
NMNum1Button.nmb_text = nmNum1String;
|
|
|
|
|
NMNum2Button.nmb_text = nmNum2String;
|
|
|
|
|
if (NMWindow != NULL)
|
|
|
|
|
{
|
|
|
|
|
(void) NMredisplay(NMWindow, &NMLabelButton.nmb_area, (Rect *) NULL);
|
|
|
|
|
(void) NMredisplay(NMWindow, &NMNum1Button.nmb_area, (Rect *) NULL);
|
|
|
|
|
(void) NMredisplay(NMWindow, &NMNum2Button.nmb_area, (Rect *) NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* NMGetLabels --
|
|
|
|
|
*
|
|
|
|
|
* Reads in a bunch of labels from the terminal, and makes the
|
|
|
|
|
* first of them "current".
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The old group of labels is re-allocated, and replaced by a new
|
|
|
|
|
* group read from the terminal. The first of the new group is
|
|
|
|
|
* made the current label in the net-list menu.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
NMGetLabels()
|
|
|
|
|
{
|
|
|
|
|
#define MAXLENGTH 200
|
|
|
|
|
char line[MAXLENGTH]; /* Holds label temporarily. */
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
TxPrintf("Enter labels, one per line, terminated by a blank line:\n");
|
|
|
|
|
for (i = 0; i < MAXLABELS; i++)
|
|
|
|
|
{
|
|
|
|
|
if (TxGetLine(line, MAXLENGTH) == NULL) line[0] = 0;
|
|
|
|
|
if (line[0] == 0)
|
|
|
|
|
{
|
|
|
|
|
/* All done. If we got any labels at all, null out all
|
|
|
|
|
* the remaining old labels.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
if (i == 0)
|
|
|
|
|
{
|
|
|
|
|
TxPrintf("No new labels given, so I'll keep the old ones.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for ( ; i < MAXLABELS; i++)
|
|
|
|
|
(void) StrDup(&(nmLabelArray[i]), (char *) NULL);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
(void) StrDup(&(nmLabelArray[i]), line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make the first label current, and extract its two numbers. */
|
|
|
|
|
|
|
|
|
|
nmCurLabel = 0;
|
|
|
|
|
nmSetCurrentLabel();
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* NMNextLabel and NMPrevLabel --
|
|
|
|
|
*
|
|
|
|
|
* These procedures are invoked in response to button pushes
|
|
|
|
|
* over the label button. They make the next or previous label
|
|
|
|
|
* in the list to be the current one.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The current label is changed.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
NMNextLabel()
|
|
|
|
|
{
|
|
|
|
|
if (nmLabelArray[nmCurLabel] == NULL)
|
|
|
|
|
{
|
|
|
|
|
TxError("Use the left button to enter labels first.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if ((nmCurLabel == MAXLABELS-1) || (nmLabelArray[nmCurLabel+1] == NULL))
|
|
|
|
|
nmCurLabel = 0;
|
|
|
|
|
else nmCurLabel += 1;
|
|
|
|
|
nmSetCurrentLabel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
NMPrevLabel()
|
|
|
|
|
{
|
|
|
|
|
if (nmLabelArray[nmCurLabel] == NULL)
|
|
|
|
|
{
|
|
|
|
|
TxError("Use the left button to enter labels first.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (nmCurLabel == 0)
|
|
|
|
|
{
|
|
|
|
|
for (nmCurLabel = MAXLABELS-1; nmLabelArray[nmCurLabel] == NULL;
|
|
|
|
|
nmCurLabel -= 1) /* null loop body */;
|
|
|
|
|
}
|
|
|
|
|
else nmCurLabel -= 1;
|
|
|
|
|
nmSetCurrentLabel();
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* NMChangeNum --
|
|
|
|
|
*
|
|
|
|
|
* This procedure increments or decrements one of the two numbers
|
|
|
|
|
* we've extracted from the current label. It is called in response
|
|
|
|
|
* to a button push inside one of the number buttons.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* One of the numbers is incremented or decremented, and the label
|
|
|
|
|
* information gets redisplayed.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
|
|
|
|
void
|
|
|
|
|
NMChangeNum(window,cmd, nmButton, point)
|
|
|
|
|
MagWindow *window; /* Window in which button was pushed. */
|
|
|
|
|
NetButton *nmButton; /* NetButton where button was pushed. */
|
|
|
|
|
TxCommand *cmd; /* Exact command invoked. */
|
|
|
|
|
Point *point; /* Cursor position in surface coords. */
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
int *pNum;
|
|
|
|
|
|
|
|
|
|
/* Figure out which number is involved. */
|
|
|
|
|
|
|
|
|
|
if (nmButton == &NMNum1Button) pNum = &nmNum1;
|
|
|
|
|
else pNum = &nmNum2;
|
|
|
|
|
|
|
|
|
|
/* Increment or decrement the number. */
|
|
|
|
|
|
|
|
|
|
if (*pNum < 0)
|
|
|
|
|
{
|
|
|
|
|
TxError("That number doesn't exist!\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (cmd->tx_button != TX_LEFT_BUTTON) *pNum += 1;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (*pNum == 0)
|
|
|
|
|
{
|
|
|
|
|
TxError("Can't decrement past zero.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
*pNum -= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fill in the new numbers in the string, and update the screen. */
|
|
|
|
|
|
|
|
|
|
(void) StrDup(&(nmLabelArray[nmCurLabel]),
|
|
|
|
|
nmPutNums(nmLabelArray[nmCurLabel], nmNum1, nmNum2));
|
|
|
|
|
nmSetCurrentLabel();
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* nmGetPos --
|
|
|
|
|
*
|
|
|
|
|
* This is a utility procedure to determine which label position
|
|
|
|
|
* was selected on a button push.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* The return value is a label position. This is determined by
|
|
|
|
|
* dividing the button area into 9 sectors and using the sector
|
|
|
|
|
* number to select a label position. The position is transformed
|
|
|
|
|
* into edit cell coordinates before returning.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
nmGetPos(button, point)
|
|
|
|
|
NetButton *button; /* Button where the mouse was clicked. */
|
|
|
|
|
Point *point; /* Exact surface position within the button. */
|
|
|
|
|
{
|
|
|
|
|
/* The following table maps from sectors to label positions. */
|
|
|
|
|
|
|
|
|
|
static int pos[] =
|
|
|
|
|
{
|
|
|
|
|
GEO_SOUTHWEST, GEO_SOUTH, GEO_SOUTHEAST,
|
|
|
|
|
GEO_WEST, GEO_CENTER, GEO_EAST,
|
|
|
|
|
GEO_NORTHWEST, GEO_NORTH, GEO_NORTHEAST
|
|
|
|
|
};
|
|
|
|
|
int x, y, tmp;
|
|
|
|
|
|
|
|
|
|
/* Divide the button area into thirds in x and y, and figure out
|
|
|
|
|
* which sector contains the point.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
tmp = (button->nmb_area.r_xtop - button->nmb_area.r_xbot + 1)/3;
|
|
|
|
|
if (point->p_x <= button->nmb_area.r_xbot + tmp) x = 0;
|
|
|
|
|
else if (point->p_x >= button->nmb_area.r_xtop - tmp) x = 2;
|
|
|
|
|
else x = 1;
|
|
|
|
|
tmp = (button->nmb_area.r_ytop - button->nmb_area.r_ybot + 1)/3;
|
|
|
|
|
if (point->p_y <= button->nmb_area.r_ybot + tmp) y = 0;
|
|
|
|
|
else if (point->p_y >= button->nmb_area.r_ytop - tmp) y = 2;
|
|
|
|
|
else y = 1;
|
|
|
|
|
return GeoTransPos(&RootToEditTransform, pos[3*y + x]);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* NMPutLabel --
|
|
|
|
|
*
|
|
|
|
|
* This procedure is invoked when the left button is pushed over
|
|
|
|
|
* the button for placing labels. It places the current label
|
|
|
|
|
* in the design at the position of the box, and with an orientation
|
|
|
|
|
* determined by the place where the button was pushed.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* A label is added to the edit cell.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
|
|
|
|
void
|
|
|
|
|
NMPutLabel(window, cmd, nmButton, point)
|
|
|
|
|
MagWindow *window; /* Window where mouse button was pushed.
|
|
|
|
|
* (ignored) */
|
|
|
|
|
NetButton *nmButton; /* Menu button activated. */
|
|
|
|
|
TxCommand *cmd; /* Complete info about command. (ignored) */
|
|
|
|
|
Point *point; /* Cursor position in surface coords. */
|
|
|
|
|
{
|
|
|
|
|
int pos;
|
|
|
|
|
char *text;
|
|
|
|
|
|
|
|
|
|
text = nmLabelArray[nmCurLabel];
|
|
|
|
|
if ((text == NULL) || (*text == 0))
|
|
|
|
|
{
|
|
|
|
|
TxError("Enter some text first (left-button the label entry).\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pos = nmGetPos(nmButton, point);
|
|
|
|
|
CmdLabelProc(text, -1, 1, 0, 0, 0, pos, 0, (TileType)-1);
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* NMReOrientLabel --
|
|
|
|
|
*
|
|
|
|
|
* This procedure is invoked by button pushes inside the net-list
|
|
|
|
|
* menu. It resets the text positions of all labels touching the
|
|
|
|
|
* box.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Label positions are changed.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
|
|
|
|
void
|
|
|
|
|
NMReOrientLabel(window, cmd, nmButton, point)
|
|
|
|
|
MagWindow *window; /* Window that was buttoned. (ignored) */
|
|
|
|
|
NetButton *nmButton; /* Button that was clicked. */
|
|
|
|
|
TxCommand *cmd; /* Detailed info on command (ignored). */
|
|
|
|
|
Point *point; /* Cursor position in surface coords. */
|
|
|
|
|
{
|
|
|
|
|
int pos;
|
|
|
|
|
Rect editArea;
|
|
|
|
|
|
|
|
|
|
/* Make sure that the box exists. */
|
|
|
|
|
|
|
|
|
|
if (!ToolGetEditBox(&editArea)) return;
|
|
|
|
|
pos = nmGetPos(nmButton, point);
|
|
|
|
|
DBReOrientLabel(EditCellUse->cu_def, &editArea, pos);
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* NMFindLabel --
|
|
|
|
|
*
|
|
|
|
|
* Use the current label as a search pattern and create feedback
|
|
|
|
|
* areas for all instances of labels with that pattern.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* New feedback areas get created.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
NMFindLabel()
|
|
|
|
|
{
|
|
|
|
|
char *pattern;
|
|
|
|
|
|
|
|
|
|
pattern = nmLabelArray[nmCurLabel];
|
|
|
|
|
if ((pattern == NULL) || (*pattern == 0))
|
|
|
|
|
{
|
|
|
|
|
TxError("Enter some text first (left-button the label entry).\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
NMShowLabel(pattern, (TileTypeBitMask *) NULL);
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* NMShowLabel --
|
|
|
|
|
*
|
|
|
|
|
* This procedure creates feedback for each instance of a label
|
|
|
|
|
* matching pattern that lies underneath the box. This procedure
|
|
|
|
|
* looks at all cells in the hierarchy, expanded or not.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Feedback areas are created and displayed.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
NMShowLabel(pattern, pMask)
|
|
|
|
|
char *pattern; /* Pattern to be searched for. */
|
|
|
|
|
TileTypeBitMask *pMask;
|
|
|
|
|
{
|
|
|
|
|
SearchContext scx;
|
|
|
|
|
MagWindow *w;
|
|
|
|
|
int nmlLabelFunc();
|
|
|
|
|
|
|
|
|
|
w = ToolGetBoxWindow(&scx.scx_area, (int *) NULL);
|
|
|
|
|
if (w == NULL)
|
|
|
|
|
{
|
|
|
|
|
TxError("There's no box! Please use the box to select\n");
|
|
|
|
|
TxError("the area to search for a label match.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scx.scx_use = (CellUse *) w->w_surfaceID;
|
|
|
|
|
scx.scx_trans = GeoIdentityTransform;
|
|
|
|
|
if (pMask == NULL)
|
|
|
|
|
pMask = &DBAllTypeBits;
|
|
|
|
|
|
|
|
|
|
(void) DBSearchLabel(&scx, pMask, 0, pattern,
|
|
|
|
|
nmlLabelFunc, (ClientData) scx.scx_use->cu_def);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
|
|
|
|
int
|
|
|
|
|
nmlLabelFunc(scx, label, tpath, rootDef)
|
|
|
|
|
SearchContext *scx; /* Describes state of search. */
|
|
|
|
|
Label *label; /* Pointer to label found. */
|
|
|
|
|
TerminalPath *tpath; /* Not used. */
|
|
|
|
|
CellDef *rootDef; /* Root def for search. */
|
|
|
|
|
{
|
|
|
|
|
char mesg[2048];
|
|
|
|
|
Rect rootArea;
|
|
|
|
|
int left;
|
|
|
|
|
|
|
|
|
|
/* Finish generating the full hierarchical name */
|
|
|
|
|
left = tpath->tp_last - tpath->tp_next - 1;
|
|
|
|
|
(void) strncpy(tpath->tp_next, label->lab_text, left);
|
|
|
|
|
tpath->tp_next[left] = '\0';
|
|
|
|
|
(void) sprintf(mesg, "%s;%s",
|
|
|
|
|
DBTypeShortName(label->lab_type), tpath->tp_first);
|
|
|
|
|
|
|
|
|
|
GeoTransRect(&scx->scx_trans, &label->lab_rect, &rootArea);
|
|
|
|
|
GEO_EXPAND(&rootArea, 1, &rootArea);
|
|
|
|
|
DBWFeedbackAdd(&rootArea, mesg, rootDef, 1,
|
|
|
|
|
STYLE_PALEHIGHLIGHTS);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|